大模型量化系列(三):GPTQ — 把大模型权重量化到 3/4 bit
论文: GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers
作者: Elias Frantar, Saleh Ashkboos, Torsten Hoefler, Dan Alistarh
发表: ICLR 2023 | arXiv:2210.17323
一句话总结: GPTQ 的意义不只是把权重压到 3/4 bit,而是证明了二阶补偿式 post-training weight quantization 可以扩展到 175B 级大模型,让低比特 weight-only 量化从简单取整走向真正可用。
一、为什么 SmoothQuant 之后还需要 GPTQ
前两篇文章讲的是另一条主线。
LLM.int8() 发现了大模型里的 activation outlier:少数 hidden dimension 会出现稳定且幅度极大的异常值,导致朴素 INT8 量化失效。它的处理方式是把 outlier channel 拆出来,用 FP16 单独计算。
SmoothQuant 则进一步问:能不能不保留 FP16 outlier 分支,而是把 activation 的量化难度迁移到 weight,让主要矩阵乘走更硬件友好的 W8A8 路线?
GPTQ 切入的是另一个问题。
它不强求 activation 进入低精度。相反,activation 仍然保留 FP16/BF16,GPTQ 只处理静态 weight:
1 | W4A16 / W3A16: |
这不是 SmoothQuant 的替代品,而是另一个部署目标下的选择。W8A8、FP8 这类路线更偏向统一低精度计算和高吞吐 serving;W4A16 weight-only 则更直接地压缩模型权重,降低显存占用和 decode 阶段的访存压力。
对自回归生成来说,这一点很重要。生成时模型通常逐 token decode,大量计算是 matrix-vector product,不一定总是算力瓶颈,很多时候更受 memory bandwidth 限制。权重越小,从显存读取权重的压力就越低。
所以 GPTQ 要回答的问题可以写成:
如果 activation 不动,只把 weight 压到 3/4 bit,能不能仍然保持大模型的语言建模能力?
这个问题看似简单,但在 GPTQ 之前,答案并不乐观。
二、RTN 为什么到 3/4 bit 会失败
最直接的 weight quantization 方法是 RTN,也就是 round-to-nearest。
它的思路非常朴素:给定一个量化网格,把每个 weight 独立地映射到最近的量化值。
1 | 原始 weight: 0.37 |
这在 8-bit 时通常还可以。因为 8-bit 有 256 个状态,量化格点比较密,单个 weight 的误差不大,累积起来也未必立刻毁掉模型。
但到 4-bit,只有 16 个状态;到 3-bit,只有 8 个状态。格点变稀疏后,独立取整的问题就暴露出来了:RTN 只关心每个 weight 自己离哪个格点最近,却不关心整个 layer 的输出会发生什么。
在线性层里,我们真正想保持的是:
量化后是:
因此更合理的目标不是让每个 weight 的误差都最小,而是让整个 layer 的输出误差最小:
这里的关键是:weight 之间不是孤立的。某个 weight 被量化后带来的误差,可能可以通过调整其他还没量化的 weight 来补偿。
RTN 完全没有这个补偿过程。
这也是论文实验里非常刺眼的地方。OPT-175B 在 WikiText2 上,FP16 perplexity 是 8.34;4-bit RTN 掉到 10.54;到了 3-bit RTN,直接崩到 7.3e3。BLOOM-176B 也类似,3-bit RTN 在 WikiText2 上达到 571。
所以 GPTQ 的出发点不是“换一个量化网格”这么简单,而是:
量化一个 weight 之后,能不能调整剩余 weight,把它造成的输出误差补回来?
答案来自 OBQ。
三、从 OBQ 到 GPTQ
GPTQ 建立在 OBQ,也就是 Optimal Brain Quantization 的基础上。
OBQ 的思想可以这样理解:当你决定把某个 weight 从
1 | 这个变化会怎样影响 layer output? |
这个“影响”由 Hessian 近似描述。
对线性层的重构目标:
它本质上是一个二次目标。对于这种目标,Hessian 信息能告诉我们不同 weight 方向上的改动会带来多大的输出误差,以及不同 weight 之间的耦合关系。
直觉上,OBQ 做的是:
- 选择一个 weight 量化
- 计算这次量化带来的误差
- 根据 Hessian inverse,把误差分摊到剩余未量化 weight 上
- 重复直到整行 weight 都被量化
这比 RTN 聪明得多。RTN 是“各量各的”;OBQ 是“量化一个,补偿一批”。
问题是,原始 OBQ 太慢。
它会对每一行 weight 独立做贪心量化,每一步还要维护和更新 Hessian inverse。对 ResNet-50 这种 2500 万参数模型,OBQ 级别的方法还能接受;但对 OPT-175B、BLOOM-176B 这种模型,逐权重贪心和频繁矩阵更新完全不可行。
所以 GPTQ 的核心贡献不是从零发明二阶补偿,而是把这个思路改造成能跑在百亿、千亿参数模型上的算法。
四、GPTQ 的三个工程化改造
GPTQ 第 4 节最值得精读。它不是堆技巧,而是连续解决了三个扩展性问题。
1. 固定量化顺序:放弃逐权重贪心
OBQ 会贪心地选择“当前量化误差最小”的 weight。这个选择很自然,但代价很高:不同 row 的量化顺序可能不同,Hessian inverse 的更新也难以共享。
GPTQ 的观察是:在大模型的大矩阵里,贪心顺序相比任意固定顺序的收益并不大。
这个观察非常关键。既然顺序可以固定,那么所有 row 就可以按相同的 column 顺序一起量化。这样一来,未量化 weight 的集合对所有 row 都相同,对应的 Hessian inverse 更新也可以共享。
复杂度因此从原始 OBQ 的:
降到:
对大模型来说,这不是小优化,而是几个数量级的差别。
2. Lazy batch update:让 GPU 真正忙起来
即使复杂度降下来了,直接实现仍然不快。
原因是很多更新操作的 compute-to-memory-access ratio 很低:每读写一个巨大矩阵元素,只做很少的 FLOPs。这种操作在 GPU 上会被 memory bandwidth 卡住,算力利用率很差。
GPTQ 的第二个改造是 lazy batch update。
它不在量化每一列后立刻全局更新所有后续 weight,而是一次处理一个 block,比如 128 columns。块内先递归更新,只维护当前 block 需要的信息;等这个 block 全部量化完,再把累积误差统一应用到后面的所有 columns。
可以把它理解成:
1 | 不要每走一步就打扫全场; |
理论计算量没有本质减少,但矩阵操作更大、更连续,更适合 GPU kernel。论文指出,这一步在大模型上带来了约一个数量级的实际加速,是 GPTQ 能跑起来的关键之一。
3. Cholesky reformulation:解决大模型数值稳定性
最后一个问题是数值稳定性。
OBQ/GPTQ 依赖 Hessian inverse。如果反复用矩阵更新公式维护它,误差会不断累积。在小模型上,加一点 dampening 可能就够了;但模型大到几十亿、上百亿参数后,某些层很容易出现数值问题,导致更新方向变坏,整层量化结果失控。
GPTQ 的处理方式是换一个更稳定的表达。
它观察到,量化第
配合对 Hessian 对角线加入轻微 dampening,算法在超大模型上就稳定得多。
这一步很容易被读成实现细节,但它其实非常重要。没有数值稳定性,再漂亮的二阶补偿都无法可靠地跑完 175B 模型。
所以 GPTQ 的三个改造可以概括为:
| 问题 | GPTQ 的处理 |
|---|---|
| OBQ 贪心顺序太贵 | 固定量化顺序,跨 row 共享更新 |
| 更新操作 GPU 利用率低 | lazy batch update,按 block 聚合更新 |
| Hessian inverse 更新不稳定 | Cholesky reformulation + dampening |
这就是 GPTQ 的本质:把 OBQ 的准确性,改造成大模型规模下可执行的算法。
五、实验结果与部署意义
GPTQ 的实验重点不是证明“小模型也能量化”,而是证明 175B 级别模型可以在 one-shot PTQ 下压到 3/4 bit。
论文的设置很克制:只用 128 个来自 C4 的随机 2048-token 片段做 calibration,不使用任务特定数据。量化过程按 Transformer block 逐块加载到单张 80GB A100 上完成。
量化耗时也在可接受范围内:
| 模型 | 量化耗时 |
|---|---|
| OPT-13B | 20.9 分钟 |
| OPT-30B | 44.9 分钟 |
| OPT-66B | 1.6 小时 |
| OPT-175B | 4.2 小时 |
| BLOOM-176B | 3.8 小时 |
最关键的是 perplexity。
OPT-175B 在 WikiText2 上:
| 方法 | Bits | WikiText2 PPL |
|---|---|---|
| FP16 | 16 | 8.34 |
| RTN | 4 | 10.54 |
| GPTQ | 4 | 8.37 |
| RTN | 3 | 7.3e3 |
| GPTQ | 3 | 8.68 |
BLOOM-176B 在 WikiText2 上:
| 方法 | Bits | WikiText2 PPL |
|---|---|---|
| FP16 | 16 | 8.11 |
| RTN | 4 | 8.37 |
| GPTQ | 4 | 8.21 |
| RTN | 3 | 571 |
| GPTQ | 3 | 8.64 |
这组数字说明了 GPTQ 的价值:4-bit 基本接近 FP16,3-bit 虽然有损失但仍然可用;而 RTN 在 3-bit 下直接崩溃。
部署意义也很直接。
论文中 3-bit OPT-175B 约占 63GB,包括保持 FP16 的 embedding 和 output layer。再加上最长 2048 token 的 KV cache,大约还能放进一张 80GB A100。作为对比,FP16 OPT-175B 需要 5 张 80GB GPU,LLM.int8() 级别的 8-bit 方案也需要 3 张。
速度方面,GPTQ 的加速不是来自 INT4 Tensor Core 直接算矩阵乘。当时主流硬件并没有很好支持 FP16 activation 乘 INT4 weight 的混合精度矩阵乘。论文的实际加速来自自定义 kernel:读取低比特权重,在需要时动态 dequantize,再和 FP16 activation 做运算。
因为 decode 阶段常常受显存带宽限制,少读权重就能提速。论文报告:
| GPU | FP16 | 3-bit GPTQ | Speedup | GPU 数量变化 |
|---|---|---|---|---|
| A100 80GB | 230ms/token | 71ms/token | 3.24x | 5 -> 1 |
| A6000 48GB | 589ms/token | 130ms/token | 4.53x | 8 -> 2 |
这也是 GPTQ 能影响后续部署生态的原因:它不仅给出了低 bit 精度结果,还说明 weight-only quantization 可以真实降低显存和 latency。
六、个人评价:真正的价值不是 4-bit,而是可扩展
GPTQ 很容易被概括成“一篇 4-bit 量化论文”。这个说法没错,但不够准确。
它真正重要的地方在于:把 accurate PTQ 从小模型时代带到了 175B 时代。
在 GPTQ 之前,大家并不是不知道二阶信息有用。OBQ、BRECQ、AdaRound 这些方法都说明,更聪明的量化决策可以显著优于 RTN。问题是它们太贵,扩展不到真正的大语言模型。
GPTQ 的贡献,是把一个理论上更准确但工程上不可用的方向,改造成可以在几小时内处理 175B 模型的流程。
这和 SmoothQuant 的优雅不太一样。
SmoothQuant 的漂亮之处在于一个等价变换:
1 | 把 activation outlier 的难度迁移到 weight |
GPTQ 的漂亮之处在于一个工程判断:
1 | 不要追求完整 OBQ 的每一步最优; |
这也是为什么 GPTQ 的结果在今天看仍然有意义。很多后续系统不一定原封不动使用论文里的实现,但它打开了一个稳定的思路:weight-only 低比特量化不能只做局部取整,必须考虑量化误差如何影响 layer output。
七、站在 2026 回看 GPTQ
站在 2026 年看,GPTQ 是 weight-only low-bit 量化路线里的关键节点。
但我们需要避免一个过度简化的结论:不是说 GPTQ 之后,W8A8 就被 W4A16 取代了。
更准确的格局是:
| 路线 | 典型目标 |
|---|---|
| W8A8 / FP8 | 高吞吐 serving、硬件原生低精度计算、统一 GEMM 路径 |
| W4A16 / W3A16 weight-only | 显存受限、本地推理、decode bandwidth、开源部署 |
| KV cache quantization | 长上下文和大 batch 下压缩 attention cache |
| FP4 / mixed precision | 新硬件支持下的更激进端到端低精度路线 |
GPTQ 所在的是第二条。
这条路线后来继续发展出很多工程分支:AWQ 关注 activation-aware 的重要权重保护;Marlin、ExLlama 等 kernel 关注 4-bit weight-only 的实际吞吐;bitsandbytes 4-bit 让普通开发者更容易加载和微调低比特模型。
现代推理系统还叠加了 paged attention、continuous batching、speculative decoding、prefix cache 等机制。今天评估一个量化方法,不能只问 perplexity 有没有掉,还要看它如何影响完整 serving stack:显存、带宽、batch size、KV cache、kernel 可用性和端到端 latency。
但 GPTQ 留下的核心问题仍然成立:
当 weight 被压到 3/4 bit 时,简单取整不够;必须让量化决策感知输出误差。
这正是它在大模型量化演进里的位置。
LLM.int8() 证明 activation outlier 不能被忽略。SmoothQuant 证明 outlier 不一定必须被单独计算。GPTQ 则证明:如果我们选择 weight-only 路线,3/4 bit 并不只是压缩率数字,而是需要二阶补偿才能站稳的工程边界。
下一篇 AWQ 会沿着这条 weight-only 路线继续往前走。GPTQ 问的是:
1 | 量化误差能不能用二阶信息补回来? |
AWQ 接着问:
1 | 是不是所有 weight 都同等重要? |