同样大小的权重,对模型的影响可能完全不同
简单介绍
AWQ 全称 Activation-aware Weight Quantization,激活感知权重量化
量化的本质是用更少的位,来存储权重,比如说fp16 -> int4 。大量节省了显存占用,同时带来一些精度损失。
普通量化基本可以理解为:
W^=Q(W)\hat W = Q(W) W^=Q(W)
然后推理:
Y^=Q(W)X \hat Y=Q(W)X Y^=Q(W)X
于是输出误差:
ΔY=(Q(W)−W)X ΔY=(Q(W)−W)X ΔY=(Q(W)−W)X
真正影响模型的不是"权重误差本身",而是权重误差 × activation。
这个activation可以是10,也可以是0.01,对模型的影响是完全不同的,这也是Activation-aware的来源
怎么找重要的weight
AWQ没有做特别复杂的计算,一个很直观的感受就是计算
aj=E∣xj∣aj=E∣x_j∣aj=E∣xj∣
那个大就是哪个重要。这些重要的参数大约占1%。而且为了方便计算,AWQ没有说是很重要的参数就不量化,因为只有一小部分参数不量化cuda算子很难适配。
等价Scaling
对于一个普通的 Linear:
y=Wx y = Wx y=Wx
AWQ 会引入一个对角缩放矩阵:
S=diag(s0,s1,...,sK−1) S=\operatorname{diag}(s_0,s_1,\dots,s_{K-1}) S=diag(s0,s1,...,sK−1)
由于 SS−1=ISS^{-1}=ISS−1=I,所以:
Wx=WSS−1x=(WS)(S−1x) Wx = WSS^{-1}x = (WS)(S^{-1}x) Wx=WSS−1x=(WS)(S−1x)
也就是说:
Wx=(WS)(S−1x) \boxed{Wx=(WS)(S^{-1}x)} Wx=(WS)(S−1x)
这意味着,我们可以把某个输入 channel 对应的权重放大 sss 倍,同时把对应的 activation 缩小 sss 倍,而不改变原来的计算结果。
对于单个权重和 activation,原本有 y=wxy=wxy=wx。做 scaling 后:
w′=sw,x′=xs w'=sw,\qquad x'=\frac{x}{s} w′=sw,x′=sx
于是:
w′x′=(sw)xs=wx w'x'=(sw)\frac{x}{s}=wx w′x′=(sw)sx=wx
因此,在浮点计算中,这种 scaling 是完全等价的。
例如,假设:
w=0.3,x=10 w=0.3,\qquad x=10 w=0.3,x=10
原始输出为:
y=0.3×10=3 y=0.3\times10=3 y=0.3×10=3
取 s=4s=4s=4,那么:
w′=0.3×4=1.2,x′=104=2.5 w'=0.3\times4=1.2,\qquad x'=\frac{10}{4}=2.5 w′=0.3×4=1.2,x′=410=2.5
最终:
y′=1.2×2.5=3 y'=1.2\times2.5=3 y′=1.2×2.5=3
结果与原来完全一致。
Scaling 真正的作用体现在量化之后。假设放大后的权重经过量化后为:
Q(sw)=sw+e Q(sw)=sw+e Q(sw)=sw+e
其中 eee 表示量化误差。那么最终的计算结果为:
(sw+e)xs (sw+e)\frac{x}{s} (sw+e)sx
wx+esx wx+\frac{e}{s}x wx+sex
因此:
wx+esx wx+\frac{e}{s}x wx+sex
原本量化误差对输出的影响大约是 exexex,而经过 scaling 后变成 esx\frac{e}{s}xsex。所以在量化步长没有明显变化的情况下,s>1s>1s>1 时,有效量化误差大约会缩小为原来的 1s\frac{1}{s}s1。
例如,假设 w=0.3w=0.3w=0.3,普通量化后变成 Q(w)=0.4Q(w)=0.4Q(w)=0.4,那么权重误差为 0.10.10.1。如果对应的 activation 为 x=10x=10x=10,输出误差就是:
0.1×10=1 0.1\times10=1 0.1×10=1
现在取 s=4s=4s=4,先把权重放大为 w′=1.2w'=1.2w′=1.2。假设量化后为 Q(w′)=1.3Q(w')=1.3Q(w′)=1.3,仍然产生 0.10.10.1 的绝对量化误差。同时 activation 被缩小为:
x′=104=2.5 x'=\frac{10}{4}=2.5 x′=410=2.5
此时量化误差对输出的影响变成:
0.1×2.5=0.25 0.1\times2.5=0.25 0.1×2.5=0.25
相比原来的 111,误差缩小了约 444 倍。
因此,AWQ 可以通过放大重要 channel 对应的权重,同时缩小对应 activation,在不改变原始浮点模型函数的情况下,降低这些重要权重的有效量化误差。这就是所谓的 protect salient weights。
需要注意的是,sss 并不是越大越好。过大的 scaling 可能扩大整个量化 group 的数值范围,使量化步长变大,反而影响其他权重,因此实际 AWQ 会搜索一个合适的 scaling factor。