LLM 量化精读笔记 · 04 量化粒度、校准与离群值
对应:Inference Engineering Ch5 的 “Granularity matters” 部分;LLM.int8() 的 outlier 分析;MIT 6.5940 Lecture 5 的逐层/逐通道量化内容。 学完本章你应该能:① 解释 per-tensor / per-channel / per-group 的差别,并手算各自的有效位宽与存储开销;② 说出校准是什么、校准集怎么选、常见统计量(min/max、分位数、熵、MSE)的取舍;③ 复述 LLM.int8() 的 outlier 统计结论(6.0、25%、6%、6.7B、0.1%、75%)并解释为什么 outlier 致命;④ 把"粒度 × 校准 × outlier"三条线串成一张决策表。
目录(本章) #
- 本章目标
- 从 02 章到本章:范围利用率是主线
- 粒度光谱:per-tensor / per-channel / per-group
- 有效位宽与存储开销:动手算
- 校准(Calibration)
- 离群值问题(Outliers)
- 敏感性分析:谁更怕量化
- 决策表:什么时候用哪种组合
- 本章小结
- 习题与解答
- 延伸阅读
1. 本章目标 #
03 章确定了"用哪种格式",本章回答"每个 scale 管多大范围、scale 怎么选、遇到 outlier 怎么办"——这是从"会量化"到"量化得好"的分水岭。
03 章:格式(FP8 / FP4 / MXFP…)$\to$码本结构 04 章:粒度(tensor / channel / group)$\to$码本拆成几份、每份自己的 scale 校准(怎么选 scale)$\to$码本对齐真实分布 outlier(分布里的"刺")$\to$为什么要拆、为什么难选
2. 从 02 章到本章:范围利用率是主线 #
02 章算过:量化范围只用了$1/2^k$,有效位宽就损失 k bit。本章所有内容都是这句话的三个推论:
- 粒度:一个 scale 管的元素越少,每个元素越可能"接近自己的范围"$\to$范围利用率高。
- 校准:scale 选得好不好,直接决定范围利用率;选 min/max 还是分位数,是在"截断风险"和"有效位宽"之间取舍。
- outlier:outlier 把范围撑大,把正常值挤进一小块网格$\to$范围利用率灾难性下降。
3. 粒度光谱:per-tensor / per-channel / per-group #
3.1 三个层次 #
设权重矩阵$W \in \mathbb{R}^{C_{\text{out}} \times C_{\text{in}}}$:
| 粒度 | 一个 scale 覆盖 | 数量 | 典型适用 |
|---|---|---|---|
| per-tensor | 整个张量 | 1 | 小模型、FP8 W8A8 的激活 |
| per-channel(权重) | 每个输出通道一行 | $C_{\text{out}}$ | 4-bit 权重的默认起点 |
| per-channel(激活) | 每个输入通道一列 | $C_{\text{in}}$ | 激活量化常用 |
| per-group | 每 G 个连续元素 | $C_{\text{out}} \times C_{\text{in}} / G$ | 4-bit 权重的主流($G=32/64/128$) |
图示(权重 W,行 = 输出通道):
per-tensor: per-channel: per-group(G=2):
┌─────────────┐ ┌─────┬─────┬─────┐ ┌──┬──┬──┬──┬──┬──┐
│ 同一 scale │ │ s1 │ s1 │ s1 │ │s1│s1│s2│s2│s3│s3│
│ s 覆盖全部 │ │ s2 │ s2 │ s2 │ │s4│s4│s5│s5│s6│s6│
│ │ │ s3 │ s3 │ s3 │ │… │… │… │… │… │… │
└─────────────┘ └─────┴─────┴─────┘ └──┴──┴──┴──┴──┴──┘
3.2 为什么权重按"输出通道"、激活按"输入通道" #
矩阵乘$Y = WX$,Y 的第 j 行由 W 的第 j 行与 X 的所有列相乘:
$$ Y[j, :] = W[j, :] \cdot X $$- 权重 W 的第 j 行只影响输出的第 j 行$\to$每行一个 scale 是"误差只影响自己那行输出"的最细合理划分。
- 激活 X 的第 i 列与 W 的所有行相乘$\to$每列一个 scale 是同理。
粒度再细(per-element)就退化回"不用量化"了。
3.3 group 量化:per-channel 的"中间态" #
per-channel 在通道数少时(如某些投影层$C_{\text{in}}$只有几百)仍然太粗。group 量化把一行切成若干段,每段(如 128 个元素)一个 scale:
$INT4 + group=128$:每个 scale 管 128 个权重
这是 GPTQ/AWQ 的默认形态(通常 group 128 + FP16 scale,或 group 32/64 用于激进场景)。
4. 有效位宽与存储开销:动手算 #
4.1 有效位宽公式 #
$$ b_{\text{eff}} = b + \text{scale\_bits} / G $$其中 b 是数据位宽,G 是每个 scale 覆盖的元素数。直觉:scale 是"额外的位",摊到每个元素头上。
4.2 数值表(b = 4) #
| 粒度 | G | scale 格式 | $b_{\text{eff}}$ | 相对纯 4-bit 的存储开销 |
|---|---|---|---|---|
| per-tensor | 全部 | FP32 | ≈ $4.000$ | $\sim 0\%$ |
| per-channel($C=4096$) | 4096 | FP16 | ≈ $4.004$ | 0.1% |
| per-group | 256 | FP16 | 4.0625 | 1.6% |
| per-group | 128 | FP16 | 4.125 | 3.1% |
| per-group | 64 | FP16 | 4.25 | 6.3% |
| per-group | 32 | FP16 | 4.5 | 12.5% |
| per-group | 16 | FP16 | 5.0 | 25% |
算例($group=128$、FP16 scale):
每个 128 元素块:128×4 bit 数据$+ 16 bit scale = 528 bit$ 每元素平均= $528/128 = 4.125 bit$
关键 tradeoff:group 越小,质量越好、开销越大。业界在 4-bit 权重上基本收敛到 $group=128$(质量/开销平衡) 和$group=32$(激进但质量仍可接受)。
4.3 一个常见误区 #
“4-bit 模型 = 正好 4 倍压缩"是错的。真实的模型文件大小要看有效位宽:
70B 模型: 纯$FP16 = 140 GB$ $INT4 group=128 = 70e9 \times 4.125/8 \approx 36.1 GB$(不是 35 GB)
$$ INT4 group=32 = 70e9 \times 4.5/8 \approx 39.4 GB $$这也是为什么估算器/模型卡片的”$4-bit = 75\%$节省"是理想值,实际要加 scale 开销。
5. 校准(Calibration) #
5.1 什么是校准 #
校准 = 用一小部分代表数据跑一遍模型,统计每层权重/激活的分布,从而确定量化参数(scale、zero-point、范围):
流程:
- 选校准集(通常$128\sim 512$条样本)
- 前向传播,记录每层输入激活 X(和需要时的权重分布)
- 按某种统计量计算 scale / 范围
- 量化并验证
注意:校准是"无梯度"的,只统计分布,不更新权重。GPTQ/AWQ 的"校准集"就是这个东西。
5.2 校准集怎么选 #
标准做法(GPTQ/AWQ 论文):从预训练语料里取$\sim 128$条、每条 2048 token 的序列。
选集的三个原则:
- 覆盖任务分布:做代码任务就用代码语料校准,别全用新闻语料。
- 避免单任务过拟合:AWQ 特意从预训练数据取校准集,而不是目标任务数据——防止量化参数"记住"评测集。
- 规模适中:128 条左右足够统计分布;太多没用,太少噪声大。
5.3 统计量选择:min/max vs 分位数 vs 熵 vs MSE #
给定一组校准激活,scale 怎么定?
| 方法 | 规则 | 优点 | 缺点 |
|---|---|---|---|
| min/max | $s = \max\vert x\vert / 2^{b-1}$ | 无截断 | 被 outlier 撑大,有效位宽被稀释 |
| 分位数 | $s = P99.99 / 2^{b-1}$ | 抗 outlier | 需要选分位点(99.9%? 99.99%?) |
| 熵(entropy) | 最小化量化前后分布 KL 散度(TensorRT 的做法) | 直接对齐分布 | 计算重、实现复杂 |
| MSE 最优(ACIQ 等) | 最小化$E[(x-\hat{x})^{2}]$ | 理论最优 | 需要分布假设/搜索 |
工程上的默认:权重用 min/max(权重 outlier 少),激活用分位数(如 99.99% / 99.999%)。neural-compressor 等工具里 SmoothQuant 的默认分位点就是 99.999%。
5.4 校准与验证要分开 #
校准集:用于选 scale(训练量化器) 验证集:用于测量化质量(perplexity / 基准 / 自定义评测,10 章)
用评测集当校准集是作弊:量化参数会"记住"评测数据,验证分数虚高,上线后现原形。
5.5 常见陷阱 #
- 校准集只有几十条$\to scale$噪声大
- 校准集与部署流量分布差异大(聊天模型用文档语料校准)$\to$上线退化
- 只校准权重不校准激活$\to W8A8$时激活 scale 拍脑袋
- 复现性:库与库之间 round/百分位实现不同,量化结果不可比
6. 离群值问题(Outliers) #
6.1 LLM.int8() 的观测(论文核心数字) #
Dettmers et al.(2022)系统统计了 Transformer 激活的 outlier:
outlier 定义:$|activation| \ge 6.0$,且出现在≥ $25\%$的层、≥ $6\%$的序列维度
关键发现:
- 规模相变:$\sim 6.7B$参数之前没有系统性 outlier;超过后,outlier 出现在所有层
- outlier 出现后:在约 75% 的序列维度上持续存在(同维度反复出现)
- outlier 占比极小:约 0.1% 的特征
- outlier 维度数量少:13B 以下模型通常≤ $7$个维度
- 作用关键:这些 outlier 对 softmax 的大概率输出至关重要(不是噪声)
6.2 为什么 outlier 对量化是致命的 #
回到 02 章的模型:outlier 让 max|X| 巨大(比如 1000+),而 99.99% 的正常值在$\pm 60$内:
8-bit 对称量化,$s = \max|X|/127 = 1000/127 \approx 7.87$ 正常值$\pm 60$只用到$\pm 60/7.87 \approx \pm 7.6$个量化层级$\to$有效位宽≈ $\log_2(16) \approx 4 bit$
outlier 用 0.1% 的特征,偷走了正常值$\sim 4 bit$的有效精度。 这正是 LLM.int8()、SmoothQuant、AWQ、per-group 全部要解决的问题。
6.3 SmoothQuant 的补充统计 #
SmoothQuant 论文(Xiao et al., 2023)对 OPT-175B 激活的统计:
99.99% 的激活值落在$[-60, 60]$ 但最大值可以超过 1000(甚至更大) $\to$激活分布是"尖峰 + 重尾",min/max 校准必然翻车
这解释了为什么激活量化比权重量化难:权重分布相对规整,激活分布带系统性 outlier。
6.4 对付 outlier 的四种策略(本系列路线图) #
| 策略 | 思路 | 代表方法 | 章节 |
|---|---|---|---|
| 分离 | 把 outlier 单独留在高精度 | LLM.int8() 混合精度分解 | 07 |
| 迁移 | 把量化难度从激活搬到权重 | SmoothQuant | 07 |
| 保护 | 识别并保护显著通道/权重 | AWQ | 06 |
| 细分 | 用更细的网格容纳局部动态范围 | per-group、MXFP8 | 04、03 |
7. 敏感性分析:谁更怕量化 #
7.1 层与模块之间的差异 #
Inference Engineering 的敏感性排序(02 章已提):
权重(线性层)< 激活 < KV cache < attention(softmax)
更细的观察(GPTQ 论文与后续工作):
- attention 的投影层比 FFN 更敏感(信息压缩集中);量化时通常优先给 attention 层更多位/更细粒度。
- 首层与末层更敏感(输入输出直接参与表示);中间层相对鲁棒。
- softmax 之前的 QK 点积不能量化(指数运算放大误差)——生产上 attention 留在 FP16。
7.2 通道之间的差异:激活幅度 = 重要性 #
AWQ 的核心观察:某个权重通道的重要性与对应输入激活的幅度强相关:
输入通道 j 的激活幅度大$\to$权重 W[:, j] 对输出贡献大$\to$量化误差影响大
所以 AWQ 用 $s_{j} = (\max|X_{j}|)^\alpha$($\alpha$网格搜索)给"重要通道"配更精细的缩放——量化不是"平均用力",而是把误差预算花在重要的地方。
7.3 Hessian 视角:二阶信息衡量敏感性 #
GPTQ 用每层输入的$Hessian H = 2XX^T + \lambda I$衡量"量化哪个权重代价最小":
损失增量≈ $(w_{q} - \hat{w}_q)^{2} / (2[H^{-1}]_qq)$(05 章完整推导)
一句话:一阶信息(幅度)告诉你"谁重要",二阶信息(Hessian)告诉你"动了谁代价最小"。 两者都是"不均匀对待权重"的数学依据。
8. 决策表:什么时候用哪种组合 #
| 场景 | 推荐粒度 | scale 格式 | 校准统计量 |
|---|---|---|---|
| FP8 W8A8 权重 | per-channel | FP32(fold 到 kernel 里) | min/max |
| FP8 W8A8 激活 | per-tensor | FP32 | 分位数 99.99% |
| INT4 权重(GPTQ/AWQ) | $group=128$ | FP16 | min/max(权重 outlier 少) |
| 激进 3-bit / 2-bit | $group=32$或更细 | FP16/FP8 | 分位数 + 校准集优化 |
| KV cache(08 章) | per-channel(K)/ per-token(V) | 每 token/通道 scale | 分位数 |
| Blackwell FP4/MX | per-group(16/32) | E4M3 / E8M0 | 分位数 |
经验法则:
- 权重不怕 min/max,激活必须防 outlier(分位数)。
- 4-bit 权重默认$group=128$;质量不够就$group=32$,而不是先换方法。
- per-tensor 只配 FP8 或 MX(有指数位托底);INT4 用 per-tensor 基本必炸。
- 校准集永远不能等于评测集。
9. 本章小结 #
- 粒度 = 范围利用率:$per-tensor \to per-channel \to per-group$,粒度越细误差越小、开销越大。
- 有效位宽$b_{\text{eff}} = b + \text{scale\_bits}/G$:$group=128$的 INT4 实际是 4.125 bit,别按 4.0 算容量。
- 校准 = 用代表数据选 scale:校准集要覆盖任务、与评测分离;激活用分位数,权重可用 min/max。
- outlier 是头号敌人:0.1% 的特征偷走$\sim 4 bit$有效精度(LLM.int8 的 6.0/25%/6%/6.7B 统计);四种对策 = 分离/迁移/保护/细分。
- 不均匀对待权重:AWQ 按激活幅度保护重要通道,GPTQ 按 Hessian 挑代价最小的量化顺序。
一句话记忆:“粒度决定网格细不细,校准决定网格放哪,outlier 决定你为什么要这么麻烦。”
10. 习题与解答 #
题 1(计算):有效位宽 #
$INT4 + group=64 + FP8 scale$的有效位宽和相对存储开销是多少?对比$group=128 + FP16$。
题 1 解答
$group=64 + FP8$:$b_{\text{eff}} = 4 + 8/64 = 4.125 bit$;开销= $8/64 = 0.125 bit/$元素 = 相对 4-bit 数据 3.125%。 $group=128 + FP16$:$b_{\text{eff}} = 4 + 16/128 = 4.125 bit$;开销= $3.125\%$。 两者有效位宽相同——FP8 scale 用一半位宽做到相同粒度开销,所以新 kernel 偏好 FP8 scale。
题 2(思考):outlier 的量化伤害 #
激活 99.99% 在$\pm 60$,$\max=1000$。8-bit 对称量化($s=\max/127$)下,正常值的有效位宽大约是多少?
题 2 解答
正常值范围$\pm 60$只占$\pm 1000$的 6%;量化层级数≈ $2\times 60/(1000/127) \approx 15.2 \to$有效位宽≈ $\log_2(15) \approx 3.9 bit$。8-bit 实际只剩不到 4 bit 的有效精度,这正是 outlier 的"偷位"效应。
题 3(设计):校准集 #
你要给一个代码生成模型做 INT4 量化。设计校准集:来源、条数、每条约多长、要避免什么。
题 3 解答要点
来源:高质量代码语料(多语言/多框架,含少量文档注释混合数据);128 条 × 2048 token;避免只用单语言/单框架;避免用评测集(如 HumanEval 样本)——那是验证集。量化后用代码相关 benchmark + 自定义任务验证(10 章)。
题 4(推导):per-channel vs per-tensor 的误差比 #
某层权重 W 有 4096 行,每行范围不同:一半行范围$[-1,1]$,一半$[-100,100]$。per-tensor min/max 下,$[-1,1]$那半行的量化步长是 per-channel 的多少倍?有效位宽损失多少?
题 4 解答
per-tensor 的$s = 100/127$;per-channel 对$[-1,1]$行的$s = 1/127$。步长比= $100$(≈ $2^{6.6}$)$\to$那半行损失约 6.6 bit 有效精度。这就是"per-channel 在通道范围差异大时是免费的精度"。
题 5(编程):校准统计量对比 #
构造分布:N(0,1) 的 99.99% + 少量$\pm 1000 outlier$。比较 min/max、P99.99、P99.999 三种 scale 下的 8-bit SQNR。
题 5 解答要点
min/max 会被 outlier 撑大(SQNR 低);P99.99 忽略最极端 0.01%,正常值有效位宽高,但 outlier 本身被截断;P99.999 介于两者之间。结果应验证:outlier 存在时,分位数校准显著优于 min/max,具体分位点按"截断代价 vs 有效位宽"权衡。
11. 延伸阅读 #
- LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale(arXiv:2208.07339):outlier 统计与混合精度分解
- SmoothQuant(arXiv:2211.10438):激活分布统计($\pm 60 / 1000+$)与$\alpha$迁移
- AWQ(arXiv:2306.00978):$s = \max|X|^\alpha$ 通道缩放与校准集设计
- GPTQ(arXiv:2210.17323):128 条 × 2048 token 校准集的标准用法
- 上一篇: 03 数值格式与硬件;下一篇:[05 权重量化 I:RTN 与 GPTQ]——把"选 scale"升级成"量化后全局补偿误差"。