CUDA out of memory

该报错通常出现在 vLLM 把 --gpu-memory-utilization 调得很高(如 0.98)、同时启用 CUDA graph capture 的场景:启动时的显存检查通过并按估算值分配了偏大的 KV cache,随后真实的 CUDA graph capture 却因显存不足抛出 CUD

快速结论:该报错通常出现在 vLLM 把 --gpu-memory-utilization 调得很高(如 0.98)、同时启用 CUDA graph capture 的场景:启动时的显存检查通过并按估算值分配了偏大的 KV cache,随后真实的 CUDA graph capture 却因显存不足抛出 CUDA out of memory。优先排查方向是 KV pool 容量与 CUDA graph 显存估算之间的余量是否足够。

适用环境:vLLM 0.29.1rc1.dev339+gda9888462(commit da9888462);GPU 为 NVIDIA GeForce RTX 5090 Laptop GPU(24 GB,SM12x),驱动 610.57.04;torch 2.13.0+cu130,CUDA 13.0;模型 Qwen3.8-27B NVFP4(hybrid attention / linear-attention);VLLM_ATTENTION_BACKEND=FLASHINFER

最快修复方案:Issue 中确认可用的规避方式是把 --gpu-memory-utilization0.98 降到 0.97(可正常启动并服务,约 138K NVFP4 KV tokens);或者在保持 0.98 的同时加 --enforce-eager(不占用 graph 显存,约 166K KV tokens,但 decode 更慢)。Issue 提交者还测试过在估算值上加安全余量的本地修改,可让 0.98 启动(KV pool 约 143,450 tokens),但该方案属于 workaround,最终未合并。

注意事项:根因(profile_cudagraph_memory() 对 CUDA graph 显存低估算)已在 #51590 中按正规方式修复,本 Issue 已关闭并以 #51590 跟踪;上述安全余量是临时规避,并非根因修复。Issue 中的测量结论来自单张 24 GB 移动版 RTX 5090,尚未在其他显卡或显存规格上验证,跨环境迁移时需自行确认。

问题场景

用户在 vLLM 中加载 Qwen3.8-27B NVFP4 模型(hybrid attention / linear-attention 结构),使用 --kv-cache-dtype nvfp4 并把 --gpu-memory-utilization 设为 0.98,希望在 24 GB 移动版 RTX 5090 上尽量多分配 KV cache。启动时的 KV-cache 分配检查通过,vLLM 分配了 150,745 tokens(约 2.97 GiB)的 KV pool,但随后在 CUDA graph capture 阶段崩溃。将 util 降到 0.97 则能正常启动并服务。

报错原文

INFO  [gpu_worker.py:642]  Available KV cache memory: 2.97 GiB
INFO  [kv_cache_utils.py]  GPU KV cache size: 150,745 tokens, Maximum concurrency for 124,000 tokens
INFO  [model_runner.py]    Graph capturing finished in 1 secs, took 0.46 GiB   # profiling estimate
DEBUG [gpu_worker.py:641]  ... Total non KV cache memory: 19.57 GiB ...
ERROR [engine/core.py:1378] torch.OutOfMemoryError: CUDA out of memory.
      Tried to allocate 136.00 MiB. GPU 0 has a total capacity of 23.46 GiB
      of which 120.88 MiB is free ...

对照的 0.97(正常)日志:

INFO  [gpu_worker.py:642]  Available KV cache memory: 2.73 GiB
INFO  [kv_cache_utils.py]  GPU KV cache size: 138,588 tokens
INFO  [gpu_worker.py:828]  CUDA graph pool memory: 0.04 GiB (actual), 0.46 GiB (estimated)

原因分析

根据 Issue 分析与维护者最终定位,这是 CUDA graph 显存估算偏小导致的 KV cache 超分配问题:

  • determine_available_memory()vllm/v1/worker/gpu_worker.py)按 available_kv = requested_memory - non_kv_cache_memory - cudagraph_memory_estimate 计算 KV pool 大小,其中 cudagraph_memory_estimate = model_runner.profile_cudagraph_memory()
  • profile_cudagraph_memory()vllm/v1/worker/gpu_model_runner.py)只捕获每个 mode 的少量样本图(descs[:2])到临时 pool,测量差值后用 first_capture + (N-1) * per_graph 外推,本次模型报告约 0.46 GiB
  • 问题在于真实的 capture_model() 发生在完整 KV pool 分配之后,此时显存环境更紧张。util 为 0.98 时 pool 更大(150,745 tok / 2.97 GiB),真实 capture 在仅剩 120.88 MiB 空闲的情况下 OOM。
  • 日志中的 0.04 GiB (actual) 是真实 capture 的净增量,不是 graph 总占用,因为大部分 graph 显存已在 profiling 阶段常驻。

需要说明的是,维护者最终确认根因是 profile_cudagraph_memory() 对 CUDA graph 显存低估算,并在 #51590 中按“测量完整 capture footprint 用于 KV 预算”的方式修复。评论中也有用户质疑这是否算 bug,理由是 vLLM 在 0.95–0.96 以上本就长期不稳定;Issue 提交者的论证是:启动内存检查通过并据此承诺了内存布局,实际却 OOM,即检查结果与真实情况不一致,这才是 bug 所在。

环境排查

  • 确认 vLLM 版本与 commit:0.29.1rc1.dev339+gda9888462(commit da9888462)。
  • 确认 GPU 型号与显存:RTX 5090 Laptop GPU,24 GB,SM12x;驱动 610.57.04。
  • 确认 torch / CUDA:torch 2.13.0+cu130,CUDA 13.0。
  • 确认 attention backend:VLLM_ATTENTION_BACKEND=FLASHINFER
  • 确认模型与量化:Qwen3.8-27B NVFP4(hybrid attention / linear-attention),--dtype bfloat16--kv-cache-dtype nvfp4
  • 确认显存相关参数:--gpu-memory-utilization--max-model-len--max-num-seqs--max-num-batched-tokens--enable-prefix-caching 是否与复现配置一致。
  • 观察启动日志中“Available KV cache memory”“GPU KV cache size”“CUDA graph pool memory (actual/estimated)”以及“Total non KV cache memory”几项,判断 KV pool 与 graph 估算的余量关系。

解决步骤

  1. 先按 Issue 中已验证的规避方式处理:把 --gpu-memory-utilization0.98 降到 0.97,重新启动服务,确认可以正常 boot 并服务(Issue 中该配置约 138K NVFP4 KV tokens)。
  2. 如果必须保留 0.98,可改用 --enforce-eager(0.98 + eager 模式),这样不产生 graph 显存开销,Issue 中约 166K KV tokens,但 decode 速度会下降。
  3. 若希望更精确地控制余量,可参考 Issue 提交者的本地 workaround:在 CUDA graph 显存估算值之上加一个安全余量(其 draft PR #57595 提供 opt-in 环境变量 VLLM_CUDAGRAPH_MEMORY_MARGIN,默认 0)。在其 24 GB 移动 5090 环境下加 128 MiB 余量后 util 0.98 可启动,KV pool 约 143,450 tokens。注意该 PR 已被关闭,未合并,仅作参考。
  4. 关注根因修复进展:#51590 正在按“测量完整 capture footprint 用于 KV 预算”的方案修复 profile_cudagraph_memory() 的低估算问题;待其合入后升级到包含该修复的版本再复测 0.98。
  5. 不要单纯依赖调高 util 来榨取显存:在接近显存上限且启用 CUDA graph 时,约束点是 graph 显存而非 KV pool。

验证方法

使用调整后的配置重新启动 vLLM,确认服务不再出现 torch.OutOfMemoryError: CUDA out of memory,日志中 CUDA graph capture 阶段正常结束,并且模型能够正常响应推理请求。若在 0.98 下采用安全余量方案,可对比启动日志中“GPU KV cache size”与“CUDA graph pool memory (estimated)”的数值,确认 KV pool 有所收窄且 capture 不再 OOM。Issue 提交者的判定基准是:无修复时 0.98 在 capture 阶段 OOM,加 128 MiB 余量后可正常 boot。

参考来源

vllm-project/vllm #57475

相关链接:vllm-project/vllm PR #57595(opt-in 安全余量 workaround,已关闭)、vllm-project/vllm #51590(根因修复跟踪)。

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 24311

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注