vLLM KV cache 与并发计算器
vLLM 把 --gpu-memory-utilization 允许的显存扣掉权重和预热试运行后剩下的部分全部给 KV cache,再按 16 个 token 一块切分。选择模型、GPU 和参数,就能看到它启动时会打印的缓存池大小、你的上下文长度下能同时处理多少请求,以及 vllm serve 命令。
– 个 token 的 KV cache(GPU KV cache size)
- 每张 GPU 的权重
- –
- 预留:激活值、CUDA graph、非 torch 内存
- –
- 每张 GPU 的 KV cache 显存
- –
- 每个 token 的 KV cache(每张 GPU)
- –
- 最大上下文下的最大并发
- –
- 平均长度下能同时处理的请求
- –
启动命令
vLLM 启动时应该打印的日志
与 vLLM 日志对照
每一行都是 GitHub issue 里公开的 vLLM 启动日志。“按日志显存计算”用日志打印的 Available KV cache memory 和本页的公式算出缓存池,检验每个 token 的字节数、分组和按块取整;“完全由我们估算”只用 GPU、设置和本页的预留估计,不看日志里的任何数字。v0.24.0 之前,混合注意力模型的日志打印的是块数 ÷ 组数 × 16,表中这些行按当时的格式比较。
| 日志 | 模型 | GPU 与设置 | 日志中的 KV 显存 | 日志中的缓存池 | 按日志显存计算 | 完全由我们估算 |
|---|---|---|---|---|---|---|
| #42593 | Llama 3.1 8B | H100 80GB HBM3,TP 1,util 0.9,auto KV,131,072 token,vLLM 0.14.1 | 51.39 GiB | 420,944 | 420,976 +0.01% | 432,048 +2.6%,52.74 GiB |
| #27604 | Llama 3.1 8B | H100 80GB HBM3,TP 1,util 0.9,fp8 KV,131,072 token,vLLM 0.11.0 | 54.32 GiB | 890,000 | 889,968 0.00% | 864,112 −2.9%,52.74 GiB |
| #38107 | Qwen3 8B | 2 × Radeon PRO W6800 32GB(ROCm),TP 2,util 0.9,auto KV,32,768 token,vLLM 0.1.dev15181 (2026-03) | 20.23 GiB | 294,624 | 294,608 −0.01% | 280,592 −4.8%,19.27 GiB |
| #26480 | gpt-oss-120b | 2 × A100 80GB PCIe,TP 2,util 0.85,auto KV,131,072 token,vLLM 0.11.0 | 31.78 GiB | 925,696 | 925,648 −0.01% | 977,808 +5.6%,33.57 GiB |
| #36849 | gpt-oss-20b | 2 × RTX 5090,TP 2,util 0.9,fp8 KV,100,000 token,vLLM 0.17.1 | 16.62 GiB | 1,452,000 | 1,452,272 +0.02% | 1,525,536 +5.1%,17.46 GiB |
| #58580 | Gemma 4 26B-A4B | H200,TP 1,util 0.9,auto KV,131,072 token,vLLM 0.28.0 | 73.43 GiB | 1,652,749 | 1,652,749 0.00% | 1,671,267 +1.1%,74.25 GiB |
#26480:A100 没有原生 MXFP4 kernel,vLLM 会重新打包专家权重,所以权重比我们的估算多 6%。
#36849:这次运行设置了 --max-num-batched-tokens 98304,是常见值的 12 倍,所以激活值预留很大。
#58580:权重里包括这次运行加载的 MTP 草稿模型(gemma-4-26B-A4B-it-assistant),它的草稿层复用主模型的缓存。日志还列出了其余部分:非 torch 内存 1.17 GiB、峰值激活值 1.89 GiB、CUDA graph 0.16 GiB。
vLLM 如何确定 KV cache 大小
以下公式来自 vLLM main 分支(ac7f3e11,与 v0.30.0 相同),检查于 。
- 可用显存(gpu_worker.py):每张 GPU 上,总显存 × gpu_memory_utilization,减去权重、一次 max_num_batched_tokens 规模的试运行中激活值的峰值、非 torch 内存(CUDA 上下文、NCCL)以及 CUDA graph 的估算值(v0.20 起默认扣除)。剩下的就是日志里的 Available KV cache memory。默认利用率从 v0.20.0 起是 0.92,之前是 0.9。
- 页(kv_cache_interface.py):一层的一个块 = 16 个 token × 每张 GPU 的 KV 头数 × (K 维 + V 维) × 每个值的字节数。张量并行时 KV 头平分到各卡,KV 头数少于卡数时每张卡保留 1 个头(复制)。MLA 每个 token 只存一个潜向量,每张卡都存完整的一份。
- 块数:块数 = 可用显存 ÷ 每块字节数(向下取整)。只有一种注意力的模型把所有层放在一组;滑动窗口和全注意力混合的模型按相同层数分组,页大小不同时给较小的页更长的块(Gemma 4 的 512 维全局层用 32 个 token 一块)。
- 容量:每个请求需要的块数是各组之和:全注意力层按 max_model_len,滑动窗口层最多 窗口 − 1 + 2 × max_num_batched_tokens 个 token(异步调度默认同时有两个批次在途),再加 1 块。最大并发 = 块数 ÷ 每个请求的块数;日志里的 GPU KV cache size = 最大并发 × max_model_len。
第 1 步中除权重外的部分无法在浏览器里测出,所以本页按 vLLM 在该显卡上默认的 max_num_batched_tokens 取一个经验值:2,048 时约 1.5 GB(0.4–2.5),8,192 时约 3.5 GB(2–5),16,384 时约 4 GB(2.5–6),依据是上表的日志。开启前缀缓存不会改变缓存池大小,但命中的请求会共享块,所以实际并发可能更高。
使用方法
- 选择模型,或加载任意 Hugging Face 模型 id,再选择 GPU 型号和数量(张量并行)。
- 设置 --gpu-memory-utilization、权重精度和 KV cache 类型。
- 设置 --max-model-len 和每个请求的平均 token 数(提示词加输出)。
- 查看缓存池、并发数和命令。如果你已经有启动日志,可以把其中的“Available KV cache memory”和这里的估算对照。
常见问题
vLLM 如何决定 KV cache 的大小?
启动时它先加载权重,用 max_num_batched_tokens 个 token 跑一次前向传播,测出激活值的峰值,并估算 CUDA graph 占用的显存。KV cache 得到的是:GPU 总显存 × --gpu-memory-utilization,减去权重、这个峰值和 PyTorch 之外的显存(CUDA 上下文、NCCL),再按 16 个 token 一块切分。Qwen3 8B 在一张 H100 上用默认设置时约为 54.0 GB,即 393,392 个 token。
启动日志里的“GPU KV cache size”和“Maximum concurrency”是什么意思?
前者是缓存池能容纳多少个 token 的上下文;后者是长度正好为 --max-model-len 的请求能同时放下几个(Qwen3 8B 在 H100 上、32,768 时为 12.01x)。实际请求通常更短:每个 4,096 个 token 时,同一个缓存池能同时处理约 96 个。vLLM 不会拒绝多出的请求,而是让它们排队,或在块用完时抢占正在运行的请求。
加一张 GPU,KV cache 会翻倍吗?
权重较大时不止翻倍。使用 --tensor-parallel-size 2 时,每张 GPU 只保存一半权重和一半 KV 头。Llama 3.1 70B 以 FP8 在一张 H100 上只剩 3.6 GB 给缓存,即 11,696 个 token,连一个 32K 请求都放不下;在两张 H100 上每张剩 36.4 GB,缓存池可容纳 238,720 个 token(32K 时并发 7.29x)。KV 头数少于 GPU 数时,每张卡都要保留一个完整的头,每个 token 的缓存就不再减少。
要不要用 --kv-cache-dtype fp8?
它把每个 token 的字节数减半,缓存池能容纳的 token 数翻倍:Qwen3 8B 在 H100 上从 393,392 增加到 786,784。质量损失通常不大,但取决于模型和注意力后端,最好在自己的任务上验证。
为什么 vLLM 报告的 gpt-oss 和 Gemma token 数比按每 token 字节数算的少?
它们混合了滑动窗口层和全注意力层。vLLM 为滑动窗口层给每个请求预留“窗口 − 1 + 两个在途批次的 token”(开启异步调度时为 2 × max_num_batched_tokens)再加 1 块;而且从 v0.24 起,日志里的 token 数是“最大并发 × --max-model-len”,把每个层组占用的块都算进去。gpt-oss-120b 在一张 H100 上、131,072 个 token 时约有 4.9 GB 留给缓存,即 125,885 个 token,放一个满长度请求处于临界状态。
为什么我日志里的“Available KV cache memory”和这里不一样?
除权重外 vLLM 预留的部分(激活值峰值、CUDA graph、NCCL、CUDA 上下文)取决于版本、注意力后端、词表大小和 max_num_batched_tokens。本页使用 vLLM 默认批大小的 5 条公开日志中,这部分为 0.5–4.8 GB。有了自己的日志后,这一行就是准确值,缓存池可以直接由它算出:按日志中的显存计算,本页公式与每条日志的 token 数相差都在 0.02% 以内。
要不要调高 --gpu-memory-utilization?
它是这个 vLLM 实例可以使用的 GPU 总显存比例,包括权重:v0.20.0 起默认为 0.92,之前是 0.9。权重和激活值用剩的部分都会变成 KV cache,所以在 H100 上把它调到 0.95,Qwen3 8B 的缓存会多出 2.4 GB(从 393,392 增加到 410,672 个 token)。请给 GPU 上的其他程序留出余量,桌面或另一个进程都可能让 vLLM 启动失败。
我输入的内容会被上传吗?
不会。计算在你的浏览器中进行,唯一的网络请求是按 id 加载模型时访问 Hugging Face。
更多计算器
- 微调显存计算器 Transformers 或 Unsloth 中全参数微调、LoRA、QLoRA 需要的显存,并与公开实测对比。 打开 →
- 我的电脑能跑什么? 在浏览器里识别你的 GPU,列出它能跑的本地大模型,以及最佳量化和速度。 打开 →
- MiniMax H3 显存计算器
(ComfyUI) MiniMax H3 视频在 ComfyUI 中的显存与系统内存:剪枝版、INT8、NVFP4 和 GGUF 文件在 8–96 GB 显卡上的表现。 打开 → - MoE 卸载计算器
(--n-cpu-moe) 根据 GGUF 真实张量大小,找出能装进你显卡的最小 llama.cpp --n-cpu-moe。 打开 → - Qwen3.8 27B 新 GGUF 量化:Bonsai 2、GSQ-RCO 与 UD 对比 Qwen3.8 27B 的 Ternary Bonsai 2、GSQ-RCO 与 Unsloth UD 文件:显存、质量、速度,以及各自需要的推理引擎。 打开 →
- Qwen-Image-2.1 显存计算器 DiT、文本编码器和 VAE 各种组合的峰值显存,附真实显卡实测数据。 打开 →
更新于