跳到主要内容

多模型推理的 GPU 显存计算:为什么大多数团队会过度配置 3 倍资源

· 阅读需 10 分钟
Tian Pan
Software Engineer

大多数在生产环境中部署 LLM 的团队都在为不需要的 GPU 容量浪费资金。根本原因并非粗心大意 —— 而是因为 LLM 推理的 GPU 显存大小涉及四个相互作用的变量(模型权重、KV 缓存、激活内存和框架开销),任何一个出错都意味着你会在整个堆栈上过度配置。当你跨共享基础设施的多个模型放大这种错误时,浪费会迅速累积。

计算本身并不难。但大多数团队从不计算,因为“直接给它一个 80GB 的 A100”比计算 48GB 的 L40S 是否足够要容易得多。本文将通过算术演示如何确定可以在单个 GPU 上放置多少个模型,以及使之成为可能的量化权衡。

LLM 推理中 GPU 显存的四个组成部分

你服务的每个模型都会消耗四个类别的 GPU 显存,你需要将它们全部考虑在内:

模型权重是基准。一个具有 P 个参数、每个参数 B 字节的模型消耗 P × B 字节。一个 FP16(2 字节)的 70B 参数模型需要 140 GB。在 INT4(0.5 字节)下,同样的模型仅需 35 GB。这是大多数人计算完就停止的地方,而这正是麻烦的开始。

KV 缓存是在生产规模下真正占主导地位的变量。对于序列中的每个 token,模型会在每一层存储键(key)和值(value)向量。公式如下:

每个 token 的 KV 缓存 = 2 × 层数 × kv_heads × head_dim × 每个元素的字节数

对于采用分组查询注意力(GQA)的 Llama 3.1 70B(80 层,8 个 KV 头,128 维头,BF16):每个 token 约为 0.31 MB。在 128K 上下文窗口中,仅单个请求就消耗约 40 GB 的 KV 缓存。四个全上下文的并发请求?160 GB —— 比模型权重本身还要多。

激活内存保存前向传播过程中的中间计算结果。这通常是模型权重显存的 5–15%,随 batch size 和序列长度而变化。

框架开销来自 vLLM、TGI 或你使用的任何推理引擎。内存管理器、调度缓冲区、CUDA 上下文和 Python 运行时都会占用 GPU 显存。根据框架和加载的模型数量,预留 1–3 GB。

核心见解:在短上下文(2K token 以下)时,模型权重占主导。在 long context(32K+)时,KV 缓存占主导。你的容量规划必须考虑实际的上下文长度分布,而不是模型的最大上限。

改变一切的 KV 缓存计算

这就是团队过度配置的原因:大多数推理引擎会为最坏情况预分配 KV 缓存内存。如果你的模型支持 128K 上下文并配置了 16 个并发槽位,引擎会预留 16 × 40 GB = 640 GB 的 KV 缓存空间 —— 即使你 90% 的请求都在 4K token 以下。

这是 LLM 服务中最大的显存浪费来源。解决办法是了解你实际的上下文长度分布并进行相应配置。

如果你的 P95 请求长度是 4K token,对于 70B 模型,每个槽位只需要约 1.25 GB 的 KV 缓存。16 个 4K 上下文的并发槽位:KV 缓存为 20 GB 而不是 640 GB。这就是需要八块 A100 与只需要两块之间的区别。

常用模型的实用 KV 缓存大小(每个 token,BF16):

  • Llama 3.1 8B (32 层, 8 KV 头, 128 维): ~0.03 MB/token
  • Mistral 7B (32 层, 8 KV 头, 128 维): ~0.03 MB/token
  • Llama 3.1 70B (80 层, 8 KV 头, 128 维): ~0.31 MB/token
  • Llama 3.1 405B (126 层, 8 KV 头, 128 维): ~0.49 MB/token

大多数现代模型使用的分组查询注意力(GQA)设计在这里是一个巨大的胜利。Llama 3.1 70B 仅使用 8 个 KV 头,而查询头为 64 个,与全多头注意力相比,KV 缓存减少了 8 倍。不带 GQA 的旧模型每个 token 将消耗成比例更多的缓存。

量化决策矩阵

量化是回收显存以使多模型推理可行的关键。但由于选项众多,团队要么随机选择,要么默认选择最保守的方案。以下是决策方法。

FP8 (8 位浮点数): 生产环境的安全默认选择。质量几乎无损失 —— 在大多数基准测试中,困惑度(perplexity)增幅小于 0.5%。与 FP16 相比,权重显存减半。H100/H200/B100 GPU 的原生硬件支持意味着没有吞吐量损失。如果你使用的是最新的 NVIDIA 硬件,从这里开始。

带有 AWQ 的 INT4 (激活感知权重量化): 通常有效的激进选择。与 FP16 相比,权重显存减少 4 倍。通用任务的质量保留率约为 95%,配合 Marlin 加速内核,AWQ 可达到 741 token/秒,而 FP16 基准为 461 token/秒 —— 快了 60%,而不是更慢。注意点:代码生成准确率下降约 7.7%(HumanEval 的 Pass@1 从 56.1% 降至 51.8%)。对于非代码任务,这通常是最佳平衡点。

带有 GPTQ 的 INT4: 压缩率与 AWQ 类似,但在代码任务上质量略低(Pass@1 为 46.3%,下降 17%)。配合 Marlin 内核的吞吐量相当,为 712 token/秒。当模型没有 AWQ 量化权重时,请使用 GPTQ。

GGUF: llama.cpp 和 Ollama 部署的正确选择。Q4_K_M 质量与 AWQ 相当,但 vLLM 中的吞吐量较差(93 token/秒,首字延迟 958ms)。如果你已经在使用 vLLM 生态系统,请避开 GGUF。

近期基准测试的关键发现:内核(kernels)比算法更重要。同样的 AWQ 量化权重,使用标准内核运行速度为 67 token/秒,而使用 Marlin 内核则为 741 token/秒 —— 10.9 倍的差距。务必检查你的推理框架是否支持针对你的量化格式优化过的内核。

混合精度是新兴趋势: 在注意力层(精度最重要的地方)使用 FP8,在 MLP 层(对压缩更具容忍度)使用 INT4。这种方法与纯 INT4 相比,在实现几乎相同压缩率的同时,将困惑度降低了 0.14。

装箱算法:在原本只够运行 1 个模型的预算下运行 4 个模型

掌握了显存计算方法后,多模型推理服务就变成了一个装箱问题(bin-packing problem):在给定 GPU 总显存的情况下,你能装下多少个模型(包括它们的 KV 缓存和额外开销)?

示例:单张 A100 80GB

扣除 CUDA 额外开销后的可用显存约为:~77 GB。

配置权重KV 缓存 (8 个插槽 × 2K)额外开销总计是否装得下?
1× Llama 70B FP16140 GB5 GB2 GB147 GB
1× Llama 70B INT435 GB5 GB2 GB42 GB是(剩余 35 GB)
1× Llama 70B INT4 + 1× Mistral 7B INT438.5 GB5.5 GB3 GB47 GB是(剩余 30 GB)
1× Llama 70B INT4 + 2× 7B INT442 GB6 GB4 GB52 GB是(剩余 25 GB)
4× 7B INT414 GB2 GB5 GB21 GB是(剩余 56 GB)

在 INT4 量化下,单张 A100 可以轻松地同时运行一个 70B 模型和两个 7B 模型 —— 而通常情况下,团队会为运行一个 FP16 模型分配同等规格的硬件。这就是 3 倍的资源过度配置差距。

动态显存交换(Dynamic memory swapping) 进一步提升了效率。NVIDIA 的 Run:ai GPU 显存交换技术可以将不活跃的模型卸载到 CPU 内存,并在 2–3 秒内将其在 GPU 上重新激活。测试显示,Llama 3.1 8B (32 GB) 和 Mistral 7B (27.5 GB) 可以在单张 48 GB 的 L40S GPU 上共享资源,尽管它们的权重总和超过了 GPU 容量。与从零开始冷启动(140–208 秒)相比,显存交换在首字延迟(time-to-first-token)上实现了 50–66 倍的提升。

当流量模式互补时,这种方案非常有效:如果模型 A 在工作时间内达到高峰,而模型 B 在夜间达到高峰,它们就可以有效地分时共享单张 GPU。

支撑运行的调度层

静态分配是利用率的天敌。来自 Aegaeon 系统 (SOSP '25) 等的研究表明,在共享 GPU 上跨多个模型进行 Token 级的调度可以显著提高效率。关键模式包括:

工作负载感知(Workload-aware)的 KV 缓存分配。 与其为每个插槽预分配最大上下文,不如根据实际请求长度动态分配 KV 缓存。vLLM 的 PagedAttention 在一定程度上已经实现了这一点,但大多数团队配置 max_model_len 时过于保守,这仍然会导致显存浪费。

基于优先级的抢占机制。 当显存面临压力时,驱逐低优先级请求的 KV 缓存,而不是拒绝新请求。这需要跟踪请求的优先级和重新计算的成本,但在流量激增期间能保持高利用率。

跨模型显存协调。 Aladdin 系统使用 prefill/decode 估算器对延迟进行建模,并求解装箱优化问题,以找到满足所有活跃 SLO 的最低成本 GPU 配置。据报道,该系统在保证延迟的前提下,最高可节省 71% 的成本。

规格评估清单

在你为 LLM 推理服务配置 GPU 基础设施之前,请务必确认以下事项:

  1. 计算所选精度下的模型权重显存。 以 FP16 为基准,然后根据你的质量要求评估 FP8 和 INT4。
  2. 分析你的上下文长度分布。 使用 P95 统计值,而非最大值。大多数生产环境的工作负载,其平均上下文长度都远短于模型的最大上限。
  3. 根据“实际并发量 × 实际上下文”来确定 KV 缓存大小。 而不是“最大并发量 × 最大上下文”。
  4. 加上框架额外开销。 根据你的推理栈,每个加载的模型通常需要 1–3 GB。
  5. 预留 10–15% 的余量,用于应对显存碎片和突发流量。
  6. 在推理框架中验证算子(kernel)对量化格式的支持。 错误的算子可能会导致吞吐量下降 10 倍。

做好这些计算的团队最终在每张 GPU 上服务的模型数量是其他团队的 3–4 倍。在 GPU 消耗占 AI 算力预算大头的环境下,这不再仅仅是优化 —— 而是生存的入场券。

References:Let's stay in touch and Follow me for more thoughts and updates