模型量化技术:让大模型更轻更快

量化是把大模型”压缩”的关键技术。4bit 量化可以让 70B 模型在 48GB 显存里跑起来。

为什么需要量化?

大模型的”重量”问题:

模型 参数量 FP16 显存 INT8 显存 INT4 显存
LLaMA 3 8B 8B ~16GB ~8GB ~4GB
LLaMA 3 70B 70B ~140GB ~70GB ~35GB
Qwen 72B 72B ~144GB ~72GB ~36GB
Mistral 7B 7B ~14GB ~7GB ~3.5GB

一张消费级显卡(RTX 4090 = 24GB)跑不了 FP16 的 70B 模型,但 INT4 量化后可以。

量化的核心思想:用更少的位数表示权重,从 32位浮点(FP32) 或 16位浮点(FP16/BF16) 降到 INT8、INT4、甚至 INT2。


量化基础概念

数值格式

FP32 (32位浮点):  1位符号 + 8位指数 + 23位尾数
                  [S][EEEEEEEE][MMMMMMMMMMMMMMMMMMMMMMM]
                  精度高,范围大

FP16 (16位浮点):  1位符号 + 5位指数 + 10位尾数
                  [S][EEEEE][MMMMMMMMM]
                  范围和精度都降低

BF16 (16位浮点):  1位符号 + 8位指数 + 7位尾数
                  [S][EEEEEEEE][MMM]
                  范围同 FP32,精度降低

INT8 (8位整数):   256 个离散值: -128 ~ 127
                  体积是 FP16 的 1/2

INT4 (4位整数):   16 个离散值: -8 ~ 7
                  体积是 FP16 的 1/4

量化误差

原始值:  0.123456789
FP16:   0.12346       (损失小)
INT8:   0.12          (误差约 3%)
INT4:   0.125         (误差约 1.5%)

INT4 看起来误差更小?别忘了那是”重新映射”后的误差。


量化方法分类

1. 训练后量化(PTQ)

在模型训练/微调完成后,直接量化。不需要重新训练,速度快。

动态量化(Dynamic Quantization)

  • 权重提前量化,激活值推理时动态量化
  • 最简单,效果一般
  • 适用于推理场景
import torch

# 动态量化(权重 INT8,激活保持 FP16)
model_dynamic = torch.quantization.quantize_dynamic(
    model, {torch.nn.Linear}, dtype=torch.qint8
)

静态量化(Static Quantization)

  • 需要校准数据集,计算激活分布
  • 权重和激活都量化
  • 效果更好,需要额外步骤
# 静态量化流程
model.eval()

# Fuse layers (Linear + ReLU -> Linear)
torch.quantization.fuse_modules(model, [['fc1', 'relu']])

# Prepare (插入观测节点)
model.qconfig = torch.quantization.get_default_qconfig('fbgemm')
torch.quantization.prepare(model, inplace=True)

# Calibrate (用校准数据)
with torch.no_grad():
    for batch in calibration_data:
        model(batch)

# Convert (真正量化)
torch.quantization.convert(model, inplace=True)

2. 量化感知训练(QAT)

在训练过程中模拟量化,让模型”适应”量化带来的误差。

# QAT 流程
# 1. 在模型中插入 FakeQuant 节点
model.qconfig = torch.quantization.get_default_qat_qconfig('fbgemm')
torch.quantization.prepare_qat(model, inplace=True)

# 2. Fine-tune on training data
train(model)

# 3. 转换
torch.quantization.convert(model.eval(), inplace=True)

QAT vs PTQ 对比

方法 精度 成本 适用场景
PTQ 动态 ⭐⭐ 免费 快速部署
PTQ 静态 ⭐⭐⭐ 生产环境
QAT ⭐⭐⭐⭐ 极致精度

高级量化技术

1. GPTQ:单卡量化 70B 模型

GPTQ(Generative Pre-trained Transformer Quantization)可以在单张 GPU 上用几小时量化 70B 模型。

from auto_gptq import AutoGPTQForCausalLM
from transformers import AutoTokenizer

model = AutoGPTQForCausalLM.from_pretrained(
    "meta-llama/Llama-3-70B",
    quantization_config={"bits": 4, "desc_act": True}
)

# bits: 4 或 8
# desc_act: 激活顺序重排,减少精度损失

GPTQ 核心原理

  1. 分块量化(Chunk-based)
  2. 递归最小化量化误差
  3. 使用 Hickup 优化补偿

2. AWQ:Activation-Aware Weight Quantization

AWQ 观察到:不是所有权重都一样重要,激活值大的权重更重要

from awq import AutoAWQForCGMModel
from transformers import AutoTokenizer

model = AutoAWQForCGMModel.from_pretrained("meta-llama/Llama-3-70B")
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3-70B")

quant_config = {
    "zero_point": True,
    "q_group_size": 128,  # 分组大小
    "w_bit": 4,
    "version": "GEMM"     # GEMM 或 GEMV
}

model.quantize(tokenizer, quant_config=quant_config)

3. GGUF:本地部署的量化格式

GGUF(GPT-Generated Unified Format)是 llama.cpp 推出的量化格式,适合 CPU 推理。

格式 量子化位数 70B 大小 适用场景
Q8_0 8bit ~70GB 接近无损
Q6_K 6bit ~55GB 高质量
Q5_K_M 5bit ~48GB 均衡
Q4_K_M 4bit ~40GB 主流选择
Q3_K_M 3bit ~35GB 低显存
Q2_K 2bit ~30GB 极致压缩
# 使用 llama.cpp 量化
./quantize ./models/llama-70b-f16.gguf ./models/llama-70b-q4_k_m.gguf q4_k_m

4. FP8:新一代量化格式

NVIDIA H100 支持 FP8(8位浮点),兼顾范围和精度。

# PyTorch FP8 支持 (需要 H100)
from torch.cuda.amp import custom_fwd, custom_bwd

@custom_fwd(device="cuda")
def forward_fp8(x):
    return x.float8_e4m3fn(x)

量化实战:用 llama.cpp 本地跑大模型

# 1. 安装 llama.cpp
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp && mkdir build && cd build && cmake .. && make

# 2. 下载模型 (Qwen 2.5 7B)
# 3. 量化
./quantize ./models/qwen-7b-f16.gguf ./models/qwen-7b-q4_k_m.gguf q4_k_m

# 4. 推理
./main -m ./models/qwen-7b-q4_k_m.gguf -n 512 -p "你好,介绍一下自己"

内存占用对比(Qwen 2.5 7B)

格式 内存占用 生成速度
FP16 ~14GB 30 tok/s
Q8_0 ~8GB 25 tok/s
Q4_K_M ~4.5GB 20 tok/s

量化方案的选用指南

场景 推荐方案 说明
生产部署 INT8 + AWQ 精度损失 < 1%
个人推理 Q4_K_M (GGUF) RTX 3090/4090 可跑 70B
极致压缩 INT2/INT3 精度损失较大,仅实验
最新模型 GPTQ / AWQ 支持大多数开源模型
CPU 部署 GGUF Q4 llama.cpp 生态成熟

💡 小结

量化是让大模型”平民化”的关键技术

量化方法 精度损失 难度 适用
动态量化 中等 快速部署
GPTQ 较小 70B+ 模型
AWQ 较小 最佳性价比
QAT 最小 极致精度

实践建议

  1. 优先尝试 AWQGPTQ(4bit)
  2. 生产环境用 INT8Q5_K_M
  3. CPU 推理用 GGUF Q4_K_M
  4. 评估时用 困惑度(Perplexity)下游任务准确率

相关阅读:AI Agent 记忆机制:让AI更懂你