模型量化(Quantization)¶
面试高频考点¶
- 量化的原理是什么?
- INT8、INT4、FP8 各有什么特点?
- GPTQ 和 AWQ 的区别?
- 量化为什么不会显著损失精度?
- SmoothQuant 如何解决激活值异常值问题?
外部图解:AWQ 量化直觉¶

图源:AWQ: Activation-aware Weight Quantization。这张图适合解释 AWQ 的核心直觉:并非所有权重同等重要,保护少量 salient weights 能保持模型质量。
一、量化的动机¶
细化理解: 量化的核心动机是减少模型权重、激活或 KV Cache 的存储和带宽成本。对推理来说,很多场景不是算力不够,而是显存容量和显存带宽限制吞吐;低精度权重可以让更大模型放进显存,也能提高 token/s。代价是数值误差,需要处理异常通道、校准数据和硬件 kernel 支持。
LLM 权重通常以 FP16 存储,70B 模型需要 140GB 显存。量化将权重压缩为低精度格式:
| 精度 | 70B 显存 | 压缩比 | 质量 |
|---|---|---|---|
| FP32 | 280 GB | 1x | 最佳 |
| FP16 / BF16 | 140 GB | 2x | 几乎无损 |
| INT8 | 70 GB | 4x | 极小损失 |
| FP8 | 70 GB | 4x | 极小损失(H100+) |
| INT4 | 35 GB | 8x | 小幅损失 |
| INT3 | ~26 GB | ~10x | 中等损失 |
| INT2 | ~17 GB | ~14x | 较大损失 |
二、量化的数学原理¶
线性量化(Affine Quantization)¶
将浮点范围 [β, α] 映射到整数范围 [0, 2^b - 1](b-bit 量化):
scale = (α - β) / (2^b - 1)
zero_point = round(-β / scale)
量化:x_q = clamp(round(x / scale + zero_point), 0, 2^b - 1)
反量化:x' = (x_q - zero_point) × scale
对称量化(简化版):令 zero_point = 0,只存 scale:
量化:x_q = round(x / scale),范围 [-2^(b-1), 2^(b-1) - 1]
反量化:x' = x_q × scale
scale = max(|x|) / (2^(b-1) - 1)
量化粒度¶
Per-Tensor(整矩阵一个 scale):
┌─────────────────────┐
│ W (4096 × 4096) │ scale = s₀
└─────────────────────┘
优点:最快
缺点:一个异常值拖累整层精度
Per-Channel(每行独立 scale):
┌─────────────────────┐
│ row₀ │ scale = s₀
│ row₁ │ scale = s₁
│ ... │ ...
│ rowₙ │ scale = sₙ
└─────────────────────┘
优点:精度好,硬件友好(矩阵乘法中每行独立 scale 不增加延迟)
缺点:存储 scale 向量需要额外显存(可忽略)
Per-Group(每 g 个元素共享 scale):
W 被切成 block_size × block_size 的子块(如 128×128)
每个子块独立的 scale
优点:精度最好(GPTQ/AWQ 使用)
缺点:需要更多 scale 存储 + 反量化开销
三、PTQ 方法详解¶
细化理解: PTQ 不重新完整训练模型,而是用校准集估计量化尺度和敏感权重。GPTQ 更偏重逐层近似重构误差,AWQ 关注激活感知的权重保护,SmoothQuant 通过平滑激活和权重范围改善量化。面试时重点讲清楚:不同方法优化目标不同,不能只用 bit 数判断效果。
GPTQ(GPT Post-Training Quantization)¶
核心思想:逐列量化权重矩阵,量化当前列时,用 Hessian 矩阵补偿前面各列引入的量化误差。本质是求解最优量化权重的二次规划问题。
算法流程:
输入:权重矩阵 W (d_row × d_col),校准数据
输出:量化后权重 W_q
1. 计算 Hessian 矩阵 H = 2XX^T(X 为校准数据的激活值)
2. 对 H 求逆:H_inv = Cholesky(H)⁻¹
3. 逐列处理(从左到右):
a. 量化当前列:w_q[:, j] = quantize(w[:, j])
b. 计算量化误差:e = (w[:, j] - w_q[:, j]) / H_inv[j, j]
c. 补偿剩余列:w[:, j+1:] -= e × H_inv[j, j+1:]
4. 重复直到所有列处理完毕
关键:步骤 3c 的补偿操作,用当前列的量化误差去修正剩余未量化的列,将信息"挤"到后面的列中。这使得 GPTQ 即使逐列贪婪量化也能维持全局低误差。
GPTQ 特点: - 仅需 128 条校准样本(约 1M tokens) - 支持 2/3/4/8 bit - 分组量化(group_size=128)可显著提升 INT4 精度 - GPU 上推理快(kernel 优化好)
AWQ(Activation-aware Weight Quantization)¶
核心发现:权重矩阵中,对应高激活值通道的权重更重要。直接量化会损害这些关键通道。
AWQ 的方案:不是保护重要通道不量化,而是在量化前放大重要通道的权重,量化后再相应地缩小激活值。
┌────────────────────────────────────┐
│ AWQ 核心流程 │
│ │
│ 1. 统计激活值分布 │
│ 对于每个输入通道: │
│ s_i = mean(|X[:, i]|) │
│ │
│ 2. 找到缩放因子(grid search) │
│ α* = argmin ||WX - Q(W·s)·(X/s)||│
│ │
│ 3. 量化前:W ← W × s │
│ 量化后:X ← X / s │
│ │
│ 数学等价于无缩放,但量化误差更小 │
└────────────────────────────────────┘
为什么有效:重要通道权重放大后,量化误差(rounding error)相对于信号的比例降低。而激活值除以同样的 factor 后,数值正确性保持不变。
AWQ vs GPTQ:
| 维度 | GPTQ | AWQ |
|---|---|---|
| 核心思路 | Hessian 矩阵补偿量化误差 | 激活感知 + per-channel 缩放 |
| 校准数据量 | 128 样本 | 128 样本 |
| INT4 精度 | 好 | 更好(尤其对异常值敏感层) |
| 推理速度 | 快 | 快(硬件友好的 per-channel 缩放) |
| 量化对象 | 仅权重 | 权重(激活可配合 SmoothQuant) |
SmoothQuant¶
问题:LLM 的激活值存在系统性异常值通道(某些通道的值比平均值大 100 倍以上),直接 INT8 量化激活值会导致严重精度损失。
SmoothQuant 方案:将量化难度从激活值"迁移"到权重:
原始计算:Y = X × W
问题:X 有异常值通道(量化误差大),W 分布较均匀
SmoothQuant 变换:
选择一个平滑因子 s(per-channel)
X' = X × diag(s)^(-1) ← 缩小激活异常值
W' = diag(s) × W ← 放大对应权重
数学等价:Y = X' × W' = X × W
效果:
- X' 更平滑,更容易 INT8 量化
- W' 仍较平滑(权重本身分布就好),INT8 量化也 OK
平滑因子的选择:
s_j = max(|X_j|)^α / max(|W_j|)^(1-α)
α 控制迁移程度:
α=0:全部迁移到权重(不推荐)
α=1:全部保留在激活(等于不迁移)
α=0.5:均分(默认推荐)
SmoothQuant 效果:实现 W8A8(权重 INT8 + 激活 INT8),推理速度较 FP16 提升 1.5-2x,精度损失极小。
四、量化感知训练(QAT)vs PTQ¶
| 维度 | PTQ(训练后量化) | QAT(量化感知训练) |
|---|---|---|
| 数据需求 | 少量校准数据(百条) | 完整训练数据 |
| 计算成本 | 低(分钟级) | 高(小时/天级) |
| 精度 | 好(INT8 几乎无损) | 更好(INT4 也可很准) |
| 适用场景 | 开源模型快速部署 | 自研模型追求极致性能 |
| 代表方法 | GPTQ, AWQ, SmoothQuant | LSQ, PACT, LLM-QAT |
工程实践:PTQ 是主力方案(成本低、效果好),QAT 只在 INT4 下 PTQ 精度不满足需求时才用。
五、FP8 详解¶
FP8 的两种格式¶
E4M3(4位指数 + 3位尾数):
┌─┬───┬───┬───┬───┬───┬───┬───┐
│S│ E │ E │ E │ E │ M │ M │ M │
└─┴───┴───┴───┴───┴───┴───┴───┘
范围:±448,精度:约 2^-3 ≈ 0.125
E5M2(5位指数 + 2位尾数):
┌─┬───┬───┬───┬───┬───┬───┬───┐
│S│ E │ E │ E │ E │ E │ M │ M │
└─┴───┴───┴───┴───┴───┴───┴───┘
范围:±57344,精度:约 2^-2 ≈ 0.25
| 格式 | 动态范围 | 精度 | 适合 |
|---|---|---|---|
| FP8 E4M3 | 较小 | 较高 | 权重、前向激活 |
| FP8 E5M2 | 较大 | 较低 | 梯度(反向传播需要大范围) |
FP8 vs INT8¶
INT8 的问题:动态范围小
INT8 范围: [-128, 127]
激活值异常值可能到 1000+ → 直接截断损失大信息
FP8 E4M3 的优势:保留了浮点格式的指数位
范围:[-448, 448],覆盖大多数激活值
非均匀分布:小值密集(高精度),大值稀疏(低精度)
天然匹配神经网络中的正态分布 → 量化误差更小
DeepSeek-V3 的 FP8 实践:训练全程用 FP8 混合精度,在 H800 GPU 上实现约 60% 的显存节省和 1.5x 的训练加速,精度与 BF16 全程训练相当。
六、GGUF / llama.cpp 量化方案¶
K-Quant 系列¶
GGUF 格式的量化不是简单的 uniform quantization,而是针对不同重要性权重的自适应量化:
| 量化类型 | 7B 模型大小 | 质量 | 推荐场景 |
|---|---|---|---|
| F16 | ~14 GB | 无损 | 开发调试 |
| Q8_0 | ~7.7 GB | 极小损失 | 高精度需求 |
| Q4_K_M | ~4.1 GB | 小损失 | 日常推荐 |
| Q4_K_S | ~3.8 GB | 中等损失 | 显存紧张 |
| Q3_K_M | ~3.1 GB | 中等损失 | 移动设备 |
| Q2_K | ~2.2 GB | 较大损失 | 仅极限场景 |
命名规则:Q{bits}_{type}_{size}
- Q4 = 4-bit
- K = K-Quant(分组量化 + 自适应精度)
- M/S = 中等/小模型文件
- _0 / _1 = 纯 4-bit(旧版)
K-Quant 的自适应策略:注意力层的权重比 FFN 层用更多 bit;每 256 个权重共享 scale;"super-block"(每 16 个 block)额外存储 FP16 最小/最大值以校准。
七、面试延伸¶
Q:INT4 量化会损失多少精度?
取决于方法和任务。GPTQ/AWQ INT4 在 MMLU 等 benchmark 上精度损失 < 1%,对通用对话基本无感。但在数学推理(GSM8K)和代码生成(HumanEval)上,INT4 损失可能达到 2-5%。对于需要精确数值计算的任务,推荐至少 INT8 或 FP8。
Q:量化感知训练(QAT)和 PTQ 的区别?
QAT 在训练中模拟量化操作(前向用低精度、反向用全精度更新),模型学会适应量化噪声,精度最高但需要重新训练。PTQ 直接对已训练好的模型量化,成本低(只需少量校准数据、几分钟完成),是工程中最常用的方案。QAT 适合自研模型追求极限性能的场景。
Q:为什么 LLM 量化的挑战比 CV 模型更大?
LLM 的激活值存在系统性异常值通道(某些通道的值比平均大 100 倍+),这在 CV 模型中不常见。这些异常值使得直接量化激活值(如 W8A8 方案)非常困难,需要用 SmoothQuant 等技巧做迁移。此外 LLM 的层数深(32-80 层),量化误差会累积传播。
Q:量化 + Flash Attention + PagedAttention 如何协同?
三个技术各司其职:量化减少模型权重的显存占用;Flash Attention 减少 Attention 计算的 IO;PagedAttention 管理 KV Cache 的显存分配。三者叠加可实现最优推理效率。vLLM 默认集成了这三个技术。
Q:2-bit / sub-1-bit 量化可能吗?
已有探索。QuIP#、AQLM 等方法实现了 2-bit 量化,精度勉强可用。NanoQuant (ICML 2026) 提出了 sub-1-bit(< 1 bit per weight)方案,但需要更复杂的编码和解码,目前尚未成为工程主流。
原始论文¶
| 论文 | 链接 |
|---|---|
| GPTQ: Accurate Post-Training Quantization (Frantar et al., ICLR 2023) | arxiv.org/abs/2210.17323 |
| AWQ: Activation-aware Weight Quantization (Lin et al., MLSys 2024) | arxiv.org/abs/2306.00978 |
| SmoothQuant (Xiao et al., ICML 2023) | arxiv.org/abs/2211.10438 |
| FP8 Formats for Deep Learning (Micikevicius et al., 2022) | arxiv.org/abs/2209.05433 |
| QLoRA: Efficient Finetuning of Quantized LLMs (Dettmers et al., NeurIPS 2023) | arxiv.org/abs/2305.14314 |
| NanoQuant: Efficient Sub-1-Bit Quantization of LLMs (ICML 2026) | arxiv.org/abs/2602.06694 |
| QuIP#: 2-Bit Quantization with Lattice Codebooks (Tseng et al., 2024) | arxiv.org/abs/2402.04396 |
延伸阅读与视频¶
| 平台 | 标题 | 说明 |
|---|---|---|
| 📺 B站 | 【13】GPTQ、AWQ、GGUF等模型量化概念讲解 | 2.4万播放,系统讲解主流量化方案 |
| 📺 B站 | DeepSpeed优化器并行ZeRO1/2/3原理(含量化内容) | 1.6万播放,ZOMI酱深入讲解量化与并行 |
| 📖 Hugging Face Docs | bitsandbytes quantization | 8-bit / 4-bit 加载和 QLoRA 常用工具 |
| 📖 Hugging Face Docs | Quanto quantization | Transformers 官方量化入口之一 |
| 📖 llama.cpp | GGUF / llama.cpp | 本地部署和 GGUF/K-Quant 生态入口 |
| 📖 AutoAWQ | AutoAWQ GitHub | AWQ 工程实现参考 |