模型量化方法:PTQ、QAT、INT8、INT4、FP8 与大模型部署(分层式精讲)

核心结论
模型量化的目标不是把所有浮点数粗暴变成整数,而是在模型精度、显存、带宽、延迟、吞吐、能耗和硬件 kernel 之间做工程取舍。PTQ 适合快速部署,QAT 适合低比特或精度敏感场景;INT8 仍是通用部署主力,INT4/INT3 常用于大语言模型权重量化,FP8/MXFP8/FP4 则在新一代 GPU 训练和推理中变得越来越重要。
更准确的一句话是:
量化收益 = 数值格式压缩 × 硬件 kernel 支持 × 内存带宽改善 × 质量回归可控
原稿里“体积缩小 4-8 倍、推理速度提升 2-4 倍、精度损失 <1%”不能作为通用结论。FP32 到 INT8 的权重存储理论上是 4 倍压缩,FP16/BF16 到 INT8 是 2 倍压缩,FP16 到 INT4 是 4 倍压缩;真实推理速度还取决于算子是否真的以低精度运行、模型是否受内存带宽限制、batch size、序列长度、KV cache、CPU/GPU/NPU 后端和编译器融合效果。
第 0 层:30 秒理解
量化可以理解为把连续的浮点数放到更少的格子里。格子越少,模型越省显存和带宽;但格子太粗,模型输出就会偏离原模型。
核心公式是:
Q = clamp(round(x / scale) + zero_point, qmin, qmax)
x' = scale × (Q - zero_point)
其中 x 可以是权重、激活,也可以是 KV cache。对称量化常让 zero_point = 0,便于硬件计算;非对称量化能更好覆盖非零中心分布,但实现更复杂。
最重要的四个问题:
| 问题 | 决定什么 |
|---|---|
| 量化谁 | 权重、激活、KV cache、梯度、optimizer state |
| 量化到什么格式 | INT8、INT4、NF4、FP8、MXFP8、FP4 |
| 用什么方法 | PTQ、QAT、权重量化、SmoothQuant、GPTQ、AWQ、QLoRA |
| 在哪里运行 | CPU、GPU、NPU、TensorRT-LLM、ONNX Runtime、TorchAO、vLLM、ExecuTorch |

第 1 层:基础概念
1.1 为什么量化能加速
量化带来的收益主要来自三处:
| 收益来源 | 解释 | 常见瓶颈 |
|---|---|---|
| 存储减少 | 参数从 FP16/FP32 变成 INT8/INT4/FP8 | checkpoint、显存、移动端包体 |
| 带宽减少 | 读取权重和 KV cache 的字节数下降 | LLM 解码阶段常受内存带宽限制 |
| 低精度算子 | Tensor Core、NPU、CPU VNNI/AMX/NEON 等执行低精度 GEMM/Conv | 没有专用 kernel 时可能不加速 |
所以量化不是“保存成 int8 文件就结束”。如果推理框架仍然把 int8 权重反量化到 FP16 再计算,模型可能只省显存,不一定省时间。真正的部署要确认计算图、kernel 和硬件路径。
1.2 PTQ 与 QAT

| 方法 | 全称 | 是否重新训练 | 优点 | 风险 |
|---|---|---|---|---|
| PTQ | Post-Training Quantization | 通常不训练,只校准或优化权重 | 快,部署成本低 | 低比特或激活 outlier 明显时精度可能掉 |
| QAT | Quantization-Aware Training | 需要训练或微调 | 精度更稳,适合低比特和小模型 | 成本高,训练稳定性和框架支持更复杂 |
传统 CNN/检测模型里,PTQ INT8 和 QAT INT8 都很常见。大语言模型里,常见路线更细:
| 路线 | 说明 | 例子 |
|---|---|---|
| W8A16 | 权重 INT8,激活 FP16/BF16 | 动态量化、LLM.int8 的部分思想 |
| W4A16 | 权重 INT4,激活 FP16/BF16 | GPTQ、AWQ、bitsandbytes |
| W8A8 | 权重和激活都 8-bit | SmoothQuant、ZeroQuant 等 |
| KV cache 量化 | 压缩注意力缓存 | KIVI、KVQuant |
| 量化微调 | 冻结低比特基座,训练 adapter | QLoRA |
| FP8 推理/训练 | 用 FP8 张量和 scaling recipe | NVIDIA Transformer Engine、TensorRT-LLM |
1.3 粒度:per-tensor、per-channel、per-group、block scaling
量化粒度决定每个 scale 覆盖多少元素。
| 粒度 | 解释 | 适合场景 |
|---|---|---|
| per-tensor | 整个张量一个 scale | 简单算子,分布均匀 |
| per-channel | 每个输出通道一个 scale | Conv/Linear 权重常用 |
| per-group | 每组若干元素一个 scale | LLM INT4 权重量化常用 |
| per-token | 每个 token 或序列位置一个 scale | 激活或 KV cache 某些设计 |
| block scaling | 每个块共享 scale | MXFP8、NVFP4 等新格式 |
粒度越细,误差越小,但 scale 元数据、kernel 复杂度和内存访问模式也更复杂。
第 2 层:PTQ 怎么做
PTQ 的基本流程是:拿到训练好的模型,用少量代表性样本估计数值范围或优化低比特权重,然后导出后端支持的量化模型。
浮点 checkpoint
-> 代表性校准数据
-> 统计权重/激活/KV 分布
-> 选择格式和粒度
-> 量化并评估
-> 导出到目标推理后端
2.1 传统 PTQ:MinMax、Percentile、MSE、KL
| 校准方法 | 核心思想 | 适合场景 |
|---|---|---|
| MinMax | 用最小最大值覆盖全部范围 | 快速基线,无明显异常值 |
| Percentile | 裁剪极端值,例如 99.9% | outlier 明显的激活 |
| MSE | 找让重建误差最小的范围 | 对精度较敏感的层 |
| KL | 让量化前后分布差异小 | 分类模型和部分视觉模型常用 |
校准数据必须代表真实分布。对 LLM 来说,校准样本的语言、领域、prompt 格式、序列长度都会影响量化效果。只用短 prompt 校准,再上线长上下文,可能低估 KV cache 和激活范围问题。
2.2 LLM PTQ:为什么不能只讲 MinMax
大模型的核心挑战是激活 outlier 和超大矩阵乘法。很多权重比较容易量化,但某些激活通道有极端值,直接 W8A8 会明显损害质量。
| 方法 | 解决的问题 | 思路 |
|---|---|---|
| LLM.int8 | 大模型 8-bit 矩阵乘 | 对异常通道保留高精度路径 |
| SmoothQuant | W8A8 中激活难量化 | 把激活 outlier 的难度迁移到权重 |
| GPTQ | 低比特权重量化 | 用近似二阶信息逐层量化权重 |
| AWQ | 权重量化保护关键通道 | 根据激活重要性保护少量显著权重通道 |
| QuaRot / SpinQuant 类方法 | 激活和权重 outlier | 通过旋转让分布更适合低比特 |

2.3 Weight-only 量化:W4A16 为什么常见
很多 LLM 部署采用 W4A16 或 W8A16:权重低比特存储,计算时与 FP16/BF16 激活配合。这样能显著降低权重带宽和显存,且比 W4A4/W8A8 更容易保持质量。
典型用法:
预训练权重 FP16/BF16
-> 逐层校准
-> 权重按 group 量化到 INT4 / NF4
-> 激活保持 FP16/BF16
-> 使用支持 W4A16 的 GEMM kernel 推理
它的风险是:如果 backend 没有高效的 4-bit weight-only kernel,可能只省显存,不明显加速。
2.4 KV cache 量化:长上下文时代的新重点
LLM 自回归生成时,KV cache 会随 batch size 和序列长度线性增长。长上下文和高并发场景下,KV cache 可能成为显存瓶颈。
KV cache 量化关注:
| 对象 | 作用 | 难点 |
|---|---|---|
| Key cache | 注意力匹配 | 分布可能按通道更适合量化 |
| Value cache | 输出聚合 | 分布可能按 token 更适合量化 |
| RoPE 后张量 | 位置编码后分布变化 | 长上下文下误差更敏感 |
| 解码阶段读取 | 每步都读 KV | 带宽瓶颈明显 |
KIVI、KVQuant 等 2024 年工作说明,KV cache 不是附属细节,而是长上下文推理成本的核心组成。
第 3 层:QAT 怎么做
QAT 在训练中插入 fake quant,让模型提前适应量化误差。它一般包含 observer、fake quant、STE 和最终转换步骤。
FP 模型
-> 插入 observer / fake quant
-> 前向模拟量化误差
-> 反向用 STE 近似梯度
-> 微调或训练
-> convert 到目标 backend 量化图
3.1 为什么不建议手写 QAT 框架
原稿中的 QAT 代码适合作为概念演示,但不适合作为工程实现,原因包括:
round的梯度几乎处处为 0,需要 STE 或框架 fake quant。- 在
forward中创建Parameter会破坏训练语义。 - 直接把权重替换成
char()不能让普通 Conv/Linear 自动调用低精度 kernel。 - Conv、Linear、MatMul、LayerNorm、残差加法、Softmax 的量化边界都需要图级处理。
- 部署端要匹配 ONNX Runtime、TensorRT、TorchAO、ExecuTorch、TFLite 或芯片 SDK。
更实际的写法是使用框架:
def quantization_eval_gate(metrics, limits):
return (
metrics["task_score_drop"] <= limits["max_task_score_drop"]
and metrics["p95_latency_ms"] <= limits["max_p95_latency_ms"]
and metrics["peak_memory_gb"] <= limits["max_peak_memory_gb"]
and metrics["format_error_rate"] <= limits["max_format_error_rate"]
)
这段代码不试图重新实现 QAT,而是强调量化发布前必须过评估闸门。
3.2 QAT 适合哪些场景
| 场景 | 是否优先 QAT | 原因 |
|---|---|---|
| 小 CNN/检测模型 INT8 部署 | 是 | 小模型冗余少,PTQ 容易掉点 |
| 超低比特 INT4/INT2 | 是 | 量化误差大,需要模型适应 |
| 大模型 W4A16 快速部署 | 不一定 | GPTQ/AWQ 等 PTQ 已很强,QAT 成本高 |
| 大模型低比特训练或微调 | 视情况 | QLoRA 是更常见的低成本路线 |
| 安全/医疗/金融等高风险任务 | 常需要 | 量化后边缘行为必须严格回归 |
3.3 QLoRA:量化不是只能用于推理
QLoRA 的核心是:把预训练模型以 4-bit 形式冻结,梯度穿过低比特模型流向 LoRA adapter,从而大幅降低微调显存。它不是传统意义上的“把模型全量变成 INT4 推理模型”,而是低比特存储 + adapter 训练的组合。
关键点:
- NF4 适合近似正态分布的权重。
- Double quantization 进一步压缩量化常数。
- Paged optimizer 缓解显存尖峰。
- 最终部署时仍要评估 adapter merge、量化格式和推理 backend。
第 4 层:INT8、INT4、FP8 到底怎么选

4.1 INT8:成熟但不是万能
INT8 最大优势是生态成熟。CPU、GPU、NPU、移动端都有大量 INT8 kernel。它适合:
- CNN、检测、分割、语音等传统模型部署。
- 对吞吐和能耗敏感的边缘设备。
- 可接受少量校准和回归测试的服务端推理。
- W8A8 LLM 推理,但需要处理激活 outlier。
INT8 的风险是:如果模型对激活异常值敏感,W8A8 可能掉点;如果只做权重 INT8 而计算仍 FP16,速度收益有限。
4.2 INT4:LLM 压缩主力之一
INT4 在 LLM 中很常见,尤其是 W4A16。它适合显存紧张、权重带宽瓶颈明显、模型可接受轻微质量波动的场景。
注意:
- INT4 不等于 8 倍加速;FP16 到 INT4 是 4 倍权重存储压缩。
- 需要 group size、zero point、scale、packing 和 kernel 支持。
group_size=32/64/128的选择会影响精度和速度。- Embedding、lm_head、第一层、最后几层、部分 attention 层可能更敏感。
4.3 FP8:更像低精度浮点计算体系
FP8 不是整数模型。常见格式:
| 格式 | 结构 | 特点 |
|---|---|---|
| E4M3 | 1 sign + 4 exponent + 3 mantissa | 精度相对更好,范围较小 |
| E5M2 | 1 sign + 5 exponent + 2 mantissa | 动态范围更大,精度较低 |
| MXFP8 | microscaling/block scaling | 每个块有 scale,更适合新硬件 |
| NVFP4 / FP4 | 更低比特浮点 | 依赖 Blackwell 等新硬件和配套 recipe |
FP8 的收益高度依赖硬件。NVIDIA Hopper、Blackwell 及 Transformer Engine/TensorRT-LLM 支持让 FP8 在训练和推理中实用化,但在不支持 FP8 Tensor Core 的设备上,FP8 可能只是存储格式,不一定加速。
4.4 BF16/FP16 仍然重要
不要把 BF16/FP16 看成过时格式。很多量化方案会保留以下模块为 FP16/BF16:
- LayerNorm / RMSNorm。
- Softmax。
- RoPE 和部分 attention 中间值。
- 输出头或极敏感层。
- 小模型的第一层和最后一层。
混合精度不是失败,而是常态。
第 5 层:策略选择矩阵

| 需求 | 推荐起点 | 不建议一开始做 |
|---|---|---|
| 视觉模型边缘部署 | PTQ INT8;掉点再 QAT | 手写量化 kernel |
| LLM 显存不够 | W4A16:AWQ/GPTQ/bitsandbytes | 直接 W4A4 |
| LLM 高吞吐服务 | W8A8 或 FP8,配合 TensorRT-LLM/vLLM 等 | 只看 checkpoint 大小 |
| 长上下文高并发 | KV cache INT8/INT4 + 分页注意力 | 只压缩权重 |
| 低成本微调 | QLoRA / LoRA + 4-bit base | 全参低比特训练起步 |
| 新 GPU 训练 | BF16 baseline,再评估 FP8/MXFP8 | 忽略 loss scale 和 amax history |
| CPU/移动端 | ONNX Runtime / TFLite / ExecuTorch INT8 | 使用 GPU 专用量化格式 |
一个稳妥流程:
先确定目标硬件和推理引擎
-> 建 FP16/BF16 baseline
-> 做最简单 PTQ
-> 加真实任务评估和延迟评估
-> 再尝试 GPTQ/AWQ/SmoothQuant/FP8/KV cache
-> 最后考虑 QAT 或混合精度
第 6 层:评估体系
量化评估不能只看 accuracy,也不能只看模型大小。必须在目标硬件上测真实 workload。

6.1 必测指标
| 指标 | 说明 |
|---|---|
| 任务质量 | accuracy、mAP、WER、BLEU、困惑度、人工偏好、代码通过率等 |
| 延迟 | 首 token 延迟、单步 decode latency、p50/p95/p99 |
| 吞吐 | tokens/s、requests/s、images/s |
| 显存 | 权重、激活、KV cache、峰值显存 |
| 模型大小 | checkpoint 大小、打包后大小、scale 元数据 |
| 能耗和成本 | 每请求能耗、GPU 利用率、实例成本 |
| 稳定性 | NaN、溢出、格式错误、长尾样本失败 |
6.2 评估代码骨架
def compare_quantized_model(fp_model, quant_model, eval_suite, measure_fn):
report = {}
for name, dataset in eval_suite.items():
fp_metrics = measure_fn(fp_model, dataset)
q_metrics = measure_fn(quant_model, dataset)
report[name] = {
"fp": fp_metrics,
"quantized": q_metrics,
"quality_drop": fp_metrics["score"] - q_metrics["score"],
"latency_ratio": q_metrics["p95_latency_ms"] / fp_metrics["p95_latency_ms"],
"memory_ratio": q_metrics["peak_memory_gb"] / fp_metrics["peak_memory_gb"],
}
return report
关键是 measure_fn 要在真实硬件上测,不能用理论 FLOPs 或 checkpoint 大小代替。
6.3 LLM 额外评估
LLM 量化至少还要看:
- 长上下文困惑度和召回能力。
- 数学、代码、多轮对话、工具调用、JSON 格式。
- 安全拒答和敏感边界。
- 不同 batch size 下的吞吐。
- prefill 与 decode 分别计时。
- KV cache 开启和关闭量化的差异。
- 采样参数变化下的输出稳定性。
第 7 层:实用落地建议
7.1 PTQ 实施清单
- 明确目标:省显存、提吞吐、降延迟、降成本,目标不同策略不同。
- 建立 FP16/BF16 baseline:同一硬件、同一 batch、同一序列长度。
- 准备校准集:覆盖真实输入长度、领域、格式和长尾样本。
- 先做安全基线:dynamic INT8 或 W8A16/W4A16。
- 对 LLM 尝试 GPTQ/AWQ;需要 W8A8 时再看 SmoothQuant。
- 检查敏感层:第一层、最后层、lm_head、attention、norm、outlier 层。
- 用目标推理引擎导出并实测,不只看离线误差。
7.2 QAT 实施清单
- 使用框架 fake quant/observer,不手写 monkey patch。
- 从已有浮点 checkpoint 微调,先用较低学习率。
- 保留可回滚 checkpoint。
- 先只量化权重,再考虑激活。
- 对敏感模块保持高精度。
- 训练中监控 scale、amax、clip ratio 和 loss spike。
- 最后必须 convert 到目标 backend,验证低精度 kernel 路径。
7.3 常见问题
| 问题 | 常见原因 | 处理 |
|---|---|---|
| 模型变小但不变快 | 没有低精度 kernel,或反量化开销大 | 换推理引擎,检查算子路径 |
| INT8 掉点严重 | 激活 outlier,校准集不代表真实分布 | SmoothQuant、percentile、混合精度、QAT |
| INT4 LLM 生成质量差 | group size 太大,敏感层被量化 | 减小 group size,保留敏感层高精度,换 AWQ/GPTQ |
| 长上下文显存仍爆 | 只量化权重,KV cache 未处理 | 加 KV cache 量化和分页注意力 |
| FP8 不稳定 | scaling recipe、amax history、硬件支持不匹配 | 用 Transformer Engine recipe,回退 BF16 对照 |
| 线上格式错误增加 | 量化影响输出分布 | 加 JSON/工具调用回归集,敏感层混合精度 |
总结与关键洞见
量化不是单个算法,而是一条部署链路:
数值格式
-> 校准/训练方法
-> 量化粒度
-> 敏感层策略
-> 推理引擎
-> 硬件 kernel
-> 真实任务评估
真正的工程判断不是“INT8 好还是 FP8 好”,而是:
- 你的模型瓶颈是权重、激活、KV cache 还是算力?
- 你的目标硬件支持什么低精度 kernel?
- 你的任务能容忍多少质量回退?
- 你的评估集是否覆盖真实长尾输入?
- 量化后是否真的降低 p95 延迟和单位请求成本?
一句话收束:
好的量化不是把模型压到最低比特,而是在目标硬件上用最小质量代价换到可验证的显存、延迟、吞吐和成本收益。
参考资料
- Jacob et al., “Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference,” CVPR 2018. https://arxiv.org/abs/1712.05877
- Esser et al., “Learned Step Size Quantization,” ICLR 2020. https://arxiv.org/abs/1902.08153
- Choi et al., “PACT: Parameterized Clipping Activation for Quantized Neural Networks,” 2018. https://arxiv.org/abs/1805.06085
- Dettmers et al., “LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale,” NeurIPS 2022. https://arxiv.org/abs/2208.07339
- Micikevicius et al., “FP8 Formats for Deep Learning,” 2022. https://arxiv.org/abs/2209.05433
- Frantar et al., “GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers,” ICLR 2023. https://arxiv.org/abs/2210.17323
- Xiao et al., “SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models,” ICML 2023. https://arxiv.org/abs/2211.10438
- Lin et al., “AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration,” MLSys 2024. https://arxiv.org/abs/2306.00978
- Dettmers et al., “QLoRA: Efficient Finetuning of Quantized LLMs,” NeurIPS 2023. https://arxiv.org/abs/2305.14314
- Liu et al., “KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache,” ICML 2024. https://arxiv.org/abs/2402.02750
- Hooper et al., “KVQuant: Towards 10 Million Context Length LLM Inference with KV Cache Quantization,” NeurIPS 2024. https://arxiv.org/abs/2401.18079
- Ashkboos et al., “QuaRot: Outlier-Free 4-Bit Inference in Rotated LLMs,” 2024. https://arxiv.org/abs/2404.00456
- PyTorch AO / TorchAO quantization project. https://github.com/pytorch/ao
- Or et al., “TorchAO: PyTorch-Native Training-to-Serving Model Optimization,” 2025. https://arxiv.org/abs/2507.16099
- ONNX Runtime quantization documentation. https://onnxruntime.ai/docs/performance/model-optimizations/quantization.html
- NVIDIA Transformer Engine FP8/FP4 documentation. https://docs.nvidia.com/deeplearning/transformer-engine/user-guide/examples/fp8_primer.html
- NVIDIA TensorRT-LLM documentation. https://docs.nvidia.com/deeplearning/tensorrt-llm/
更多推荐




所有评论(0)