推理与量化 / 低比特数值与量化基础 原理笔记入门 6 分钟阅读 查看源文件 ↗

低比特数值格式#

本页内容7 个部分

在学习量化算法之前,先要回答一个更基础的问题:低 bit 到底如何表示数字?

4 bit 最原始的含义只有:

24=162^4=16

也就是说,一个 4-bit code 只有 16 种状态。但 4 bit 并没有规定这 16 个状态分别代表哪些真实数值。INT4、FP4、NF4 之所以不同,本质上是因为它们用不同方式把有限的 bit pattern 映射到数轴。

这篇笔记只讨论 low-bit number representation 本身,不进入具体量化算法。


1. Bit-width:码点是一种预算#

nn bit 一共提供:

2n 个可区分状态\boxed{2^n\text{ 个可区分状态}}

例如 4 bit:

0000
0001
0010
...
1110
1111

一共只有 16 种 pattern。我们可以让它们表示均匀整数,也可以表示浮点数,甚至可以直接查一张任意的 16-entry codebook。

因此第一条基本原则是:

bit width≠number format\boxed{\text{bit width}\neq\text{number format}}

低 bit 表示的核心问题其实是:

有限的 reconstruction levels 应该放在数轴的哪些位置?

可以把每一个 reconstruction level 看成一份表示能力预算。4 bit 只有 16 份预算,把更多码点放在某个数值区域,就意味着其他区域必须更稀疏,或者干脆无法覆盖。


2. Integer:均匀网格#

最直接的方法是让 code 对应等间距整数。

例如 signed INT4 的 two's-complement 编码可以表示:

−8,−7,…,−1,0,1,…,7-8,-7,\ldots,-1,0,1,\ldots,7

数轴上的相邻整数间距固定:

-8 -7 -6 -5 -4 -3 -2 -1  0  1  2  3  4  5  6  7
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

因此 integer family 的核心几何特征是:

uniform grid\boxed{\text{uniform grid}}

2.1 Signed 与 Unsigned#

如果数据同时包含正负值,可以使用 signed integer;如果数据天然非负,则可以把全部码点放在正半轴。

例如 UINT4:

q∈{0,1,…,15}q\in\{0,1,\ldots,15\}

0  1  2  3  4  5  ...  13 14 15
|  |  |  |  |  |       |  |  |

同样是 4 bit,signed / unsigned 的区别本质上也是:把 16 个码点预算分配到数轴的什么位置。

2.2 Code 不等于真实 reconstruction value#

在神经网络量化里,INT4 code 通常还会配合 scale。假设使用对称整数范围:

q∈[−7,7]q\in[-7,7]

真实重建值可以写成:

x^=sq\boxed{\hat{x}=sq}

所以需要区分:

  • qq:低 bit code;
  • x^\hat{x}:反量化后真正参与数值计算的 reconstruction value。

如果为了严格正负对称而使用 [−7,7][-7,7],那么 two's-complement INT4 中的 -8 pattern 不被量化器使用,实际只有 15 个有效 reconstruction levels。这也说明:物理上有 16 个 bit pattern,不代表某个具体 quantizer 一定会使用全部 16 个。


3. Floating Point:用 exponent 换动态范围#

Floating point 不再追求数轴上的等间距,而是把 bits 拆成:

sign∣exponent∣mantissa\boxed{\text{sign}\mid\text{exponent}\mid\text{mantissa}}

忽略特殊值和编码细节,可以粗略理解成:

x≈(−1)s×2e×(1+m)x\approx(-1)^s\times2^e\times(1+m)

其中:

  • sign 决定正负;
  • exponent 决定数量级,因此主要控制 dynamic range;
  • mantissa 决定同一数量级内部能分多细,因此主要控制 local precision。

所以:

更多 exponent bits⇒更大的 dynamic range\boxed{\text{更多 exponent bits}\Rightarrow\text{更大的 dynamic range}}

更多 mantissa bits⇒更高的局部精度\boxed{\text{更多 mantissa bits}\Rightarrow\text{更高的局部精度}}

3.1 常见格式#

格式 Sign Exponent Mantissa 直觉
FP16 1 5 10 标准半精度
BF16 1 8 7 保留接近 FP32 的 exponent range
FP8 E4M3 1 4 3 更偏 precision
FP8 E5M2 1 5 2 更偏 range
FP4 E2M1 1 2 1 极低 bit 浮点

E4M3 与 E5M2 很能体现浮点设计的 trade-off:二者都是 8 bit,但 E5M2 多给 exponent 一位,因此覆盖范围更大;E4M3 多给 mantissa 一位,因此局部表示更细。

3.2 FP 的网格为什么不均匀#

Integer 更像:

|--|--|--|--|--|--|--|--|

Floating point 更像:

| | | |  |  |   |    |        |

随着 magnitude 增大,相邻 representable values 的绝对间距也会增大。因此 floating point 更接近保持 relative precision,而 uniform integer 更接近保持固定的 absolute spacing。

这也意味着 FP 并不天然比 INT 更适合低 bit。总状态数固定时,FP 必须拿出一部分编码能力表示 exponent。如果数据本身动态范围并不大,而主要集中在一个有限区间,那么为远端数量级预留的表示能力可能并不划算。

低 bit 下没有天然“更高级”的格式,只有 reconstruction grid 是否匹配数据分布。


4. Codebook / Non-uniform Formats:直接设计 reconstruction levels#

既然 4 bit 只有 16 个 code,那么并不一定需要通过整数公式或 exponent/mantissa 来解释它们。最自由的方法是直接定义:

q⟶LUT[q]\boxed{q\longrightarrow LUT[q]}

例如:

0000 → -1.00
0001 → -0.70
0010 → -0.52
0011 → -0.39
...
1110 → +0.72
1111 → +1.00

这就是 codebook quantization。16 个 reconstruction points 可以完全不等间距,因此可以根据数据分布把更多码点放到高概率区域。

4.1 NF4#

上面的 LUT 只是示意值,不是 NF4 的实际 codebook。NF4 的码点按正态分位数构造并包含精确的零;它不是对任意权重分布、任意误差指标都最优。

NF4(NormalFloat 4-bit)可以从这个视角理解:它不是简单缩小版的 IEEE floating point,而是一种面向近似 normal / bell-shaped neural-network weight distribution 的非均匀 4-bit representation。

Uniform grid:

|----|----|----|----|----|----|

Distribution-aware non-uniform grid 的直觉则是:

|------|---|-|-|-|-|---|------|
             ↑
          中心更密

如果数据大量集中在中心区域,就可以把更多 reconstruction levels 分配在那里,提高有限 bit budget 的利用率。

4.2 自由度与 decode 成本#

Codebook 的优势是 reconstruction levels 几乎可以任意设计;代价是 decode 往往需要 data-dependent lookup:

q→LUT[q]q\rightarrow LUT[q]

相比之下,uniform integer 一类格式可能只需要简单 arithmetic。于是低 bit format 的设计不只是数值误差问题,还天然包含一个工程 trade-off:

更自由的 grid↔更简单的 decode\boxed{\text{更自由的 grid}\leftrightarrow\text{更简单的 decode}}


5. Block Scaling / Microscaling:把动态范围交给共享 metadata#

单个 4-bit value 的表示能力非常有限。如果要求每个 value 独自同时承担很大的 dynamic range 和很高的 local precision,通常很困难。

现代低 bit 表示常用的办法是:把数据分成小 block,让多个低 bit values 共享额外的 scale。

Block 0
┌──────────────────────────┐
│ shared scale = s₀        │
│ 4b  4b  4b  4b  ...     │
└──────────────────────────┘

Block 1
┌──────────────────────────┐
│ shared scale = s₁        │
│ 4b  4b  4b  4b  ...     │
└──────────────────────────┘

概念上:

x^i=sg f(qi)\boxed{\hat{x}_i=s_g\,f(q_i)}

其中:

  • qiq_i 是低 bit element code;
  • f(qi)f(q_i) 是 element format 的 reconstruction rule;
  • sgs_g 是整个 block 共享的 scale。

可以把两者理解成:

sg⏟block magnitude×f(qi)⏟local shape\underbrace{s_g}_{\text{block magnitude}} \times \underbrace{f(q_i)}_{\text{local shape}}

这样 element format 不再需要独自覆盖整个 tensor 的数量级变化。

5.1 MX / Microscaling#

MX family 可以从这个框架理解为:

low-bit element format+shared block scale\boxed{\text{low-bit element format}+\text{shared block scale}}

MXFP4 常用 32 个 E2M1 元素共享一个 E8M0 scale;NVFP4 则采用 16 个 E2M1 元素共享 E4M3 scale,并另有 tensor scale。因此 FP4 与 MXFP4 不是同一层概念:前者描述单个 element 如何编码,后者进一步规定一组 elements 如何共同表示数值。

5.2 NVFP4#

NVFP4 同样属于 block-scaled FP4 的思路。可以用三级结构建立直觉:

Tensor
│
├── tensor / global scale
│
├── Block 0
│     ├── FP8 E4M3 block scale
│     └── 16 × FP4 E2M1 values
│
├── Block 1
│     ├── FP8 E4M3 block scale
│     └── 16 × FP4 E2M1 values
│
└── ...

概念上:

x^i≈FP4E2M1(qi)×sblockE4M3×stensor\boxed{ \hat{x}_i \approx FP4_{E2M1}(q_i) \times s_{block}^{E4M3} \times s_{tensor} }

这里不同层次负责不同问题:

  • FP4 E2M1:描述 block 内部的低 bit local value;
  • FP8 E4M3 block scale:让小 block 适配自己的局部 magnitude;
  • tensor/global scale:承担更高层次的整体动态范围。

NVFP4 使用较细的 block(16 elements),其基本 trade-off 是:

smaller block⇒更好的 local adaptation↔更多 scale metadata\boxed{ \text{smaller block} \Rightarrow \text{更好的 local adaptation} \leftrightarrow \text{更多 scale metadata} }

这也是 block scaling 的一般规律。


6. 统一视角:Code + Reconstruction + Metadata#

到这里,各种低 bit representation 可以放进同一个框架:

Low-bit Representation=Code Space+Reconstruction Rule+Shared Metadata\boxed{ \text{Low-bit Representation} = \text{Code Space} + \text{Reconstruction Rule} + \text{Shared Metadata} }

Representation Code Space Reconstruction Rule Shared Metadata
INT4 4-bit integer uniform integer grid 无或外部 scale
FP4 E2M1 4-bit FP code sign/exponent/mantissa decode 无
NF4 4-bit index non-uniform codebook / LUT 常与 block scale 配合
MXFP4 FP4 element FP4 decode × block scale shared block scale
NVFP4 FP4 E2M1 element FP4 × local scale × higher-level scale FP8 block scale + tensor/global scale

这张表最重要的不是记格式名字,而是形成三个问题:

  1. 有多少 code? —— bit-width 决定状态预算。
  2. 每个 code 在数轴上对应哪里? —— reconstruction rule 决定 grid geometry。
  3. 一组 values 还能共享什么信息? —— metadata 帮助低 bit element 获得额外 dynamic range / local adaptation。

最后还要严格区分:

Number Format≠Quantization Scheme\boxed{\text{Number Format}\neq\text{Quantization Scheme}}

INT4、FP4 E2M1 主要是在描述 number format / code space;而一个完整的神经网络 quantization scheme 往往还需要进一步指定 scale、zero-point、granularity、calibration、clipping,以及最终的硬件 decode 路径。

因此学习顺序最好是:

low-bit number formats
        ↓
quantization mapping / scale / zero-point / granularity
        ↓
quantization algorithms
        ↓
hardware-aware deployment

先理解“这些 bits 如何表示数字”,后面的量化方法才有统一的坐标系。

参考资料#

QLoRA:NF4 的定义、NVIDIA:NVFP4 与 MXFP4 的格式比较。格式的特殊值、scale 编码与支持的算子应以具体实现为准。

相关阅读路线

理解低比特推理 ↗