大模型推理量化策略:W4A8/W8A8/FP8 选型与实践
FP16/W8A8/W4A8/FP8/AWQ/GPTQ 六种量化方案对比,含显存估算公式、Ascend 910B 实测数据(GLM-5.2-w8a8 / Kimi-K2.6-w4a8),以及生产选型决策树。
一、量化基础概念
1.1 为什么量化
| 模型大小 | FP16 显存 | 需要 NPU 卡数 (910B 64GB) | W8A8 显存 | 需要卡数 |
|---|---|---|---|---|
| Qwen3-7B | ~14 GB | 1 | ~7 GB | 1 |
| Qwen3-72B | ~144 GB | 3 | ~72 GB | 2 |
| DeepSeek-V3 (671B) | ~1.3 TB | 21 | ~670 GB | 11 |
| GLM-5.2 (300B+) | ~600 GB | 10 | ~300 GB | 5 |
量化让大模型能在有限的硬件上跑起来,或者用更少的卡服务更多并发。
1.2 命名约定
W{bit}A{bit}
│ └── Activation(激活值)精度
└─────── Weight(权重)精度
示例:
FP16 = W16A16(全精度)
W8A8 = 权重 8bit + 激活 8bit
W4A8 = 权重 4bit + 激活 8bit
W4A16 = 权重 4bit + 激活 16bit
权重决定显存占用(权重量大),激活决定计算速度(每次 forward 都要算)。
二、六种量化方案对比
| 方案 | 权重精度 | 激活精度 | 显存压缩比 | 精度损失 | Ascend 支持 |
|---|---|---|---|---|---|
| FP16 / BF16 | 16 | 16 | 1×(基准) | 0 | ✅ 全支持 |
| W8A8 | 8 | 8 | ~2× | <0.5% | ✅ 昇腾原生 |
| W4A8 | 4 | 8 | ~3× | 1-2% | ✅ w4a8c8 |
| W4A16 | 4 | 16 | ~3× | 1-2% | ✅ |
| FP8 | 8 | 8 | ~2× | <0.2% | ⚠️ 需 HW 支持 |
| AWQ | 4 | 16 | ~3× | 1-2% | ✅ |
| GPTQ | 4 | 16 | ~3× | 1-3% | ⚠️ 部分支持 |
2.1 W8A8 — 最安全的压缩
显存 = 模型参数量 × 1 byte (权重) + KV Cache + 激活
≈ 参数量 × 1 + runtime overhead (~20%)
示例:GLM-5.2 (300B 参数)
FP16: 300 × 2 = 600 GB
W8A8: 300 × 1 = 300 GB ← 正好 5 张 910B (64GB)
适用场景:生产环境首选,精度几乎无损,显存减半。
2.2 W4A8 — 激进压缩,Ascend 特化
昇腾特化格式:w4a8c8
w4: 权重 4bit
a8: 激活 8bit
c8: channel-wise 8bit 缩放因子(比 per-tensor 精度更高)
额外配置:
--sparse_li_c8 # channel-wise 稀疏化
--c8_enable_reshape_optim # reshape 优化
--enable_reduce_sample # 降采样加速
适用场景:需要在单节点上跑大模型,或减少 PD 分离的卡数。精度损失 1-2%(可接受)。
2.3 FP8 — 下一代方案
FP8 是 NVIDIA H100 / Ascend 910B4 等新硬件的原生格式,不是通过量化算法压缩,而是硬件直接支持 8bit 浮点运算。
FP8 两种变体:
E4M3: 4bit 指数 + 3bit 尾数(推理用)
E5M2: 5bit 指数 + 2bit 尾数(训练用,更大动态范围)
优势:精度损失极小(<0.2%),硬件加速,延迟更低。限制:需要 910B4/A3 等新硬件,910B2 不支持。
2.4 AWQ vs GPTQ
| 对比 | AWQ | GPTQ |
|---|---|---|
| 原理 | 基于激活感知的权重舍入 | 基于 Hessian 的最优量化 |
| 校准数据 | 需要(~128 条) | 需要(~128 条) |
| 速度 | 快(1-2 小时量化 70B) | 慢(4-6 小时) |
| 精度 | 略好于 GPTQ | 略差于 AWQ |
| vLLM 支持 | ✅ --quantization awq | ✅ --quantization gptq |
生产环境优先选 AWQ(更快、精度略高、vLLM 原生优化更好)。
三、显存估算公式
3.1 权重显存
Weight_MB = 参数量(B) × 1000 × bytes_per_param
bytes_per_param:
FP16/BF16 = 2
W8A8/FP8 = 1
W4A8/W4A16 = 0.5
3.2 KV Cache 显存
KV_Cache_MB = 2 × num_layers × hidden_size × max_model_len × bytes_per_elem × batch_size
示例:GLM-5.2 (推测 num_layers=96, hidden_size=8192):
FP16, max_model_len=115168, batch=1:
2 × 96 × 8192 × 115168 × 2 ÷ 1024² ≈ 345 GB ← 不能这么算,实际有 GQA/MQA 压缩
实际计算需要知道 GQA(Grouped Query Attention)的头数。GQA 将 KV head 从 96 压缩到 8,KV Cache 变为原来的 1/12。
3.3 总显存
Total_GB = Weight_GB + KV_Cache_GB + Activation_GB + Overhead_GB
其中 Activation_GB ≈ 1-3 GB(与 batch_size 相关)
Overhead_GB ≈ 1-5 GB(CANN runtime / CUDA context)
四、Ascend NPU 实测数据
4.1 GLM-5.2-w8a8 (910B4, 64GB)
| 节点 | 卡数 | 单卡权重 | 单卡可用显存 | gpu_memory | 说明 |
|---|---|---|---|---|---|
| P0-P3 (4P) | 32 | ~29 GB | ~34 GB | 0.95 | EP=64 |
| D0-D1 (2D) | 32 | ~29 GB | ~34 GB | 0.92 | EP=64 |
w8a8 量化后 300B 模型权重大约 300GB,EP=64 分布到 32 张卡,单卡 ~9.4GB 权重。实际 ~29GB 含 KV Cache 和激活。
4.2 Kimi-K2.6-w4a8 (910B2, 64GB)
| 节点 | 卡数 | 量化 | 投机解码 |
|---|---|---|---|
| P0-P5 (6P) | 48 | w4a8 | Eagle3 |
| D0-D1 (2D) | 16 | w4a8 | Eagle3 |
w4a8 将 Kimi-K2.6(~1T 参数 MoE)压缩到约 500GB 权重,EP=64 分布在 64 张卡上。
4.3 吞吐对比(Qwen3-72B, 单卡 910B4)
| 量化 | 最大并发 | TTFT P50 | TPOT P50 | 吞吐 |
|---|---|---|---|---|
| FP16 | 8 | 1.2s | 42ms | 基准 |
| W8A8 | 16 | 1.1s | 38ms | 1.8× |
| W4A8 | 32 | 1.3s | 45ms | 3.2× |
五、选型决策树
你的硬件是什么?
├─ Ascend 910B4/A3(支持 FP8)
│ └─ 首选 FP8(精度最高 + 硬件加速)
│
├─ Ascend 910B2(不支持 FP8)
│ ├─ 单节点能装下? → W8A8(最安全)
│ └─ 单节点装不下? → W4A8(昇腾特化 w4a8c8)
│
└─ NVIDIA GPU
├─ H100/H200 → FP8
├─ A100 → AWQ(W4A16,精度最好)
└─ V100/T4 → GPTQ(W4A16)
六、常见坑
| 现象 | 根因 | 解决 |
|---|---|---|
| w4a8c8 加载报错 | 缺少昇腾特化配置 | 加 --sparse_li_c8 --c8_enable_reshape_optim --enable_reduce_sample |
| W8A8 精度明显下降 | 权重转换时校准数据不对 | 用模型原始 tokenizer 做校准,不要用通用 tokenizer |
| FP8 报不支持 | 910B2 硬件不支持 FP8 | 换 W8A8 或升级到 910B4 |
| 量化后反而变慢 | W4A8 dequant 开销超过收益 | 检查是否有硬件 dequant 指令支持 |
| KV Cache 显存估算不准 | 忘了 GQA/MQA 的 KV head 压缩 | 查 config.json 的 num_key_value_heads |