量化方法对比:INT8 / INT4 / GPTQ / AWQ
1. 量化基础
什么是量化
将模型权重(通常 FP16/BF16)映射到更低比特的表示(INT8、INT4 等),以减少模型大小和推理显存需求。
基本公式
其中 为目标比特数, 为量化步长。
量化分类
| 类型 | 描述 | 代表方法 |
|---|---|---|
| 训练后量化 (PTQ) | 训练完成后量化,无需重新训练 | GPTQ, AWQ, RTN |
| 量化感知训练 (QAT) | 训练过程中模拟量化 | LLM-QAT |
| 仅权重量化 (W-only) | 只量化权重,激活保持高精度 | GPTQ, AWQ |
| 权重+激活量化 (W+A) | 同时量化权重和激活 | SmoothQuant |
QUESTION 面试题:PTQ 和 QAT 的区别?LLM 通常用哪种?
- PTQ (Post-Training Quantization):模型训练完成后量化,需要少量校准数据(128-256 条),时间短(分钟到小时),精度略有损失
- QAT (Quantization-Aware Training):训练过程中模拟量化效应,精度更好但需要完整训练
LLM 通常使用 PTQ,因为:(1) LLM 训练成本极高,不适合重新训练;(2) PTQ 在 INT8 和 INT4 下已经能达到可接受的精度;(3) GPTQ、AWQ 等 PTQ 方法在 LLM 上效果很好。
2. 浮点数表示基础
IEEE 754 浮点数格式
在理解量化之前,需要理解浮点数的表示方式:
- :符号位(Sign)
- :指数位(Exponent)
- :尾数位(Mantissa)
| 格式 | 符号位 | 指数位 | 尾数位 | 总位宽 | 取值范围 |
|---|---|---|---|---|---|
| FP32 | 1 | 8 | 23 | 32 | |
| FP16 | 1 | 5 | 10 | 16 | |
| BF16 | 1 | 8 | 7 | 16 | |
| FP8 (E4M3) | 1 | 4 | 3 | 8 | |
| FP8 (E5M2) | 1 | 5 | 2 | 8 | |
| INT8 | - | - | - | 8 | |
| INT4 | - | - | - | 4 |
BF16 vs FP16
| 对比 | FP16 | BF16 |
|---|---|---|
| 指数位 | 5 位 | 8 位(与 FP32 相同) |
| 尾数位 | 10 位 | 7 位 |
| 精度 | 更高 | 较低 |
| 动态范围 | 较小(易溢出) | 与 FP32 相同 |
| 训练适用 | 需要损失缩放 | 直接替换 FP32 |
QUESTION 面试题:BF16 和 FP16 有什么区别?为什么 LLM 训练多用 BF16? BF16 和 FP16 都是 16 位浮点数,但位宽分配不同:
- FP16:5 位指数 + 10 位尾数,精度高但动态范围小,训练时容易出现上溢/下溢,需要 Loss Scaling
- BF16:8 位指数 + 7 位尾数,动态范围与 FP32 相同(不易溢出),但精度略低
LLM 训练多用 BF16,因为:(1) 动态范围大,不需要 Loss Scaling,训练更稳定;(2) A100/H100 等 Ampere+ GPU 原生支持 BF16;(3) LLM 参数量大,数值范围广,BF16 更安全。
FP8 的两种格式
| 格式 | 指数位 | 尾数位 | 适用场景 |
|---|---|---|---|
| E4M3 | 4 | 3 | 前向传播(权重和激活) |
| E5M2 | 5 | 2 | 反向传播(梯度) |
E4M3 精度更高,E5M2 动态范围更大。NVIDIA H100 的 FP8 Tensor Core 支持这两种格式。
3. 量化方法详解
RTN (Round-to-Nearest)
最简单的量化方法,直接四舍五入:
- 优点:无需校准数据,极快
- 缺点:4-bit 及以下精度损失严重
- 适用:INT8 量化(几乎无损)
GPTQ
论文:《GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers》(2022)
核心思想:基于 Hessian 矩阵的二阶信息,逐层量化权重,最小化量化误差对输出的影响。
工作流程:
- 逐层处理,固定其他层
- 使用校准数据集计算 Hessian 矩阵
- 按照 OBQ (Optimal Brain Quantization) 顺序逐个量化权重
- 每量化一个权重,调整剩余权重以补偿误差
特点:
- 需要校准数据集(通常 128-256 条样本)
- 量化时间:数分钟到数小时
- GPU 推理优化好(CUDA 内核)
- 支持 group-wise 量化(128 group size 常用)
QUESTION 面试题:GPTQ 的核心原理是什么? GPTQ 基于 OBQ (Optimal Brain Quantization) 算法,核心思想是:利用 Hessian 矩阵(损失函数的二阶导数)来量化权重,使得量化引起的输出误差最小。 具体流程:
- 对每一层,使用校准数据计算 Hessian 矩阵
- 按照对输出影响从小到大的顺序量化权重
- 每量化一个权重 ,使用 Hessian 信息调整剩余权重
- 这样量化误差被"分摊"到剩余权重上,总输出误差最小化
AWQ (Activation-aware Weight Quantization)
论文:《AWQ: Activation-Aware Weight Quantization for LLM Compression and Acceleration》(2023)
核心思想:并非所有权重同等重要。根据激活值大小识别"显著权重"(salient weights),对它们使用更高精度或缩放保护。
工作流程:
- 分析校准数据上的激活分布
- 识别对输出影响最大的权重通道
- 对显著通道应用缩放因子保护
- 量化非显著通道到低比特
特点:
- 需要校准数据集
- 在相同比特数下精度通常优于 GPTQ
- GPU 推理速度快
- 支持任意比特数
GPTQ vs AWQ 对比
| 维度 | GPTQ | AWQ |
|---|---|---|
| 核心原理 | Hessian 二阶信息,误差补偿 | 激活感知,保护显著通道 |
| 校准数据 | 128-256 条 | 128-256 条 |
| 量化速度 | 较慢(需计算 Hessian) | 较快 |
| 精度(4-bit) | 略低 | 略高 |
| 推理速度 | 快(优化 CUDA Kernel) | 快(优化 CUDA Kernel) |
| 稳定性 | group_size 敏感 | 更鲁棒 |
GGUF / llama.cpp
核心思想:为 CPU/混合 CPU-GPU 推理设计,支持多种量化方案(K-Quant)。
K-Quant 方案:
| 方案 | 比特数 | 描述 | 适用 |
|---|---|---|---|
| Q8_0 | 8-bit | 均匀量化 | 质量优先 |
| Q5_K_M | ~5-bit | 混合精度(重要层更高精度) | 平衡 |
| Q4_K_M | ~4-bit | 混合精度 | 推荐默认 |
| Q4_0 | 4-bit | 均匀量化 | 速度优先 |
| Q2_K | ~2-bit | 极低比特 | 极致压缩 |
QUESTION 面试题:GGUF 的 K-Quant 是什么?为什么推荐 Q4_K_M? K-Quant 是 llama.cpp 的混合精度量化方案,不同层使用不同比特数:
- 注意力权重和 FFN 的 down/up projection 使用更高精度
- 其他层使用较低精度
_M(Medium) 和_S(Small) 表示不同的精度配置Q4_K_M 推荐的原因:平均 ~4.8 bit,在模型大小和精度之间取得最佳平衡。相比 Q4_0(均匀 4-bit),Q4_K_M 在关键层保留更高精度,Perplexity 更低;相比 Q5_K_M,体积更小且精度差异不大。
SmoothQuant
核心思想:将激活的量化难度"平滑"到权重上。
通过逐通道的缩放因子,将激活中的异常值平滑到权重中,使得 W8A8(权重 8-bit + 激活 8-bit)成为可能。
bitsandbytes 量化
bitsandbytes 是一个自定义 CUDA 函数的轻量级包装器,支持两种主要量化方式:
| 方式 | 描述 | 适用 |
|---|---|---|
| LLM.int8() | 混合精度分解:异常值用 FP16,其余用 INT8 | 推理 |
| QLoRA (NF4) | 4-bit Normal Float + 双重量化 | 微调 |
LLM.int8() 原理:
- 检测激活中的异常值(幅度 > 阈值的维度)
- 异常值维度用 FP16 精度计算
- 非异常值维度用 INT8 矩阵乘法
- 合并两部分结果
QLoRA 中的 NF4:
- Normal Float 4-bit:假设权重服从正态分布,使用等分位量化
- 双重量化(Double Quantization):对量化常数本身再量化,进一步节省显存
- 分页优化器:将优化器状态卸载到 CPU
4. 精度损失数据对比
Perplexity 对比(WikiText-2,LLaMA-2-7B)
| 量化方案 | 模型大小 | Perplexity | 相对 FP16 增加 |
|---|---|---|---|
| FP16 (基线) | 13.5 GB | 5.47 | - |
| INT8 (Q8_0) | ~7.0 GB | 5.50 | +0.5% |
| GPTQ 4-bit (128g) | ~3.8 GB | 5.60-5.75 | +2.4-5.1% |
| AWQ 4-bit (128g) | ~3.8 GB | 5.55-5.65 | +1.5-3.3% |
| GGUF Q4_K_M | ~4.1 GB | 5.65-5.80 | +3.3-6.0% |
| GGUF Q4_0 | ~3.6 GB | 5.85-6.00 | +6.9-9.7% |
| INT3 / 3-bit | ~2.8 GB | 6.5+ | >19% |
基准任务精度对比(LLaMA-2-70B)
| 量化方案 | MMLU (5-shot) | HumanEval | GSM8K |
|---|---|---|---|
| FP16 | 69.8% | 43.9% | 56.2% |
| GPTQ 4-bit | 68.5-69.0% | 41.5-42.5% | 53.0-54.5% |
| AWQ 4-bit | 68.8-69.3% | 42.0-43.0% | 54.0-55.5% |
| Q4_K_M | 67.5-68.5% | 40.0-42.0% | 51.0-53.0% |
| INT8 | 69.5-69.8% | 43.5-44.0% | 55.5-56.0% |
关键结论
- INT8 几乎无损(< 0.5% 精度下降),是最安全的选择
- AWQ 4-bit 略优于 GPTQ 4-bit(因激活感知保护显著权重)
- GGUF K-Quant 提供灵活的质量-大小权衡
- 3-bit 量化精度损失明显(> 15%),不建议用于关键任务
QUESTION 面试题:INT8 和 INT4 量化对模型精度的影响有多大?
- INT8:几乎无损(Perplexity 增加 < 0.5%),MMLU 下降 < 0.3 个百分点。推荐用于对精度要求高的生产场景
- INT4(GPTQ/AWQ):轻度损失(Perplexity 增加 2-5%),MMLU 下降 1-2 个百分点。适用于大多数场景
- INT3 及以下:明显损失(Perplexity 增加 > 15%),不建议用于关键任务
实际选择时:优先尝试 INT8,显存不够再用 AWQ 4-bit,极端场景考虑 GGUF Q2_K。
5. 显存与速度对比
显存占用(7B 模型)
| 方案 | 显存占用 | 相比 FP16 |
|---|---|---|
| FP16 | 14 GB | 基准 |
| INT8 | 7 GB | -50% |
| GPTQ 4-bit | 4 GB | -71% |
| AWQ 4-bit | 4 GB | -71% |
| GGUF Q4_K_M | 4.5 GB | -68% |
| QLoRA 4-bit (训练) | 4-5 GB | -68% |
推理速度
| 方案 | GPU 吞吐 | CPU 吞吐 | 适用硬件 |
|---|---|---|---|
| FP16 | 基准 | N/A | A100/H100 |
| GPTQ 4-bit | 接近或超过 FP16 | 不支持 | GPU 部署 |
| AWQ 4-bit | 接近或超过 FP16 | 不支持 | GPU 部署 |
| GGUF Q4_K_M | 可用 GPU 加速 | 最佳 | CPU / 混合部署 |
注意:4-bit 推理速度可能快于 FP16,因为虽然计算量相同(反量化后计算),但内存带宽需求大幅降低,而推理通常是内存带宽受限的。
6. 选型指南
你的部署场景是什么?
│
┌────┼────┐
↓ ↓ ↓
GPU CPU 混合
│ │ │
↓ ↓ ↓
GPTQ GGUF GGUF
或 Q4_K_M Q4_K_M
AWQ + GPU offload
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| GPU 服务器部署 | AWQ 4-bit | 最佳精度+速度平衡 |
| GPU 集群高吞吐 | GPTQ 4-bit | 成熟的 GPU 内核 |
| 消费级 GPU | AWQ 或 GPTQ 4-bit | 显存友好 |
| CPU/Mac 部署 | GGUF Q4_K_M | 最佳 CPU 推理 |
| 最大精度 | INT8 / SmoothQuant W8A8 | 几乎无损 |
| 极致压缩 | GGUF Q2_K | 可接受损失换取最小体积 |
| W8A8 全量化 | SmoothQuant | 同时量化权重和激活 |
| QLoRA 微调 | bitsandbytes NF4 | 专为微调设计 |
QUESTION 面试题:如何为你的场景选择量化方案? 根据部署硬件和精度要求选择:
- GPU 服务器(追求吞吐):AWQ 4-bit 或 GPTQ 4-bit,精度和速度的平衡
- GPU 服务器(追求精度):INT8 或 SmoothQuant W8A8,几乎无损
- CPU / Mac 本地部署:GGUF Q4_K_M,CPU 推理最佳
- 消费级 GPU(如 RTX 3090 24GB):AWQ 4-bit 7B 模型可以运行,GPTQ 4-bit 13B 也可以
- 微调场景:bitsandbytes QLoRA (NF4),4-bit 量化下仍可微调
7. 量化实践
GPTQ 量化
# 使用 AutoGPTQ
python -m auto_gptq quantize \
--model_name meta-llama/Llama-3-8B \
--bits 4 \
--group_size 128 \
--desc_act True
AWQ 量化
# 使用 AutoAWQ
python -m awq quantize \
--model_path meta-llama/Llama-3-8B \
--w_bit 4 \
--q_group_size 128 \
--zero_point True
GGUF 量化
# 使用 llama.cpp
./llama-quantize \
/path/to/gguf-fp16.gguf \
/path/to/output-Q4_K_M.gguf \
Q4_K_M
vLLM 量化推理
# AWQ 模型推理
python -m vllm.entrypoints.openai.api_server \
--model casperhansen/llama-3-8b-chat-awq \
--quantization awq
# GPTQ 模型推理
python -m vllm.entrypoints.openai.api_server \
--model ModelCloud/llama-3-8b-chat-gptq-4bit \
--quantization gptq
8. 量化对推理速度的数学分析
Decode 阶段是访存密集型,量化加速的核心是减少 HBM 读取量:
| 精度 | 7B 模型权重大小 | HBM 读取时间(A100, 2TB/s) |
|---|---|---|
| FP16 | 14 GB | ~7 ms |
| INT8 | 7 GB | ~3.5 ms |
| INT4 | 3.5 GB | ~1.75 ms |
量化不减少 FLOPs(反量化后用原精度计算),但减少了 HBM I/O 量,因此对访存密集的 Decode 阶段有显著加速。
跨库关联
- 通用模型压缩方法 — 量化在压缩三件套(剪枝/蒸馏/量化)中的位置