在这里插入图片描述

核心结论

模型量化的目标不是把所有浮点数粗暴变成整数,而是在模型精度、显存、带宽、延迟、吞吐、能耗和硬件 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 实施清单

  1. 明确目标:省显存、提吞吐、降延迟、降成本,目标不同策略不同。
  2. 建立 FP16/BF16 baseline:同一硬件、同一 batch、同一序列长度。
  3. 准备校准集:覆盖真实输入长度、领域、格式和长尾样本。
  4. 先做安全基线:dynamic INT8 或 W8A16/W4A16。
  5. 对 LLM 尝试 GPTQ/AWQ;需要 W8A8 时再看 SmoothQuant。
  6. 检查敏感层:第一层、最后层、lm_head、attention、norm、outlier 层。
  7. 用目标推理引擎导出并实测,不只看离线误差。

7.2 QAT 实施清单

  1. 使用框架 fake quant/observer,不手写 monkey patch。
  2. 从已有浮点 checkpoint 微调,先用较低学习率。
  3. 保留可回滚 checkpoint。
  4. 先只量化权重,再考虑激活。
  5. 对敏感模块保持高精度。
  6. 训练中监控 scale、amax、clip ratio 和 loss spike。
  7. 最后必须 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 延迟和单位请求成本?

一句话收束:

好的量化不是把模型压到最低比特,而是在目标硬件上用最小质量代价换到可验证的显存、延迟、吞吐和成本收益。

参考资料

  1. Jacob et al., “Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference,” CVPR 2018. https://arxiv.org/abs/1712.05877
  2. Esser et al., “Learned Step Size Quantization,” ICLR 2020. https://arxiv.org/abs/1902.08153
  3. Choi et al., “PACT: Parameterized Clipping Activation for Quantized Neural Networks,” 2018. https://arxiv.org/abs/1805.06085
  4. Dettmers et al., “LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale,” NeurIPS 2022. https://arxiv.org/abs/2208.07339
  5. Micikevicius et al., “FP8 Formats for Deep Learning,” 2022. https://arxiv.org/abs/2209.05433
  6. Frantar et al., “GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers,” ICLR 2023. https://arxiv.org/abs/2210.17323
  7. Xiao et al., “SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models,” ICML 2023. https://arxiv.org/abs/2211.10438
  8. Lin et al., “AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration,” MLSys 2024. https://arxiv.org/abs/2306.00978
  9. Dettmers et al., “QLoRA: Efficient Finetuning of Quantized LLMs,” NeurIPS 2023. https://arxiv.org/abs/2305.14314
  10. Liu et al., “KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache,” ICML 2024. https://arxiv.org/abs/2402.02750
  11. Hooper et al., “KVQuant: Towards 10 Million Context Length LLM Inference with KV Cache Quantization,” NeurIPS 2024. https://arxiv.org/abs/2401.18079
  12. Ashkboos et al., “QuaRot: Outlier-Free 4-Bit Inference in Rotated LLMs,” 2024. https://arxiv.org/abs/2404.00456
  13. PyTorch AO / TorchAO quantization project. https://github.com/pytorch/ao
  14. Or et al., “TorchAO: PyTorch-Native Training-to-Serving Model Optimization,” 2025. https://arxiv.org/abs/2507.16099
  15. ONNX Runtime quantization documentation. https://onnxruntime.ai/docs/performance/model-optimizations/quantization.html
  16. NVIDIA Transformer Engine FP8/FP4 documentation. https://docs.nvidia.com/deeplearning/transformer-engine/user-guide/examples/fp8_primer.html
  17. NVIDIA TensorRT-LLM documentation. https://docs.nvidia.com/deeplearning/tensorrt-llm/
Logo

免费领 150 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐