INT4/INT8 量化推理:从 GPTQ 到 AWQ 的取舍
同样是 4 bit 权重量化,有的模型几乎无损,有的直接崩掉十几个点。这个差异不是随机的,根源在激活值的离群通道。这篇把 GPTQ 和 AWQ 的取舍讲清楚,并附上我们在几个模型上的实测数据。
一、量化到底在做什么
把一个 FP16 张量映射到 b bit 整数,最简单的对称量化是:
关键变量是缩放因子 s 的粒度。整个张量共用一个 s(per-tensor)最省事,但只要有一个异常大的值,s 就被拉高,其余绝大多数权重被挤进很少的几个量化格子里,信息全丢了。
所以实践中至少要做到 per-channel,主流方案是 group-wise:每 128 个连续权重共用一组 scale 和 zero-point。存储开销的账:
每 128 个权重占用:
128 × 4 bit = 64 bytes # 量化值
1 × fp16 scale = 2 bytes
1 × 4 bit zero-point = 0.5 bytes
------------------------------------------
合计 66.5 bytes / 128 权重 ≈ 4.16 bit/权重
比理论 4 bit 多 4%,换来的精度提升远超这个代价。group size 取 128 是甜点,取 64 精度再涨一点点但开销到 4.3 bit,取 256 开始明显掉点。
二、离群通道:所有麻烦的来源
大模型的激活值有一个反复被观察到的性质:极少数特征通道的幅值比其余通道高 1–2 个数量级,而且这些通道在不同输入上高度稳定。在 6.7B 以上的模型里,大约 0.1%–1% 的通道贡献了绝大部分的激活动态范围。
这解释了几件事:
- 为什么权重量化到 8 bit 通常无损,但激活量化到 8 bit 会掉点——激活的动态范围被离群通道撑爆了。
- 为什么小模型量化更容易,大模型更难——离群现象随规模增强。
- 为什么同规模不同模型差异巨大——训练配置(尤其是是否使用某些归一化方式)会显著影响离群通道的强度。
三、GPTQ:逐列纠错
GPTQ 的出发点是逐层重建:不追求权重本身接近,而是让量化后该层的输出接近原输出。目标函数是
其中 X 是一小批校准数据在该层的输入。这是一个最小二乘问题,可以用海森矩阵 H = 2XXᵀ 的逆来求解。GPTQ 的做法是按列依次量化,每量化一列就把产生的误差按 H⁻¹ 的方向补偿到尚未量化的列上:
for j in range(n_cols):
q = quantize(W[:, j])
err = (W[:, j] - q) / H_inv[j, j]
W[:, j] = q
W[:, j+1:] -= err[:, None] * H_inv[j, j+1:][None, :] # 误差转移
优点是精度好、不需要重训。缺点也明确:依赖校准集。如果校准数据的分布和实际使用场景差异大,H 估计不准,补偿方向就是错的。我们踩过的具体案例:用纯英文语料校准的模型,在中文任务上比用混合语料校准的版本低 2.3 个点。
四、AWQ:保护重要通道
AWQ 的观察更简单直接:既然只有少数通道重要,那就别对它们一视同仁。具体做法是在量化前引入一个逐通道的缩放变换:
数学上完全等价,但把 W 的重要通道放大之后再量化,这些通道占据了更多量化格子,相对误差下降;对应的缩放逆变换被吸收进上一层的输出(或者归一化层的权重里),推理时零额外开销。
s 的选择依据是激活的幅值而非权重的幅值——这是 AWQ 的核心主张:权重本身的大小不代表重要性,被大激活乘到的权重才重要。
五、实测对比
在四个开源模型上跑的结果(相对 FP16 的 MMLU 保持率,group size 128,校准集为 512 条混合中英语料):
| 模型 | GPTQ INT4 | AWQ INT4 | 校准敏感度 |
|---|---|---|---|
| 7B dense | 99.1% | 99.4% | 低 |
| 13B dense | 98.7% | 99.2% | 低 |
| 34B dense | 97.9% | 98.8% | 中 |
| 8×7B MoE | 93.2% | 97.1% | 高 |
最后一行是重点。MoE 模型量化明显更难,原因是每个专家只被一部分 token 激活,校准集里冷门专家拿到的样本可能只有几十条,海森估计极不可靠。缓解办法:给 MoE 用大 4 倍的校准集,并且按专家利用率做分层采样,保证每个专家至少 128 条样本。这样处理后 GPTQ 能回到 96.5%。
六、W8A8 是另一条路
上面讨论的都是「只量化权重、激活保持 FP16」(W4A16)。它降低的是显存和访存,算力仍然走 FP16 张量核。如果想真正吃到 INT8 算力,需要把激活也量化,也就是 W8A8。
此时离群通道又回来了。SmoothQuant 的处理方式和 AWQ 同源:把激活的量化难度按通道迁移一部分到权重上——
α 控制迁移强度,取 0.5 是常见起点。激活容易量化的模型可以调低,离群严重的调到 0.75 以上。这个参数值得为每个模型单独扫一遍,我们在一个 13B 模型上从 0.5 调到 0.7,MMLU 保持率从 96.8% 升到 98.4%。
七、什么时候不该量化
如果服务是大批量吞吐导向、且已经被算力打满,W4A16 带来的收益很有限——它优化的是访存,而大 batch 下瓶颈在计算。这种场景要么上 W8A8 吃 INT8 算力,要么干脆保持 FP16 把工程精力花在批处理调度上。量化不是免费午餐,先确认瓶颈在哪。