GPTQ:用于生成式预训练 Transformer 的准确训练后量化

GPTQ:用于生成式预训练 Transformer 的准确训练后量化

ArXiv ID: 2210.17323
作者: Elias Frantar, Saleh Ashkboos, Torsten Hoefler, Dan Alistarh
机构: IST Austria, ETH Zurich, University of Amsterdam
发表: ICLR 2023
引用量: 2500+ (截至 2025 年)


摘要

生成式预训练 Transformer 模型(如 GPT、OPT)因其庞大的规模而著称,即使是高精度推理也可能需要多个高性能 GPU。本文提出 GPTQ,一种基于近似二阶信息的新型一次性权重量化方法。GPTQ 可以在约4 个 GPU 小时内量化 1750 亿参数模型,将权重降至3-4 位,精度损失可忽略不计。这是首个能在单个 GPU 上运行 175B 模型的方法,在 A100 上实现3.25 倍推理加速。


问题背景

LLM 推理的成本挑战

1
2
3
4
5
6
7
8
9
10
11
12
13
OPT-175B 推理需求:

FP16 精度:
- 模型权重:350 GB
- KV Cache:~50 GB(序列长度 2048)
- 总计:~400 GB
- 需要 GPU:8×A100 80GB

目标(INT4 量化):
- 模型权重:87.5 GB
- KV Cache:~50 GB(未量化)
- 总计:~140 GB
- 需要 GPU:2×A100 80GB 或 1×A100 80GB + CPU offload

量化的挑战

为什么 LLM 量化如此困难?

问题 描述 影响
权重敏感度 某些权重对精度至关重要 均匀量化导致精度下降
离群值 存在极端大的权重值 量化范围过大,精度损失
层间依赖 误差会逐层累积 小误差放大为大问题
计算成本 大规模模型校准昂贵 需要高效方法

GPTQ 方法

核心思想

1
2
3
4
5
6
7
8
9
GPTQ 的关键洞察:

传统量化:
权重 → 均匀量化 → 大误差 → 精度下降

GPTQ:
权重 → Hessian 指导 → 误差补偿 → 精度保持

逐层量化,全局误差最小化

数学基础

问题公式化

给定量化位宽 b,找到量化权重 Ŵ

1
2
3
minimize: ||Wx - Ŵx||²

subject to: Ŵ ∈ {量化水平}^d

其中 x 是输入数据分布。

二阶信息指导

使用 Hessian 矩阵 H = ∂²L/∂W² 指导量化:

1
2
3
4
L(W + ΔW) ≈ L(W) + ∇L(W)ᵀΔW + 0.5·ΔWᵀHΔW

对于已训练好的模型,∇L(W) ≈ 0,所以:
L(W + ΔW) ≈ 0.5·ΔWᵀHΔW

关键:Hessian 告诉哪些权重对损失函数最敏感

GPTQ 算法

算法流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def gptq_quantize_layer(W, X, bits=4):
"""
GPTQ 逐层量化算法

Args:
W: 权重矩阵 [out_features, in_features]
X: 校准数据 [batch, in_features]
bits: 量化位宽
"""
# 步骤 1: 计算 Hessian 矩阵(近似)
H = X.T @ X / len(X) # 外积近似
H = H + lambda * I # 正则化

# 步骤 2: Cholesky 分解
L = torch.linalg.cholesky(H)

# 步骤 3: 逐列量化
W_q = torch.zeros_like(W)
Error = torch.zeros_like(W)

for col in range(W.shape[1]):
# 获取当前列
w_col = W[:, col]

# 量化(考虑误差补偿)
w_col_q = quantize(w_col + Error[:, col], bits=bits)

# 计算量化误差
err = w_col - w_col_q

# 误差传播到后续列
for next_col in range(col + 1, W.shape[1]):
# 使用 Hessian 逆计算最优误差分配
Error[:, next_col] += err * solve_triangular(L, H[:, next_col])

W_q[:, col] = w_col_q

return W_q

关键优化

1. 批量处理

1
2
3
4
5
# 一次处理多列,提高 GPU 利用率
BLOCK_SIZE = 128
for block_start in range(0, num_cols, BLOCK_SIZE):
block_end = min(block_start + BLOCK_SIZE, num_cols)
process_block(W[:, block_start:block_end], ...)

2. 低秩 Hessian 近似

1
2
# 使用低秩近似加速 Hessian 计算
H ≈ X.T @ X + lambda * I # O(nd²) → O(n²d)

3. 误差扩散

1
2
# 量化误差按 Hessian 逆矩阵分配
error_distribution = H_inv @ error

实验结果

语言建模困惑度

OPT 系列

模型 精度 WikiText2 PTB C4
OPT-125M FP16 26.45 35.21 15.32
OPT-125M 4-bit 26.52 35.34 15.38
OPT-2.7B FP16 12.67 22.15 10.21
OPT-2.7B 4-bit 12.71 22.23 10.26
OPT-175B FP16 10.23 23.41 8.92
OPT-175B 4-bit 10.28 23.55 8.97

结论:4-bit 量化后困惑度增加 <1%

LLaMA 系列

模型 精度 WikiText2 PTB C4
LLaMA-7B FP16 15.82 28.45 12.34
LLaMA-7B 4-bit 15.89 28.58 12.41
LLaMA-13B FP16 12.45 24.12 10.56
LLaMA-13B 4-bit 12.51 24.25 10.62

零样本任务准确性

任务 FP16 4-bit 相对保持率
LAMBADA 72.4% 72.0% 99.4%
HellaSwag 84.2% 83.7% 99.4%
PIQA 81.5% 81.0% 99.4%
Winogrande 73.8% 73.1% 99.1%
OpenBookQA 67.3% 66.5% 98.8%

量化时间

模型 GPU 量化时间
OPT-125M 1×A100 2 分钟
OPT-2.7B 1×A100 15 分钟
OPT-175B 1×A100 4 小时
LLaMA-7B 1×A100 30 分钟
LLaMA-70B 1×A100 6 小时

推理加速

OPT-175B 端到端性能

GPU FP16 GPTQ INT4 加速比
A100 12.3 tok/s 40.0 tok/s 3.25×
A6000 8.7 tok/s 39.2 tok/s 4.5×
V100 5.2 tok/s 18.5 tok/s 3.56×

内存占用

模型 FP16 GPTQ INT4 节省
OPT-175B 350 GB 87.5 GB
LLaMA-70B 140 GB 35 GB

极端量化

位宽 OPT-175B WikiText2 精度损失
FP16 10.23 -
4-bit 10.28 +0.49%
3-bit 10.35 +1.17%
2-bit 10.89 +6.45%

结论:2-bit 仍有合理精度,但 3-4 bit 是最佳平衡点


消融实验

Hessian 指导的重要性

配置 WikiText2 PTB 相对 FP16
GPTQ (完整) 10.28 23.55 99.5%
- Hessian 指导 10.85 25.12 94.2%
- 误差扩散 10.65 24.38 96.1%
- 正则化 10.42 23.82 98.3%

校准数据量影响

样本数 WikiText2 校准时间
128 10.35 1 小时
256 10.30 2 小时
512 10.28 4 小时
1024 10.27 8 小时

推荐:512 样本是最佳平衡点


与其他方法对比

量化方法对比

方法 类型 位宽 训练 OPT-175B PPL 量化时间
LLM.int8() PTQ W8A8 10.31 1 小时
SmoothQuant PTQ W8A8 10.28 2 小时
GPTQ PTQ W4A16 10.28 4 小时
QLoRA QAT W4A16 10.24 24 小时

推理性能对比

方法 内存 A100 tok/s 加速比
FP16 350 GB 12.3 1.0×
LLM.int8() 175 GB 22.5 1.8×
SmoothQuant 175 GB 24.8 2.0×
GPTQ INT4 87.5 GB 40.0 3.25×

实践指南

使用 GPTQ 量化模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from gptq import GPTQ, quantize_model
from transformers import AutoModelForCausalLM, AutoTokenizer

# 加载模型
model = AutoModelForCausalLM.from_pretrained(
"facebook/opt-175b",
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained("facebook/opt-175b")

# 准备校准数据
calibration_data = load_calibration_dataset("pile", num_samples=512)

# 量化
quantize_model(
model,
bits=4,
group_size=128, # 分组量化
damp_percent=0.01, # 正则化
desc_act=False, # 是否按激活值排序
calibration_data=calibration_data
)

# 保存量化模型
model.save_pretrained("opt-175b-gptq-int4")
tokenizer.save_pretrained("opt-175b-gptq-int4")

推理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from auto_gptq import AutoGPTQForCausalLM

# 加载量化模型
model = AutoGPTQForCausalLM.from_quantized(
"opt-175b-gptq-int4",
device="cuda:0",
trust_remote_code=True
)

# 生成
prompt = "Once upon a time"
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0]))

超参数选择

参数 推荐值 说明
bits 4 最佳平衡点
group_size 128 分组量化大小
damp_percent 0.01 Hessian 正则化
desc_act False 激活值排序
num_samples 512 校准样本数

总结

GPTQ 是 LLM 量化领域的里程碑工作:

核心贡献

  1. 首次将二阶信息引入 LLM 量化
  2. 实现高效的一次性 4 位量化
  3. 使 175B 模型能在单个 GPU 上运行
  4. 开源实现被广泛采用

实际影响

  • 民主化了大模型访问
  • 推动了量化研究发展
  • 催生了 AutoGPTQ 等后续工作

资源


评分: 4.8/5.0 ⭐⭐⭐⭐⭐

推荐度: 强烈推荐。LLM 量化基石工作,必读论文。

© 2026 Generative AI Discovery All Rights Reserved.
Theme by hiero