模型量化技术详解
约 1431 字大约 5 分钟
quantizationoptimization
2025-09-01
模型量化通过降低权重和激活值的数值精度来减少内存占用和加速推理。本文介绍各种数值格式、量化方法以及主流量化工具。
数值格式
| 格式 | 位数 | 范围 | 精度 | 内存 (7B模型) |
|---|---|---|---|---|
| FP32 | 32 | 极大 | 高 | 约28 GB |
| FP16 | 16 | 65504 | 中 | 约14 GB |
| BF16 | 16 | 与FP32相近 | 中偏低 | 约14 GB |
| INT8 | 8 | -128到127 | 较低 | 约7 GB |
| INT4 | 4 | -8到7 | 低 | 约3.5 GB |
| FP8 (E4M3) | 8 | 448 | 较低 | 约7 GB |
BF16 vs FP16:BF16 保留了 FP32 的指数范围(8位指数),牺牲了尾数精度(7位尾数 vs FP16 的 10 位),在训练中更稳定(不易溢出/下溢)。
量化基本原理
量化将连续的浮点值映射到离散的低精度整数空间。核心公式为:量化值 = round(原始值 / 缩放因子) + 零点。反量化则为:还原值 = 缩放因子 * (量化值 - 零点)。
对称量化 vs 非对称量化
import torch
import numpy as np
def symmetric_quantize(tensor, num_bits=8):
"""对称量化:零点固定为 0"""
qmax = 2 ** (num_bits - 1) - 1
scale = tensor.abs().max() / qmax
quantized = torch.round(tensor / scale).clamp(-qmax, qmax).to(torch.int8)
return quantized, scale
def asymmetric_quantize(tensor, num_bits=8):
"""非对称量化:零点可偏移"""
qmin, qmax = 0, 2 ** num_bits - 1
scale = (tensor.max() - tensor.min()) / (qmax - qmin)
zero_point = round((-tensor.min() / scale).item())
quantized = torch.round(tensor / scale + zero_point).clamp(qmin, qmax).to(torch.uint8)
return quantized, scale, zero_point量化粒度
Per-group 量化(如每 128 个元素一组)是当前 LLM 量化的主流选择。
训练后量化(PTQ)
PTQ 不需要重新训练模型,使用少量校准数据即可完成量化。
权重量化
仅量化权重,推理时先反量化为 FP16 再计算。优点是实现简单,不影响计算精度。
权重 + 激活量化(W8A8)
权重和激活值都量化为 INT8,使用 INT8 矩阵乘法加速计算。需要解决激活值中 outlier(离群值)的问题。
# 使用 PyTorch 原生量化
import torch.quantization as quant
model_fp32 = MyModel()
model_fp32.eval()
# 动态量化(权重静态量化,激活动态量化)
model_int8 = torch.quantization.quantize_dynamic(
model_fp32,
{torch.nn.Linear}, # 量化 Linear 层
dtype=torch.qint8,
)
# 静态量化(需要校准数据)
model_fp32.qconfig = torch.quantization.get_default_qconfig('x86')
model_prepared = torch.quantization.prepare(model_fp32)
# 校准
with torch.no_grad():
for data in calibration_loader:
model_prepared(data)
model_int8 = torch.quantization.convert(model_prepared)量化感知训练(QAT)
QAT 在训练过程中模拟量化效果,使模型学会适应低精度表示。前向传播使用量化权重,反向传播使用 straight-through estimator (STE) 近似梯度。
# PyTorch QAT 流程
model.train()
model.qconfig = torch.quantization.get_default_qat_qconfig('x86')
# 插入伪量化节点
model_qat = torch.quantization.prepare_qat(model)
# 正常训练
for epoch in range(num_epochs):
for data, target in train_loader:
output = model_qat(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
optimizer.zero_grad()
# 转换为量化模型
model_quantized = torch.quantization.convert(model_qat)GPTQ
GPTQ(Frantar et al., 2023)是专为大型语言模型设计的 PTQ 方法,基于 Optimal Brain Quantization (OBQ) 理论,逐列量化权重矩阵,并用 Hessian 矩阵信息来最小化量化误差。
特点:
- 仅需约 128 条校准样本
- 支持 3/4/8 bit 量化
- 量化后可使用 GPU int4 矩阵乘法加速
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
# 配置量化参数
quantize_config = BaseQuantizeConfig(
bits=4,
group_size=128,
desc_act=True,
damp_percent=0.01,
)
# 加载模型并量化
model = AutoGPTQForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
quantize_config=quantize_config,
)
# 使用校准数据量化
model.quantize(calibration_dataset)
model.save_quantized("llama-2-7b-gptq-4bit")AWQ(Activation-aware Weight Quantization)
AWQ 观察到权重中只有少部分对模型输出影响很大(对应激活值中的 outlier 通道),保护这些"显著权重"可以大幅降低量化误差。
核心策略:不直接跳过显著权重,而是对显著通道乘以一个缩放因子使其值更大,量化后相对误差更小。
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer
model_path = "meta-llama/Llama-2-7b-hf"
quant_path = "llama-2-7b-awq-4bit"
model = AutoAWQForCausalLM.from_pretrained(model_path)
tokenizer = AutoTokenizer.from_pretrained(model_path)
quant_config = {
"zero_point": True,
"q_group_size": 128,
"w_bit": 4,
"version": "GEMM",
}
model.quantize(tokenizer, quant_config=quant_config)
model.save_quantized(quant_path)GGUF 格式
GGUF(GPT-Generated Unified Format)是 llama.cpp 使用的量化模型格式,支持多种量化类型,可在 CPU 上高效运行。
常见量化类型:
- Q4_0:4-bit 均匀量化,速度快但精度一般
- Q4_K_M:4-bit k-quant medium,精度和速度平衡
- Q5_K_M:5-bit k-quant medium,推荐的默认选择
- Q8_0:8-bit 量化,精度接近原始模型
# 使用 llama.cpp 转换和量化
# 转换为 GGUF
python convert_hf_to_gguf.py meta-llama/Llama-2-7b-hf --outfile llama-2-7b.gguf
# 量化
./llama-quantize llama-2-7b.gguf llama-2-7b-Q4_K_M.gguf Q4_K_M
# 运行推理
./llama-cli -m llama-2-7b-Q4_K_M.gguf -p "Hello, " -n 100精度与速度权衡
实践建议
| 场景 | 推荐方案 |
|---|---|
| 生产部署(GPU) | AWQ 4-bit 或 GPTQ 4-bit |
| 本地推理(CPU/Apple Silicon) | GGUF Q5_K_M |
| 精度敏感任务 | INT8 或 BF16 |
| 训练/微调 | BF16(不量化) |
| 边缘设备 | INT4 + 知识蒸馏 |
总结
量化技术使 LLM 在有限硬件上的部署成为可能。GPTQ 和 AWQ 是当前最主流的 4-bit 量化方案,GGUF 则是 CPU 推理的标准格式。选择量化策略时需要在精度、速度和内存之间找到平衡,通常建议在目标任务上进行量化后评估。
贡献者
更新日志
9f6c2-feat: organize wiki content and refresh site setup于