大语言模型量化技术(三):AWQ
AWQ 的核心思想
AWQ(Activation-aware Weight Quantization,激活感知权重量化)是一种面向大语言模型的后训练权重量化(PTQ)算法,属于 weight-only 量化方法。AWQ 的论文中提出一个发现:大语言模型中只有少量权重特别重要,通常约占全部权重的 。这些重要权重往往不是绝对值最大的权重,而是位于输入激活值较大的通道所对应的权重列中。因此,让这些重要权重在量化时获得更高的精度,可以显著降低因量化而引入的误差。
假设线性层为:
其中 ,, 的第 列会与 的第 个输入通道相乘。
如果第 个激活通道经常出现较大数值,那么 的第 列发生量化误差时,对输出的影响就比较大。因此,AWQ 使用校准数据统计输入激活值 各通道的平均幅度:
越大,通常说明第 个输入通道对应的权重列对量化误差越敏感。
AWQ 为了让重要权重在量化时获得更高的精度,提出了一个简单而有效的做法,在量化前按输入通道的幅值大小对权重列进行缩放,相对放大重要通道对应的权重,并相对缩小其他通道对应的权重。这样,重要权重在共享量化网格上可由更多整数等级表示,从而降低其量化误差。推理时再将输入 对应的输入通道等比缩小,从而保持输出不变。
假如一个重要通道中的权重分布在 之间,量化步长为 ,那么该通道中所有参数只能被量化为 -0.01、0 或 0.01,量化误差较大。如果将该通道的权重放大 10 倍,权重的分布范围变为 ,在量化步长不变的情况下,这个范围可以被量化为 -0.1、-0.09、…、0.09、0.1,量化等级数从原来的 3 个变为 21 个,重要权重的量化误差就会显著下降。
论文做了一个实验:将占总量 1% 的重要权重保留为 FP16,其余权重量化为 INT4。实验结果显示模型性能几乎没有下降,说明只有少量权重对模型精度特别重要。

但在推理时保留少量 FP16 权重会引入额外的计算开销。FP16 权重和 INT4 权重需要分别计算,再合并结果。AWQ 的做法是在量化前按输入通道缩放权重列,相对放大重要通道对应的权重,并相对缩小其他通道对应的权重。这样,重要权重在共享量化网格上可由更多整数等级表示,从而降低其量化误差。
例如,某个权重组的量化步长为 ,其中一个重要权重为 ,它只能被近似为 。若将该权重放大为 ,且放大后它仍未超过该组的最大绝对值,则量化步长仍为 ,它就可以被精确表示为 ,没有任何精度的损失。这里的关键不是扩大整个权重组的量化范围,而是在量化步长基本不变时,提高重要权重的幅度,让原本只能被粗略量化的权重,能够由更多整数等级表示,从而降低量化误差。

权重被放大后,在推理时需要将输入 对应的输入通道等比缩小,从而保持输出不变。通过缩放操作,重要权重的量化误差可以显著下降,最终的效果和保留少量 FP16 权重通道的效果相当,但不会引入额外的计算开销。
这里每个输入通道的缩放系数由该通道输入激活值的幅度决定,幅度越大,缩放系数越大。在推理时,输入激活值会除以缩放系数,从而抵消权重的放大操作。其数学上等价于:
这里 是一个对角矩阵,,其中 是第 个输入通道的缩放系数。 是 的逆矩阵,对角线元素为 。在量化时,会对 进行量化,而在推理时,会对输入激活值 进行缩放 ,从而保持输出 不变。
AWQ 原理详解
前面描述了 AWQ 的核心思想,从直觉上,AWQ 通过识别重要权重通道,并在量化前放大这些通道的权重,在量化步长不变的情况下,增加了重要权重的量化等级数,从而降低了它们的量化误差。因为权重被放大了,所以在推理时需要将对应的输入通道缩小,以保持输出不变。
这一节将详细介绍 AWQ 的原理,并解释 AWQ 设计时的一些关键考虑。
衡量权重的重要性
AWQ 的量化目标不是简单地让量化后的权重接近原始权重,而是让量化后的权重在与输入激活值相乘后,尽可能接近原始输出。也就是说,AWQ 的目标是:
这就需要考虑输入激活值的大小,因为即使两个权重的量化误差相同,如果它们对应的输入激活值不同,对输出的影响也会不同。
考虑一个简单的线性层:
假设两个权重量化后产生相同大小的误差:
如果输入激活值为:
那么它们产生的输出误差分别是:
虽然两个权重的量化误差相同,但第一个权重造成的输出误差是第二个的 1000 倍。
因此,不能简单地认为 越大,权重越重要。更准确地说, 越大,该权重的量化误差对最终输出的影响就越大。AWQ 基于输入激活值的大小,找出对模型输出影响更大的输入通道。
如何保护重要权重
知道少量权重非常重要后,最直接的想法是:
- 普通权重使用 INT4
- 重要权重保留 FP16
这种方法在理论上是可行的,可以将矩阵中包含重要权重的列单独存储为 FP16,而其他列使用 INT4 量化。在推理时,可以使用两个矩阵乘法分别计算 FP16 权重和 INT4 权重的输出,然后将两部分结果相加。LLM.int8() 就是采用了这种方法,它将幅度较大的通道保留为 FP16,幅度较小的权重量化为 INT8,这样就可以将重要的权重保留为高精度,从而降低量化误差。

但这种方法在实际推理中会引入额外的计算开销。因为 FP16 权重和 INT4 权重需要分别计算,然后再合并结果,这会增大计算开销,还会引入额外的数据拷贝,降低实际推理效率。
因此,AWQ 虽然通过“以高精度保留重要权重”证明了重要权重的重要性,但它最终采用的硬件友好方案不是将这些权重实际保留为 FP16,而是降低重要权重的量化误差。
降低量化误差的一种思路是缩小量化范围,因为量化范围越小,量化步长通常越小,量化误差也越小。AWQ 则在共享量化 scale 的权重组内重新分配各通道的动态范围。具体做法是在不显著增大量化步长的前提下,放大重要权重,使其能由更多整数等级表示。
放大权重为什么有效
对同一组数据使用相同位宽进行量化时,数据的范围越小,量化步长就越小,量化误差通常也越小。AWQ 将权重放大,直觉上看似乎会扩大量化范围,从而增加量化误差。但实际上,AWQ 是在共享同一个量化 scale 的权重组内部,只放大重要权重,而这个被放大的重要权重并不一定是这个组中绝对值最大的权重,因此量化步长不一定会改变。
实际的 INT4 权重量化通常采用 group-wise 量化,例如一组 128 个权重共享一个 scale:
问题在于,一些重要权重的绝对值可能比较小,但由于组内 scale 由较大的权重决定,这些较小的权重只能使用非常粗糙的量化等级表示,量化误差很大。
AWQ 的做法是将这些重要权重放大:
只要放大后的重要权重仍未成为该组最大值,整个 group 的量化范围就不会明显变化:
但重要权重变大了,它能使用更多整数等级表示。
假设一个重要权重原来是 ,量化步长为 ,那么它会被量化为 ,量化误差为 。如果将它放大 10 倍,变为 ,量化步长仍然是 ,那么它会被量化为 ,量化误差为 。
但如果不断增大缩放因子 ,放大后的重要权重可能超过原来的 group 最大值,此时量化范围和量化步长都会增大,虽然被放大的通道的权重的量化精度可以提高,但其他通道的权重的量化误差会增大,整体未必能降低整体量化误差。因此,AWQ 需要搜索合适的缩放因子,在保护重要权重与控制量化步长之间取得平衡。
等价缩放
对于:
引入一个对角缩放矩阵:
可以对权重和输入激活值进行缩放,此时输出 不变:
在没有量化时,这个变换不会改变线性层输出。它所做的事情是将权重矩阵第 列乘以 ,将对应的输入激活通道除以 。
令:
则:
可见,全精度计算的结果保持不变。而 AWQ 中的主要新增误差来自对 的量化,对权重的缩放正是为了降低这部分误差。
缩放通道与缩放因子
AWQ 不会简单地把激活值最大的通道统一放大固定倍数,而是使用校准数据搜索合适的缩放因子。然后对每个输入通道使用不同的缩放因子进行缩放。
可以将缩放因子写为:
其中:
- 是第 个输入通道的平均幅度 ;
- 是一个在 0 到 1 之间搜索的超参数(通常取接近 0.5 的值),用于控制缩放强度:
- 当 时,,所有通道的缩放因子趋于相同;
- 当 时,,所有通道的缩放因子与激活值幅度成正比;
- 是用于缩放权重通道的系数。
直接使用 时,激活值较大的通道可能得到过大的缩放系数。实际工程实现中,会对缩放系数整体进行一次缩放,控制其动态范围:
scale = scale.pow(alpha).clamp(min=1e-4).view(-1)
scale = scale / sqrt(scale.max() * scale.min())
这种处理可以调整缩放系数的动态范围,保持整体缩放较为平衡。
为了得到合适的 ,AWQ 使用校准数据尝试不同的 ,并计算量化前后的输出误差:
这里 是由 计算得到的缩放矩阵:
AWQ 选择使输出误差最小的 :
因此,AWQ 中的 “Activation-aware” 体现在两个方面:
- 使用输入激活值判断哪些权重通道更加敏感;
- 使用校准激活值评估不同缩放配置的输出误差。
对于较重要的输入通道,缩放因子通常较大,其对应权重列会被相对放大,其他通道的权重列则会被相对缩小。这让重要权重的范围在整个量化组中占据更大的比例,这样重要权重就可以由更多整数等级表示,从而降低量化误差。
AWQ 的完整流程
AWQ 的流程主要包括以下几个步骤:
识别显著通道
选取少量具有代表性的文本作为校准数据。这些数据不用于训练,只用于收集激活值和搜索量化参数。对模型执行前向传播,记录各个线性层的输入激活值:
计算每个输入通道的激活幅度等统计量,根据激活值判断哪些输入通道对应的权重更加敏感。 越大,则对应权重列越值得保护。
搜索缩放因子
通过等价变换:
尝试不同的通道缩放强度,并比较量化前后的输出误差,找到最优的缩放因子配置。
搜索裁剪范围
AWQ 实现中通常还会搜索权重裁剪范围,少量极端权重会扩大量化范围和步长,适当裁剪极端值,有时反而能降低整体量化误差:
但裁剪过度也会损害重要权重,因此需要使用校准数据选择阈值。
量化
对缩放后的权重进行量化:
常见配置是使用 INT4 权重量化,激活值保留 FP16/BF16,并使用 group-wise 量化,通常 group size 设为 128。
部署推理
推理时计算近似为:
实际系统中,并不会在推理时显式地执行 。因为这里 是来自前一层的输出,通常是前一层的归一化输出或前一层的矩阵乘结果。因此可以把对 的缩放操作融入前一层的归一化或矩阵乘中,从而避免引入额外的计算开销。
AWQ 与其他量化策略的对比
普通 RTN(Round-to-Nearest)量化直接在权重上执行量化操作:
其优化目标是让量化前后的权重尽可能接近:
但 AWQ 的优化目标是让量化前后的输出尽可能接近:
即使两个权重的量化误差相同,只要对应的输入激活值不同,对输出的影响就可能完全不同。RTN 对所有权重同等对待,AWQ 根据激活值保护更加重要的权重通道。
GPTQ 和 AWQ 都属于权重量化方法,都属于后训练量化(PTQ),但二者处理量化误差的方式不同。
| 比较项 | GPTQ | AWQ |
|---|---|---|
| 主要依据 | 输入二阶统计量和近似 Hessian | 输入激活值的通道幅度 |
| 核心操作 | 逐列量化并补偿后续列 | 缩放重要通道后统一量化 |
| 如何处理误差 | 修改未量化权重抵消已有误差 | 预先重新分配各通道的量化难度 |
| 校准计算成本 | 通常较高 | 通常较低 |
| 常见配置 | W4A16 | W4A16 |
GPTQ 是在一列量化出错以后,调整后续列来补偿误差,而 AWQ 是在量化之前,根据激活值找出重要通道,先把这些通道调整到更容易被准确量化的状态。
总结
AWQ 的设计目标是让量化后的权重与输入激活值相乘后的结果尽可能接近原始输出。为此,AWQ 利用激活值识别重要输入通道,并在量化前按通道缩放相应的权重列,使重要权重在共享量化网格中获得更高的有效分辨率,从而降低量化误差。推理时再将输入 的对应通道按相反比例缩小,从而保持输出不变。