Prhub

#21551 [MPS] Fix Triton stub sub-module imports on Python 3.12+

原始 PR 作者 karanb192 合并时间 2026-04-01 11:26 文件变更 1 提交数 7 评论 11 代码增减 +14 / -16

执行摘要

修复 macOS 上 Python 3.12+ 中 Triton stub 子模块导入失败的 bug。

该变更旨在修复issue #21548中报告的问题:在macOS上,SGLang使用Triton stub模拟triton模块,以便在没有真实Triton的环境下运行。但随Python 3.12发布,CPython移除了sys.meta_pathfind_module()的回退机制(当finder未实现find_spec()时),导致旧stub无法处理点分triton.*子模块导入,引发ModuleNotFoundError: No module named 'triton.compiler'。PR body中引用具体表述:"On Python 3.12, CPython removed the sys.meta_path fallback to find_module() when a finder does not implement find_spec(), so the old stub no longer materialized those sub-modules."

该PR值得精读,尤其对于处理Python导入系统兼容性、macOS/MPS环境集成或代码重构的工程师。关注点包括:

  • find_spec方法的实现细节,展示了如何动态模拟模块和子模块。
  • find_module/load_modulefind_spec的迁移决策,体现了对Python版本演进的适应。
  • 讨论中如何通过测试验证修复,确保跨Python版本的兼容性。
讨论亮点

review讨论中,主要交锋围绕移除过时导入协议和验证修复效果:

  • yeahdongcn 在Issue评论中提问根因并建议测试Python 3.11和3.12兼容性,随后在review中建议"Could you please remove find_module/load_module",认为这些方法自Python 3.4起已过时。
  • karanb192 回应确认问题是Python 3.12特有,并通过测试验证修复有效;在后续提交中移除了find_module/load_module方法,并说明"The latest revision removes find_module / load_module entirely and uses only find_spec"。
  • 讨论还涉及移除冗余mock,karanb192 在评论中解释"find_spec() on _TritonFinder already handles dotted triton.* sub-module imports dynamically, so the explicit triton.compiler mocks and their old inline comment are no longer needed."

实现拆解

实现集中在python/sglang/_triton_stub.py文件中的_TritonFinder类。关键改动包括:

  • 移除find_moduleload_module方法,这些是Python遗留导入协议。
  • 新增find_spec方法,遵循PEP 451标准,动态处理tritontriton.*子模块导入。该方法检查sys.modules,若模块不存在则创建_MockModule实例并注册到sys.modules,同时建立父子模块关系。
  • 移除代码中冗余的显式triton.compilertriton.compiler.compilermock注册,因为find_spec()已能动态处理所有子模块。
文件 模块 状态 重要度
python/sglang/_triton_stub.py import system stub modified 6.0

关键符号

_TritonFinder.find_spec

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

评论区精华

移除过时的 find_module/load_module 方法 设计

yeahdongcn 建议移除 deprecated 的 find_module/load_module 方法,因为这些自 Python 3.4 起已过时;karanb192 回应并执行了移除,说明只使用 find_spec()。

结论:已移除 find_module/load_module,仅保留 find_spec() 方法,遵循 PEP 451 标准。 · 已解决

风险与影响

技术风险较低,但需注意:

  • 回归风险:find_spec方法实现需确保正确处理所有triton.*子模块导入,如果逻辑有误(如父子模块关系设置错误),可能导致其他导入失败或无限递归。代码中已通过检查sys.modules和动态创建mock来规避。
  • 兼容性风险:变更依赖于PEP 451的find_spec,SGLang要求Python 3.9+,而find_spec自Python 3.4可用,因此风险可控。移除过时方法可能影响旧代码,但无证据表明有依赖。
  • 测试覆盖:PR body提供了详细的测试矩阵,在Python 3.11和3.12上验证了关键导入和端到端功能,但缺少单元测试代码变更。

影响范围有限但重要:

  • 对用户:修复了macOS上Python 3.12+用户在使用torch 2.9+时无法运行SGLang的问题(如bench_one_batch失败),提升了用户体验和系统可用性。
  • 对系统:改进了导入系统的健壮性,遵循现代Python标准(PEP 451),降低了未来Python版本升级的潜在兼容性问题。
  • 对团队:提供了一个从遗留导入协议迁移的示例,有助于类似代码重构;变更集中在单个文件,影响面小,易于维护。
Python 版本兼容性 导入系统变更

关联 Issue

#21548 [MPS] Triton stub sub-module resolution broken on macOS with torch 2.9+ / Python 3.12+

完整报告

参与讨论