论文精读 · ICLR 2023 · POST-TRAINING QUANTIZATION

GPTQ:从公式 1 到公式 2
把二阶量化的每一步拆开

GPTQ 最难的并不是记住“用 Hessian 逆补偿误差”,而是理解:它究竟在最小化什么?公式 (2) 为什么必然从公式 (1) 出发?分母为什么是逆 Hessian 的对角元素?本文沿原论文符号,把这条链完整推一遍。

原论文:GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers
Frantar, Ashkboos, Hoefler, Alistarh · arXiv:2210.17323v2 · ICLR 2023
先记住四句话
问题背景

01GPTQ 到底要解决什么

一个线性层在浮点模型里计算 Y=WX。权重 W 可能有几十亿个 FP16 元素;把它压成 4 bit,模型体积可接近四分之一,也能降低推理时的显存带宽压力。但每个权重都必须被舍入到稀疏的量化格点,得到 \widehat W,输出就会从 WX 变成 \widehat WX

常见误解:逐元素最近舍入已经最好
逐元素 RTN 只保证每个 |w-\widehat w| 局部较小,却没有考虑输入激活。某个方向几乎从不被激活,即使权重偏差较大也可能无害;另一个方向在真实数据上很活跃,同样大小的权重偏差会被放大成巨大输出误差。模型真正执行的是矩阵乘法,不是比较两张权重表。

GPTQ 属于训练后量化(PTQ):不重新训练模型,只用一小批校准数据收集各层输入 X,逐层寻找低比特权重。它继承 OBQ(Optimal Brain Quantization)的二阶误差补偿,并用固定顺序、lazy batch update 与 Cholesky 重构把它扩展到 175B 模型。

FP16 权重 W校准激活 X构造 H=2XXᵀ逐列量化未量化列补偿低比特 Ŵ
论文原式

02公式 (1):量化目标究竟是什么

论文首先把每个线性层单独处理。原文公式 (1) 是:

论文沿用矩阵 2-范数记法;这里的语义是对校准样本上的全部输出误差求平方和,通常更明确地写成 Frobenius 范数 \|\cdot\|_F^2
W\in\mathbb R^{d_{out}\times d_{in}}
原始浮点权重矩阵。每一行产生一个输出通道,每一列对应一个输入特征。
\widehat W
待寻找的量化权重。其元素不能任意取实数,而要落在给定 bit 数、scale 和 zero-point 确定的量化格点上。
X\in\mathbb R^{d_{in}\times N}
N 个校准 token 在当前层入口处的激活。列是样本位置,行是输入特征。
WX-\widehat WX
同一批输入经过浮点层和量化层后的输出差。GPTQ 直接保护的是这个量,不是参数本身。
\arg\min
寻找使输出平方误差最小的量化权重,而不是只求最小误差数值。

为什么它能按行拆开

Frobenius 范数是所有元素平方和。把 W 的第 r 行记为 w_r^\top,就有:

每一项只涉及权重矩阵的一行,因此不同输出行可以独立量化;所有行又共享同一个输入 X,也就共享同一个 Hessian。这一“逐行独立、曲率共享”的结构,是后续大规模加速的基础。

公式 (1) 的一句话翻译
给定一小批真实输入,找一张低比特权重表,让这一层在这些输入上的答案尽可能接近原层。它是一种局部层重构代理目标,不等同于直接最小化整个语言模型的最终 loss。
关键桥梁

03从公式 (1) 到 Hessian 二次型

只看任意一行,把量化后的变化定义为 \delta w=\widehat w-w。因为 w-\widehat w=-\delta w,平方会消掉符号:

步骤 1:改写单行输出误差
步骤 2:把范数展开成矩阵乘法

行向量的 2-范数平方等于它和自身转置的内积。\delta w^\top X 是一个 1\times N 行向量,所以:

把右边的转置拆开 (\delta w^\top X)^\top=X^\top\delta w,再把两个 \delta w 提到两端:

中间的 XX^\top 是一个只依赖校准输入、与权重无关的 d_{in}\times d_{in} 常量矩阵。

步骤 3:定义 Hessian

为了写成标准二阶形式,令 H=2XX^\top

这里不是“用二阶泰勒近似猜一个损失”。层重构损失本身就是关于 \delta w 的二次函数,所以二阶展开是精确的:原点处常数项为 0,梯度为 0,三阶及更高项不存在。

为什么一阶项为 0
\nabla\mathcal L=2XX^\top\delta w。在原权重处 \delta w=0,输出误差恰好为 0,因此梯度也为 0。
H 的几何含义
H 描述不同权重方向的扰动会怎样在校准输入上形成输出误差;大曲率方向动一点就很贵。
为什么会出现 H⁻¹
我们已知某一坐标必须移动,要求其余坐标以最低代价联动。逆曲率把约束施加的“力”转换成最低损失的位移。
为什么需要 damping
若校准样本不足或特征共线,XX^\top 可能奇异。实现会用 H+\lambda I 保证可逆并稳定 Cholesky。
核心推导

04公式 (2):选谁量化,其他权重怎样补偿

论文在回顾 OBQ 时给出公式 (2)。它把两个动作写在一起:

更严谨地说,第一式选择的是索引 q^*F 表示当前仍未被固定、还能参加补偿的权重集合。
先统一符号,避免正负号看乱
定义取整造成的必需变化 r_q=\operatorname{quant}(w_q)-w_q。于是论文第二式也可写成 \delta_F=\frac{r_q}{[H_F^{-1}]_{qq}}(H_F^{-1})_{:,q}。两种写法完全相同,因为 -(w_q-quant(w_q))=r_q

4.1 固定候选 q 后,优化问题是什么

现在先不讨论“选哪个 q”,只假设第 q 个权重已经决定要量化。它的第 q 维必须变化 r_q,而其他未量化权重仍可自由调整:

e_q 是第 q 个标准基向量;左乘 e_q^\top 只是从完整扰动中取出第 q 个坐标。约束说的是:无论其他权重怎么帮忙,第 q 个权重必须准确落到量化格点。

4.2 用拉格朗日乘子求补偿方向

这是一个严格凸二次目标 + 单个线性等式约束的问题,可以用一个拉格朗日乘子 \lambda 精确求解。下面每一步只做一件事,不合并。

第 1 步 · 写出拉格朗日函数

把目标函数和约束用乘子 \lambda 合并成一个无约束函数:

第 2 步 · 对扰动向量 δ_F 求梯度并令其为零

二次项求导得 H_F\delta_F,线性项求导得 \lambda e_q,因此驻点条件是:

第 3 步 · 解出 δ_F(还含未知的 λ)

把上式移项,两边左乘 H_F^{-1}

这里已经能看出关键信息:H_F^{-1}e_q 就是逆 Hessian 的第 q 列。也就是说,最优补偿方向不是谁凭经验指定的,而是驻点方程直接决定的——其余权重必须沿着这一列的方向联动。

第 4 步 · 代回约束,解出 λ

补偿必须满足“第 q 维恰好变化 r_q”这个约束。把第 3 步的 \delta_F 代入 e_q^\top\delta_F=r_q

第 5 步 · 把二次型识别成对角元素

注意 e_q^\top H_F^{-1}e_q 就是从逆 Hessian 里取出第 q 行第 q 列那一个数,即对角元素:

于是第 4 步的方程变成一个标量方程:

第 6 步 · 解出乘子 λ
第 7 步 · 把 λ 代回,得到论文的补偿式

把第 6 步的 \lambda 代回第 3 步的 \delta_F=-\lambda H_F^{-1}e_q

这正是论文公式 (2) 的第二部分(最优补偿)。

第 8 步 · 逐坐标验证它确实满足约束

把补偿写成逐分量形式:

j=q 时,分子里的 [H_F^{-1}]_{qq} 与分母抵消,得到 \delta_q^*=r_q——第 q 个权重准确落到量化格点,约束满足;当 j\ne q 时,\delta_j^* 就是第 j 个未量化权重为补偿这次量化而承担的位移。

4.3 把补偿代回,得到第一部分的选点分数

现在我们知道:一旦决定量化第 q 个权重,其他权重会以上面的最优方式补偿。那么这一步不可避免的最小损失是多少?把 \delta_F^* 代回二次目标 \Delta\mathcal L=\tfrac12\delta_F^\top H_F\delta_F

A · 代入并利用 H_F H_F⁻¹=I

中间三项 H_F^{-1}H_FH_F^{-1}=H_F^{-1},于是化简为 e_q^\top H_F^{-1}e_q=[H_F^{-1}]_{qq}

B · 约掉一个对角元素

这就是“量化 q、并允许其他权重做最佳补偿后,仍然躲不掉的最小输出损失”。

C · 去掉共同常数,得到选点判据

对每个候选 q,比较的都是这个最小损失。常数 \tfrac12 对所有候选都一样,不改变谁最小,所以论文把它省掉,选损失最小的那个:

这正是论文公式 (2) 的第一部分(贪心选点)。论文写成 w_q=\arg\min_{w_q}\cdots,但从语义看,它选的是索引 q^*

分子 r_q^2
该权重距离量化格点有多远。越远,必须承受的坐标变化越大。
分母 [H_F^{-1}]_{qq}
在当前剩余自由度里,这个坐标变化有多大“可补偿空间”。越大,达到同样第 q 维位移的最低二次代价越小。
整列 (H_F^{-1})_{:,q}
各未量化权重应该朝哪个方向、移动多少,才能最有效地抵消 q 的量化误差。
概念边界

05为什么是最优,又为什么不是全局最优

固定 q:精确全局最优
若阻尼后的 H_F\succ0,目标是严格凸二次函数,约束是线性等式。KKT 条件充分且必要,求出的补偿唯一且全局最优。
选择下一项:单步最优
每个候选 q 的最小损失都已精确算出,再取最小者,所以这是当前一步的 greedy-optimal 选择。
完整离散量化:不保证全局最优
所有权重最后都要落到离散格点,不同步骤互相耦合。第一步最便宜,不代表最终整条决策路径是组合全局最优。
GPTQ 还进一步近似
OBQ 每行都贪心选 q;GPTQ 为让所有行共享顺序并高效批处理,改成固定列顺序。因此公式 (2) 是理论起点,不是 Algorithm 1 原封不动的执行顺序。
最准确的一句话
公式 (2) 证明的是:如果现在必须量化一个权重,那么它能给出每个候选的精确最低单步代价和对应的最佳连续补偿;它没有证明全部低比特权重的离散组合是全局最优。
手算验证

06一个 2×2 例子:补偿到底补了多少

设单行权重为 w=[1.30,0.80]^\top,校准数据给出的 Hessian 为:

量化第一个权重:1.30\to1.25,所以 r_1=-0.05

不补偿
按公式 (2) 补偿

第一个坐标准确落到 1.25;第二个尚未量化的权重临时从 0.80 移到 0.8333。代价变成:

结果
补偿把单步输出误差从 0.005 降到 0.00333,下降约 33.3%。它没有消灭第一个权重的取整误差,而是利用第二个权重的自由度,让两者在真实输入方向上造成的输出偏差部分相消。
算法落地

07从 OBQ 公式到 GPTQ Algorithm 1

朴素 OBQ 精度高,但每一行都要反复寻找当前最便宜的 q、更新有效逆 Hessian,扩展到大模型太慢。GPTQ 保留“量化一个位置后,让未量化位置吸收误差”的核心,做了三项关键改造。

固定列顺序
不再为每行做独立贪心排序,而按共同的列顺序处理。各输出行便能共享 Hessian 信息并向量化执行。
Lazy batch update
块内逐列立即修正,跨块的大范围更新先累积,块结束后用矩阵乘一次性写回,减少内存带宽瓶颈。
Cholesky reformulation
对阻尼后的逆 Hessian 信息做 Cholesky 分解,避免逐步删行列造成的数值误差,并高效提供递归更新所需因子。
逐行并行
同一列的所有输出行一起量化;每行误差不同,但共享输入曲率结构,适合 GPU 上的批量矩阵运算。
GPTQ 原论文 Figure 2 量化流程
原论文 Figure 2:GPTQ quantization procedure。粗框是当前列块;块内递归逐列量化,块结束后批量更新右侧尚未量化的区域。图把固定顺序、lazy batch update 和 Cholesky 重构集中画在一起。打开 arXiv 源码中的原始矢量 PDF

概念上,量化第 i 列后对后续列 j 的更新仍可理解为公式 (2) 的矩阵化版本:

不要把概念式和伪代码中的符号机械逐项对照
论文 Algorithm 1 在 Cholesky reformulation 后复用 H^{-1} 这个符号表示分解后的因子信息,因此伪代码里的对角项形式与未经分解的完整逆 Hessian 概念式不同。两者表达同一误差传播逻辑,但中间表示已经改变。

论文公式 (3)–(5) 在整条链里的位置

原论文位置作用与公式 (1)(2) 的关系
Eq. (1)定义层输出重构目标回答“到底最小化什么”
Eq. (2)OBQ 的贪心选点与最优补偿回答“量化一个权重后怎样最小损失”
Eq. (3)某坐标被固定后,更新剩余逆 Hessian让下一轮继续在正确的有效子问题上工作
Eq. (4)–(5)把逐列更新整理成块矩阵更新减少反复访问大权重矩阵
Algorithm 1固定顺序 + 分块 + Cholesky 的完整 GPTQ把理论补偿变成可在超大模型上运行的算法
论文实验

08原论文图片告诉了我们什么

GPTQ 原论文 Figure 3 LAMBADA 精度
原论文 Figure 3:LAMBADA 零样本精度。左、右分别为 OPT 与 BLOOM,比较 FP16、GPTQ 与 RTN。4-bit 整体较稳定;进入更困难的 3-bit 后,朴素 RTN 明显失效,而 GPTQ 的二阶补偿仍保留较好的精度。这张图直接证明“只做最近舍入”与“考虑输入曲率后补偿”并不等价。原始矢量 PDF
GPTQ 原论文 Figure 4 分组量化消融
原论文 Figure 4:4-bit GPTQ 的 group-size 消融。更细粒度的分组量化(g1024、g128)通常比整行共享一套量化网格更接近 FP16,因为每组的动态范围更容易拟合。需注意:原论文主实验不是今天部署生态里常见的“默认 g128”;g128 后来成为常用工程折中。原始矢量 PDF
图与公式的对应关系
Figure 3 体现公式 (2) 的价值:相同低 bit 下,补偿显著优于独立舍入。Figure 4 则说明量化格点本身也很重要:公式 (2) 能优化既定格点下的误差传播,但更合理的分组 scale 会先减小分子里的取整误差 r_q^2
边界与实践

09GPTQ 的优势、局限与常见混淆

问题结论
是否需要训练不需要反向训练;需要少量校准数据做前向,收集各层输入激活。
Hessian 是否来自模型训练 loss这里核心是层输出重构损失的 Hessian 2XX^\top,不是直接计算整个语言模型交叉熵的完整 Hessian。
是否真的显式求“大模型全 Hessian”不是。按层处理,并在一行权重的输入维度上构造共享的 Gram/Hessian 矩阵。
公式 (2) 是否等于 GPTQ 全部创新不是。它来自 OBQ,是理论起点;GPTQ 的贡献在于把这套补偿通过固定顺序、分块和稳定分解扩展到超大模型。
act-order / desc_act 是否来自原论文 Algorithm 1不是原论文默认步骤,而是后续 GPTQ-for-LLaMa、AutoGPTQ 等生态常见扩展。
group_size=128 是否是原论文默认不是。原论文主设置采用 row-wise 网格,并额外展示 g1024/g128 消融;g128 是后续部署生态常见选择。
优势
低 bit 权重量化精度高;只需校准前向;4-bit GPU 推理生态成熟;对 RTN 在 3-bit 附近的崩塌有明显改善。
局限
依赖校准分布;逐层局部目标不等于端到端最优;量化阶段比简单 RTN/AWQ 搜索更重;主要处理权重误差,不直接解决低 bit 激活量化。
最终把整篇压缩成一条推导链
\|WX-\widehat WX\|^2(保护层输出) → 按行拆分 → \frac12\delta^\top H\delta, H=2XX^\top(精确二次型) → 强制 \delta_q=r_q(量化约束) → 拉格朗日/KKT → \delta^*=r_qH^{-1}_{:,q}/[H^{-1}]_{qq}(最佳补偿) → \Delta L_q^*=r_q^2/(2[H^{-1}]_{qq})(单步最小损失) → 固定顺序、分块、Cholesky(GPTQ 工程化)。
资料来源

10原始论文与代码

论文:GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers,arXiv:2210.17323v2,ICLR 2023。

作者代码:IST-DASLab/gptq

图片:本文 Figure 2、3、4 均抽取自 arXiv v2 源码包中的原始论文资源;页面展示 PNG 便于浏览,同时保留原始矢量 PDF 链接。

口径说明:公式 (1)(2) 按 v2 核对。拉格朗日推导、最小损失公式与 2×2 示例是本文为解释原式补充的推导,不冒充论文原编号公式。