Prhub

#27774 [NPU] Fix dead patch_model monkey-patch breaking NPU torch.compile capture

原始 PR 作者 ch-wan 合并时间 2026-06-10 16:15 文件变更 1 提交数 1 评论 3 代码增减 +3 / -5

执行摘要

修复 NPU torch.compile 捕获的 monkey-patch 失效 bug

CUDA Graph Runner/Backend 重构 (#23906) 破坏了 NPU 的 --enable-torch-compile 路径,导致 NPU CI 测试 test_npu_compile_graph_tp1_bf16.py 在 CUDA 图捕获时失败。根本原因是重构后 patch_model 的导入方式使得 NPU 的 monkey-patch 变成了静默的 no-op。修复方案是改变导入方式,在调用点通过模块名访问 patch_model,从而让 monkey-patch 生效。

该 PR 值得合并,它是一个针对特定平台(NPU)的精确 bug 修复,修改简洁且安全。关注点:代码评审者应注意到 Python 导入语义的陷阱——from module import name 会创建本地引用副本,而 import module 允许动态属性访问。这种模式在需要支持 monkey-patch 的场景下尤为重要。

讨论亮点

该 PR 仅有作者的自我操控评论和自动 CI 评论,无人工 review 讨论。自动代码审查机器人 gemini-code-assist[bot] 仅声明无反馈。

实现拆解

  1. 修改导入语句:在 python/sglang/srt/model_executor/runner/decode_cuda_graph_runner.py 中,将 from sglang.srt.compilation.torch_compile_decoration import patch_model 替换为 from sglang.srt.compilation import torch_compile_decoration。同时保留另一个导入 set_torch_compile_config,因为它没有被 monkey-patch,无需修改。
  2. 修改调用点:在 _capture_one_stream 方法中,将 with patch_model(...) 改为 with torch_compile_decoration.patch_model(...)。这样,每次调用时都会从模块对象中动态解析 patch_model,从而能让 NPU 运行前设置的 monkey-patch 生效。
  3. 测试验证:通过重新运行 NPU --enable-torch-compile 相关测试和 GPU 编译测试来验证修复。
文件 模块 状态 重要度
python/sglang/srt/model_executor/runner/decode_cuda_graph_runner.py 解码器 modified 5.8

关键符号

_capture_one_stream

关键源码片段

python/sglang/srt/model_executor/runner/decode_cuda_graph_runner.py data-contract

修复的核心文件:修改导入方式,将 `from ... import patch_model` 替换为 `import torch_compile_decoration`,并在调用点使用模块属性访问 `patch_model`,从而恢复 NPU monkey-patch 的有效性。

# decode_cuda_graph_runner.py (head version)# 修改前:from ...torch_compile_decoration import patch_model # 按值导入,monkey-patch 失效
# 修改后:导入模块本身,运行时动态解析 patch_model
from sglang.srt.compilation import torch_compile_decoration
# set_torch_compile_config 没有被 monkey-patch,仍然可以按值导入
from sglang.srt.compilation.torch_compile_decoration import set_torch_compile_configclass DecodeCudaGraphRunner:
    # ... 其他代码 ...
​
    def _capture_one_stream(self, stream_idx: Optional[int] = None) -> None:
        # ... 前面的代码 ...
        for bs in capture_range:
            for variant_label, _variant_has_lora in lora_variants:
                _set_capture_lora_variant(variant_label)
                # 修改前:with patch_model(...) # 使用本地副本,monkey-patch 无效
                # 修改后:通过模块属性访问,每次调用都解析最新的 patch_model
                with torch_compile_decoration.patch_model(
                    self.model_runner.model,
                    bs in self.compile_bs,
                    num_tokens=bs * self.num_tokens_per_bs,
                    tp_group=self.model_runner.tp_group,
                ) as forward:
                    self.capture_one_shape(bs, forward, stream_idx, variant_label)

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

本 PR 修改集中在导入和调用方式上,风险极低。修改后的代码在 GPU 上行为不变(模块属性解析到相同的默认 patch_model),在 NPU 上恢复正确的 monkey-patch 行为。唯一的潜在风险是如果未来有其他代码同样通过 from ... import patch_model 方式导入并期望被 monkey-patch,则可能再次出现类似问题。

受影响用户:NPU 平台上使用 --enable-torch-compile 的用户。修复后,他们能正常使用 CUDA 图捕获,获得性能提升。GPU 用户无影响。影响范围:仅修改 decode CUDA graph runner 的导入,不影响其他后端或功能。

平台特定代码 依赖 Python 导入语义

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论