已合并
sync: defer dynamo and inductor imports to first torch.compile (from v2.9.0_import) #44299
黄桂军创建于 25 天前
sync: defer dynamo and inductor imports to first torch.compile (from v2.9.0_import) #44299
已合并
黄桂军创建于 25 天前
黄桂军
黄桂军成员
25 天前

同步 v2.9.0_import 分支的 15 个 import optimization commits 到 v2.12.0,将 Dynamo 和 Inductor 初始化延迟到首次 torch.compile 调用。详见 v2.12.0_syn.md 逐文件分类和冲突解决记录。

【合入来源】

【修改方案】

同步 v2.9.0_import 的 lazy import optimization(15 commits)到 v2.12.0。将 Dynamo/Inductor 初始化从 import 时延迟到首次 torch.compile。主要改动包括:

  1. _dynamo.py: 线程锁 + fork 安全 + lazy 初始化架构
  2. _rng_prims_patch.py: 提取 RNG patches 到独立模块
  3. registry_manager.py: 移除 import 时 dynamo/inductor 注册
  4. dynamo/init.py: lazy torchair, backend entrypoints
  5. distributed: lazy fsdp, dtensor_patch 隔离, _graph_tree_state 轻量模块
  6. deterministic.py: 本地 _forbid_in_graph 避免 torch._dynamo 导入
  7. npugraph_ex: 延迟 torch._inductor 导入
  8. setup.py: torch_dynamo_backends entry_points
  9. test_compile_trigger.py + test_torch_npu_init.py: 验证测试

PyTorch 2.12 适配: EventVariable 在 streams, _ConfigEntry 需要 name, _TorchCompileInductorWrapper.init 有 name=None

【资料变更】

不涉及

【接口变更】

不涉及

【功能验证】

conda torch-npu-build-2.12.0-py311 验证:

  • 导入 torch_npu 后 torch._dynamo/torch._inductor 不加载 ✓
  • test_compile_trigger.py 21 passed
  • test_torch_npu_init.py test_02/test_04 通过 ✓

【CheckList】

likedislike
Pull Request已成功合入, 合并人@ascend-robot
(感谢 黄桂军 的贡献)
黄桂军黄桂军成员
25 天前 创建了 pull request,commit baa0b211
atomgit-bot
atomgit-bot
25 天前 评论:

变更摘要

本次 PR 将 v2.9.0_import 分支的 15 个 import 优化 commit 同步到 v2.12.0,核心目标是将 torch._dynamotorch._inductor 的初始化从 import torch_npu 时延迟到首次 torch.compile 调用时。主要手段包括:引入 _DynamoPostImportFinder/_DynamoPostImportLoader 在 Dynamo 首次被导入时触发 NPU 集成;将 RNG prim patches 从 _inductor.py 提取到独立的 _rng_prims_patch.py 模块;重构 registry_manager.py 移除 import 时的 Dynamo/Inductor 注册;新增线程安全的 run_once 装饰器和 fork 安全的锁重置机制;以及通过 setup.pytorch_dynamo_backends entry_points 替换 import 时后端注册。

主要改动

  • 延迟初始化架构:在 torch_npu/utils/_dynamo.py 中新增 _DynamoPostImportFinder_DynamoPostImportLoader,当 torch._dynamo 首次被导入时自动调用 _lazy_dynamo_setup() 完成 NPU 集成;_setup_inductor_for_compile() 在首次 torch.compile 时触发 _lazy_inductor_setup(),将 Inductor 后端加载延迟到实际编译路径。

  • RNG patches 模块化分离:将 torch_npu/utils/_inductor.py 中的 patch_philox_rand_offsetpatch_register_philox_randpatch_register_run_and_save_rng_state_op 等 RNG prim patches(约 220 行)提取到新增的 torch_npu/utils/_rng_prims_patch.py,通过 apply_rng_prims_patches() 在 import 时统一调用,registry_manager.py_register_rng_prims() 替代了原来的 _register_inductor()

  • 注册管理重构registry_manager.py 移除 _register_dynamo()_register_inductor(),不再在 import torch_npu 时注册 Dynamo 后端、trace rules 和 Inductor device op overrides;Dynamo 后端注册移至 dynamo/__init__.py_register_backends()(带去重保护),Inductor 注册由 _InductorNpuRegistry 在首次编译时按需执行。

  • 线程安全与 fork 安全run_once 装饰器改为基于 threading.Condition 的实现,支持并发等待和 fork 后状态重置;_NpuBackendScope 改为在 __enter__/__exit__ 中使用 _INDUCTOR_NPU_BACKEND_LOCK 保护;_reset_compiler_locks_after_fork 通过 os.register_at_fork 在 fork 后重置锁和 run_onceCondition

  • 编译入口点与 entry_pointssetup.py 新增 torch_dynamo_backends entry_points,声明 npunpugraph_exnpugraphs 三个后端入口;dynamo/__init__.py 新增 _npu_backend_entrypoint_npugraph_ex_backend_entrypoint_NpugraphsBackendEntryPoint 类,每个入口在调用时先触发 _lazy_dynamo_setup(),并处理与 setuptools entry point 的去重逻辑。

likedislike
atomgit-bot
atomgit-bot
25 天前 评论:

代码审查

审查总结

已完成对全部 8 个变更文件的逐文件审查:

文件 审查结果
setup.py 无问题 — 新增 torch_dynamo_backends entry_points,引用的符号经验证存在
test/dynamo/test_compile_trigger.py 无问题 — 新增 1440 行测试,覆盖 lazy import、fork 安全、并发安全、导出语义等场景
test/test_torch_npu_init.py 无问题 — 从 EXPECTED_LOADED_MODULES 移除 torch_npu.utils._inductor,加入 EXPECTED_NOT_LOADED_MODULES,并移除对已失效 eager 注册的断言
torch_npu/_compat/utils.py 1 个 P3 问题 — 版本兼容注释中的版本号引用不准确
torch_npu/_inductor/utils.py 无问题 — compile_fx 显式导入确保模块在 patch_has_triton 调用前已加载
torch_npu/_init/patches/dynamo_patches.py 无问题 — 移除的 apply_npugraph_tree_patch 已迁移至 lazy Inductor 初始化路径
torch_npu/_init/registry/registry_manager.py 无问题 — _register_dynamo/_register_inductor 替换为 _register_rng_prims,Dynamo/Inductor 注册推迟至首次 torch.compile
torch_npu/contrib/transfer_to_npu.py 无问题 — 显式导入 Dynamo/Inductor 模块替代 torch_npu 的副作用导入,filesystem 引用方式变更语义等价

发现统计:P0: 0,P1: 0,P2: 0,P3: 1

总体风险评估:低风险。该 PR 将 Dynamo/Inductor 初始化推迟到首次 torch.compile 调用,变更逻辑清晰,配套测试覆盖全面(lazy import 语义、fork 安全、并发安全、后端注册、入口点加载等),唯一发现为注释措辞不准确,不影响运行时行为。


审查总结

逐文件审查结果

文件 审查结论
torch_npu/distributed/__init__.py 无新增问题:__getattr__/__dir__ 延迟加载模式正确
torch_npu/distributed/fsdp/__init__.py 无新增问题:import torch.distributed.fsdp 确保补丁依赖可用
torch_npu/distributed/tensor/__init__.py 无新增问题:导入重排 + experimental 延迟加载正确
torch_npu/distributed/tensor/_dtensor_patch.py 发现 2 个问题(见下)
torch_npu/dynamo/__init__.py 无新增问题:延迟注册 / entrypoint 架构合理(_allowed_list 限制为已有问题)
torch_npu/npu/_graph_tree.py 无新增问题:MarkStepBox/mark_step_begin 移动到轻量模块,导入链保持完整
torch_npu/npu/_graph_tree_state.py 无新增问题:新模块定义与原定义一致
torch_npu/npu/deterministic.py 无新增问题:本地 _forbid_in_graph 与原始实现功能等价

发现的问题

优先级 数量
P1 1
P3 1

总体风险判断

中风险。P1 问题(字符串版本号比较)会导致 DTensor 补丁在 PyTorch 2.1~2.9 全系列上静默不生效,可能造成 DTensor 算子分片策略不完整。建议在合入前修复该版本比较逻辑。其余变更结构合理,延迟加载架构设计正确。


现在我已完成对所有 6 个文件的审查,以下是我的最终报告。


审查摘要

优先级 数量 文件位置
P3 3 utils/__init__.py_graph_tree.py_dynamo.py
P0–P2 0

各文件审查结果:

  • torch_npu/npu/npugraph_ex/__init__.py — 无问题。将 fwd_only 从模块级导入改为 register_replacement 内的延迟导入,模式正确。TYPE_CHECKING 守卫与 from __future__ import annotations 配合使用以进行仅用于类型检查的导入,是正确的惰性加载设计。

  • torch_npu/utils/__init__.py — 1 个 P3 发现问题:第 14 行的死导入 _max_unpoolnd_patch。该函数被导入但从未在此文件中使用;实际的补丁应用通过 registry_manager.py 中的 apply_rng_prims_patches() 进行。

  • torch_npu/utils/_dynamo.py — 1 个 P3 发现问题:_normalize_compile_options(第 174-189 行)在将连字符替换为下划线后,如果输入字典同时包含 "npu-backend""npu_backend",会静默丢弃重复的键。其余大规模重构(run_once 装饰器配合 Condition_NpuBackendScope 配合 RLock 锁管理、_DynamoPostImportFinder/Loader 惰性触发、fork 安全的锁重置)设计合理,无正确性或死锁问题。

  • torch_npu/utils/_graph_tree.py — 1 个 P3 发现问题:第 362-368 行,npugraphs**compile_kwargs 传递给 aot_npugraphsaot_autograd 的返回值),后者不接受额外的关键字参数。目前,由于 Dynamo 的后端分发机制不传递额外的 kwargs,因此 compile_kwargs 始终为空,问题尚未触发,但这是一个潜在的 bug。

  • torch_npu/utils/_inductor.py — 无问题。RNG 补丁已提取到 _rng_prims_patch.py;剩余的 DeviceOpOverrides 代码未发生变化。

  • torch_npu/utils/_rng_prims_patch.py — 无问题。新文件正确地将 RNG 补丁从旧的 _inductor.py 提取并封装到 apply_rng_prims_patches() 中,并附带一个额外的 patch_max_unpoolnd()aten = torch.ops.aten 模块级赋值供新的 _max_unpoolnd_patch 函数使用。当 run_and_save_rng_state / run_with_rng_state 不可用时的潜在崩溃问题在移动前即已存在,并非由本次 diff 引入。

总体风险判断: 低风险。本次 diff 是一个结构良好的惰性初始化重构。未发现任何 P0–P2 级别的正确性或安全性问题。3 个 P3 发现均为次要问题:两个是死代码/脆性代码(死导入、潜在的未来 kwargs 冲突),一个是输入验证的边界情况(键冲突静默丢弃)。核心惰性加载架构——run_once 配合条件变量、RLock 保护的注册表、sys.meta_path 钩子以及 fork 安全重置——设计正确且线程安全。

类型 数量
🔴 阻塞 2
🟡 建议 1

⛔ 需要修改

likedislike
ascend-robotascend-robot成员
25 天前 添加了label:ascend-cla/yes
此处折叠了374条消息 查看更多
renyujin成员
22 天前 评论:

/lgtm

likedislike
ascend-robotascend-robot成员
22 天前 添加了label:lgtm
ascend-robotascend-robot成员
22 天前 合入了pull request
ascend-robot
ascend-robot成员
22 天前 评论:

Pull Request 已合并或已关闭。

If you want to solve this problem, you can click here to do it in the FAQs.

likedislike
ascend-robot
ascend-robot成员
22 天前 评论:
流水线 pytorch_gitcode_PR_multiVersion#13969 [ commitID:df146c46 ] 已完成
likedislike