图 1:本文封面,一次推理服务的显存总账与三把「省钱的刀」。
上一篇真题解析讲了 PagedAttention 的分页机制本身,本篇把镜头拉远:一次大模型推理服务,显存到底花在哪几本账上,每本账随什么增长、怎么估算、用什么手段省。面试里被问「7B 模型部署要多少显存」时,能当场把账算清的人,和只会说「参数乘 2 字节」的人,高下立判。先说明,本文为知识延伸文章,机制与公式以官方文档口径为准。
账一:模型参数,随参数量线性。
最直观的一本账。FP16 精度下每个参数 2 字节,N 十亿参数的模型就是约 2N GB:7B 约 13 GB,13B 约 24 GB,70B 约 130 GB。这是显存的地板,任何优化都绕不开它。对应的省法是权重量化:Hugging Face 量化文档列出的主流方案(GPTQ、AWQ、bitsandbytes 等)可以把权重压到 INT8(每参数 1 字节,减半)甚至 INT4(再减半),精度损失通常在可接受范围。注意量化只砍权重这本账,对 KV Cache 是另一套机制。
账二:KV Cache,随并发乘上下文长度增长。
这是推理服务真正的变量大头,公式要背下来:
KV Cache 字节数 = 2 × 层数 × KV 头数 × 头维 × 每元素字节 × token 总数
开头的 2 是 Key 和 Value 两路。以 7B 档典型配置(32 层、32 个 KV 头、头维 128、FP16)算,每个 token 的 KV Cache 约 512 KB——听起来不大,乘上规模就吓人:单条 2048 长度的序列约 1 GB,16 条并发就是 16 GB,64 条 4K 上下文直接破 128 GB,超过参数本身好几倍。省这本账的手段有三个层次:PagedAttention 消灭管理浪费(上一篇展开过,此处不重复);GQA/MQA 减少 KV 头数从源头缩小体积;KV Cache 量化把每元素字节再砍半或更多;最朴素的一条是控制最大上下文长度。
账三:激活与临时缓冲,随 batch 波动。
前向计算中的中间张量、算子临时缓冲。推理只有前向没有反向,激活比训练时小得多,但 batch 一大、算子没融合,峰值也不可小觑。省法是连续批处理(把更多请求摊进同一次计算,摊薄每条请求的固定开销)和算子融合(减少中间张量落盘)。
账四:框架与碎片开销,按零头预留。
运行时上下文、显存分配器的碎片,通常按总量的零头预留几 GB。PagedAttention 的固定块分配、显存池化本质上也在压这本账。
用代码把账本跑一遍。
下面这个估算器按上面两本主账的公式,对 7B 档模型算出各档数字(Node.js 22.15.0,node vram.js):
const GB = 1024 ** 3;
const params = 7e9, layers = 32, kvHeads = 32, headDim = 128;
console.log('参数显存(FP16):', (params * 2 / GB).toFixed(1), 'GB');
console.log('参数显存(INT8):', (params * 1 / GB).toFixed(1), 'GB');
console.log('参数显存(INT4):', (params * 0.5 / GB).toFixed(1), 'GB');
// KV Cache = 2(K,V) × 层数 × KV头数 × 头维 × 字节 × token数
const kvPerToken = 2 * layers * kvHeads * headDim * 2;
console.log('每 token 的 KV Cache:', (kvPerToken / 1024).toFixed(0), 'KB');
for (const [seqs, len] of [[1, 2048], [16, 2048], [64, 4096]]) {
console.log(`并发${seqs}条×长度${len}:`, (kvPerToken * seqs * len / GB).toFixed(1), 'GB');
}
const budget = 80 * GB - params * 2 - 4 * GB; // 80G 卡扣掉参数与框架零头
console.log('80GB 卡 4K 上下文可装并发:', Math.floor(budget / (kvPerToken * 4096)));
实测输出:
参数显存(FP16): 13.0 GB
参数显存(INT8): 6.5 GB
参数显存(INT4): 3.3 GB
每 token 的 KV Cache: 512 KB
并发1条×长度2048: 1.0 GB
并发16条×长度2048: 16.0 GB
并发64条×长度4096: 128.0 GB
80GB 卡 4K 上下文可装并发: 31
一张 80 GB 的卡,7B 模型 FP16 占 13 GB,剩下预算按 4K 上下文只能装约 31 条并发——KV Cache 才是吞吐的真正天花板,这就是所有推理优化都围着它转的原因。
图 2:四本账的对照矩阵与决策链。
一个容易算漏的细节:KV 头数不等于注意力头数。
用 GQA 的模型里 KV 头数远小于查询头数,套公式时若拿错数,KV Cache 能高估好几倍。估算前务必先查模型配置里的 num_key_value_heads,而不是想当然地等于注意力头数。
决策链:先定位最大头,再选刀。
显存问题从来不是「够不够」,而是「哪本账超了」。参数超了上量化;KV Cache 超了上分页管理、KV 量化、GQA 或压上下文;激活和开销超了上连续批处理与算子融合。动手之前先按公式估一遍每本账的量级,再决定砍哪里——估算能力本身就是面试考察点。你部署模型时最先撞上的是哪本账?用的什么手段压下去的?欢迎交流实战经验。