跳到主内容
@wquguru
精选85Avi Chawla技巧与观点

8种LLM精度格式详解:从FP32到NF4

8 LLM precision formats, clearly explained:

原文
发到 X
推荐理由

做模型推理和量化的同学必看,这篇把FP32到NF4的精度格式讲得清清楚楚,还附了KV缓存和DeepSeek V4的注意力设计,值得收藏。

8 LLM precision formats, clearly explained:

8种LLM精度格式,清晰解释:

(bookmark this)

(收藏本文)

A 12GB consumer GPU cannot hold a 7B model in FP32, which needs 28GB just for the weights.

一块12GB的消费级GPU无法在FP32下容纳7B模型,仅权重就需要28GB。

Yet, running `ollama run mistral` on that card works anyway, because Ollama pulls a 4-bit build that fits in about 4GB.

然而,在该显卡上运行`ollama run mistral`仍然可行,因为Ollama会拉取一个4位构建,仅占用约4GB。

Every format below FP32 does the same thing, i.e., it trades numeric detail for memory.

FP32以下的每种格式都做同样的事情,即用数值细节换取内存。

The visual below explains 8 such LLM precision formats:

下图解释了8种这样的LLM精度格式:

Before we dive into them, some background:

在深入探讨之前,先了解一些背景:

A floating-point number splits its bits three ways.

浮点数将其位分为三部分。

One sign bit, then exponent bits that set how large a value can get, then mantissa bits that set how finely nearby values are told apart.

一个符号位,然后是指数位,决定数值可以达到多大,然后是尾数位,决定相邻数值的区分精细度。

  • Reducing exponent bits causes large values to overflow. - Reducing mantissa bits causes nearby values to round into each other.
  • 减少指数位会导致大数值溢出。 - 减少尾数位会导致相邻数值相互舍入。

Different formats focus on different sides.

不同格式侧重于不同方面。

1) FP32 has 8 exponent bits and 23 mantissa bits.

1) FP32有8个指数位和23个尾数位。

It costs 4 bytes per parameter and by default still holds the optimizer states even in low-precision runs, because gradient updates are small enough that 16-bit storage would round them away.

每个参数占用4字节,即使在低精度运行中,默认情况下仍保留优化器状态,因为梯度更新很小,16位存储会将它们舍入掉。

2-3) BF16 and FP16 are both 16 bits and split them in opposite directions.

2-3) BF16和FP16都是16位,但分配方向相反。

BF16 keeps FP32's 8 exponent bits and drops to 7 mantissa bits, so casting down never overflows.

BF16保留FP32的8个指数位,将尾数位降至7位,因此向下转换时不会溢出。

FP16 keeps 10 mantissa bits and only 5 exponent bits, so it resolves values eight times more finely but covers a far smaller range, roughly up to 65504.

FP16保留10个尾数位和仅5个指数位,因此其分辨率精细8倍,但覆盖范围小得多,大约到65504。

Small gradients fall below that floor and flush to zero, which is why FP16 training scales the loss up before the backward pass and divides it back out before the update.

小梯度会低于该下限并刷新为零,这就是FP16训练在反向传播前缩放损失,并在更新前将其除回的原因。

4) TF32 sits between them and never touches memory.

4) TF32介于两者之间,且从不触及内存。

It computes with FP32's exponent and FP16's mantissa inside the tensor core, so matmuls get faster while storage stays exactly the same.

它在张量核心内使用FP32的指数和FP16的尾数进行计算,因此矩阵乘法更快,而存储完全相同。

5) FP8 ships two layouts because one is not enough.

5) FP8提供两种布局,因为一种不够用。

  • E4M3 reaches 448 and carries weights and activations, - E5M2 reaches 57344 and carries gradients, which span more orders of magnitude.
  • E4M3最大可达448,承载权重和激活值, - E5M2最大可达57344,承载梯度,梯度跨越多个数量级。

6-7) INT8 and INT4 leave floating point behind.

6-7) INT8和INT4告别浮点。

Values map onto 256 or 16 evenly spaced levels with the scale factor stored separately.

值映射到256或16个均匀间隔的级别,比例因子单独存储。

But even spacing is a problem here. A single outlier stretches the range so far that every ordinary value falls inside the first step and rounds to zero.

但均匀间隔在这里是个问题。一个离群值会将范围拉伸得如此之远,以至于所有普通值都落在第一步内并舍入为零。

This creates most problems on activations, and LLM[.]int8 and SmoothQuant were built to handle this.

这在激活值上造成最多问题,而LLM[.]int8和SmoothQuant正是为此而构建的。

8) NF4 spaces its 16 levels unevenly, following the distribution that pretrained weights actually have.

8) NF4将其16个级别不均匀地分布,遵循预训练权重实际具有的分布。

That allows QLoRA to hold the frozen base model in 4 bits while LoRA adapters train in BF16 on top.

这使得QLoRA能够将冻结的基础模型保持在4位,而LoRA适配器在其上以BF16进行训练。

Halving the bits halves the memory, but the bits have to come out of either the exponent or the mantissa.

将位数减半会减少内存,但位数必须从指数或尾数中扣除。

If you take them from the exponent, large values cannot go past a certain range.

如果从指数中扣除,大数值将无法超过一定范围。

If you take them from the mantissa, values that were close become identical, and that error compounds layer after layer.

如果从尾数中扣除,原本接近的值会变得相同,并且这种误差会逐层累积。

That said, weights are only one part of the memory costs that quantization addresses.

尽管如此,权重只是量化所解决的内存成本的一部分。

The KV cache is the other, and it behaves differently, since it grows with every generated token.

KV缓存是另一部分,其行为不同,因为它随着每个生成的标记而增长。

On long contexts, it outgrows the weights entirely.

在长上下文中,它完全超过权重的规模。

I wrote a full walkthrough of that side of inference.

我写了一篇关于推理这一方面的完整指南。

It covers the split between prefill, which is compute-bound and processes all input tokens in parallel, and decode, which is memory-bound and produces one token at a time.

它涵盖了预填充(prefill)和解码(decode)之间的区别,预填充是计算密集型的,并行处理所有输入标记,而解码是内存密集型的,一次生成一个标记。

It goes through what the KV cache is useful for, its costs, and how DeepSeek V4 redesigned attention around the cache itself to cut it to a tenth of the previous version at 1M context.

它详细介绍了KV缓存的用途、其成本,以及DeepSeek V4如何围绕缓存重新设计注意力机制,在1M上下文中将其削减到前一版本的十分之一。

Read it below.

请在下方阅读。

更进一步:量化金融体系

看懂新闻只是起点——沿量化金融路径,把它变成能交付的工程能力

进入量化体系 →

相似阅读

关联信息,但可能不是同一事件