# PR #28740 完整报告

- 仓库：`sgl-project/sglang`
- 标题：refactor(runner): reuse a prepared static buffer for every dummy run
- 合并时间：2026-06-20 04:16
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/28740

---

# 执行摘要

- 一句话：复用静态缓冲区替代逐次分配，优化 dummy run 内存管理
- 推荐动作：该 PR 值得精读，尤其是 `_dummy_run` 的缓冲区接管模式和 `_autotune_buffers` 的适配器设计。review 中提出的问题值得在后续 PR 中跟进修复。建议关注其与 #28387 等 runner 重构 PR 的关联，形成对 SRT 运行器架构演进的全局理解。

# 功能与动机

原始 flashinfer-autotune dummy forward 会分配一个与 req_to_token_pool.size 等大的临时 DecodeInputBuffers 集合。该 PR 改为复用 runner 已经分配的静态缓冲区，避免不必要的分配，同时修复旧版重填充可能超出复用缓冲区边界的溢出风险。

# 实现拆解

1. **变更入口：BaseRunner.warmup 与 _flashinfer_autotune**- 修改 `warmup()`，在触发 autotune 前通过 `_autotune_buffers()` 获取缓冲区集并断言非空；修改 `_flashinfer_autotune` 接受 `buffers` 和 `batch_size` 参数，直接传递给 `_dummy_run`，不再分配缓冲区。
2. **子类适配器：_autotune_buffers 实现 **- `DecodeCudaGraphRunner` 直接返回自身 `buffers` 和 `max_bs`；`EagerRunner` 从 `_eager_registry` 构建适配器，填补遗漏字段（logits 缓冲区、PP 代理张量、custom_mask 等），并保存 `_eager_max_bs` 和 `_eager_num_tokens_per_bs` 供复用。
3. **DeepGEMM PP 并行预热优化 **- `pp_parallel_deep_gemm_warmup` 通过 `runner._alloc_dummy_decode_buffers` 预分配一个最大缓冲区集，在整个 batch size 扫描中复用；新增内联 `_align()` 函数，使用 `lcm(cp, attn_tp_size)` 对齐，避免后续 MLP sync 对齐破坏 CP 倍数。
4. **共享缓冲区分配函数 **- 新增 `BaseRunner._alloc_dummy_decode_buffers` 作为统一入口，供非 autotune 预热场景（如 DeepGEMM 预热）使用。
5. **配置与依赖调整 **- 从 `base_runner.py` 移除 `ceil_align` 和 `require_mlp_sync` 的直接导入，改为局部导入；其他文件相应调整依赖。

关键文件：
- `python/sglang/srt/model_executor/runner/base_runner.py`（模块 运行器；类别 source；类型 data-contract；符号 _flashinfer_autotune, _alloc_dummy_decode_buffers, _autotune_buffers）: 核心修改文件，重构了 _flashinfer_autotune 和 _dummy_run 的缓冲区管理，新增 _alloc_dummy_decode_buffers 方法，是本次重构的关键入口。
- `python/sglang/srt/model_executor/runner/eager_runner.py`（模块 运行器；类别 source；类型 data-contract；符号 _autotune_buffers, _slot）: 新增 _autotune_buffers 适配器，从 eager registry 构建可复用缓冲区集合，支持 autotune 复用。
- `python/sglang/srt/layers/deep_gemm_wrapper/compile_utils.py`（模块 编译工具；类别 source；类型 core-logic；符号 _align）: 修改 pp_parallel_deep_gemm_warmup 使用单个预分配缓冲区，并优化对齐逻辑（lcm(cp, attn_tp_size)），避免 MLP sync 下的对齐问题。
- `python/sglang/srt/model_executor/runner/decode_cuda_graph_runner.py`（模块 运行器；类别 source；类型 data-contract；符号 _autotune_buffers）: 新增 _autotune_buffers 方法，复用自身 buffers 作为静态缓冲区，节省分配。

关键符号：_flashinfer_autotune, _alloc_dummy_decode_buffers, _autotune_buffers, _slot, _align


# 评论区精华

review 中识别出三个关键问题：
- gemini-code-assist 指出 `buffers.mrope_positions` 在非多模态模型下可能为 None，直接切片会引发 TypeError，建议添加 None 检查。
- chatgpt-codex-connector 指出 eager registry 创建时 `seq_len_fill_value=0`，导致 autotune dummy decode 的 `seq_lens` 为零，可能影响 autotune 正确性（P1）。
- chatgpt-codex-connector 指出 eager autotune 的 batch 未经 MLP sync 对齐，可能导致集合通信异常（P2）。
以上评论均未在 PR 中收到作者回复，但 PR 已合并，可能已通过其他方式解决或确认不影响。

- mrope_positions 切片缺少 None 检查 (correctness): 未收到明确回复，但 PR 已合并，可能已修复或认为不影响。
- eager registry 使用 seq_len_fill_value=0 导致 autotune dummy decode 的 seq_lens 为零 (correctness): 未回复，待作者确认。
- eager autotune batch 未对齐 MLP sync (correctness): 未回复，待作者确认。

# 风险与影响

- 风险：
 1. **类型错误风险**：base_runner.py 中 `buffers.mrope_positions[:, :num_tokens]` 在非多模态模型下可能为 None，直接切片会引发 TypeError，需添加 None 检查。
 2. **eager autotune 正确性风险**：eager registry 的 `seq_len_fill_value=0` 导致 seq_lens 为零，与旧版行为不同，可能影响 autotune 的有效性。
 3. **MLP sync 对齐风险**：eager autotune 的 batch 未对齐 MLP sync，可能导致集合通信异常，需要对齐到 attn_tp_size。
 4. **回归风险**：改动涉及多个 runner 基类和子类，若其他未覆盖的 forward mode（如预填充）也调用 _dummy_run，可能因缓冲区不匹配而断言失败。
 - 影响：**影响范围**：中等。直接影响所有使用 flashinfer autotune 和 DeepGEMM 预热的模型启动过程，包括 eager 和 cuda graph 模式。**影响程度**：正向性能改善（减少 warmup 分配），并修复潜在溢出 bug。对于非受影响模型（如 DLLM），逻辑不变。
 - 风险标记：缓冲区对齐风险 , 类型错误风险 , eager autotune 未对齐 MLP sync, seq_lens 为零风险

# 关联脉络

- PR #28387 [runner] refactoring preparation (from PR body: Builds on #28387): 本 PR 直接构建于此 PR 之上，属于同一重构系列。
- PR #28385 refactor(runner): split BaseRunner (shared) from BaseCudaGraphRunner: 同一 runner 重构系列，拆分基类为本 PR 提供基础。
- PR #28677 fix(runner): size eager static buffers for prefill budget and MLP-sync autotune: 也是关于 eager static buffer 尺寸调整，与本 PR 缓冲区复用理念相关。