# PR #29598 完整报告

- 仓库：`sgl-project/sglang`
- 标题：[NPU][Bugfix] Accept in_capture in Ascend replay metadata
- 合并时间：2026-06-29 14:37
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/29598

---

# 执行摘要

- 一句话：修复 NPU 调度器因缺少 in_capture 参数启动失败
- 推荐动作：该 PR 是典型的最小修复（1 行），可直接合并。对于阅读者，它展示了在多后端架构中，当基类接口演化时如何快速修复子类签名不匹配。值得注意的设计点是使用可选参数 `in_capture: bool = False` 而非强制参数，以保持向后兼容。

# 功能与动机

根据 PR body 描述，在 hybrid linear attention 的 graph capture 流程中，基类 `MambaAttnBackendBase` 的 `_replay_metadata` 调用开始传递 `in_capture` 关键字参数，但 Ascend 子类 `AscendMambaAttnBackendBase._replay_metadata` 的签名未接受该参数，触发 `TypeError: AscendMambaAttnBackendBase._replay_metadata() got an unexpected keyword argument 'in_capture'`，导致 NPU 调度器无法启动。

# 实现拆解

1. **定位问题**：在 `python/sglang/srt/hardware_backend/npu/attention/ascend_hybrid_linear_attn_backend.py` 中，`AscendMambaAttnBackendBase._replay_metadata` 方法签名缺少 `in_capture` 参数。
2. **修改方法签名**：在第 134 行添加参数 `in_capture: bool = False`，使用默认值 `False` 保持向后兼容。
3. **功能验证**：除编译检查和签名一致性验证外，还提供了本地启动和 benchmark 基准测试，结果显示性能不变。无需修改方法体，因为该参数仅为签名对齐，Ascend 后端在 graph capture 阶段的行为无需额外变更。

关键文件：
- `python/sglang/srt/hardware_backend/npu/attention/ascend_hybrid_linear_attn_backend.py`（模块 后端适配；类别 source；类型 core-logic；符号 _replay_metadata）: 这是唯一变更文件，修复了 Ascend 后端中 `_replay_metadata` 方法的签名缺失问题，使 NPU 调度器在 graph capture 阶段能正常启动。

关键符号：_replay_metadata

## 关键源码片段

### `python/sglang/srt/hardware_backend/npu/attention/ascend_hybrid_linear_attn_backend.py`

这是唯一变更文件，修复了 Ascend 后端中 `_replay_metadata` 方法的签名缺失问题，使 NPU 调度器在 graph capture 阶段能正常启动。

```python
    def _replay_metadata(
        self,
        bs: int,
        req_pool_indices: torch.Tensor,
        forward_mode: ForwardMode,
        spec_info: Optional[SpecInput],
        seq_lens_cpu: Optional[torch.Tensor],
        num_padding: Optional[int] = None,
        # 新增参数 in_capture，默认 False，仅用于签名对齐，不改变行为
        in_capture: bool = False,
    ):
        # out_graph passes seq_lens_cpu=None at capture; mirror the base guard.
        if seq_lens_cpu is None:
            num_padding = 0
        else:
            num_padding = torch.count_nonzero(
                seq_lens_cpu == self.get_cuda_graph_seq_len_fill_value()
            )
        # Make sure forward metadata is correctly handled for padding reqs
        req_pool_indices[bs - num_padding :] = 0
        mamba_indices = self.req_to_token_pool.get_mamba_indices(req_pool_indices)
        mamba_indices[bs - num_padding :] = 0
        self.state_indices_list[bs - 1][: len(mamba_indices)].copy_(mamba_indices)
        if forward_mode.is_decode_or_idle():
            if num_padding == 0:
                self.query_start_loc_list[bs - 1].copy_(
                    self.cached_cuda_graph_decode_query_start_loc[: bs + 1]
                )
            else:
                self.query_start_loc_list[bs - 1][: bs - num_padding].copy_(
                    self.cached_cuda_graph_decode_query_start_loc[: bs - num_padding]
                )
                self.query_start_loc_list[bs - 1][bs - num_padding :].fill_(
                    bs - num_padding
                )
        elif forward_mode.is_target_verify():
            # ... 其余代码不变

```

# 评论区精华

本 PR 无 review 评论或讨论。机器人 `sglang-npu-bot` 已自动批准。

- 暂无高价值评论线程

# 风险与影响

- 风险：该变更风险极低。仅添加了一个带有默认值的可选参数，不改变任何现有逻辑。`in_capture` 默认值为 `False`，当调用方不传递此参数时行为完全不变。唯一潜在风险是如果其他代码直接反射检查签名（如 `inspect.signature` 或类型检查工具），但该场景极罕见。没有测试文件变更，但 PR 提供了本地 py_compile 和 git diff --check 验证。
- 影响：**影响范围**：仅影响 NPU 后端中使用了 hybrid linear attention 且触发了 graph capture 路径的场景。**影响程度**：修复了 NPU 调度器在特定条件下的启动崩溃，属于必现 bug 修复。对未使用 NPU 或未触发 graph capture 的场景无任何影响。
- 风险标记：缺少测试覆盖 , 向后兼容

# 关联脉络

- PR #29576 Fix DSA indexer fusion bug causing excessive memory consumption.: 同样是 NPU 后端的 bugfix，涉及 graph capture 路径，反映了近期对 NPU 后端稳定的持续关注。
- PR #29343 [dflash] fa3/fa4: device-side page table; drop seq_lens_cpu D2H sync: 该 PR 调整了基类 `_replay_metadata` 的调用方式（增加 `in_capture` 参数），是导致本次兼容性问题的上游变更。