本地部署 70B 模型的显存账:量化、KV Cache 与并发

从实测出发,算清 70B 模型在单机或多机部署时显存到底花在哪,以及量化档位和并发数如何互相制约。

部署 70B 级别模型时,最常见的误判是“权重放得下就行”。实际上权重只占一部分,KV Cache 会随着并发和上下文长度线性膨胀,往往才是压垮显存的最后一根稻草。

权重占用

参数量乘以每参数字节数就是权重的理论下限。70B 模型在不同精度下:

精度 每参数字节 权重大小 单卡 80GB 可否
FP16 / BF16 2 ~140 GB 否
FP8 1 ~70 GB 勉强(无余量)
INT4 (GPTQ/AWQ) ~0.5 ~35 GB 可以,余量大

注意”~0.5”不是精确值:4bit 量化通常还带 per-group 的 scale 和 zero-point,实际大小比理论值高几个百分点。

KV Cache 才是变量

KV Cache 的大小可以按下面的式子估算:

bytes = 2 (K 和 V) × layers × kv_heads × head_dim × seq_len × batch × dtype_bytes

以 Llama-3 70B 为例(80 层,GQA 8 个 KV head,head_dim 128,BF16):

  • 单条 4K 上下文:约 1.25 GB
  • 单条 32K 上下文:约 10 GB
  • 8 并发 × 32K:约 80 GB

最后一行说明:权重放得下不代表能跑。这也是为什么长上下文场景通常要配合 PagedAttention 或 KV 量化。

量化档位的取舍

INT4 带来的显存节省很可观,但代价要在具体任务上量。我的经验是:

  1. 通用对话和摘要:INT4 与 FP16 的差距通常在可接受范围
  2. 代码生成、数学推理:量化损失更明显,建议至少 FP8
  3. 结构化抽取:对精度敏感,最好做一轮自己的评测集对比

不要只看 perplexity。用你自己的 50~200 条真实请求做 A/B,比任何公开榜单都可靠。

并发规划

把显存预算拆成三块来规划:

总显存 = 权重 + KV Cache(并发 × 上下文) + 运行时开销

运行时开销(CUDA context、激活值、框架缓冲)通常要预留 3~6 GB,别把账算满。留 10% 余量能避免 OOM 导致的请求失败。

一个实用检查顺序

上线前按这个顺序验证,能省掉大部分返工:

  1. 单请求、短上下文跑通,确认权重和运行时开销
  2. 逐步拉长上下文到目标值,观察显存曲线
  3. 逐步加并发,找到显存拐点
  4. 在拐点以下留 20% 余量作为生产配置

如果第 3 步很快就撞墙,说明瓶颈在 KV Cache,此时提高并发不如先做 KV 量化或前缀缓存。