Tensor NotesNotes on machine learning
Inference

INT4/INT8 量化推理:从 GPTQ 到 AWQ 的取舍

INT4/INT8 量化推理:从 GPTQ 到 AWQ 的取舍题图

同样是 4 bit 权重量化,有的模型几乎无损,有的直接崩掉十几个点。这个差异不是随机的,根源在激活值的离群通道。这篇把 GPTQ 和 AWQ 的取舍讲清楚,并附上我们在几个模型上的实测数据。

一、量化到底在做什么

把一个 FP16 张量映射到 b bit 整数,最简单的对称量化是:

s = max|W| / (2b−1 − 1), Wq = round(W / s), Ŵ = s · Wq

关键变量是缩放因子 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 的出发点是逐层重建:不追求权重本身接近,而是让量化后该层的输出接近原输出。目标函数是

argminŴ ‖ W X − Ŵ X ‖²F

其中 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 X = (W · diag(s)) · (diag(s)−1 X)

数学上完全等价,但把 W 的重要通道放大之后再量化,这些通道占据了更多量化格子,相对误差下降;对应的缩放逆变换被吸收进上一层的输出(或者归一化层的权重里),推理时零额外开销。

s 的选择依据是激活的幅值而非权重的幅值——这是 AWQ 的核心主张:权重本身的大小不代表重要性,被大激活乘到的权重才重要。

不同量化方案的相对吞吐与精度对比
图 1 · A100 单卡、batch 1、seq 2048 下的相对吞吐。INT4 的收益主要来自访存带宽,不是算力

五、实测对比

在四个开源模型上跑的结果(相对 FP16 的 MMLU 保持率,group size 128,校准集为 512 条混合中英语料):

模型GPTQ INT4AWQ INT4校准敏感度
7B dense99.1%99.4%
13B dense98.7%99.2%
34B dense97.9%98.8%
8×7B MoE93.2%97.1%

最后一行是重点。MoE 模型量化明显更难,原因是每个专家只被一部分 token 激活,校准集里冷门专家拿到的样本可能只有几十条,海森估计极不可靠。缓解办法:给 MoE 用大 4 倍的校准集,并且按专家利用率做分层采样,保证每个专家至少 128 条样本。这样处理后 GPTQ 能回到 96.5%。

选型建议校准数据充足且贴近实际分布 → GPTQ 和 AWQ 差距不大,选生态支持更好的。校准数据有限、或部署场景多样 → 优先 AWQ,它对校准集的依赖弱得多。MoE 模型 → 一律 AWQ,并扩大校准集。

六、W8A8 是另一条路

上面讨论的都是「只量化权重、激活保持 FP16」(W4A16)。它降低的是显存和访存,算力仍然走 FP16 张量核。如果想真正吃到 INT8 算力,需要把激活也量化,也就是 W8A8。

此时离群通道又回来了。SmoothQuant 的处理方式和 AWQ 同源:把激活的量化难度按通道迁移一部分到权重上——

Y = (X · diag(s)−1) · (diag(s) · W), sj = max|Xj|α / max|Wj|1−α

α 控制迁移强度,取 0.5 是常见起点。激活容易量化的模型可以调低,离群严重的调到 0.75 以上。这个参数值得为每个模型单独扫一遍,我们在一个 13B 模型上从 0.5 调到 0.7,MMLU 保持率从 96.8% 升到 98.4%。

七、什么时候不该量化

如果服务是大批量吞吐导向、且已经被算力打满,W4A16 带来的收益很有限——它优化的是访存,而大 batch 下瓶颈在计算。这种场景要么上 W8A8 吃 INT8 算力,要么干脆保持 FP16 把工程精力花在批处理调度上。量化不是免费午餐,先确认瓶颈在哪。

上一篇:扩散模型的噪声调度:DDPM、DDIM 与 …下一篇:RAG 不是搜索加拼接:分块、重排与上下文压…

继续阅读

Related