模型量化技术
量化是通过降低模型数值精度来减少内存占用和计算成本的关键技术。
为什么量化?
- 减少内存:INT8 比 FP16 节省 50% 内存
- 加速推理:低精度运算更快(尤其 GPU Tensor Core)
- 降低成本:可部署到更小的硬件,降低云成本
- 边缘部署:手机、IoT 设备也能运行大模型
量化级别
训练后量化(Post-Training Quantization, PTQ)
训练完成后直接转换,无需重新训练。
| 精度 | 内存占用 | 精度损失 | 工具 |
|---|---|---|---|
| FP16 | 16 bit | 0% | 原生支持 |
| BF16 | 16 bit | <0.5% | 原生支持 |
| INT8 | 8 bit | ~1-2% | ONNX, TensorRT |
| INT4 | 4 bit | ~3-5% | GPTQ, AWQ |
| NF4 | 4 bit 浮点 | <1% | bitsandbytes |
量化感知训练(Quantization-Aware Training, QAT)
在训练过程中模拟量化误差,精度损失更小 (~0.5%),但需要重新训练。
主流量化方法
GPTQ
- 原理:贪心逐层量化,最小化重建误差
- 精度:INT4 接近 FP16
- 速度:一次前向量化,无需训练
- 支持:Llama, GPT, Mistral 等
bash
# 使用 AutoGPTQ
python -m transformers.onnx \
--model=model \
--output=quantized \
--quantize=gptq \
--bits=4AWQ(Activation-aware Weight Quantization)
- 原理:根据激活重要性保留重要权重
- 精度:优于 GPTQ
- 特点:不依赖校准数据
python
from awq import AutoAWQForCausalLM
model = AutoAWQForCausalLM.from_pretrained(
"model-path",
quantize=True,
bits=4,
group_size=128
)GGUF(GGML 格式)
专为 CPU 推理优化的量化格式:
bash
# llama.cpp 转换
python convert.py model.safetensors --outtype q4_0python
# 使用
from llama_cpp import Llama
llm = Llama(model_path="model-q4_0.gguf", n_ctx=2048)bitsandbytes(NF4)
Hugging Face 的量化库,支持 4-bit 和 8-bit:
python
from transformers import BitsAndBytesConfig
import torch
quant_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4", # 4-bit 浮点
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_use_double_quant=True # 二级量化进一步压缩
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b",
quantization_config=quant_config,
device_map="auto"
)量化参数
Bit Width
- 4-bit:最常用,精度损失可接受
- 8-bit:接近 FP16,适合高精度需求
- 2-bit:实验性,精度损失较大
Group Size
将权重分组量化,每组共享缩放因子:
- -1:每列量化(最高精度)
- 32, 64, 128:典型值,平衡精度和速度
- 越大:内存节省越多,精度损失越大
Symmetric vs Asymmetric
- Symmetric:对称量化([-scale, scale]),计算简单
- Asymmetric:非对称 ([0, 2^b-1]),精度略高
量化流程(PTQ)
- 准备校准数据:100-1000 个样本
- 统计激活值:计算每层的 min/max
- 确定缩放因子:根据范围计算 scale/zero_point
- 转换权重:FP16 → INTx
- 验证精度:在验证集评估
精度评估
量化后必须在验证集上评估:
python
from evaluate import load
perplexity = load("perplexity", module_type="metric")
results = perplexity.compute(
predictions=quantized_outputs,
references=original_outputs
)
print(f"Perplexity: {results['perplexity']}")建议指标:
- PPL(困惑度):语言模型主要指标
- 准确率:分类/问答任务
- BLEU/ROUGE:生成任务
硬件支持
| 硬件 | 支持精度 | 优化库 |
|---|---|---|
| NVIDIA GPU | FP16, BF16, INT8, INT4 | TensorRT, cuDNN |
| CPU (x86/ARM) | INT8, INT4 | ONNX Runtime, OpenVINO |
| Apple Silicon | FP16, INT8 | Core ML, MLX |
| 华为 Ascend | FP16, INT8 | CANN |
实用建议
- 先试 8-bit:精度损失小,兼容性好
- 4-bit 测 PPL:确保困惑度 < 1.1× FP16
- 任务相关测试:不要只看 PPL,测实际任务效果
- 注意特殊层:LayerNorm、Softmax 保持 FP16
- 混合精度:关键层保持高精度
工具对比
| 工具 | 支持模型 | 精度 (4-bit) | 速度 | 易用性 |
|---|---|---|---|---|
| bitsandbytes | HuggingFace | NF4 (~1%) | 快 | ⭐⭐⭐⭐⭐ |
| GPTQ | 主流开源 | ~3% | 非常快 | ⭐⭐⭐⭐ |
| AWQ | 主流开源 | ~2% | 快 | ⭐⭐⭐ |
| GGUF | llama.cpp | ~3% | CPU 快 | ⭐⭐⭐⭐ |
量化是大模型落地的关键技术,选择合适的量化策略能显著降低成本!
