多模型推理服务的 GPU 显存计算:为什么大多数团队会过度配置 3 倍资源
大多数运行 LLM 推理的团队将 GPU 配置视作一场猜谜游戏。他们看到模型在 FP16 精度下需要 “140 GB”,便感到恐慌,于是申请四张 A100-80GB 显卡,然后就觉得万事大吉了。他们没有计算的是 KV 缓存、并发和量化是如何相互作用并决定实际显存占用的——而这种误算通常意味着他们多支付了 3 倍的冤枉钱。
这套计算并不复杂。但在签署云服务合同之前,几乎没有人去计算。本文将详细介绍这些精确的公式,揭示隐藏的显存黑洞,并解释装箱(bin-packing)策略,让你能在原本只够运行一个模型的硬件预算下服务四个模型。
大多数人都会搞错的显存公式
初始公式很简单:显存 = 参数量 × 每个参数的字节数。一个拥有 70B 参数的模型在 FP16 精度下(每个参数 2 字节)仅权重就需要 140 GB。在 INT8 精度下,这一数字降至 70 GB。在 INT4 精度下,则为 35 GB。
以下是流行模型的显存占用情况:
| 模型 | 参数量 | FP16 | INT8 | INT4 |
|---|---|---|---|---|
| Mistral 7B | 7B | ~14 GB | ~7 GB | ~3.5 GB |
| Llama 3.1 70B | 70B | ~140 GB | ~70 GB | ~35 GB |
| Llama 4 Scout (MoE) | 109B (17B 活跃) | ~218 GB | ~109 GB | ~55 GB |
但这仅仅是模型权重。大多数团队的计算到此为止。在生产环境中,权重往往占总显存占用的不到一半。其余部分来自三个来源,它们随你的流量而非模型规模而变化。
在推理过程中,激活显存消耗模型权重大小的 5–10%。来自 vLLM、TGI 或你的服务栈的框架开销会再增加 10–15%。接着就是 KV 缓存——这是在并发负载下主导一切的显存组件。
KV 缓存:吞噬 GPU 的显存组件
模型处理的每个 token 都会生成键(key)和值(value)张量,这些张量必须存储起来用于注意力计算。公式如下:
每个 token 的 KV 缓存 = 2 × 层数 × KV 头数 × 头维度 × 每个元素的字节数
以 Llama 3.1 70B 为例,它有 80 层、8 个 KV 头(分组查询注意力)以及 128 维度的头,在 BF16 精度下,每个 token 大约占用 0.31 MB。
听起来微不足道。但它累积得很快:
| 上下文长度 | KV 缓存 (1 个请求) | KV 缓存 (16 个并发) |
|---|---|---|
| 2K tokens | ~0.6 GB | ~10 GB |
| 8K tokens | ~2.5 GB | ~40 GB |
| 32K tokens | ~10 GB | ~160 GB |
| 128K tokens | ~40 GB | ~640 GB |
在 128K 上下文和 16 个并发请求下,仅 KV 缓存(640 GB)就是模型权重(140 GB)的 4 倍以上。这就是过度配置陷阱所在。团队根据模型权重加上一个模糊的缓冲来确定 GPU 规模,结果发现他们要么只能服务长上下文,要么只能服务高并发——但无法两者兼顾。
核心洞察:**KV 缓存随上下文长度和批次大小线性增长。**如果你将其中任何一个翻倍,缓存就会翻倍。如果两个都翻倍,缓存就会变成原来的四倍。你的容量规划必须基于实际的流量分布——即 P95 上下文长度乘以你的目标并发量——而不是模型理论上支持的最大上下文长度。
静态分配:无声的浪费
大多数服务框架会根据支持的最大序列长度静态预分配 KV 缓存。如果你的模型支持 128K token,但你的中位数请求仅使用 2K,那么你为每个请求槽预留的显存是典型流量实际需求的 64 倍。
vLLM 的 PagedAttention 通过按需分配固定大小块的 KV 缓存来解决这个问题,类似于虚拟内存分页。它不再为每个请求预留 128K token 的缓存,而是随着序列的增长分配页面。仅此一项就能在相同硬件上实现 2–4 倍的并发请求。
实际影响:一个在 4×A100-80GB 上运行 Llama 3.1 70B 并使用简单静态分配的团队,在 8K 上下文下可能只能支持 8 个并发请求。而使用 PagedAttention,同样的硬件在相同的上下文长度下可以服务 20–30 个并发请求,因为从过度分配的槽位中释放出来的显存可以用于额外的序列。
如果你的服务栈不支持分页分配,你几乎肯定处于过度配置状态。对于大多数推理部署来说,这是投资回报率最高的一项优化。
真正重要的量化-质量权衡曲线
量化是降低显存需求最有效的手段。但团队通常引用的基准测试——Wikitext-2 上的困惑度(perplexity)——并不能说明全部问题。以下是与生产相关的评估情况:
各方法的质量保持情况(基于 Llama 的模型):
| 方法 | 困惑度 (Wikitext-2) | HumanEval Pass@1 | 显存节省 |
|---|---|---|---|
| FP16 (基准) | 6.56 | 56.1% | — |
| BitsandBytes INT8 | 6.67 | 51.8% | ~50% |
| AWQ INT4 | 6.84 | 51.8% | ~75% |
| GGUF Q4_K_M | 6.74 | 51.8% | ~75% |
| GPTQ INT4 | 6.90 | 46.3% | ~75% |
各种量化方法之间的困惑度差异很小——都在基准值的 6% 以内。但 HumanEval 反映了不同的情况:GPTQ 使代码生成准确率下降了近 10 个百分点,而 AWQ 和 GGUF 在相同的 4-bit 压缩下保持了与 BitsandBytes 相当的水平。
**吞吐量的情况甚至更令人惊讶。**量化模型不仅体积更小——如果有合适的内核(kernel),它们还会更快:
| 方法 | 输出吞吐量 | 对比 FP16 基准 |
|---|---|---|
| Marlin-AWQ | 741 tok/s | +61% |
| Marlin-GPTQ | 712 tok/s | +54% |
| FP16 基准 | 461 tok/s | — |
| 标准 GPTQ | 277 tok/s | -40% |
| 标准 AWQ | 68 tok/s | -85% |
Marlin 内核为 AWQ 推理带来的速度提升是标准实现的 10.9 倍。量化算法只是方程的一半——计算内核决定了你是获得速度提升还是速度惩罚。
生产建议: 在 vLLM 中配合 Marlin 内核使用 AWQ 是显存节省、质量保持和吞吐量的最佳组合。对于 CPU 或边缘端部署,GGUF Q4_K_M 是 llama.cpp 和 Ollama 的原生格式。在生产中应避免使用标准(非 Marlin)GPTQ 和 AWQ 内核——尽管它们占用的显存更少,但速度比 FP16 还要慢。
装箱(Bin-Packing):用 1 台设备的硬件预算运行 4 个模型
一旦你通过量化(Quantization)和高效的 KV 缓存管理优化了单个模型的大小,下一个机会就是将多个模型打包到同一个 GPU 池中。实践中有三种有效的模式:
模式 1:按规模分类路由 (Size-Class Routing)
根据查询的复杂度将传入的请求路由到不同层级的模型。一个轻量级分类器(其自身仅占用极小部分 GPU 资源)会检查每个请求并将其路由到合适的模型:
- 简单查询(常见问题、分类、提取):7B 模型,INT4 量化 —— 约 4 GB
- 标准查询(摘要、分析):70B 模型,INT4 量化 —— 约 35 GB
- 复杂查询(多步推理、代码生成):70B 模型,FP16 精度或推理模型
在单台 A100-80GB 上,你可以同时运行一个 7B INT4 模型(约 4 GB)和一个 70B INT4 模型(约 35 GB),并且仍有约 30 GB 空间用于 KV 缓存和开销。大多数生产环境的流量分布都严重向简单查询倾斜,因此小模型可以处理 60–70% 的流量,而大模型处理剩余部分。
模式 2:LoRA 适配器复用 (LoRA Adapter Multiplexing)
与其运行 N 个独立的微调模型,不如运行一个基础模型并根据请求即时切换 N 个 LoRA 适配器。LoRA 适配器通常不到基础模型大小的 1% —— 一组用于 Llama 70B 的 rank-16 适配器每个仅增加约 100–300 MB。
S-LoRA 证明了通过在 CPU 和 GPU 内存之间动态交换适配器权重,可以在单块 GPU 上同时提供数千个并发 LoRA 适配器的服务。基础模型常驻在 GPU 内存中,而适配器按需加载,通过一个统一的分页系统处理 KV 缓存和适配器权重,避免碎片化。
对于为每个客户、每个领域或每个任务进行微调的团队来说,这是颠覆性的:你不再需要 N × (模型大小) 的内存,而只需要 1 × (模型大小) + N × (适配器大小)。一百个针对特定客户的模型原本需要 100 个 GPU 实例,现在只需要一个实例外加 30 GB 的适配器存储空间。
模式 3:预填充-解码解耦 (Prefill-Decode Disaggregation)
预填充阶段(处理输入上下文)是计算密集型(Compute-bound)的。解码阶段(生成 Token)是内存密集型(Memory-bound)的。在同一个 GPU 上运行这两者会浪费当前阶段未使用的资源。
NVIDIA 的 Dynamo 框架和类似系统将这些阶段解耦到独立的 GPU 池中。预填充 GPU 可以承载高计算负载,而解码 GPU 则针对内存带宽和 KV 缓存容量进行优化。这种架构拆分通常比统一推理服务提高 40–60% 的整体 GPU 利用率。
容量规划工作表
在配置 GPU 之前,请计算这四个数字:
1. 权重内存。 参数量 × 所选精度的每个参数字节数。应用量化节省的空间。
2. KV 缓存预算。 使用公式 (2 × 层数 × KV 头数 × 头维度 × 字节数) × (P95 上下文长度) × (目标并发请求数)。这是大规模运行时的主要成本。
3. 开销(Overhead)。 为激活内存、框架缓冲区和 CUDA 上下文预留 20%。特别是对于 vLLM,gpu-memory-utilization 参数(默认 0.9)控制引擎将使用多少可用显存 —— 剩余的 10% 即预留给这些开销。
4. 余量(Headroom)。 为流量峰值预留 10–15%。如果你的 P99 并发量是中位数的 2 倍,你需要缓冲区来吸收突发流量,防止 OOM(显存溢出)崩溃。
示例:使用 INT4 量化的 Llama 3.1 70B 为聊天机器人提供服务,平均上下文为 8K,并发用户数为 32。
- 权重:70B × 0.5 字节 = 35 GB
- KV 缓存:0.16 MB/Token × 8K Token × 32 用户 = 约 41 GB
- 开销:(35 + 41) × 0.2 = 约 15 GB
- 余量:(35 + 41 + 15) × 0.15 = 约 14 GB
- 总计:约 105 GB → 2× A100-80GB(使用张量并行)
如果不使用量化(采用 FP16):仅权重就需要 140 GB,BF16 精度下的 KV 缓存约为 80 GB,总计超过 260 GB —— 需要 4× A100-80GB。量化将 GPU 数量减少了一半。
如果不进行计算:大多数团队为了“保险”会为 70B 模型配置 4× A100-80GB,然后发现在正常负载下只使用了不到 60% 的可用显存。
导致成本激增 3 倍的常见错误
三种最常见的过度配置模式:
按最大上下文长度而非实际分布进行扩缩容。 如果你的模型支持 128K,但 95% 的请求使用的 Token 少于 4K,那么按 128K 规划 KV 缓存会使每个请求槽位浪费 32 倍的内存。在配置之前分析你的流量特征。
因为“质量可能会下降”而忽略量化。 使用 AWQ 的 INT4 量化在基准测试中可以保留 92–95% 的模型质量,同时减少 75% 的内存占用。质量差异通常比同一个问题的不同提示词(Prompt)写法带来的差异还要小。在你的特定任务上运行自己的评估 —— 数据几乎总是支持量化的。
在流量不足的情况下为每个 GPU 只运行一个模型。 一个 INT4 量化的 7B 模型在 80 GB 的显卡上仅占用 4 GB。这就是 95% 的浪费。你应该共同部署较小的模型,对微调变体使用 LoRA 复用,或者通过基于流量的路由在不同模型规模间共享 GPU。
GPU 显存是 AI 基础设施中最昂贵的资源。 “配置后祈祷”与“计算后装箱”之间的区别通常是 2–3 倍的硬件成本。计算只需要一个下午,而节省的成本每个月都在累积。
- https://www.spheron.network/blog/gpu-memory-requirements-llm/
- https://docs.jarvislabs.ai/blog/vllm-quantization-complete-guide-benchmarks
- https://developer.nvidia.com/blog/mastering-llm-techniques-inference-optimization/
- https://www.digitalocean.com/community/conceptual-articles/vllm-gpu-sizing-configuration-guide
- https://arxiv.org/html/2503.08311v2
- https://lmsys.org/blog/2023-11-15-slora/
- https://www.infoq.com/news/2025/12/nvidia-dynamo-kubernetes/
- https://www.runpod.io/articles/guides/gpu-memory-management-for-large-language-models-optimization-strategies-for-production-deployment
- https://cast.ai/blog/demystifying-quantizations-llms/
- https://arxiv.org/html/2511.22880v1
