显存账本与容量估算
一句话定义
显存账本把"能不能部署"拆成一个可加总公式:权重 + KV Cache 上限 + 激活与框架开销,其中每一项都能从模型参数与精度直接推出来。
为什么重要
部署事故里最常见的不是精度崩了,而是 OOM(显存溢出)。选型期一次 5 分钟的账本计算,能避免"模型装不下""并发上不去""长上下文一打就崩"三类返工;它也是量化决策(kp-009)与服务容量规划(kp-028)的输入。
前置知识
- kp-003(知道 decode 每步要读权重与 KV)。
- bit/byte 与二进制换算(1GB ≈ 2^30 字节)。
核心概念
显存四大项:权重(固定,由参数量×精度决定)、KV Cache(随并发×上下文线性增长,是最大可变项)、激活峰值(prefill 长序列时显著)、框架与运行时开销(CUDA 上下文、cuBLAS 工作区、CUDA Graph 等,按 1.1–1.3 的系数计)。账本原则:按峰值记账,且给系统预留(vLLM 默认预留 10–20% 缓冲)。
原理与机制
显存要按"峰值 × 并发"记账:权重是固定项,KV 是随上下文×并发线性增长的唯一大头,激活只在长 prefill 时形成尖峰,运行时开销按系数兜底。逐项推导的价值在于可复算——部署参数(gpu-memory-utilization、max-model-len、并发上限)都能反推回这份账本;排错时先对账、再动参数,是本领域的固定次序。
公式与模型
FP16/ BF16:B=2;INT8:B=1;INT4:B=0.5。7B 模型分别约 14GB / 7GB / 3.5GB。
2 来自 K 与 V 各一份;L 是层数,H_kv 是 KV 头数(GQA 时小于 Q 头数),d_head 是头维度,B 是每参数字节数。
可复现推导(Llama-2-7B:L=32,MHA 即 H_kv=32,d_head=128,FP16):
- 每 token KV = 2 × 32 × 32 × 128 × 2B = 524,288 B ≈ 0.5 MB/token;
- 单请求 4096 上下文 ≈ 2.1 GB——比很多人直觉的"几 MB"大 100 倍;
- 若换成 GQA 8 头(如多数 7B 新模型):0.13 MB/token,4096 上下文约 537 MB。
总账模板:
示例:7B FP16 + 20 并发 × 4k 上下文 = 14 + 20×2.1×1.2 ≈ 64.4 GB → 单张 A100-80G 可行但紧,量化到 INT4(3.5GB 权重)后绰绰有余。
图示
显存水位(80GB 卡,7B FP16,20 并发×4k ctx)
[权重 ████████ 14GB][KV ██████████████████████ 42GB][激活+开销 ████ ~8GB][预留/碎片]
^ KV 是随流量伸缩的部分
实例或案例
选型对比(4k 上下文):70B FP16 权重 140GB → 需要 2×A100-80G 起;70B INT4 权重 35GB → 单张 A100-80G 可跑出可观并发。这个对比解释了为什么生产端 70B 级模型几乎都跑 4-bit。
常见误区
- 只算权重:KV 与激活被忽略,导致"模型装得下、一上并发就 OOM"。
- 按平均值而非峰值记账:长上下文请求的激活峰值(如 32k prefill 的注意力中间量)远超平均。
- 忘记框架开销与碎片:驱动、编译器工作区、显存碎片合计常占 5–10%。
- 混淆参数量与显存:4-bit 的 7B ≈ 3.5GB 权重,但运行时远不止 3.5GB。
自测题
- 计算 Llama-2-7B(GQA,H_kv=8)FP16 下每 token KV 与 8k 上下文单请求 KV 显存。
要点:2×32×8×128×2 = 131,072 B = 0.125 MB/token;8k ≈ 1 GB。
- 13B INT8 权重多少 GB?比 FP16 省多少?
要点:13GB;省一半(26→13)。
- 一张 24GB 卡想跑 7B FP16 + 4k 上下文,账本结论是什么?
要点:权重 14GB + 单请求 KV 2.1GB + 开销已逼近 17GB+,仅能支撑 1–2 并发且极易 OOM,应量化或减小上下文。
与其他知识点的关系
kp-005 解释精度字节从哪来;kp-013 展开 KV 这一项的机制;kp-022 的 gpu-memory-utilization 参数就是给这份账本留口子;kp-027 排错清单第一步就是重算此账本。
延伸阅读
vLLM 文档中对 gpu-memory-utilization 与 KV Cache 预留的说明,与本页账本逐项对应。