惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News | PayPal Newsroom
P
Proofpoint News Feed
Cyberwarzone
Cyberwarzone
C
Cisco Blogs
SecWiki News
SecWiki News
Know Your Adversary
Know Your Adversary
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Vercel News
Vercel News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
NISL@THU
NISL@THU
WordPress大学
WordPress大学
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Threat Research - Cisco Blogs
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
Security Archives - TechRepublic
Security Archives - TechRepublic
有赞技术团队
有赞技术团队
L
LINUX DO - 热门话题
Hacker News: Ask HN
Hacker News: Ask HN
V
V2EX
G
GRAHAM CLULEY
TaoSecurity Blog
TaoSecurity Blog
Hugging Face - Blog
Hugging Face - Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Fortinet All Blogs
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
Latest news
Latest news
The Hacker News
The Hacker News
aimingoo的专栏
aimingoo的专栏
T
Troy Hunt's Blog
S
Schneier on Security
I
Intezer
Google DeepMind News
Google DeepMind News
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threatpost
爱范儿
爱范儿
The Register - Security
The Register - Security
S
SegmentFault 最新的问题
Blog — PlanetScale
Blog — PlanetScale
博客园 - 聂微东
宝玉的分享
宝玉的分享
Recent Commits to openclaw:main
Recent Commits to openclaw:main
美团技术团队
B
Blog RSS Feed

土法炼钢兴趣小组的算法知识备份

国密算法与国密 TLS 系列索引 【系统架构设计】架构质量属性:不只是"高可用高性能" 【系统架构设计百科】告警策略:如何避免"狼来了" 【系统架构设计】CQRS:读写分离的架构哲学 【系统架构设计】空间架构:极端扩展场景的解法 【系统架构设计】微服务架构深度审视:优势、代价与适用边界 【系统架构设计】扩展性原理:水平、垂直与对角扩展 【系统架构设计】无状态设计:扩展的第一步也是最难的一步 【系统架构设计】缓存架构:从本地到分布式的多级缓存体系 【系统架构设计】管道与过滤器:Unix 哲学的架构表达 【系统架构设计】复杂性管理:架构的核心战场 【系统架构设计】消息队列架构:异步解耦的设计与陷阱 【系统架构设计】CDN 架构:全球加速的设计原理 【系统架构设计】连接池设计:被忽视的性能杀手 【系统架构设计】弹性设计模式:熔断器、舱壁与超时 【系统架构设计】高可用设计模式:冗余、故障转移与仲裁 【系统架构设计】容量规划:从拍脑袋到数据驱动 【系统架构设计】数据库扩展:分库分表的工程实践与替代方案 【系统架构设计】SLO 工程:可靠性的量化管理 【系统架构设计】性能建模:用数学思维分析系统瓶颈 【系统架构设计】混沌工程:主动验证系统的韧性 【系统架构设计】零拷贝与内存映射:数据搬运的极致优化 【系统架构设计】线程模型:从 thread-per-request 到协程 【系统架构设计】容灾架构:多活与灾备设计 【系统架构设计】数据库性能模式:索引、查询与连接管理 【系统架构设计】数据建模:从关系范式到文档模型的真实权衡 【系统架构设计】吞吐量优化:批处理、流水线与并发模型 【系统架构设计】流处理架构:从批处理到实时的范式迁移 【系统架构设计】搜索引擎架构:倒排索引之上的系统设计 【系统架构设计】时序数据架构:监控与 IoT 的存储设计 【系统架构设计】数据迁移与版本化:在线不停机的数据演进 【系统架构设计】数据湖与数据仓库:分析架构的演进路线 【系统架构设计】API 网关设计:入口层的职责边界 【系统架构设计】应用层数据一致性模式:在正确性与性能之间走钢丝 【系统架构设计】多模数据库选型:Polyglot Persistence 的工程实践 【系统架构设计】服务发现与注册:动态拓扑的基础设施 【系统架构设计】配置管理架构:从配置文件到配置中心 【系统架构设计】全链路压测:大规模系统的性能验证 【系统架构设计】幂等性设计:分布式环境下的安全重试 【系统架构设计】契约测试与 Schema 演进:服务间的信任协议 【系统架构设计】长连接与推送架构:WebSocket、SSE 与 MQTT 【系统架构设计】延迟分析:从 P50 到 P999 的全链路追踪 【系统架构设计百科】DDD 战术模式:聚合、实体与值对象 【系统架构设计百科】防腐层与开放主机服务:系统集成的 DDD 方案 【系统架构设计百科】领域事件与事件风暴:从业务到架构的桥梁 【系统架构设计百科】CQRS + Event Sourcing 完整实战:从领域建模到部署 【系统架构设计百科】DDD 与微服务:用领域模型划分服务边界 【系统架构设计】DDD 战略设计:限界上下文与上下文映射 【系统架构设计百科】认证架构:从 Session 到 JWT 到 OIDC 【系统架构设计】API 设计哲学:REST vs GraphQL vs gRPC 的真实权衡 排序算法专题:从 TimSort 到并行排序 【密码学百科】国密算法体系:SM2/SM3/SM4/SM9 全景解读 【密码学百科】承诺方案:Pedersen 承诺、向量承诺与多项式承诺 【密码学百科】不经意传输与隐私信息检索:OT、OT 扩展与 PIR 【密码学百科】门限密码学:门限签名、门限解密与分布式密钥生成 完美哈希:从理论到 gperf 实践 【密码学百科】安全多方计算:从 Yao 的混淆电路到实用 MPC 【密码学百科】同态加密:从 Paillier 到全同态加密(FHE) 【密码学百科】零知识证明系统:zk-SNARKs、zk-STARKs 与 Bulletproofs 【密码学百科】概率论与密码分析:生日攻击、差分分析与线性分析 【密码学百科】计算复杂性与归约:密码安全性证明的基石 【密码学百科】秘密共享:Shamir 方案、VSS 与安全多方计算入口 【密码学百科】椭圆曲线代数:Weierstrass 方程、点群运算与曲线选择 【密码学百科】离散对数与配对密码学:从 DLP 到 BLS 签名 【密码学百科】格密码数学基础:SVP、LWE 与格基约化 【密码学百科】抽象代数:群、环、域的密码学视角 【密码学百科】有限域算术:GF(2^n) 运算与在 AES/ECC 中的应用 【密码学百科】数论进阶:二次剩余、椭圆曲线上的 Weil 配对 【密码学百科】密码学简史:从凯撒密码到量子时代 【密码学百科】威胁模型与安全目标:CIA 三要素之外 【密码学百科】Kerckhoffs 原则与现代密码设计哲学 【密码学百科】随机性:密码学的基石 【密码学百科】信息论入门:熵、完美保密与 Shannon 定理 【密码学百科】分组密码原理:Feistel 网络与 SPN 结构 【密码学百科】AES 逐步拆解:SubBytes 到 MixColumns 的数学 【密码学百科】分组密码工作模式全览:ECB/CBC/CTR/OFB/CFB 【密码学百科】流密码:RC4 的兴衰与 ChaCha20 的崛起 【密码学百科】密码学哈希函数:MD5→SHA-2→SHA-3 的进化之路 【密码学百科】MAC 与 HMAC:消息认证的正确姿势 【密码学百科】认证加密(AEAD):GCM、ChaCha20-Poly1305 与 OCB 【密码学百科】密钥派生函数:HKDF、PBKDF2、Argon2 与密码存储 【密码学百科】公钥密码的数论基础:模运算、群、原根 【密码学百科】RSA 从原理到攻击:教科书 RSA 为什么不安全 【密码学百科】Diffie-Hellman 密钥交换与离散对数问题 【密码学百科】椭圆曲线密码学(ECC):从几何直觉到点群运算 【密码学百科】数字签名:ECDSA、EdDSA 与 Schnorr 签名 【密码学百科】现代密钥交换:X25519、ECDHE 与前向保密 【密码学百科】混合加密与 KEM/DEM 范式:ECIES 与 HPKE 【密码学百科】填充方案:PKCS#1 v1.5、OAEP 与 PSS 【密码学百科】TLS 协议全解析:从握手到 0-RTT 【密码学百科】PKI 与数字证书:信任链的构建与崩塌 【密码学百科】密码认证协议:从 SRP 到 OPAQUE 【密码学百科】零知识证明入门:如何证明你知道而不泄露 【密码学百科】安全信道构造:Noise 协议框架与 Signal 协议 【密码学百科】密钥管理工程:HSM、KMS 与密钥生命周期 【密码学百科】侧信道攻击:从时序攻击到功耗分析 【密码学百科】密码学实现陷阱:三层漏洞分类、审计工具链与系统性预防 密码敏捷性:如何设计可升级的密码系统 【密码学百科】OpenSSL/BoringSSL 架构剖析:ENGINE、Provider 与 FIPS 模块 排序基准测试:用数据说话
【大模型基础设施工程】14:量化工程 —— INT8 / FP8 / FP4 / AWQ / GPTQ
2026-04-22 · via 土法炼钢兴趣小组的算法知识备份

系列第 14 篇。上一篇 vLLM / SGLang / TensorRT-LLM / TGI 对比了推理引擎的调度与吞吐,本篇深入推理优化的另一条主轴 —— 量化(Quantization):把模型权重、激活、KV Cache 从 FP16/BF16 压到 FP8、INT8、FP4、INT4,乃至 1.58-bit,换来显存、带宽、成本的数量级收益。

量化是 2023 年以来 LLM 推理侧最显著的工程变量之一。一块 80 GB 的 H100 放不下 Llama-3-70B BF16(140 GB),但 FP8 只要 70 GB、INT4 只要 35 GB,一张卡就能跑起来;生产环境里 decode 是 memory-bound,带宽砍一半,吞吐基本翻一倍。本篇按”为什么 → 数据类型 → 算法 → 粒度 → 硬件 → 引擎 → 实操”的顺序把量化这门”黑艺术”拆开。

一、为什么量化:显存、带宽、成本

1.1 显存账:参数量 × 位宽

对一个参数量为 \(N\) 的模型,权重显存 \(= N \times b / 8\) 字节,其中 \(b\) 是每个参数的比特数。以 Llama-3-70B 为例:

精度 位宽 权重显存 相对 BF16
FP32 32 280 GB 200%
BF16 / FP16 16 140 GB 100%
FP8 (E4M3) 8 70 GB 50%
FP6 6 52.5 GB 37.5%
INT4 / FP4 4 35 GB 25%
BitNet b1.58 1.58 13.8 GB 9.9%

加上 KV Cache、activation buffer、CUDA graph,实际占用要再加 10%–30%。但数量级结论很清晰:BF16 → FP8 节省 50%,BF16 → INT4 节省 75%

1.2 带宽账:decode 阶段 memory-bound

在自回归 decode 阶段,每生成一个 token 要把全部权重从 HBM 读一遍(prefill 不同,是 compute-bound)。Roofline 模型下:

\[ T_{\text{decode}} \approx \frac{\text{model\_size}}{\text{HBM\_BW}} \]

H100 SXM 的 HBM3 带宽约 3.35 TB/s。Llama-3-70B: - BF16:140 GB / 3.35 TB/s ≈ 42 ms/token(单卡理论下界) - FP8:70 GB / 3.35 TB/s ≈ 21 ms/token - INT4:35 GB / 3.35 TB/s ≈ 10.5 ms/token

这解释了为什么量化 decode 能近似线性提速 —— 带宽减半,延迟减半。实际还要乘上 dequant 开销、kernel 实现效率,通常能拿到 60%–90% 的理想加速。

1.3 成本账:更大 batch、更长上下文、更便宜的卡

权重压下去后省出来的显存可以用来:

  • 扩 batch:KV Cache 预算变大,continuous batching 的 max_num_seqs 可以从 128 提到 512;
  • 加长上下文:32k → 128k,对长文档 / Agent 工作流收益大;
  • 降级硬件:70B INT4 可以塞进 A10G(24 GB × 2)或 L40S(48 GB),推理单价可能降一个数量级;
  • 节省出口管制下的算力:H20、910B、4090D 环境里,量化是唯一可行的大模型方案。

二、浮点与整数数据类型

2.1 传统浮点:FP32 / FP16 / BF16

IEEE 754 浮点结构:符号位 S | 指数 E | 尾数 M,数值为 \((-1)^S \times 2^{E - \text{bias}} \times 1.M\)

类型 总位 符号 指数 尾数 动态范围 精度
FP32 32 1 8 23 ±3.4e38 ~7 位十进制
FP16 16 1 5 10 ±65504 ~3–4 位
BF16 16 1 8 7 ±3.4e38 ~2–3 位
TF32 19 1 8 10 ±3.4e38 ~3–4 位

BF16 保留 FP32 的指数范围,牺牲尾数,解决 FP16 训练中常见的溢出问题,是当前训练的主流;FP16 精度略高但动态范围窄,训练需要 loss scaling。TF32 是 Ampere 起 Tensor Core 内部的 19-bit 格式,用户侧仍写 FP32。

2.2 FP8:Hopper/Ada 引入,两种变体

Hopper(H100 / H200 / H20)和 Ada(L40S)原生支持 FP8 Tensor Core,吞吐是 BF16 的 2 倍。两种变体:

类型 符号 指数 尾数 动态范围 用途
E4M3 1 4 3 ±448 权重 / 激活(训练前向、推理)
E5M2 1 5 2 ±57344 梯度(训练反向、动态范围要求高)

E4M3 精度高但范围窄,E5M2 相反。NVIDIA Transformer Engine(TE) 会在训练中自动做 per-tensor scaling:统计 amax,乘 scale 后转 FP8,反向用 E5M2。

2.3 FP6:Blackwell 新增

Blackwell(B100 / B200 / GB200)新增 FP6 Tensor Core,位宽在 FP8 和 FP4 之间,精度优于 FP4、吞吐高于 FP8。社区常用的 FP6 布局是 E3M2(NVIDIA FP6-LLM 论文中使用 E2M3 和 E3M2 两种)。FP6 适合”INT4 精度不够、FP8 显存太大”的中间地带。

2.4 FP4:Blackwell Tensor Core 原生

Blackwell 支持 FP4(E2M1):1 符号 + 2 指数 + 1 尾数,可表示 \(\{\pm0, \pm0.5, \pm1, \pm1.5, \pm2, \pm3, \pm4, \pm6\}\) 共 16 个值。B200 的 FP4 Tensor Core 吞吐达到 FP8 的 2 倍、BF16 的 4 倍,官方宣称 GPT-MoE 1.8T 推理吞吐是 H100 的 30 倍主要来自 FP4 + NVLink72。

2.5 微缩放(MX)格式:OCP 标准

2023 年 Open Compute Project(AMD、ARM、Intel、Meta、Microsoft、NVIDIA、Qualcomm)联合发布 Microscaling (MX) Formats v1.0

  • 共享 scale:每 32 个元素共享一个 E8M0(8-bit 指数)的 scale,再加上元素自身的低精度浮点;
  • MXFP8 / MXFP6 / MXFP4 / MXINT8:元素分别是 FP8 / FP6 / FP4 / INT8;
  • 每 32-元素块的总位宽 = \(32 \times b + 8\),等价有效位宽 \(b + 0.25\)

MX 格式把 per-block scaling 硬件化,Blackwell Tensor Core 直接消费 MXFP8/FP6/FP4,省去 CUDA kernel 手动做 dequant,大幅简化软件栈。2026 年起会逐步成为训练和推理的默认量化格式。

2.6 INT8 / INT4

纯整数量化,最简单的线性映射:

\[ q = \text{round}\left(\frac{x}{s}\right) + z, \quad x \approx s \cdot (q - z) \]

其中 \(s\) 是 scale、\(z\) 是 zero-point。对称量化 \(z=0\)非对称量化 \(z \neq 0\)。INT8 范围 \([-128, 127]\),INT4 范围 \([-8, 7]\)。INT 量化在消费卡(4090、3090)、昇腾、AMD MI250 等没有 FP8 的硬件上仍是首选。

2.7 各数据类型位布局 SVG

![各数据类型位布局 SVG](images/14-quantization-fig1.svg)

三、PTQ:训练后量化

PTQ(Post-Training Quantization) 不更新权重梯度,只用少量校准数据(通常 128–512 条)统计分布、求 scale / 修正权重,几分钟到几小时完成,是生产部署的主流路径。

3.1 朴素 RTN(Round-To-Nearest)

最简单:对每层权重独立求 \(s = \max(|W|) / q_{\max}\),round 到最近的量化格点。INT8 下精度通常可接受,INT4 下 LLM 质量显著下降,需要更聪明的算法。

3.2 GPTQ:基于 Hessian 的逐列最小二乘

GPTQ(Frantar et al., ICLR 2023) 把权重量化建模为带约束最小二乘:

\[ \min_{\hat W} \| W X - \hat W X \|_F^2, \quad \hat W \in \text{QuantGrid} \]

其中 \(X\) 是校准激活。GPTQ 按列(或分组)贪心量化,每量化一列用剩余列补偿误差,依赖 Hessian \(H = 2 X X^\top\) 的 Cholesky 分解:

  1. 计算 \(H^{-1}\)
  2. 按列遍历 \(W\):当前列 \(w_j\) 量化为 \(\hat w_j\),误差 \(\epsilon = (w_j - \hat w_j) / [H^{-1}]_{jj}\)
  3. \(\epsilon\) 均摊到剩余未量化列:\(w_k \leftarrow w_k - \epsilon \cdot [H^{-1}]_{jk}\)\(k > j\))。

对 175B 模型 4-bit 量化约需 4 小时单卡 A100。GPTQ 是 INT4 权重量化的事实标准之一,AutoGPTQ / GPTQModel 库覆盖 Llama / Qwen / Mixtral 等主流结构。

3.3 AWQ:Activation-aware Weight Quantization

AWQ(Lin et al., MLSys 2024) 观察:权重并非同等重要,被大激活通道乘的权重列更敏感。做法:

  • 对每个 in-channel \(c\) 乘缩放 \(s_c\),对应激活除以 \(s_c\)\[ Y = (W \cdot \text{diag}(s)) \cdot (\text{diag}(s)^{-1} X) = W' X' \]
  • 只量化 \(W'\),激活不量化;
  • \(s_c\) 通过网格搜索最小化 \(\|W'_q X' - W X\|\)

AWQ 不依赖反向传播,只需一次前向校准,比 GPTQ 快约 10 倍,在 Llama-7B INT4 上 wikitext PPL 比 GPTQ 低 0.2–0.5。AutoAWQ 库是 vLLM / TensorRT-LLM 的首选 INT4 量化器。

3.4 SmoothQuant:权重 / 激活联合平滑

SmoothQuant(Xiao et al., ICML 2023) 针对 W8A8(权重激活都 INT8)量化:激活 outlier 集中在少数通道,直接量化会严重掉点。SmoothQuant 引入逐通道缩放 \(s_c\)

\[ Y = (X / \text{diag}(s)) \cdot (\text{diag}(s) W) = \tilde X \tilde W, \quad s_c = \max(|X_c|)^\alpha / \max(|W_c|)^{1-\alpha} \]

参数 \(\alpha\)(常取 0.5)把量化难度从激活转移一部分到权重,两者都能较平滑地 INT8,无 outlier。SmoothQuant 是 NVIDIA TensorRT-LLM INT8 的默认路径之一。

3.5 SpinQuant / QuaRot:旋转矩阵消除 outlier

2024 年涌现的一类方法,观察:outlier 来源于 Transformer residual stream 的 few-channel 集中,用正交旋转矩阵 \(R\)(Hadamard 或学习得到)做变换:

\[ \hat W = R_1^\top W R_2, \quad \hat X = R_1 X \]

在数学上等价(\(R^\top R = I\)),但旋转后的激活近似高斯,outlier 被打散,可以干净地量化到 INT4 / FP4。

  • QuaRot(Ashkboos et al., 2024):用 Hadamard 旋转,计算量 \(O(n \log n)\),支持 W4A4 KV4 端到端 INT4;
  • SpinQuant(Meta, 2024):旋转矩阵作为可学习参数,一次小规模 SFT 优化,W4A4 下 Llama-2-7B 相对 FP16 掉点 < 2.9 PPL。

旋转法目前是把 FP4 / INT4 激活量化做到实用的关键技术,Meta Llama 3 的 W4A4 部署方案就是基于 SpinQuant。

四、QAT:量化感知训练

PTQ 在 INT4 以下、或权重激活都量化(W4A4、W4A8)时经常掉点。QAT(Quantization-Aware Training) 在训练过程中插入 fake-quant 算子,梯度穿透(STE,Straight-Through Estimator)保持可微,让模型”学会”适应量化误差。

4.1 LLM-QAT(Meta, 2023)

在 Llama 基座上做 W4A8KV4 的 QAT:用原模型自己生成 100k 条蒸馏数据(避免依赖外部语料),KL 蒸馏 + 交叉熵,几千步训练即可收敛。

4.2 BitDistiller

在 SFT 阶段同步做 INT2/INT3 量化训练,结合 self-distillation,把 Llama-2-7B 压到 2-bit 仍保持可用质量。

4.3 BitNet 与 BitNet b1.58

BitNet(Microsoft, 2023):1-bit 权重(\(\{-1, +1\}\))从零训练 Transformer,证明在 3B 以下和 FP16 匹敌。

BitNet b1.58(Microsoft, 2024):权重取三值 \(\{-1, 0, +1\}\),等效 \(\log_2 3 \approx 1.58\) bit。核心变化: - 权重 absmean 量化(每矩阵一个 scale); - 激活 absmax 量化到 INT8; - LayerNorm 前加入额外的 scale; - 从头 QAT 训练(PTQ 无法得到三值)。

论文声称 3B 参数下匹敌 FP16 Llama,7B 时速度快 4 倍、显存省 7 倍。社区有 bitnet.cpp(Microsoft 官方 CPU 推理)、HuggingFace BitNet-b1.58-3B 等复现;主要限制是必须从头训练,不能量化现有模型,落地多见于边缘设备和研究项目。

五、KV Cache 量化

对长上下文、大 batch 的推理场景,KV Cache 显存占比可能超过权重。以 Llama-3-70B(Grouped-Query-Attention、head_dim=128、kv_heads=8、80 层)为例,单 token KV = \(2 \times 80 \times 8 \times 128 \times 2\text{B} = 327.68 \text{ KB}\);128k 上下文、batch=16 时 KV 总量 = \(128000 \times 16 \times 327.68 \text{KB} \approx 640 \text{ GB}\),远超权重。量化 KV Cache 收益非常可观。

5.1 FP8 KV

NVIDIA H100 上 FP8 KV Cache 几乎无损,直接用 E4M3 per-tensor 或 per-token scaling,vLLM、TensorRT-LLM、SGLang 都有原生支持:

# vLLM
llm = LLM(model="Qwen/Qwen2.5-72B-Instruct",
          kv_cache_dtype="fp8_e4m3",
          calculate_kv_scales=True)

5.2 INT8 KV:KVQuant / KIVI

  • KVQuant:per-channel 量化 Key(K 的通道分布偏态大)、per-token 量化 Value;
  • KIVI:类似但无需校准,per-channel K + per-token V,对 Llama-2-7B 在 LongBench 上相对 FP16 掉点 < 1%。

5.3 INT4 KV

KIVI-2、Atom 等方法可做 INT4 KV,显存省 75%。但 INT4 KV 对长上下文(> 32k)会明显掉质量,工程上常与 FP8 混合(近期 token FP8、历史 token INT4)。

5.4 实操:vLLM FP8 KV

from vllm import LLM, SamplingParams

llm = LLM(
    model="meta-llama/Meta-Llama-3.1-70B-Instruct",
    quantization="fp8",          # 权重 FP8
    kv_cache_dtype="fp8_e4m3",   # KV FP8
    max_model_len=128000,
    tensor_parallel_size=2,
)
out = llm.generate(["解释 KV Cache 量化的带宽收益"],
                   SamplingParams(max_tokens=256))
print(out[0].outputs[0].text)

单机 2×H100 80GB,原本 BF16 70B 需 4 卡,FP8 权重 + FP8 KV 后 2 卡即可,吞吐反而更高。

六、激活量化与 outlier 通道

6.1 LLM.int8() 的观察(Dettmers, 2022)

Dettmers 在 6.7B 规模首次观察到:极少数(≈0.1%)激活通道的幅值是其他通道的 100×–1000×,这些”outlier 通道”直接量化会毁掉数值精度。LLM.int8() 的解法简单粗暴:

  • 按通道拆两路:outlier 通道走 FP16,其余走 INT8;
  • 最后把两路结果相加。

这给 6.7B 以上模型带来了几乎无损的 INT8,代价是 15%–30% 速度损失(混合精度 kernel 难优化)。

6.2 outlier 从何而来

后续研究发现 outlier 与 residual stream 中几个”承载任务路由信息”的固定通道强相关,且随训练稳定。LayerNorm 的 scale 参数 \(\gamma\) 会放大这些通道,使 outlier 在更深层愈发明显。

6.3 对策谱系

方法 思路 代表
混合精度 outlier 走 FP16 LLM.int8()
激活缩放 把难度转移到权重 SmoothQuant
权重敏感加权 activation-aware AWQ
正交旋转 打散 outlier QuaRot / SpinQuant
块级 scaling 限制 outlier 影响范围 MXFP4 / MXINT8

七、量化粒度:per-tensor / per-channel / per-group / per-block

粒度 scale 数量 精度 计算开销 典型用途
per-tensor 1 FP8 激活(TE 默认)
per-token seq_len INT8 激活
per-channel out_channels INT8 权重、KVQuant K
per-group out_channels × (in/g) GPTQ/AWQ group_size=128
per-block(MX) 每 32 元素一个 很高 硬件支持好 MXFP8/FP6/FP4

per-group 是 INT4 权重的主流,group_size=64 或 128 在精度和 scale 存储间平衡。per-block(MX) 是 Blackwell 起的硬件标配,scale 随数据流动,无需软件干预。

八、硬件支持矩阵

硬件 BF16 FP8 FP6 FP4 INT8 INT4 权重
NVIDIA H100/H200/H20 ✓ E4M3/E5M2 dequant → FP16
NVIDIA B100/B200/GB200 ✓ MXFP6 ✓ MXFP4 dequant → FP8
NVIDIA L40S / Ada dequant → FP16
NVIDIA A100 dequant → FP16
AMD MI300X / MI325X ✓ E4M3/E5M2 dequant → FP16
AMD MI350X(2025)
Intel Gaudi 3
华为昇腾 910B ✗ (910C 支持) dequant
华为昇腾 910C(2025)
寒武纪思元 590 部分
海光 DCU K100 dequant

“dequant → FP16” 表示硬件不直接计算 INT4 × FP16 矩阵乘,CUDA kernel 要先把 INT4 权重解压到 FP16 再上 Tensor Core —— 这也是为什么 GPTQ / AWQ 在 Ampere / Hopper 上拿不到理论 4× 的带宽收益,但仍可拿到 1.5×–2× decode 加速。

NVIDIA Transformer Engine 是 FP8 训练的官方路径,自动管理 per-tensor amax / scale / history;推理侧 vLLM、TensorRT-LLM 都集成了 TE 的 FP8 GEMM。

九、推理引擎的量化支持矩阵

引擎 FP16/BF16 FP8 FP4 INT8 W INT4 W (AWQ) INT4 W (GPTQ) INT8 KV FP8 KV
vLLM ✓ (B200)
SGLang ✓ (B200)
TensorRT-LLM
TGI (HF) 实验 部分
llama.cpp 部分 ✓ GGUF ✓ GGUF
MLC-LLM
LMDeploy (书生)

9.1 llama.cpp 的 GGUF 量化体系

llama.cppGGUF 格式是 CPU / 小 GPU / Apple Silicon 的主流,提供一整套精细化量化级别:

名称 等效位宽 说明
Q8_0 8.5 FP16 → INT8 block 32,几乎无损
Q6_K 6.6 k-quant,6-bit 主 + 8-bit scale/min
Q5_K_M 5.7 混合:重要层 Q6_K、其他 Q5_K
Q4_K_M 4.8 社区默认:质量 / 大小平衡最好
Q4_K_S 4.6 更小
Q3_K_M 3.9 明显掉点,极端受限场景
IQ2_XS 2.3 基于 importance matrix 的 2-bit
Q2_K 2.6 仅 70B 以上可用

Q4_K_M 是桌面 / Mac 跑 70B 的黄金组合,40 GB 左右内存即可,质量接近 FP16。

十、工程实操:AutoAWQ 量化 Qwen + 部署 vLLM

10.1 环境

pip install autoawq==0.2.6 vllm==0.6.3 transformers==4.45.0

10.2 AutoAWQ 量化脚本

from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer

model_path = "Qwen/Qwen2.5-7B-Instruct"
quant_path = "./qwen2.5-7b-awq-int4"
quant_config = {
    "zero_point": True,
    "q_group_size": 128,
    "w_bit": 4,
    "version": "GEMM",
}

model = AutoAWQForCausalLM.from_pretrained(
    model_path, device_map="auto", safetensors=True
)
tok = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)

# 校准数据:通用 + 领域混合 128 条足够
calib = [
    "量化是把高精度张量映射到低位宽的过程。",
    "vLLM 使用 PagedAttention 管理 KV Cache。",
    # ...
] * 16

model.quantize(tok, quant_config=quant_config, calib_data=calib)
model.save_quantized(quant_path, safetensors=True)
tok.save_pretrained(quant_path)
print("AWQ done ->", quant_path)

7B 模型单卡 A100 约 20 分钟完成。产物为 safetensors + quant_config.json,体积约 5.5 GB(原 BF16 约 14 GB)。

10.3 GPTQ 脚本(对比)

from gptqmodel import GPTQModel, QuantizeConfig

cfg = QuantizeConfig(bits=4, group_size=128, desc_act=True, sym=True)
model = GPTQModel.from_pretrained("Qwen/Qwen2.5-7B-Instruct", quantize_config=cfg)
model.quantize(calib_dataset=calib, batch_size=1)
model.save("./qwen2.5-7b-gptq-int4")

GPTQ 依赖 Hessian,显存峰值和耗时高于 AWQ,但在某些任务(数学、代码)上略稳定。

10.4 vLLM 部署

python -m vllm.entrypoints.openai.api_server \
  --model ./qwen2.5-7b-awq-int4 \
  --quantization awq_marlin \
  --kv-cache-dtype fp8_e4m3 \
  --max-model-len 32768 \
  --gpu-memory-utilization 0.92 \
  --port 8000

awq_marlin 是 vLLM 集成的高性能 AWQ kernel(基于 NVIDIA Marlin),decode 吞吐比早期 AWQ 快 2–3 倍。

10.5 TensorRT-LLM 部署(FP8)

# 权重转换 + 校准
python convert_checkpoint.py \
  --model_dir Qwen2.5-72B-Instruct \
  --output_dir ./ckpt-fp8 \
  --dtype bfloat16 --use_fp8 --fp8_kv_cache

# Engine 构建
trtllm-build --checkpoint_dir ./ckpt-fp8 \
  --output_dir ./engine-fp8 \
  --gemm_plugin fp8 --max_batch_size 64 --max_input_len 32768

# 运行
mpirun -n 2 trtllm-run --engine_dir ./engine-fp8 \
  --input_text "解释 FP8 的 E4M3 与 E5M2 区别"

10.6 精度前后对比:MMLU / GSM8K / PPL

一个经验性的参考表(Qwen2.5-7B-Instruct,单次评估,具体数值因版本和评测脚本而异):

版本 wikitext PPL MMLU (5-shot) GSM8K (strict) 显存(单卡)
BF16 6.85 74.2 80.5 14.2 GB
FP8 (E4M3, per-tensor) 6.87 74.1 80.3 7.3 GB
INT8 W + INT8 A (SmoothQuant) 6.92 73.8 79.6 7.6 GB
INT4 W AWQ g128 7.08 73.5 78.9 5.7 GB
INT4 W GPTQ g128 7.15 73.2 78.4 5.7 GB
INT4 W + INT4 KV (Atom) 7.40 72.1 76.3 4.8 GB
GGUF Q4_K_M 7.12 73.4 78.7 5.3 GB (CPU/GPU)

结论: - FP8 几乎无损,显存减半; - W8A8 SmoothQuant 几乎无损; - INT4 AWQ 掉 < 1 分 MMLU,是显存 / 质量最优解; - INT4 KV 要谨慎,长上下文任务掉点明显。

十一、精度 vs 速度权衡图

![精度 vs 速度权衡图](images/14-quantization-fig2.svg)

十二、常见坑与经验法则

12.1 “量化后模型胡说八道”排查

  • 校准集不匹配:用通用语料量化,业务是中文 / 代码,换成业务相关数据再跑一次;
  • group_size 过大:INT4 g=256 掉点明显,改 128 或 64;
  • outlier 层未跳过:embedding、lm_head、最后一层 norm 常跳过量化;
  • kv_cache_dtype INT4 太激进:先只量化权重,再逐步量化 KV。

12.2 “量化后速度没变快”排查

  • kernel fallback 到 FP16:Ampere / 非 Hopper 卡跑 FP8 会 emulate,反而变慢;
  • batch 太大,compute-bound:量化主要降 decode 延迟,prefill 阶段收益小;
  • max_model_len 过小:KV 占比低,省带宽价值不明显;
  • 未用融合 kernel:AWQ 要跑在 awq_marlin、GPTQ 要跑在 exllamav2 / marlin

12.3 经验法则

  1. 有 Hopper 以上就 FP8:训练推理同构,精度无损,工程最省心;
  2. A100 / Ampere 用 AWQ INT4 + FP16 KV:单卡跑 70B 的最佳组合;
  3. 消费卡跑 70B:llama.cpp GGUF Q4_K_M;
  4. B200 部署:MXFP4 权重 + FP8 KV,吞吐最大化;
  5. 出口管制硬件(H20、910B):FP8(H20) / INT8(910B)是主路径;
  6. KV Cache 量化在长上下文才有价值:< 8k 场景先别碰;
  7. 从 PTQ 开始,不够再 QAT:QAT 训练成本高,98% 情况 PTQ 足够。

十三、产业现状(2026 Q1 快照)

  • OpenAI:GPT-4o / o3 内部使用 FP8 训练和推理(Blackwell FP4 推理已在灰度);
  • Anthropic:Claude 系列 AWS Trainium / H100 上 FP8 + FP8 KV;
  • Meta:Llama 3 / 3.1 官方发布 BF16 + FP8 + Int4(AWQ / SpinQuant W4A4)三套权重;
  • Google:Gemini 在 TPU v5p / Trillium 上用 BF16 + INT8;
  • DeepSeek:V3 原生 FP8 训练(DeepSeek-V3 技术报告),推理默认 FP8;
  • Qwen 系列:官方发布 GPTQ-Int4 / AWQ / FP8 三种,社区 GGUF 覆盖全系;
  • Kimi / MoonShot:长上下文场景使用 INT8 KV + FP8 权重;
  • 字节豆包 / 火山引擎:自研推理引擎支持 FP8、INT8、INT4,混合量化策略;
  • llama.cpp 生态:社区 GGUF 已成为本地部署事实标准,HF Hub 上每个主流开源模型都有 10+ GGUF 变体。

十四、小结

量化已从”压缩模型的 trick”演进为推理栈的一等公民:

  • 数据类型:FP8 → FP6/FP4 → MX 格式,硬件和软件都在快速迭代;
  • 算法:AWQ / GPTQ / SmoothQuant / SpinQuant 覆盖 PTQ 主要路径,QAT / BitNet 探索极限;
  • KV Cache:和权重同等重要,FP8 KV 已是生产标配;
  • 工程:AutoAWQ → vLLM、Transformer Engine → TensorRT-LLM、GGUF → llama.cpp 三套成熟组合;
  • 决策:硬件 → 选位宽 → 选算法 → 选引擎 → 选粒度 → 选 KV 策略。

理解清楚上述每一环,结合业务 SLO(延迟、吞吐、质量、成本),才能做出正确的量化选型。下一篇 推测解码与 MTP 进入推理优化的”预测并行”维度 —— 和量化正交,叠加使用收益可再翻倍。

参考资料

  1. Dettmers et al. LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale. NeurIPS 2022.
  2. Frantar et al. GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers. ICLR 2023.
  3. Lin et al. AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration. MLSys 2024.
  4. Xiao et al. SmoothQuant: Accurate and Efficient Post-Training Quantization for LLMs. ICML 2023.
  5. Ashkboos et al. QuaRot: Outlier-Free 4-Bit Inference in Rotated LLMs. NeurIPS 2024.
  6. Liu et al. SpinQuant: LLM Quantization with Learned Rotations. Meta, 2024.
  7. Ma et al. The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bits. Microsoft, 2024.
  8. Xu et al. KIVI: A Tuning-Free Asymmetric 2-bit KV Cache Quantization. ICML 2024.
  9. Hooper et al. KVQuant: Towards 10 Million Context Length LLM Inference. NeurIPS 2024.
  10. OCP Microscaling Formats (MX) Specification v1.0, 2023.
  11. NVIDIA Transformer Engine Documentation(FP8 / MXFP8)。
  12. NVIDIA TensorRT-LLM 仓库与 Qwen / Llama 量化示例。
  13. vLLM / SGLang / llama.cpp / AutoAWQ / GPTQModel 官方仓库与 README。
  14. DeepSeek-AI DeepSeek-V3 Technical Report(FP8 训练实践)。
  15. Meta Llama 3.1 / 3.2 Quantization Recipes

上一篇vLLM / SGLang / TensorRT-LLM / TGI 对比 下一篇推测解码与 MTP

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。