# PR #49390 完整报告

- 仓库：`vllm-project/vllm`
- 标题：[Perf] Raise Blackwell CUDA graph capture default to 1024
- 合并时间：2026-08-08 03:18
- 原文链接：http://prhub.com.cn/vllm-project/vllm/pull/49390

---

# 执行摘要

- 一句话：Blackwell 默认 CUDA 图捕获上限提至 1024
- 推荐动作：该 PR 值得精读，因为它展示了如何通过调整默认 CUDA 图捕获上限来获取大幅性能提升，并体现了平台差异化默认策略的设计思路。建议重点关注 `_set_cudagraph_sizes` 中平台判断与约束的结合方式，以及测试对 `current_platform` 的 mock 技巧。后续应跟踪 B200 验证结果，并评估是否需要在其他平台（如消费级 Blackwell）做类似调整。

# 功能与动机

在 B300 上运行 DeepSeek-V4-Flash DSpark 工作负载（固定验证，7 个 draft token）时，将 CUDA 图捕获上限从 512 提至 1024 后，输出吞吐显著提升（并发 64/128/256 下分别 +571%/+464%/+393%），TPOT 大幅改善。PR 旨在为数据中心 Blackwell 提供更优的默认 CUDA 图配置，同时保留其他平台默认值，避免影响未受益的场景。

# 实现拆解

实现拆解分四步：
1. 在 `vllm/config/vllm.py` 的 `_set_cudagraph_sizes` 中，当 `max_cudagraph_capture_size` 为 `None` 时，首先导入 `current_platform`，并通过 `is_device_capability_family(100)` 判断是否为数据中心 Blackwell；若为真则默认上限设为 1024，否则仍为 512。随后仍沿用 `max_num_seqs * decode_query_len * 2` 与该默认值取最小值，再与 `max_num_batched_tokens` 取最小值。同时更新函数 docstring 中的说明文字，匹配新逻辑。
2. 在 `vllm/config/compilation.py` 中更新 `CompilationConfig.max_cudagraph_capture_size` 字段的文档注释，明确“未指定时默认上限为 512，Blackwell 上为 1024”的语义，并调整了关于启动时间和内存开销的表述。
3. 在 `tests/compile/test_config.py` 新增 `test_blackwell_cudagraph_default` 测试，通过 `patch.object` 模拟 `is_device_capability_family` 的返回值，分别验证 Blackwell 与非 Blackwell 平台上默认值为 1024 与 512。测试构造了最小 `VllmConfig`，直接调用 `_set_cudagraph_sizes`，并断言 `max_cudagraph_capture_size` 结果正确。
4. 配套验证：作者运行 `tests/compile/test_config.py` 全部通过，并完成了 256 请求的 serving benchmark，零失败。

关键文件：
- `vllm/config/vllm.py`（模块 配置核心；类别 source；类型 core-logic；符号 _set_cudagraph_sizes）: 核心逻辑变更：在 `_set_cudagraph_sizes` 中按平台决定默认 CUDA 图捕获上限，直接影响 Blackwell 用户默认行为。
- `vllm/config/compilation.py`（模块 配置；类别 source；类型 documentation）: 更新 `max_cudagraph_capture_size` 字段的文档说明，使配置语义与实现一致，属于配套文档调整。
- `tests/compile/test_config.py`（模块 测试；类别 test；类型 test-coverage；符号 test_blackwell_cudagraph_default）: 新增 `test_blackwell_cudagraph_default`，通过 mock 平台判断验证默认上限的差异化逻辑，防止回归。

关键符号：_set_cudagraph_sizes, test_blackwell_cudagraph_default

## 关键源码片段

### `vllm/config/vllm.py`

核心逻辑变更：在 `_set_cudagraph_sizes` 中按平台决定默认 CUDA 图捕获上限，直接影响 Blackwell 用户默认行为。

```python
# vllm/config/vllm.py - _set_cudagraph_sizes 中的默认上限计算（关键改动）

def _set_cudagraph_sizes(self):
    # ... 前面的逻辑省略 ...
    # 仅在用户未显式指定时，依据平台决定默认上限
    if max_cudagraph_capture_size is None:
        from vllm.platforms import current_platform

        decode_query_len = 1 + self.num_speculative_tokens
        # 数据中心 Blackwell（计算能力 10.x）使用 1024 上限，
        # 其他平台维持 512；显式配置不会被覆盖
        default_max_graph_size = (
            1024 if current_platform.is_device_capability_family(100) else 512
        )
        max_cudagraph_capture_size = min(
            self.scheduler_config.max_num_seqs * decode_query_len * 2,
            default_max_graph_size,
        )
    # 后续仍受 max_num_batched_tokens 约束
    max_num_tokens = self.scheduler_config.max_num_batched_tokens
    max_cudagraph_capture_size = min(max_num_tokens, max_cudagraph_capture_size)
    # ... 后续生成 capture sizes 列表的逻辑 ...

```

### `tests/compile/test_config.py`

新增 `test_blackwell_cudagraph_default`，通过 mock 平台判断验证默认上限的差异化逻辑，防止回归。

```python
# tests/compile/test_config.py - 验证平台相关默认上限

@pytest.mark.skipif(
    not current_platform.support_static_graph_mode(),
    reason="静态图模式不支持时跳过",
)
@pytest.mark.parametrize(("is_blackwell", "expected_max_size"), [(False, 512), (True, 1024)])
def test_blackwell_cudagraph_default(is_blackwell, expected_max_size):
    # 构造一个最小 VllmConfig，绕过引擎初始化
    vllm_config = VllmConfig()
    vllm_config.model_config = MagicMock(enforce_eager=False)
    vllm_config.scheduler_config = SchedulerConfig(
        max_num_seqs=512,
        max_num_batched_tokens=2048,
        max_model_len=2048,
        is_encoder_decoder=False,
    )
    vllm_config.compilation_config = CompilationConfig(
        cudagraph_mode=CUDAGraphMode.FULL_AND_PIECEWISE,
    )

    # mock 平台判断，分别覆盖 Blackwell 与非 Blackwell
    with patch.object(
        current_platform,
        "is_device_capability_family",
        return_value=is_blackwell,
    ):
        vllm_config._set_cudagraph_sizes()

    assert vllm_config.compilation_config.max_cudagraph_capture_size == expected_max_size

```

# 评论区精华

该 PR 的 review 讨论较少，主要来自 issue 评论：WoosukKwon 表示“I 100% support this!”，mgoin 触发 CI 并最终 APPROVED，Buildkite CI #82866 运行通过。claude[bot] 指出 PR 来自 fork，自动审查被禁用，需维护者手动触发。PR body 中作者明确说明 B200 验证尚待完成，因此以 draft 状态提交，这是当前唯一未解决的疑虑。

- B200 验证尚未完成 (question): 未解决。作者计划在后续补充 B200 实测数据，合并前应确认验证结果或明确风险。
- 维护者支持与 CI 触发 (testing): CI 已通过（Buildkite #82866），变更获得维护者认可。
- claude 自动审查禁用 (other): 已由 mgoin 人工批准，无需进一步操作。

# 风险与影响

- 风险：
 1. 启动时间与内存开销：捕获至 1024 将增加 CUDA 图数量，实测在该配置下捕获需 80 秒、每 GPU 占用 4.88 GiB，可能在内存紧张场景引发 OOM，尽管 `max_num_seqs` 约束仍会限制实际大小。
 2. 平台判断准确性：`is_device_capability_family(100)` 只匹配计算能力 10.x，若未来有其他 10.x 设备（如消费级）可能误启用，需确认语义是否限定数据中心版。
 3. B200 未验证：作者仅实测 B300，B200 的捕获行为与性能收益未知，存在回归可能。
 4. 显式配置不受影响：用户若设置 `max_cudagraph_capture_size` 或 `cudagraph_capture_sizes`，本改动不会覆盖，风险限于未显式配置的用户。
 - 影响：影响范围限定在数据中心 Blackwell GPU（计算能力 10.x）且未显式配置 CUDA 图捕获大小的用户：默认行为改变，可能显著提升高并发吞吐，但增加启动时间和显存占用。其他 NVIDIA 平台（如 Hopper、Ada）及 AMD/Intel 平台不受影响。团队需关注 B200 验证结果，并考虑是否在文档中提示该默认值的变化。测试覆盖补充了平台差异逻辑，降低了回归风险。
 - 风险标记：默认配置变更 , 启动时间增加 , 内存占用增加 , B200 未验证

# 关联脉络

- 暂无明显关联 PR