模型推理量化#
本页内容8 个部分
模型推理量化(Inference Quantization)的目标,是用更低精度的数字表示模型的权重与推理过程中的中间状态,从而降低显存占用、内存带宽与计算成本,同时尽量保留原模型能力。
这篇笔记只建立基础数值框架:量化什么、INT4 / FP4 / NF4 的区别、scale、outlier、zero-point,以及量化粒度。
1. 为什么要量化#
以一个 70B 参数模型为例,只按十进制 GB 粗略计算权重 payload(不是 GiB,也不含 scale、zero-point、padding、KV cache 和运行时 workspace):
| 精度 | 每参数 | 70B 权重大小 |
|---|---|---|
| FP32 | 4 bytes | ~280 GB |
| FP16 / BF16 | 2 bytes | ~140 GB |
| INT8 | 1 byte | ~70 GB |
| INT4 | 0.5 byte | ~35 GB |
| INT2 | 0.25 byte | ~17.5 GB |
量化的核心并不是“把 FP16 改成 INT4”这么简单,而是:
在尽可能减少 bits 的同时,让量化后的模型尽可能接近原模型,并且真的能在目标硬件上跑得更快。
因此实际优化目标始终是多目标权衡:
2. 量化到底在量什么:W、A、KV#
2.1 Weight(W)#
模型参数本身。例如 W4A16 表示权重使用 4-bit,而 activation 仍保持 16-bit。Weight-only quantization 是 LLM 推理中非常常见的一条路线。
2.2 Activation(A)#
每层计算产生的中间结果。常见记法包括 W8A8、W4A8、W4A16。Activation 的分布随输入变化,通常比静态权重更难量化。
2.3 KV Cache#
自回归生成时,Attention 需要保存历史 token 的 Key / Value。上下文越长,KV Cache 越大,因此也存在 FP16 → FP8 / INT8 / INT4 的 KV Cache quantization。
可以把推理量化先拆成:
LLM Inference Quantization
│
┌────┼────┐
│ │ │
Weight Act. KV Cache
│ │ │
W4/W8 A8/A4 KV8/KV4
3. INT4、FP4、NF4 有什么区别#
它们都可能只用 4 bit,但“这 16 个 bit pattern 对应哪些数值”完全不同。
3.1 INT4:均匀整数网格#
Signed INT4 可以理解为一组基本均匀的离散整数等级,例如:
-8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
相邻等级间距固定,结构简单、规则、硬件友好。
3.2 FP4:极低比特浮点#
浮点数大体具有:
sign | exponent | mantissa
一种常见 FP4 格式是 E2M1:1 bit sign + 2 bit exponent + 1 bit mantissa。因为有 exponent,FP4 的可表示值不是均匀排列的:小数量级附近可以更密,大数量级更稀疏,从而用很少的 bits 获得更大的动态范围。
直觉上:
INT4: |--|--|--|--|--|--|--|
基本均匀
FP4: |-|-|--|----|--------|
小数密集 大数稀疏
3.3 NF4:面向神经网络权重分布#
NF4(NormalFloat 4-bit)不是简单的 E2M1 浮点格式。它使用针对神经网络权重分布设计的非均匀 quantization levels,常见于 QLoRA 等场景。
| 格式 | 核心思想 |
|---|---|
| INT4 | 均匀整数网格 |
| FP4 | sign + exponent + mantissa,强调动态范围 |
| NF4 | 针对神经网络权重分布设计的非均匀 4-bit levels |
3.4 MXFP4 / block scaling 的直觉#
4 bit 本身的信息容量非常低,因此一种重要思路是让一小组 FP4 数值共享额外的 scale:
Block
┌─────────────────────────┐
│ shared scale │
│ │
│ FP4 FP4 FP4 FP4 FP4 ... │
└─────────────────────────┘
这类 block-scaled 表示在存储成本、动态范围与硬件实现之间做进一步权衡。
4. Scale:量化的核心#
以下假设 。全零 tensor 应单独处理或采用非零安全 scale,不能直接用 作除数。
Scale 可以理解为:整数世界的一格,在真实浮点世界里到底有多长。
假设一组权重:
使用对称 INT4,并令量化整数范围为 。最大绝对值是 ,于是可以选择:
量化:
反量化:
例如 :
恢复得到:
因此:
original quantized dequantized
0.4 → 3 → 0.386
就是这次离散化带来的 quantization error。
4.1 Scale 的 trade-off#
如果 scale 很大,一格覆盖的真实区间很宽:
- 可表示 range 更大
- resolution 更差
如果 scale 很小:
- resolution 更高
- 可表示 range 更小,更容易 clipping
即:
这也是低比特量化的基本矛盾之一。
5. 为什么 Outlier 很麻烦#
考虑:
绝大多数值都位于 ,但存在一个 的 outlier。
如果 scale 由最大绝对值决定:
那么:
结果可能近似变成:
-0.12 → 0
0.08 → 0
-0.15 → 0
0.21 → 0
0.09 → 0
4.80 → 7
为了覆盖一个异常值,大量正常的小值失去了有效分辨率。
Outlier 的危险不只是它自己难表示,而是它会改变共享 scale,从而伤害同组里的其他值。
6. Zero-point:把整数网格平移到数据上#
前面的对称公式默认:
但数据并不总是围绕 0 对称。例如 activation 可能位于:
如果仍强制使用以 0 为中心的 signed INT4,那么负数一侧的大量量化等级会被浪费。
于是引入 zero-point :
反量化:
zero-point 的含义是:
整数空间里的哪个整数,代表真实浮点空间里的 0。
6.1 Symmetric quantization#
数据近似围绕 0:
float: -a -------- 0 -------- +a
integer: -7 -------- 0 -------- +7
通常 ,计算简单、硬件友好。
6.2 Asymmetric quantization#
如果数据实际位于 ,可以直接把整个整数网格平移过去,更充分利用有限的量化等级。这时通常 。
更完整的 affine quantization 写成:
其中 clip / saturation 表示:如果计算结果超出整数格式能表达的范围,就截断到边界。
7. Granularity:谁和谁共享一把尺子#
Scale 越贴合局部数据分布,通常量化误差越小;但 scale 本身也需要存储,而且过细的粒度会增加实现复杂度。
7.1 Per-tensor#
整个 tensor 共用一个 scale:
[ tensor ]
↓
1 scale
metadata 最少,但一个 outlier 就可能影响整个 tensor。
7.2 Per-channel#
每个 channel 使用自己的 scale:
[channel 1] → s₁
[channel 2] → s₂
[channel 3] → s₃
[channel 4] → s₄
不同 channel 的动态范围不再互相干扰。
7.3 Per-group / Group-wise#
进一步把 channel 内的权重分成小组:
[128 weights][128 weights][128 weights] ...
↓ ↓ ↓
s₁ s₂ s₃
因此 INT4, group size = 128 可以理解为:
权重本身使用 4-bit 表示,每 128 个权重共享一套量化参数(典型情况下至少包括 scale)。
7.4 为什么不每个 weight 一个 scale?#
因为 scale 自己也占空间。假设一个 INT4 weight 配一个 FP16 scale:
weight = 4 bit
scale = 16 bit
--------------
total = 20 bit
压缩意义基本消失。
若 128 个 INT4 weights 共用一个 FP16 scale,则平均额外开销只有:
平均约为:
因此 group size 本身也是 trade-off:
8. 一张总览图#
一个基础量化方案可以从四个维度理解:
Quantization
│
┌───────────────┼───────────────┐
│ │ │
Format Mapping Granularity
│ │ │
INT / FP / NF scale + zero tensor
8/4/2 bit point channel
group
更紧凑地说:
其中最值得保留的几个直觉是:
- bit-width 决定有多少离散状态可用。
- scale 决定整数的一格在真实数值空间里有多长。
- zero-point 决定整数网格放在真实数轴的什么位置。
- granularity 决定多少数值共享同一把“尺子”。
- outlier 会通过共享 scale 伤害同组的正常值。
- 最终评价量化方案不能只看数学误差,还必须看真实硬件上的 kernel、带宽与吞吐。
相关资料与下一步:低比特格式、AWQ、QuaRot / SpinQuant。