量化(Quantization)通过低精度数值表示模型参数或中间数据,以减少内存占用、数据传输量,并在适合的硬件上提高推理效率。
1. 量化技术分类
Quantization
├── 量化对象
│ ├── Weights
│ ├── Activations
│ └── KV Cache
│
├── 数值格式
│ ├── INT8 / INT4
│ ├── FP8 / FP4
│ └── NF4
│
├── 量化粒度
│ ├── Per-tensor
│ ├── Per-channel
│ └── Per-group
│
├── 量化方法
│ ├── PTQ
│ └── QAT
│
├── 量化算法
│ ├── GPTQ
│ ├── AWQ
│ └── SmoothQuant
│
└── 工具与格式
├── bitsandbytes
├── GGUF
└── GPTQ / AWQ Model Files
需要区分:
| 概念 | 分类 | 主要作用 |
|---|---|---|
| INT4 / INT8 | 数值精度 | 降低数据位宽 |
| NF4 / FP4 | 低精度表示 | 使用不同的数值编码 |
| GPTQ | 量化算法 | 减少权重量化误差 |
| AWQ | 量化算法 | 利用 Activation 信息保护敏感权重 |
| SmoothQuant | 量化算法 | 改善 Activation 量化 |
| bitsandbytes | 软件库 | 提供低精度加载和计算 |
| GGUF | 模型文件格式 | 存储权重、量化信息及元数据 |
2. Symmetric 与 Asymmetric Quantization
Symmetric Quantization
使用对称的整数取值范围,零对应整数零。
例如:
Float Range: -1.0 ~ 1.0
INT8 Range: -127 ~ 127
量化:
反量化:
其中:
- (x):原始数值。
- (q):量化整数。
- (s):Scale。
- :恢复出的近似数值。
Asymmetric Quantization
引入 Zero Point,允许整数区间适应非对称数值分布。
其中 (z) 是 Zero Point。
实际量化还需要根据目标整数范围执行裁剪。
两种方式没有绝对优劣,取决于数值分布、硬件支持和具体量化算法。
3. Quantization Granularity:量化粒度
Per-tensor
整个 Tensor 使用一组量化参数。
问题是不同 Channel 的数值范围可能差异很大。
Channel A: -0.1 ~ 0.1
Channel B: -10 ~ 10
如果共用一个 Scale,Channel A 可能损失大量精度。
Per-channel
每个 Channel 使用独立的量化参数。
Channel 1 → Scale 1
Channel 2 → Scale 2
Channel 3 → Scale 3
实际对应权重矩阵的哪个维度,取决于量化实现。
Per-group / Group-wise
将权重分成多个小组,每组使用独立 Scale。
128 Weights → Scale 1
128 Weights → Scale 2
128 Weights → Scale 3
Group Size 越小,通常越容易适应局部数值分布,但需要更多元数据。
常见 Group Size 包括 32、64、128 等。
4. Weight-only 与 Weight-Activation Quantization
W4A16
Weights → INT4 / 4-bit Format
Activations → FP16 / BF16
主要用于减少:
- 模型权重占用。
- 显存带宽需求。
- 模型加载和传输的数据量。
很多 4-bit LLM 推理方案属于这一类。
W8A8
Weights → INT8
Activations → INT8
不仅压缩权重,也尝试使用低精度矩阵运算提高计算效率。
| 方案 | 主要优势 | 难点 |
|---|---|---|
| W4A16 | 大幅减少权重内存 | Dequantization 和 Kernel 效率 |
| W8A8 | 可利用低精度矩阵计算 | Activation Quantization |
| FP8 | 在支持的硬件上提高计算和内存效率 | 数值范围、Scale 和硬件兼容性 |
为什么 Activation 更难量化?
Weight 在训练后通常固定,可以提前分析数值分布。
Activation 则随输入内容、Token 和模型层而变化,可能出现动态 Outlier。
因此 Activation Quantization 通常需要更谨慎的校准或动态量化策略。
5. PTQ、QAT 与 Calibration
PTQ:Post-Training Quantization
模型完成训练后再量化。
常见方法:
- GPTQ。
- AWQ。
- SmoothQuant。
不需要重新进行完整模型训练。
QAT:Quantization-Aware Training
训练期间模拟量化误差,使模型适应低精度计算。
通常仍保留适合梯度更新的高精度训练状态。
Calibration Dataset
部分 PTQ 方法需要代表性样本,用于分析:
- Activation 分布。
- Outlier。
- 权重敏感程度。
- 量化误差。
例如提供几百到几千条代表性文本进行校准。
Calibration Dataset 与实际使用场景越接近,通常越有利于获得合理的量化结果。
但并非所有量化方法都要求 Calibration Dataset。
6. GPTQ
GPTQ 是典型的训练后权重量化算法。
核心思想:
在量化权重时,使用近似二阶信息衡量量化误差,并对尚未量化的权重进行补偿。
Original Weights
W1 W2 W3 W4
↓
Quantize W1
↓
Estimate Error
↓
Adjust Remaining Weights
↓
Continue Quantization
主要特点:
- 常用于 4-bit Weight-only Quantization。
- 通常需要校准数据。
- 量化过程可能比较耗时。
- 可以在较低位宽下保持较好的模型质量。
GPTQ 的优势在于量化误差控制,而不是保证任何硬件上都能获得最佳推理速度。
7. AWQ
AWQ:Activation-aware Weight Quantization。
核心思想:
模型中不同权重对于最终输出的重要程度不同,仅观察 Weight Magnitude 不够,还要考虑对应 Activation 的特征。
AWQ 通过 Activation Statistics 识别敏感权重或 Channel,并利用 Scaling 等方法降低其量化误差。
Calibration Data
↓
Activation Statistics
↓
Identify Salient Channels
↓
Protect Sensitive Weights
↓
Quantized Model
与 GPTQ 对比:
| 对比 | GPTQ | AWQ |
|---|---|---|
| 主要依据 | 近似二阶误差信息 | Activation Statistics |
| 核心策略 | 量化误差补偿 | 保护敏感权重 |
| 常见用途 | 4-bit 权重量化 | 4-bit 权重量化 |
| 是否需要校准 | 通常需要 | 通常需要 |
GPTQ 和 AWQ 都是常见的低比特推理选择,实际性能取决于模型、硬件和推理引擎。
8. SmoothQuant
SmoothQuant 主要用于解决 Activation 难以量化的问题。
观察:
Weights → 相对容易量化
Activations → Outlier 较明显
核心思想是通过等价变换,将部分 Activation 的数值范围压力转移到 Weight 侧。
Original:
Activation Range → Large
Weight Range → Moderate
After Smoothing:
Activation Range → Smaller
Weight Range → Larger
从而使 W8A8 Quantization 更容易实现。
与 GPTQ、AWQ 的典型 Weight-only 方案相比,SmoothQuant 更侧重 Weight + Activation 低精度计算。
9. bitsandbytes
bitsandbytes 是低精度计算和量化工具库,常与 Hugging Face Transformers、PEFT 配合使用。
典型用途:
- 8-bit 模型加载。
- 4-bit 模型加载。
- NF4 / FP4。
- QLoRA 微调。
4-bit NF4 加载
import torch
from transformers import (
AutoModelForCausalLM,
BitsAndBytesConfig,
)
quant_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
)
model = AutoModelForCausalLM.from_pretrained(
"your-model-id",
device_map="auto",
quantization_config=quant_config,
)
这里:
load_in_4bit:启用 4-bit 权重量化。bnb_4bit_quant_type:选择 NF4。bnb_4bit_compute_dtype:设置相关计算精度。bnb_4bit_use_double_quant:量化部分量化元数据。
实际 GPU 支持依赖 bitsandbytes、PyTorch 和设备环境。
bitsandbytes 主要适合 Hugging Face 生态的低精度加载与 QLoRA,并不意味着它一定是高并发生产推理的最佳方案。
10. NF4、FP4 与 Double Quantization
NF4:NormalFloat 4-bit
NF4 是针对近似正态分布权重设计的非均匀 4-bit 表示。
普通均匀量化的数值间隔通常固定,而 NF4 使用适合特定分布的量化级别。
它在 QLoRA 中尤其重要。
FP4
FP4 是 4-bit 浮点表示的一类统称。
需要注意,不同实现的 FP4 编码可能不同。bitsandbytes 中的 FP4 与现代 GPU 支持的其他 FP4 格式不能直接视为同一个格式。
Double / Nested Quantization
权重量化后还需要存储 Scale 等参数。
Double Quantization 进一步压缩部分量化元数据。
Original Weights
↓
4-bit Quantization
↓
Weights + Scales
↓
Quantize Scales
↓
Reduce Metadata Overhead
它降低的是量化元数据成本,不是把已经量化的所有权重再统一量化一次。
11. GGUF Quantization
GGUF 是 llama.cpp 生态常用的模型文件格式。
常见量化类型:
| 类型 | 特征 |
|---|---|
| Q4_0 | 较早期的 4-bit Block Quantization |
| Q4_K_S | K-Quant 4-bit,较小的混合方案 |
| Q4_K_M | K-Quant 4-bit,常见平衡方案 |
| Q5_K_M | 更高精度,文件通常更大 |
| Q6_K | 6-bit K-Quant |
| Q8_0 | 8-bit 量化,通常质量损失较小 |
Q4_K_M 与 Q5_K_M
K-Quant 使用分块量化、分组 Scale 等方式存储权重。
其中:
Q4/Q5表示主要量化位宽。K表示 K-Quant 系列。_S/_M表示不同的模型级量化组合策略。
Q4_K_M 和 Q5_K_M 可能对不同 Tensor 使用不同量化精度,并非所有 Tensor 都严格采用相同位宽。
因此实际模型大小大于简单的:
Parameters × 4 bits
量化版本如何选择?
对于同一个模型,一般可以这样理解:
Q4_K_M → 更重视内存和质量的平衡
Q5_K_M → 愿意增加内存换取更高精度
Q6_K → 进一步降低量化误差
Q8_0 → 通常更接近原始高精度模型
这不是跨模型的绝对质量排名。实际效果需要比较相同模型的不同量化版本。
llama.cpp 提供的量化参考数据显示,Q5_K_M 相比 Q4_K_M 通常拥有更大的文件体积和更低的 Perplexity 损失。
12. FP8 与 FP4
FP8
FP8 常见格式:
E4M3 → 1 Sign + 4 Exponent + 3 Mantissa
E5M2 → 1 Sign + 5 Exponent + 2 Mantissa
E4M3 具有较高的有效数字精度,E5M2 具有更大的指数范围。
与 INT8 相比,浮点表示能够覆盖较广的动态范围,但仍需要合理的 Scale 管理。
现代数据中心 GPU 对 FP8 的硬件支持不断完善,因此它在大规模推理和训练中越来越重要。
FP4
FP4 可以进一步降低权重与 Activation 的数据量。
但 FP4 的实际性能高度依赖 GPU 是否具有对应的低精度计算硬件、量化策略和 Kernel。
不能因为 FP4 使用 4 bit,就认为它一定比 FP8 快两倍。
13. Dequantization 与推理速度
Dequantization 是将量化值恢复成近似浮点值,或在计算 Kernel 内部完成等价的数据转换与计算。
例如:
INT4 Weights
↓
Read Compressed Weights
↓
Dequantization / Fused Kernel
↓
Matrix Computation
为什么 W4A16 可能更快?
假设模型原本有 16 GB 的 BF16 权重:
BF16 Weights ≈ 16 GB
INT4 Weights ≈ 4 GB + Metadata
对于 Memory-bound 的 Decode,降低权重读取量可能显著提高速度。
为什么量化不一定更快?
实际速度取决于:
- GPU 是否支持对应的低精度运算。
- 是否存在优化良好的 Quantized Kernel。
- Dequantization 开销。
- Batch Size。
- Prefill / Decode 比例。
- Kernel Fusion。
- Memory Bandwidth。
如果某个 GPU 的 BF16 Tensor Core 性能很强,而所选 INT4 Kernel 实现较差,那么 INT4 可能只节省显存,却不能提高速度。
因此需要分别衡量内存节省、模型质量和实际推理性能。
14. KV Cache Quantization
量化不仅可以用于 Weights,也可以用于 KV Cache。
例如:
Model Weights: INT4
KV Cache: FP8 / INT8
Activations: BF16
KV Cache Quantization 的主要价值:
- 降低长上下文的内存占用。
- 提高可支持的并发数量。
- 减少 Attention 读取 KV Cache 的数据量。
代价是可能引入额外的精度误差和量化计算开销。
对于长上下文和高并发推理,KV Cache Quantization 的意义可能非常明显。
15. 量化方案与推理引擎
模型能否运行,不仅由量化方法决定,还取决于模型文件格式和推理引擎支持的 Kernel。
| 方案 | 常见生态 | 典型用途 |
|---|---|---|
| GPTQ | Transformers、兼容的 GPU 推理引擎 | 4-bit 权重推理 |
| AWQ | Transformers、兼容的 GPU 推理引擎 | 4-bit 权重推理 |
| bitsandbytes NF4 | Transformers、PEFT | 低精度加载、QLoRA |
| GGUF Q4_K_M | llama.cpp、Ollama | 本地低内存推理 |
| FP8 | vLLM、SGLang 等兼容引擎 | 数据中心 GPU 推理 |
具体支持情况会随着推理引擎版本、模型架构及硬件改变。
不能简单地将 GGUF、GPTQ 和 AWQ 文件视为可以互换的模型文件。
16. 如何评估量化效果
量化需要同时比较三个维度。
| 维度 | 指标 |
|---|---|
| Memory | 模型体积、VRAM、KV Cache |
| Performance | TTFT、TPOT、Throughput |
| Quality | Perplexity、Benchmark、任务成功率 |
建议在相同条件下比较:
Same Model Architecture
Same Evaluation Dataset
Same Hardware
Same Input / Output Length
Same Concurrency
↓
BF16 vs INT8 vs INT4
Quality
可以观察:
- Perplexity。
- Benchmark Accuracy。
- 代码生成正确率。
- 工具调用正确率。
- 长上下文任务表现。
量化误差可能影响不同任务的程度不同,因此不能只依赖单个 Benchmark 判断模型质量。
17. LoRA、QLoRA、Distillation 与 Pruning
这几种技术与量化相关,但解决的问题不同。
LoRA
LoRA(Low-Rank Adaptation)是一种参数高效微调方法。
假设某个权重矩阵为 (W),训练时冻结原始矩阵,并增加低秩更新:
[ W'=W+BA ]
其中:
- (A)、(B):可训练的低秩矩阵。
- Rank (r):控制低秩更新的容量。
- 原始权重 (W):通常保持冻结。
因此只需要训练较少的新增参数。
QLoRA
将量化与 LoRA 结合:
Base Model
↓
4-bit NF4
↓
Frozen Base Weights
↓
Train LoRA Adapters
主要目的不是让模型推理更快,而是减少大模型微调过程中的显存需求。
Distillation
使用 Teacher Model 训练 Student Model。
常见方式:
- Output Distillation。
- Logit Distillation。
- Reasoning / Trace Distillation。
其目标通常是把大模型的部分能力迁移到更小的模型。
Pruning
删除或稀疏化不重要的参数、通道或结构。
包括:
- Unstructured Pruning:将部分权重置零。
- Structured Pruning:删除 Head、Channel、Neuron 或 Layer。
需要注意:稀疏化不等于一定加速,实际速度取决于硬件和 Sparse Kernel 支持情况。
技术对比
| 技术 | 核心动作 | 主要目的 |
|---|---|---|
| Quantization | 降低数值精度 | 减少内存和数据传输 |
| LoRA | 训练低秩增量参数 | 低成本微调 |
| QLoRA | 量化基础模型 + LoRA | 低显存微调 |
| Distillation | Teacher 训练 Student | 知识迁移、小模型化 |
| Pruning | 删除或稀疏化参数 | 压缩模型结构或计算 |
总结
量化最重要的知识可以归纳为:
| 分类 | 核心知识 |
|---|---|
| 基础原理 | Scale、Zero Point、Symmetric、Asymmetric |
| 量化粒度 | Per-tensor、Per-channel、Per-group |
| 量化对象 | Weight、Activation、KV Cache |
| 方法 | PTQ、QAT、Calibration |
| 核心算法 | GPTQ、AWQ、SmoothQuant |
| 具体生态 | bitsandbytes、NF4、GGUF、FP8 |
| 性能评估 | Memory、Quality、TTFT、TPOT、Throughput |
实际选型可以从场景出发:
Local Inference
↓
GGUF + llama.cpp / Ollama
GPU Weight-only Inference
↓
GPTQ / AWQ 等兼容方案
GPU FP8 Inference
↓
Hardware-supported FP8 Kernels
Low-memory Fine-tuning
↓
NF4 + QLoRA
核心原则:
量化主要通过降低数值精度节省内存和数据传输,但能否加速、加速多少、质量损失多大,都依赖具体模型、量化方案、硬件和推理引擎。