量化:FP8 / AWQ / GPTQ / Marlin 在 SGLang
谁该读这一篇? 显存装不下、或者想榨 TPOT 的工程师。 前置阅读:
00-prerequisites.md§4(KV cache 计算)。 耗时: 35 分钟 学完能: 1. 区分权重量化、激活量化、KV 量化三类; 2. 列出 FP8 / FP4 / INT8 / INT4 / AWQ / GPTQ 各自的位宽、精度损失、速度收益; 3. 选对量化方案给定一个具体模型; 4. 在 SGLang 启动时配置量化; 5. 排查"量化后输出质量明显下降"的可能原因。
1. 三类量化
模型推理时三处需要数值:
权重 W (固定,加载时确定)
激活 X (动态,每次 forward 不同)
KV cache (动态,逐 token 累积)
量化:
权重量化:W 改成低位 (W_q)
激活量化:X 改成低位 (X_q)
KV 量化:KV cache 改成低位
各自的代价:
| 维度 | 权重量化 | 激活量化 | KV 量化 |
|---|---|---|---|
| 何时做 | 加载前(offline) | 推理时每步 | 写入 cache 时 |
| 精度影响 | 小到中 | 大 | 中 |
| 速度收益 | matmul 加速 + 显存省 | matmul 加速(需配套 kernel) | KV 容量翻倍 |
| 主流方法 | AWQ / GPTQ / FP8 weight | FP8 dynamic / FP8 static | FP8 KV / INT8 KV |
2. 具体方法
2.1 FP8(W8A8 或 W8A16)
- W8A8:权重 + 激活都 FP8。需要 Hopper / Blackwell(H100 / H200 / B100)原生支持 FP8 算子。
- W8A16:只权重 FP8,激活 BF16。Ampere(A100)也能跑(权重存 FP8,算前转 BF16)。
精度损失:极小(FP8 e4m3 范围足够 LLM weight)。 速度:H100 上 FP8 matmul 是 BF16 的 2×。
源码:fp8.py、fp8_kernel.py。
2.2 FP4
更激进的 4 位浮点。Blackwell(B100)原生支持。 精度损失中等(需要 GPTQ 或自定义校准帮忙)。
2.3 AWQ (Activation-aware Weight Quantization)
INT4 权重量化的代表,特点:
- 算法层先观察 activation 大小,对"重要 channel"保留更高精度。
- 显存:每权重 4 bit + 少量 scale(约权重的 1/4)。
- 速度:需要专门 INT4 matmul kernel(Marlin / GPTQModel)。
精度损失很小,在 GSM-8k 这类 benchmark 上和 fp16 基本看不出差距。
源码:awq/。
2.4 GPTQ
更老牌的 INT4 权重量化,迭代式校准。 特点和 AWQ 类似,但精度略低一点(实测差距小)。 SGLang 集成了 GPTQModel 的 kernel。
2.5 Marlin
不是量化算法,是 NVIDIA 针对 INT4/FP4 weight 的 kernel。
SGLang 中 AWQ / GPTQ / FP4 都可以走 Marlin kernel(marlin/ 系列)。
2.6 INT8 / Blockwise INT8
简单 W8 量化,无需校准。 精度比 FP8 差一点,但 Ampere 上有原生 INT8 算子(更便宜)。
2.7 KV Cache 量化(FP8 KV / INT8 KV)
kv = quantize_fp8(kv_compute)
write_to_cache(kv)
读时反量化为 BF16 跑 attention。 KV 容量直接翻倍(80 GB H100 装下两倍长 context)。 精度损失:FP8 KV 几乎无;INT8 KV 长文摘要会有可感知下降。
源码:fp4_kv_cache_quant_method.py。
3. 速度收益与精度损失矩阵
| 方案 | 权重位宽 | 激活位宽 | KV位宽 | TPOT 收益 | 显存收益 | 精度损失 |
|---|---|---|---|---|---|---|
| BF16 (baseline) | 16 | 16 | 16 | 1× | 1× | - |
| FP8 W8A8 | 8 | 8 | 16 | 1.5-1.8× | 50% | 极小 |
| FP8 W8A8 + FP8 KV | 8 | 8 | 8 | 1.6× | 67% | 极小 |
| AWQ (W4A16) | 4 | 16 | 16 | 1.2-1.5× | 75% | 小 |
| AWQ + FP8 KV | 4 | 16 | 8 | 1.3× | 80% | 小 |
| GPTQ INT4 | 4 | 16 | 16 | 1.2-1.4× | 75% | 小到中 |
| FP4 | 4 | 4 | 8 | 2-3× (B100) | 80% | 中 |
上表是粗略,实际依赖模型、batch、硬件。FP4 仅 Blackwell 上有意义。
4. 在 SGLang 使用
4.1 FP8(最常用)
python -m sglang.launch_server \
--model-path neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 \
--quantization fp8 \
--tp 2
模型需要是预量化版本(HuggingFace 上有 neuralmagic、TheBloke 等仓库)。
或者用 --quantization fp8 + 让 SGLang 在线量化(慢,不推荐生产)。
4.2 KV 量化
--quantization fp8 \
--kv-cache-dtype fp8_e5m2 # 或 fp8_e4m3, int8, fp4
4.3 AWQ
python -m sglang.launch_server \
--model-path TheBloke/Llama-3-70B-Instruct-AWQ \
--quantization awq
4.4 GPTQ
--quantization gptq
5. 选型指南
| 你的目标 | 推荐 |
|---|---|
| H100 + 70B 模型、最大吞吐 | FP8 W8A8 |
| A100 + 70B、装得下、保精度 | AWQ W4A16 |
| 单卡 24G、跑 70B(必须 INT4) | AWQ + KV INT8 |
| B100、新模型、追求极致 | FP4 |
| RTX 4090 跑 8B | FP8 或 AWQ |
| 长文场景(context 32k+) | 加 KV FP8 |
| DeepSeek-V3 (MoE) | FP8(官方提供量化版) |
6. 校准与精度回归测试
量化前需要的"校准集":
- 几百条业务真实 prompt(不是 random)。
- 覆盖各种长度 / 主题。
- 通过工具(llmcompressor、AutoAWQ、GPTQModel)跑一次校准。
校准后必跑的精度回归测试:
- GSM-8K / MMLU:通用能力。
- HumanEval / MBPP:代码能力。
- 业务私有 eval:最重要!
精度下降标准:
- 学术 benchmark < 1 个百分点 → 安全。
- < 3 个百分点 → 需业务确认。
-
3 个百分点 → 量化方案不行。
7. 常见 bug
| 现象 | 排查 |
|---|---|
| 启动报 "no quantization config" | 模型不是预量化版本 |
| 输出突然变蠢 | KV 量化过度(试 fp8_e4m3 而非 e5m2) |
| 启动报 kernel 不存在 | GPU 不支持(FP8 需 H100+) |
| AWQ 速度没快 | 没装 Marlin / GPTQModel kernel |
| 量化后 OOM 反而更严重 | 校准过程占用显存;用 offline 校准 |
8. 与其它优化的组合
| 配合 | 是否兼容 | 备注 |
|---|---|---|
| FP8 + Cascade Inference | ✓ | 完全兼容 |
| AWQ + CUDA Graph | ✓ | 完全兼容 |
| 量化 + 投机解码 | ✓ | 注意 draft 和 target 一致 |
| KV FP8 + RadixCache | ✓ | KV pool 类型自动选 FP8 子类 |
| MoE + 量化 | ✓ | DeepSeek-V3 FP8 路径成熟 |
9. 源码地图
srt/layers/quantization/
├── __init__.py ← 注册表
├── base_config.py
├── base_scheme.py
├── fp8.py ← W8A8
├── fp8_kernel.py
├── fp8_utils.py
├── fpgemm_fp8.py
├── fp4_utils.py
├── fp4_kv_cache_quant_method.py
├── awq/
├── compressed_tensors/
├── auto_round.py
├── bitsandbytes.py
├── blockwise_int8.py
├── configs/
10. 小结
- 三类量化:权重、激活、KV。SGLang 都支持。
- FP8 在 H100 上是默认推荐;AWQ 是 A100/RTX 上的最佳 INT4 方案。
- KV 量化能让长文场景容量翻倍。
- 必须用预量化模型或离线校准,避免在线量化的开销。
- 选完一定要跑业务私有 eval。
11. 自检
- FP8 W8A8 和 W8A16 的差别?哪种 A100 能跑?
答案
W8A8:权重 + 激活都 FP8,matmul 走 FP8 Tensor Core;要求硬件原生 FP8 算子,Hopper(H100/H200)+ Blackwell(B100/B200)才支持。 W8A16:只权重 FP8 存储省显存,激活仍是 BF16;matmul 前把权重 dequantize 成 BF16 再算,走 BF16 Tensor Core。 **A100 只能跑 W8A16**(FP8 没有原生 Tensor Core);H100 优先 W8A8(吞吐 1.5-2× BF16)。 实际 SGLang 启动时 `--quantization fp8` 在 A100 上自动退化为 W8A16;H100 用 W8A8。- AWQ vs GPTQ 在精度 / 速度上的对比?
答案
**AWQ**(Activation-aware):观察 activation magnitude 决定哪些 channel "重要",对重要 channel 保留更高位 scale 抗噪。精度损失常 < 1% GSM8K / MMLU。 **GPTQ**:迭代式 Hessian-based 校准,逐 column 量化时校正前面引入的误差。精度同样不错,但对校准集 size 敏感。 速度:两者都用 Marlin kernel,**INT4 matmul 速度基本相同**(FlashInfer/GPTQModel 集成)。差异主要在精度评估,AWQ 在中文 / 多语言上略稳;GPTQ 在英文 reasoning 任务上偶尔更好。 实战通常 AWQ 是默认选;模型卡里如果只给 GPTQ checkpoint,那就用 GPTQ。- KV FP8 e4m3 vs e5m2 的取舍?
答案
FP8 两种格式(IEEE): - **e4m3**(4 exponent / 3 mantissa):范围 ±448,**精度更高**(更多 mantissa bit),适合数值集中、动态范围窄的 KV cache 主流场景。 - **e5m2**(5 exponent / 2 mantissa):范围 ±57344,**范围更大**(更多 exponent bit),适合长上下文中部分 K/V 数值非常大的边缘场景,但精度差。 推荐:**默认 e4m3**——长上下文长文摘要 / RAG 业务实测精度损失 < 1%;只在 e4m3 出现 NaN / 数值溢出时切 e5m2(极少见)。- 量化后 OOM 加重是什么原因?
答案
反直觉但常见: (a) **校准过程占显存**:在线 AWQ / GPTQ 校准需要把 BF16 权重 + INT4 中间结果 + scale 都装显存,反而比纯 BF16 还多一份。**用预量化模型**(HF 上 neuralmagic / TheBloke 仓库)即可避免。 (b) **FlashInfer workspace 与量化路径冲突**:量化 kernel 有自己的 workspace 需求,叠加原 workspace 总量更大。 (c) **KV pool 扩大触发碎片**:量化省下的权重显存被 SGLang 直接给 KV pool(`--mem-fraction-static` 自动跟随),KV pool 更大但 alloc 难度也涨。 (d) **Marlin kernel 对 page_size 有约束**:某些量化路径要求 page_size 对齐,分配粒度变粗。 先看启动日志确认是哪种 OOM,再针对性调。- 我的业务 eval 下降 5%,怎么办?
答案
按以下顺序排查 + 缓解: (1) **确认 baseline**:BF16 + 同采样参数跑一遍,确保 5% 真是量化引入的,不是采样 noise。 (2) **看是哪个量化层**:W4A16 < FP8 W8A8 ≤ BF16 通常精度递增;如果用 KV 量化,关掉 KV 量化先看是不是这层惹的祸。 (3) **换 backend**:AWQ 换 GPTQ 试试(或反过来),有时只是 calibration set 不匹配业务。 (4) **加 calibration**:用业务 prompt 自己校准 AWQ,比 wikitext 默认校准好。 (5) **混合精度**:关键层(最后几层 / lm_head)保持 BF16,其它量化——能省 70% 显存换回 4-5% 精度。 (6) **退回 BF16 + 加副本**:如果精度不可接受,财务允许就回退。业务 eval 不到 1% 才是健康,5% 通常不可接受。12. 下一步
04-cuda-graph.md— CUDA Graph。09-advanced-features/04-lora.md— LoRA 与量化的组合。- 源码:
srt/layers/quantization/。