大模型的开发应用(十八):大模型量化:GPTQ 与 AWQ

0 前言

前面在介绍QLoRA的时候,我们介绍了 NF4 和 LLM.int8() 量化,这两种量化方式是比较常用的大模型在线量化方式,对于离线量化,目前比较常用的是 GPTQ 和 AWQ。当然,我个人做过对比实现,发现 GPTQ 和 AWQ 效果都不好容易导致模型智商下降,但面试的时候又经常被问到,因此在此对这两种量化方式做个详细的介绍。本文涉及到了比较多的数学推导,读者最好知道多元函数的泰勒泰勒展开、运筹优化的标准数学表达式和 L2 范数的含义,其他像拉格朗日乘数、Cholesky 分解。

本文主要参考了知乎博主杨远航的文章QLoRA、GPTQ:模型量化概述

1 GPTQ 的基础

1.1 海森矩阵

定义

海森矩阵(Hessian Matrix)是一个描述多元函数局部曲率性质的二阶偏导数方阵,由德国数学家路德维希·奥托·赫斯(Ludwig Otto Hesse)于19世纪提出,因此得名。它在优化、图像处理、机器学习等领域有广泛应用。以下从数学形式、性质和应用场景展开说明:

对于一个 n 元实值函数 f ( w 1 , w 2 , … , w n ) f(w_1, w_2, \ldots, w_n) f(w1,w2,,wn),若其二阶偏导数均存在,其海森矩阵 H ( f ) \mathbf{H}(f) H(f) 是一个 n×n 的对称矩阵,定义为:

H ( f ) = [ ∂ 2 f ∂ w 1 2 ∂ 2 f ∂ w 1 ∂ w 2 ⋯ ∂ 2 f ∂ w 1 ∂ w n ∂ 2 f ∂ w 2 ∂ w 1 ∂ 2 f ∂ w 2 2 ⋯ ∂ 2 f ∂ w 2 ∂ w n ⋮ ⋮ ⋱ ⋮ ∂ 2 f ∂ w n ∂ w 1 ∂ 2 f ∂ w n ∂ w 2 ⋯ ∂ 2 f ∂ w n 2 ] \mathbf{H}(f) = \begin{bmatrix} \frac{\partial^2 f}{\partial w_1^2} & \frac{\partial^2 f}{\partial w_1 \partial w_2} & \cdots & \frac{\partial^2 f}{\partial w_1 \partial w_n} \\ \frac{\partial^2 f}{\partial w_2 \partial w_1} & \frac{\partial^2 f}{\partial w_2^2} & \cdots & \frac{\partial^2 f}{\partial w_2 \partial w_n} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial^2 f}{\partial w_n \partial w_1} & \frac{\partial^2 f}{\partial w_n \partial w_2} & \cdots & \frac{\partial^2 f}{\partial w_n^2} \end{bmatrix} H(f)= w122fw2w12fwnw12fw1w22fw222fwnw22fw1wn2fw2wn2fwn22f

关键点

  • 矩阵元素为函数对变量两两组合的二阶偏导数 ∂ 2 f ∂ w i ∂ w j \frac{\partial^2 f}{\partial w_i \partial w_j} wiwj2f
  • 若函数二阶连续可导,则矩阵对称 ( ∂ 2 f ∂ w i ∂ w j = ∂ 2 f ∂ w j ∂ w i (\frac{\partial^2 f}{\partial w_i \partial w_j} = \frac{\partial^2 f}{\partial w_j \partial w_i} (wiwj2f=wjwi2f)。

核心性质

  1. 对称性
    当函数二阶偏导数连续时,海森矩阵是对称矩阵,混合偏导数与求导顺序无关。

  2. 与泰勒展开的关系
    函数在点 w 0 \mathbf{w}_0 w0 处的二阶泰勒展开为:

    f ( w ) ≈ f ( w 0 ) + ∇ f ( w 0 ) T ( w − w 0 ) + 1 2 ( w − w 0 ) T H ( f ) ( w 0 ) ( w − w 0 ) f(\mathbf{w}) \approx f(\mathbf{w}_0) + \nabla f(\mathbf{w}_0)^T (\mathbf{w} - \mathbf{w}_0) + \frac{1}{2} (\mathbf{w} - \mathbf{w}_0)^T \mathbf{H}(f)(\mathbf{w}_0) (\mathbf{w} - \mathbf{w}_0) f(w)f(w0)+f(w0)T(ww0)+21(ww0)TH(f)(w0)(ww0)
    其中 H ( f ) \mathbf{H}(f) H(f) 决定了函数的局部曲率(凸性/凹性)。

  3. 极值判定(了解即可,不重要)
    在梯度 ∇ f = 0 \nabla f = 0 f=0 的临界点 w 0 \mathbf{w}_0 w0 处:

    • H \mathbf{H} H 正定(所有特征值 > 0)→ 局部极小值
    • H \mathbf{H} H 负定(所有特征值 < 0)→ 局部极大值
    • H \mathbf{H} H 不定(特征值有正有负)→ 鞍点(非极值)。

1.2 OBD(Optimal Brain Damage)算法原理

这是发表于1990年的关于神经网络的剪枝算法,关于模型剪枝,实际上就是去掉神经网络中的一些不重要的连接,表现在权重矩阵上,就是把矩阵中的一些元素改成0。剪枝最大的挑战在于,你不知道哪些连接该剪,哪些不该剪。这需要有一套规则来进行判断,不同的剪枝算法,对应的判断规则不一样。

OBD算法则是通过泰勒展开近似替代原始模型,进而计算各个参数对目标函数(损失函数)的影响,以此来判断剪枝的优先级。

先假设模型的输入数据是固定的,E 表示损失函数,那么 E = f ( w 1 , w 2 , … , w n ) E=f(w_1, w_2, \ldots, w_n) E=f(w1,w2,,wn) Δ E \Delta E ΔE 表示参数变化( Δ w \Delta \mathbf w Δw)给损失函数带来影响,则有:

Δ E = f ( w 1 + Δ w 1 , w 2 + Δ w 2 , … , w n + Δ w n ) − f ( w 1 , w 2 , … , w n ) = f ( w 1 , w 2 , … , w n ) + ∑ i g i Δ w i + 1 2 ∑ i h i i Δ w i 2 + 1 2 ∑ i ≠ j h i j Δ w i Δ w j + O ( Δ w 3 ) − f ( w 1 , w 2 , … , w n ) = ∑ i g i Δ w i + 1 2 ∑ i h i i Δ w i 2 + 1 2 ∑ i ≠ j h i j Δ w i Δ w j + O ( Δ w 3 ) \begin{align*} \Delta E &= f(w_1+\Delta w_1, w_2+\Delta w_2, \ldots, w_n+\Delta w_n) - f(w_1, w_2, \ldots, w_n) \\ &= f(w_1, w_2, \ldots, w_n) + \sum_{i} g_{i} \Delta w_{i} + \frac{1}{2} \sum_{i} h_{ii} \Delta w_{i}^{2} + \frac{1}{2} \sum_{i \neq j} h_{ij} \Delta w_{i} \Delta w_{j} + O\left( \Delta \mathbf{w}^{3} \right) - f(w_1, w_2, \ldots, w_n) \\ &= \sum_{i} g_{i} \Delta w_{i} + \frac{1}{2} \sum_{i} h_{ii} \Delta w_{i}^{2} + \frac{1}{2} \sum_{i \neq j} h_{ij} \Delta w_{i} \Delta w_{j} + O\left( \Delta \mathbf{w}^{3} \right) \end{align*} ΔE=f(w1+Δw1,w2+Δw2,,wn+Δwn)f(w1,w2,,wn)=f(w1,w2,,wn)+igiΔwi+21ihiiΔwi2+21i=jhijΔwiΔwj+O(Δw3)f(w1,w2,,wn)=igiΔwi+21ihiiΔwi2+21i=jhijΔwiΔwj+O(Δw3)

式中加黑部分表示向量,此外:

  • g i = ∂ E ∂ w i g_{i} = \dfrac{\partial E}{\partial w_{i}} gi=wiE 为参数的一阶偏导
  • h i j = ∂ 2 E ∂ w i ∂ w j h_{ij} = \dfrac{\partial^{2} E}{\partial w_{i} \partial w_{j}} hij=wiwj2E 为海森矩阵的元素
  • h i i h_{ii} hii 为对角线元素

OBD 简化假设

  • 假设目标函数是二阶的,因此忽略高阶项 O ( Δ w 3 ) O(\Delta \mathbf w^{3}) O(Δw3)
  • 模型训练充分收敛,所有参数一阶偏导为零: g i = 0 , ∀ i g_{i} = 0,\quad \forall i gi=0,i
  • 假设删除任意一个参数后,其他参数对目标函数的影响不变。也就是说,每个参数对目标函数的影响是独立的。于是我们也可以不考虑交叉项:: h i j = 0 , ∀ i , j ,   i ≠ j h_{ij} = 0,\quad \forall i,j,\ i \neq j hij=0,i,j, i=j

基于上述假设,公式可简化为:
Δ E = 1 2 ∑ i h i i Δ w i 2 \Delta E = \frac{1}{2} \sum_{i} h_{ii} \Delta w_{i}^{2} ΔE=21ihiiΔwi2

若将神经网络中参数 w i w_i wi 对应的连接删除,即令 Δ w i = − w i \Delta w_i = -w_i Δwi=wi,其他参数不变,则对目标函数的影响为: Δ E = 1 2 h i i w i 2 \Delta E = \frac{1}{2} h_{ii} w_{i}^{2} ΔE=21hiiwi2

剪枝次序确定

通过计算参数对应的海森矩阵对角元素: h i i = ∂ 2 E ∂ w i 2 h_{ii} = \dfrac{\partial^{2} E}{\partial w_{i}^{2}} hii=wi22E,可以按照下面的方式确定剪枝的优先级:

  1. h i i w i 2 h_{ii} w_{i}^{2} hiiwi2 值升序排序
  2. 优先删除影响最小的参数。

1.3 OBS(Optimal Brain Surgeon)算法原理

(1)基本原理与首次剪枝

OBS 认为,参数之间的独立性不成立,因为真实模型无法用数学表达式表达出来,上面的泰勒展开式只是近似,我们还是要考虑交叉项,因此有:
Δ E = 1 2 ∑ i h i i Δ w i 2 + 1 2 ∑ i ≠ j h i j Δ w i Δ w j = 1 2 Δ w T H Δ w \Delta E = \frac{1}{2} \sum_{i} h_{ii} \Delta w_{i}^{2}+\frac{1}{2} \sum_{i \neq j} h_{ij} \Delta w_{i} \Delta w_{j} = \frac{1}{2} \Delta \mathbf{w}^{\mathrm{T}} \mathbf{H} \Delta \mathbf{w} ΔE=21ihiiΔwi2+21i=jhijΔwiΔwj=21ΔwTHΔw

式中加黑部分表示向量或者矩阵。

现在我们假设删除一个权重后,可以调整其他权重参数,来抵消剪枝带来的影响。

若删除权重 w q w_q wq,即 Δ w \Delta \mathbf{w} Δw 的第 q q q 维固定为 − w q -w_q wq,但其他维度的值可变,用以抵消剪枝带来的影响,那么此时可以得到一个约束条件:
e q T ⋅ Δ w + w q = 0 \mathbf{e}_{\mathbf{q}}^{\mathbf{T}} \cdot \Delta \mathbf{w} + w_{q} = 0 eqTΔw+wq=0

其中, e q \mathbf{e}_{\mathbf{q}} eq 为 one-hot 向量,第 q q q 个分量为 1,其他分量为 0。

接下来要寻找最优的权重索引 q q q,使得将 w \mathbf{w} w 的第 q q q 个维度置零后,通过调整其他权重 Δ w i \Delta w_i Δwi i ≠ q i \neq q i=q),使剪枝给损失函数 E E E 带来的影响最小。当然,这个听起来有点绕,说得浅显一点就是,先预判每个权重删除+系统补偿后的最小损失变化,然后选择影响最小的权重(假设索引为 q) 优先剪枝,以此模型压缩中的性能-精简度最优平衡。

寻找 q q q 的过程,可以表示为一个最优化问题:

min ⁡ Δ w , q 1 2 Δ w T H Δ w subject to e q T ⋅ Δ w + w q = 0 \min _{\Delta \mathbf{w}, q} \frac{1}{2} \Delta \mathbf{w}^{\mathrm{T}} \mathbf{H} \Delta \mathbf{w} \\ \quad \text{subject to} \quad \mathbf{e}_{q}^{\mathrm{T}} \cdot \Delta \mathbf{w} + w_{q} = 0 Δw,qmin21ΔwTHΔwsubject toeqTΔw+wq=0

学过运筹学的同学对上面的表达式会比较熟悉,这是一个凸优化问题,可以通过 Lagrange 乘数法求解。

定义函数:
L = 1 2 Δ w T H Δ w + λ ( e q T ⋅ Δ w + w q ) L = \frac{1}{2} \Delta \mathbf{w}^{\mathrm{T}} \mathbf{H} \Delta \mathbf{w} + \lambda \left( \mathbf{e}_{q}^{\mathrm{T}} \cdot \Delta \mathbf{w} + w_{q} \right) L=21ΔwTHΔw+λ(eqTΔw+wq)

优化结果为:
Δ w = − w q [ H − 1 ] q q H − 1 ⋅ e q and L = 1 2 w q 2 [ H − 1 ] q q \Delta \mathbf{w} = -\frac{w_{q}}{ \left[ \mathbf{H}^{-1} \right]_{qq} } \mathbf{H}^{-1} \cdot \mathbf{e}_{q} \quad \text{and} \quad L = \frac{1}{2} \frac{w_{q}^{2}}{ \left[ \mathbf{H}^{-1} \right]_{qq} } Δw=[H1]qqwqH1eqandL=21[H1]qqwq2

上式中, H − 1 \mathbf{H}^{-1} H1 表示海森矩阵的逆矩阵, [ H − 1 ] q q [\mathbf{H}^{-1} ]_{qq} [H1]qq 表示逆矩阵的第 q q q 行第 q q q 列。这部分涉及运筹学知识,不需要掌握,只需要知道优化结果的表达式即可。

从最后的优化结果来看,我们只需要求解海森矩阵的逆,就可以计算每个参数对目标的影响 L q = 1 2 w q 2 [ H − 1 ] q q L_q = \frac{1}{2} \frac{w_{q}^{2}}{ \left[ \mathbf{H}^{-1} \right]_{qq} } Lq=21[H1]qqwq2

剪枝的时候,可以先按照影响从小到大给参数排序,然后删除影响最小的权重 w q w_q wq,最后更新其他参数以补偿剪枝带来的影响(只有补偿后,影响才能降到 1 2 w q 2 [ H − 1 ] q q \frac{1}{2} \frac{w_{q}^{2}}{ \left[ \mathbf{H}^{-1} \right]_{qq} } 21[H1]qqwq2),其他参数更新的公式为: w new = w + Δ w \mathbf{w}_{\text{new}} = \mathbf{w} + \Delta \mathbf{w} wnew=w+Δw

(2)迭代剪枝

删除完第一个参数后,如果想继续剪枝,需要更新 H − 1 \mathbf{H}^{-1} H1,更新的公式如下:
H new − 1 = H − 1 − H − 1 e q e q ⊤ H − 1 [ H − 1 ] q q \mathbf{H}_{\text{new}}^{-1} = \mathbf{H}^{-1} - \frac{\mathbf{H}^{-1} \mathbf{e}_q \mathbf{e}_q^{\top} \mathbf{H}^{-1}}{\left[\mathbf{H}^{-1}\right]_{qq}} Hnew1=H1[H1]qqH1eqeqH1
随后使用更新后的 H − 1 \mathbf{H}^{-1} H1 进行下一轮剪枝。

在OBS的算法流程中,过程可以总结为以下几步:

  1. 初始化​:训练收敛后,计算全局 H − 1 \mathbf{H}^{-1} H1(仅需一次)。
  2. ​迭代剪枝​:
    • 计算每个权重的显著性(saliency) L q = 1 2 w q 2 [ H − 1 ] q q L_q = \frac{1}{2} \frac{w_{q}^{2}}{ \left[ \mathbf{H}^{-1} \right]_{qq} } Lq=21[H1]qqwq2​​。
    • 删除显著性最小的权重 w q w_q wq,即在参数向量 w \mathbf{w} w 中,把第 q 维置0​。
    • ​增量更新 H − 1 \mathbf{H}^{-1} H1 和剩余权重​(使用公式 w new = w + Δ w \mathbf{w}_{\text{new}} = \mathbf{w} + \Delta \mathbf{w} wnew=w+Δw)。
  3. ​重复​:直接使用更新后的 H − 1 \mathbf{H}^{-1} H1 进行下一轮剪枝,无需重算。

(3)何时更新 H \mathbf{H} H H − 1 \mathbf{H}^{-1} H1

上面在迭代剪枝的时候,没有重复计算海森矩阵及其逆矩阵,那什么时候需要重新计算呢?在以下两种情况下可能需要完全重算:

  • ​跨层剪枝​:当剪枝涉及不同层时,参数间的相关性可能因层结构变化而改变,此时需为每层独立计算 H \mathbf{H} H H − 1 \mathbf{H}^{-1} H1(如L-OBS方法)
  • 数值稳定性问题​:增量更新可能因舍入误差累积导致数值不稳定,此时可定期(如每剪枝100个权重)重新计算 H \mathbf{H} H H − 1 \mathbf{H}^{-1} H1,以重置误差。

(4)剪枝效果对比:OBS VS OBD

在LeNet5上的剪枝实验表明:

  • 使用优化补偿法(OBS):精度损失仅 0.8%
  • 使用简单指定法(OBD):精度损失达 2.3%
  • 差异来源:关联参数未能主动补偿

1.4 OBC(Optimal Brain Compression)算法原理

OBD 和 OBS 都存在一个缺点,就是剪枝需要计算全参数的海森矩阵(及其它的逆矩阵)。但在动辄上亿参数的神经网络下求解海森矩阵显然不可能。于是,我们可以假设参数矩阵的同一行参数互相之间是相关的,而不同行之间的参数互不相关,这样就只需要在每一行内单独计算海森矩阵就行了。

假如模型的参数是一个 3×3 的矩阵,每一行都有3个参数。在 OBD 或 OBS 中是统一计算模型的全部参数的海森矩阵,这将是一个 9×9 的矩阵,而在 OBC 中,则是对其的每一行计算海森矩阵,那么每个海森矩阵都是一个 3×3 的矩阵,这样的矩阵有3个,示意图如下:

在这里插入图片描述

参数矩阵定义与目标函数

假设参数矩阵的维度为 ( d row d_{\text{row}} drow, d col d_{\text{col}} dcol),OBC 论文中,将目标函数定义为:

E = ∑ i = 1 d row ∥ W i , : X − W ^ i , : X ∥ 2 2 E = \sum_{i = 1}^{d_{\text{row}}} \| \mathbf{W}_{i,:} \mathbf{X} - \hat{\mathbf{W}}_{i,:} \mathbf{X} \|_{2}^{2} E=i=1drowWi,:XW^i,:X22

  • W i , : \mathbf{W}_{i,:} Wi,::原始参数矩阵的第 i i i 行向量
  • W ^ i , : \hat{\mathbf{W}}_{i,:} W^i,::压缩(剪枝或量化)后的参数矩阵第 i i i 行向量,如果第 q q q 个参数被剪枝,则对应位置置为0
  • X \mathbf{X} X:输入特征矩阵(隐含定义)
  • ∥ ⋅ ∥ 2 \| \cdot \|_2 2 L 2 L_2 L2 范数(欧几里得范数)

注意,这里 E 不再是损失函数了。

直观来看,E 反映的是,参数压缩前后,在同样的输入(具有代表性的校准数据)下,输出结果的差异。

由于每一行的参数相互独立,我们只需为每行量化后的参数 W ^ i , : \hat{\mathbf{W}}_{i,:} W^i,: 计算对应的海森矩阵:

∂ E ∂ W ^ i , : 2 = H i = 2 X X T , ∀ i = 1 , 2 , ⋯   , d row \frac{\partial E}{\partial \hat{\mathbf{W}}_{i,:}^{2}} = \mathbf{H}_{i} = 2\mathbf{X}\mathbf{X}^{\mathrm{T}}, \quad \forall i = 1, 2, \cdots, d_{\text{row}} W^i,:2E=Hi=2XXT,i=1,2,,drow

参数矩阵一行共 d col d_{\text{col}} dcol 个参数,如果删除 k 个参数,那么 OBC 的算法流程如下,截图中,M是参数的索引(从1开始):
在这里插入图片描述

从 for 循环开始逐行分析:

  • Line 1:找到对目标函数影响最小的参数所在索引 p;
  • Line 2:对第 p 个参数剪枝,并更新其他参数;
  • Line 3:更新 H − 1 \mathbf{H}^{-1} H1,这里用了数学的等价表达,其实和我们前面介绍的 OBS 更新 H − 1 \mathbf{H}^{-1} H1 的方式没差,这里 H : , p − 1 H p , : − 1 \mathbf{H}^{-1}_{:,p} \mathbf{H}^{-1}_{p,:} H:,p1Hp,:1 表示第 p 列乘第 p 行。

OBC 还对性能做了一些优化(空间换计算、计算换空间),不过这些和本文主题无关。

总的来说,OBC 就是对每一行使用 OBS 算法,就这么简单。

1.5 OBQ(Optimal Brain Quantization)的算法原理

OBQ 和 OBC 是同一篇文章提出来的,OBQ 认为,剪枝是一种特殊的量化(即剪枝的参数等价于量化到 0 点),即:
lim ⁡ quant ⁡ ( w q ) → 0 量化解 = 剪枝解 \lim_{\operatorname{quant}(w_q) \to 0} \text{量化解} = \text{剪枝解} quant(wq)0lim量化解=剪枝解

式中, quant ⁡ ( w q ) \operatorname{quant}(w_q) quant(wq) 是参数 w \mathbf{w} w 的第 q q q 维经过量化后的值,当然,这里说的量化,指的是 “量化+反量化”。

我们只需要修改一下 OBC 的约束条件,即可把 OBC 推广到一般量化场景。

一般量化的约束条件按如下方式修改:
e q T ⋅ Δ w + w q = quant ⁡ ( w q ) \mathbf{e}_{q}^{\mathrm{T}} \cdot \Delta \mathbf{w} + w_{q} = \operatorname{quant}(w_{q}) eqTΔw+wq=quant(wq)

量化后,参数 w \mathbf{w} w 的第 q q q 维的变化量为 quant ⁡ ( w q ) − w q \operatorname{quant}(w_q) - w_q quant(wq)wq,即 Δ w q = quant ⁡ ( w q ) − w q \Delta w_q= \operatorname{quant}(w_q) - w_q Δwq=quant(wq)wq

接下来要计算其他参数 Δ w i \Delta w_i Δwi i ≠ q i \neq q i=q )的更新量,以及 Δ w q \Delta w_q Δwq 量化后的影响(其他参数更新后的补偿影响)。

在OBC中, Δ w q = − w q \Delta w_q= -w_q Δwq=wq,而这里为 Δ w q = quant ⁡ ( w q ) − w q \Delta w_q= \operatorname{quant}(w_q) - w_q Δwq=quant(wq)wq,因此只需要将OBC剪枝解中的 w q w_q wq 替换为 w q − quant ⁡ ( w q ) w_q - \operatorname{quant}(w_q) wqquant(wq),可以得到通用解:
Δ w = − w q − quant ⁡ ( w q ) [ H − 1 ] q q H − 1 ⋅ e q L = 1 2 ( w q − quant ⁡ ( w q ) ) 2 [ H − 1 ] q q \Delta \mathbf{w} = -\frac{w_{q} - \operatorname{quant}(w_{q})}{\left[\mathbf{H}^{-1}\right]_{qq}} \mathbf{H}^{-1} \cdot \mathbf{e}_{q} \\ L = \frac{1}{2} \frac{\left( w_{q} - \operatorname{quant}(w_{q}) \right)^{2}}{\left[\mathbf{H}^{-1}\right]_{qq}} Δw=[H1]qqwqquant(wq)H1eqL=21[H1]qq(wqquant(wq))2

此公式组实现了OBC框架从剪枝到量化的完美扩展,通过量化误差替代剪枝量保持数学一致性。该结果是OBQ算法(OBC的量化版本)的理论基础,已在GPTQ等现代量化技术中广泛应用。

如果要量化 k 个参数,那么 OBQ 的算法流程如下:
在这里插入图片描述
OBQ算法对 k 个参数做量化的时间复杂度为 O ( k ⋅ d c o l 2 ) O(k\cdot d^2_{col}) O(kdcol2),这里 O ( d c o l 2 ) O(d^2_{col}) O(dcol2) 是排序的开销(我个人认为不需要排序,只需要选最小就行了,选最小的时间复杂度是 O ( n ) O(n) O(n),但为何要有平方,这个我就不清楚了)。

量化一般都是整行一起做(下一段会介绍细节),即 k = d c o l k=d_{col} k=dcol,所以对一行做量化的时间复杂度为 O ( d c o l 3 ) O(d^3_{col}) O(dcol3),对整个参数矩阵做量化的时间复杂度为 O ( d r o w ⋅ d c o l 3 ) O(d_{row} \cdot d^3_{col}) O(drowdcol3)

若整行一起量化,第 1 个参数量化时,会更新第 2、3、…… 、 d c o l d_{col} dcol 个参数,以补偿量化第 1 个元素带来的影响,但第 2 个参数量化时,只会更新第 3、4、…… 、 d c o l d_{col} dcol 个参数,不会更新第 1 个参数,也就是说,只会更新后面的,不影响前面已量化的。这个和剪枝的时候,计算其他参数的更新值,只计算未剪枝的,不计算已剪得,道理类似。

至此,GPTQ 的前置知识介绍完毕。

2 GPTQ(Gradient-based Post-training Quantization) 算法

GPTQ 是一种针对大型语言模型(LLMs)的高效训练后量化​(PTQ)算法,其核心目标是在不重新训练模型的前提下,将模型权重压缩至低比特(如4-bit),同时最小化精度损失。其原理基于分层误差补偿和海森矩阵优化,结合计算效率改进,实现大规模模型的高效量化。

2.1 原理

OBQ 的算法复杂度还是太高了,GPTQ 对 OBQ 做了一些算法和性能上的优化,以实现大模型的高效量化。

GPTQ 的创新点有:

  • 1 OBS 采用贪心策略,先量化对目标影响最小的参数,但 GPTQ 发现直接按顺序做参数量化,对精度影响也不大。
    • 这项改进使得参数矩阵每一行的量化可以做并行的矩阵计算,同时将时间复杂度从 O ( d r o w ⋅ d c o l 3 ) O(d_{row} \cdot d^3_{col}) O(drowdcol3) 降低到 O ( d c o l 3 ) O(d^3_{col}) O(dcol3),在大模型环境下,这项改进使得量化速度快了一个数量级;
  • 2 Lazy Batch-Updates (惰性批量更新),延迟一部分参数的更新,它能够缓解 bandwidth (带宽)的压力;
  • 3 Cholesky Reformulation,用 Cholesky 分解(柯列斯基分解法)求海森矩阵的逆,在增强数值稳定性的同时,不再需要对海森矩阵做更新计算,进一步减少了计算量。

上述改进中,第一点比较好理解,第三点需要有数值计算方法的基础(理论上说应该是线性代数的知识,但国内本科线性代数普遍不学这个,我是在硕士期间的《数值计算》方法那门课上学的),我们只需要知道第三点用了更稳定的方法计算海森矩阵的逆,了解到这一点就行了。

这里我们重点谈一下第2点:

OBQ 算法在量化某一行时,每次量化一个参数,但本行的其他所有未量化的参数都要更新,以补偿量化带来的影响,也就是说,量化第一个参数要读写参数矩阵 d c o l − 1 d_{col}-1 dcol1 次,量化第二个参数,要读写参数矩阵 d c o l − 2 d_{col}-2 dcol2 次,以此类推,整行量化完,读写参数矩阵的时间复杂度为 O ( d c o l 2 ) O(d^2_{col}) O(dcol2)

OBQ更新时,若多行并行量化,则参数量化是一列一列按次序进行的,第 i 列的参数的量化结果受到前 i-1 列量化的影响,但第 i 列的量化结果不影响前面列的量化,示意图如下:
在这里插入图片描述

对于第 i 列之前的参数(i 从1到 i-1),我们不需要每量化一次就更新一遍第 i 列的参数(这样第 i 列还没量化时,就更新了 i-1 次了),而是可以先记录第 i 列的更新量,等到量化到第 i 列时,再一次性更新参数,这样就可以减少 IO 的次数。

实际操作时,为了减少读写参数矩阵的次数,可以将参数矩阵按每 128 列划分为一个个 group,量化某一列时,同一个 group 内的后面的参数立即更新,后面的 group 只记录更新量。当一个 group 的参数全部量化完成,再统一对后面的所有参数做一次更新,这就是 Lazy Batch-Updates。

Lazy Batch-Updates 示意图如下:
在这里插入图片描述

2.3 海森矩阵与组内补偿

在GPTQ算法中,当模型权重按分组(Block)独立量化时,​其他组的参数更新量并非直接计算,而是通过“延迟批量更新”(Lazy Batch Update)机制间接实现。其核心思想是:​分组内量化误差通过海森矩阵局部补偿,而分组间的影响则通过全局误差累积后统一调整。

以下是具体原理和实现步骤:

  1. ​分组独立计算:将权重矩阵的每行按列分组(例如每组128列),每个组称为一个Block,对每个Block内的权重单独计算海森矩阵,组内权重的量化和更新与 OBQ 算法没差
  2. ​跨组延迟批量更新:量化当前组时,先记录组外权重变化量(加入到累积误差中),但不更新组外权重,当前组量化完成后,一次性应用到全局剩余权重矩阵​(即所有未处理的组)​:
    W global ← W global − ∑ block ϵ block ⋅ H global − 1 e block W_{\text{global}} \leftarrow W_{\text{global}} - \sum_{\text{block}} \epsilon_{\text{block}} \cdot \mathbf{H}_{\text{global}}^{-1} \mathbf{e}_{\text{block}} WglobalWglobalblockϵblockHglobal1eblock

其中, H global \mathbf{H}_{\text{global}} Hglobal 是全局海森矩阵的近似(实际工程中通过分组预计算获得), ϵ block \epsilon_{\text{block}} ϵblock 是当前组量化时,组外未处理的权重的变化量的累积,假如当前组有128列,那么 ϵ block \epsilon_{\text{block}} ϵblock 是128次变化量累加的结果。

百度飞火平台实测显示,当 group_size=128 时,GPTQ量化百亿模型精度损失<1%。

2.4 量化参数

GPTQ量化一般是分组线性量化,量化用的缩放因子和零点每个分组计算一次,组内参数共享一套量化参数。当然,也可以是每一列计算一次量化参数,不过这样容易导致量化参数过多。

3 AWQ (Activation-aware Weight Quantization)算法

AWQ(Activation-aware Weight Quantization)的算法逻辑步骤围绕“保护关键权重”的核心思想展开,通过激活感知动态调整量化策略,实现低比特量化下的高精度保持。以下是其算法逻辑的完整步骤:

3.1 算法原理

  1. 权重并非同等重要

    • 研究发现,大模型中仅有 0.1%-1% 的权重(显著权重,Salient Weights) 对模型输出影响较大。若保留这些权重的原始精度(FP16),量化其他权重可显著降低量化误差。
    • 显著权重的识别:通过激活值分布(而非权重自身分布)确定重要权重。激活值较大的通道对应更关键的权重,因其处理更重要的特征。
  2. 缩放保护代替混合精度

    • 直接保留部分权重为 FP16 会导致硬件效率低下(混合精度计算开销大)。
    • AWQ 的解决方案:对显著权重乘以缩放因子(s > 1),再量化所有权重。缩放后显著权重的相对量化误差减小,而非显著权重的误差增加量也不多,可以实现整体误差最小化。
      • 数学原理
        • 量化公式: w ′ = Round ( w ⋅ s / Δ ′ ) w' = \text{Round}(w \cdot s / \Delta') w=Round(ws/Δ),这里 Δ ′ \Delta' Δ 是量化参数
        • 反量化公式: Δ ′ ⋅ w ′ / s \Delta' \cdot w' / s Δw/s
        • 缩放后显著权重的误差比例降为原始误差的 1 / s 1/s 1/s

3.3 量化步骤

一、激活统计与通道重要性评估 [citation:1][citation:2]

  1. 校准数据前向传播
    使用少量校准数据(如128~512样本)输入FP16模型,收集每层输入激活值(Activation)的统计分布

    • 关键指标:计算每个输入通道(Channel)的激活绝对值均值或分位数( s X j = E [ ∣ X j ∣ ] s_{X_j} = \mathbb{E}[|X_j|] sXj=E[Xj])。
    • 物理意义:激活幅度大的通道处理更重要的特征(如语义关键词、图像轮廓),其对应权重对输出影响更大。
  2. 识别显著权重通道
    根据激活幅度排序通道,筛选Top 0.1%~1%的通道作为显著权重(Salient Weights)。实验表明:

    • 基于激活的筛选使OPT-6.7B的困惑度(PPL)从43.2降至13.0,而基于权重L2范数的筛选仅降至23.54。

二、缩放因子优化与动态保护

  1. 参数化缩放因子
    为每个通道设计缩放因子 s j s_j sj,关联其激活统计值:
    s j = ( s X j ) α s_j = (s_{X_j})^\alpha sj=(sXj)α

    • α \alpha α 的作用:控制缩放强度( α = 0 \alpha=0 α=0:不缩放; α = 1 \alpha=1 α=1:最强缩放)。
    • 设计动机:放大显著权重,使其量化后相对误差减小至原始误差的 1 / s 1/s 1/s
  2. 网格搜索最优 α \alpha α
    在校准集上优化目标函数:
    min ⁡ α ∥ Q ( W ⋅ diag ( s ) ) ⋅ ( diag ( s ) − 1 X ) − W X ∥ F \min_{\alpha} \| Q(W \cdot \text{diag}(s)) \cdot (\text{diag}(s)^{-1} X) - WX \|_F αminQ(Wdiag(s))(diag(s)1X)WXF

    • 搜索方式:在 α ∈ [ 0 , 1 ] \alpha \in [0,1] α[0,1] 区间网格搜索,选取使输出误差最小的 α \alpha α
    • 高效性:仅需单参数搜索,成本远低于GPTQ的二阶优化。

三、权重缩放与量化执行

  1. 权重预缩放
    将权重矩阵按通道缩放: W scaled = W ⋅ diag ( s ) W_{\text{scaled}} = W \cdot \text{diag}(s) Wscaled=Wdiag(s)

    • 数学等价性:缩放后线性运算 y = ( W ⋅ s ) ⋅ ( x / s ) = W x y = (W \cdot s) \cdot (x / s) = Wx y=(Ws)(x/s)=Wx 保持不变。
    • 误差控制:显著权重的量化误差比例降至 1 / s 1/s 1/s,非显著权重误差容忍度提高。
  2. 分组量化(Group Quantization)

    • 量化方式:对 W scaled W_{\text{scaled}} Wscaled 进行低比特均匀量化(如INT4)。
    • 硬件友好设计
      • 按输出通道分组(如每组128个权重),共享量化参数(scale/zero_point)。
      • 避免混合精度,支持SIMD指令并行处理。
  3. 可选权重裁剪
    限制 W scaled W_{\text{scaled}} Wscaled 的数值范围(如裁剪至 [ − c , c ] [-c, c] [c,c]),降低离群值影响,进一步减小量化缩放系数 Δ ′ \Delta' Δ

四、反量化与推理加速

  1. 运行时反量化
    推理时,权重从INT4动态反量化为FP16:
    W dequant = Δ ′ ⋅ INT4 / s W_{\text{dequant}} = \Delta' \cdot \text{INT4} / s Wdequant=ΔINT4/s

    • 硬件优化:与内核融合(Kernel Fusion)结合,减少内存访问开销。
  2. 框架级优化

    • vLLM/TinyChat:将反量化融入GEMM运算,实现3-4倍加速[citation:1][citation:7]。

3.4 关键创新与优势总结

步骤技术贡献效果
激活感知重要性评估用输入激活(非权重自身)识别关键通道避免权重冗余干扰,提升显著权重筛选精度
单参数缩放因子搜索 α \alpha α 控制全局缩放强度,替代混合精度硬件友好,保持全低比特存储
通道分组量化组内共享量化参数,适配SIMD指令推理延迟降低60%(对比GPTQ)
动态反量化融合与计算内核融合,减少DRAM访问资源受限设备(如树莓派)可运行70B模型

4 AWQ 与 GPTQ 的对比

在模型量化领域,AWQ(Activation-aware Weight Quantization)和GPTQ(Generative Pre-trained Transformer Quantization)是两种主流技术,各自适配不同的部署场景。以下是基于技术特性、硬件兼容性和任务需求的综合对比与选择建议:

4.1 核心差异对比

维度AWQGPTQ
核心原理激活感知缩放保护关键权重(0.1%-1%显著权重)基于海森矩阵的逐层误差补偿(二阶优化)
量化精度更优(低比特下精度损失<5%)良好(4-bit下可能损失5-10%)
推理速度更快(比GPTQ快1.45倍)中等(需权重重排序)
硬件兼容性GPU/边缘设备(适配vLLM/TinyChat)主流GPU(依赖CUDA/exllama)
模型泛化支持多模态(视觉+语言)专注Transformer类模型(如GPT/LLaMA)
部署复杂度中等(需校准数据)较低(AutoGPTQ工具链成熟)
校准数据需求少(128样本)多(512-1024样本)

4.2 选择建议:优先使用AWQ的场景

  1. 边缘设备部署(如手机/嵌入式系统)

    • 理由:AWQ通过权重打包(4-bit打包为INT16)和内核融合优化内存访问,显存占用降至1/4,树莓派5可运行7B模型。
    • 工具链:TinyChat框架适配Jetson Orin等低功耗设备。
  2. 多模态模型(视觉-语言联合任务)

    • 理由:AWQ首次实现视觉语言模型的高效量化(仅量化语言部分),GPTQ缺乏此类支持。
  3. 高精度敏感型任务(如医疗/金融决策)

    • 理由:激活感知保护显著权重,INT4量化下困惑度(PPL)接近FP16(如OPT-6.7B的PPL从43.2→13.0)。
  4. 小batch推理与低延迟API

    • 理由:AWQ在增量生成任务中延迟更低,配合TGI引擎支持动态批处理。

4.3 选择建议:优先使用GPTQ的场景

  1. 云端高吞吐服务(如聊天机器人API)

    • 理由:GPTQ量化模型在vLLM引擎下吞吐量更高(70B模型达100+ tokens/s),适合并发请求。
    • 工具链:AutoGPTQ + vLLM组合成熟度高。
  2. 极致压缩需求(显存严重受限)

    • 理由:GPTQ支持更低比特(如3-bit)压缩,显存占用比AWQ更低。
  3. 纯Transformer架构模型(如LLaMA/Mistral)

    • 理由:专为GPT类模型优化,社区支持广泛(HuggingFace模型库覆盖全)。

4.4 决策流程图

graph TD
    A[部署场景] --> B{资源受限?}
    B -->|是| C{是否边缘设备?}
    C -->|是| D[选AWQ]
    C -->|否| E{是否多模态?}
    E -->|是| D[选AWQ]
    E -->|否| F[选GPTQ]
    B -->|否| G{是否高吞吐?}
    G -->|是| F[选GPTQ]
    G -->|否| H{是否低比特压缩?}
    H -->|是| F[选GPTQ]
    H -->|否| D[选AWQ]

4.5 实践注意事项

  1. 量化校准

    • AWQ需确保校准数据代表实际输入分布,否则显著权重识别可能偏差。
    • GPTQ需调优分块大小(block size),平衡速度与精度。
  2. 混合精度策略

    • 对敏感层(如输出层)保留FP16,其余用AWQ/GPTQ量化,可进一步提升精度。
  3. 工具链更新

    • AWQ生态快速发展(如AutoAWQ支持Qwen/Mistral),建议定期跟踪GitHub更新。

4.6 总结

  • 选AWQ:边缘设备、多模态模型、高精度需求、低延迟场景。
  • 选GPTQ:云端高并发、纯Transformer模型、极致压缩需求。
    两者并非互斥,生产环境中可对模型分层混合使用(如关键层AWQ+其他层GPTQ),实现精度与效率的帕累托最优。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值