已合并
refactor for torch_npu init module. #35494
bellatan创建于 5月13日
refactor for torch_npu init module. #35494
已合并
Pull Request已成功合入, 合并人@ascend-robot
(感谢 bellatan 的贡献)ascend-robot
5月13日 评论:
5月13日 评论:
Thanks for your pull-request.
The full list of commands accepted by me can be found at here。
You can get sig-info at here
PR Approval Progress
✅ Congratulations! All modules have met the lgtm and approve requirements.
Module Approval Details
| module | lgtm status | approve status |
|---|---|---|
| repo-Ascend/pytorch | ✅ liujunzhu, hbhu_bin (2/2) | ✅ liujunzhu (1/1) |
| test | ✅ hbhu_bin, liujunzhu (2/2) | ✅ liujunzhu (1/1) |
| torch_npu/distributed | ✅ liujunzhu, hbhu_bin (2/2) | ✅ liujunzhu (1/1) |
| torch_npu/dynamo | ✅ liujunzhu, hbhu_bin (2/2) | ✅ liujunzhu (1/1) |
| torch_npu/npu | ✅ liujunzhu, hbhu_bin (2/2) | ✅ liujunzhu (1/1) |
| torch_npu/profiler | ✅ liujunzhu, hbhu_bin (2/2) | ✅ liujunzhu (1/1) |
| torch_npu/utils | ✅ hbhu_bin, liujunzhu (2/2) | ✅ liujunzhu (1/1) |
💡 Tip:
- Committer can comment
/approveor/lgtm- Commenting
/approveimplies both code review (lgtm) and intent to merge (approve)
CLA Signature Pass
bellatan, thanks for your pull request. All authors of the commits have signed the CLA. 👍


5月13日 添加了label:ascend-cla/yes
ascend-robot
5月13日 评论:
5月13日 评论:
当前仓库存在以下 保护分支 :
| Protected Branch | Version | Release |
|---|---|---|
| master | ||
| v2.7.1 | ||
| v2.9.0 | ||
| v2.10.0 | ||
| v2.11.0 | ||
| v2.12.0 |
评论 /sync <branch1> <branch2> ... 可将当前 PR 修改同步到其它分支(创建同步 PR):
a) 如果当前 PR 是 Open 状态,同步操作将延迟到 PR 被合并时执行
b) 如果当前 PR 已经 Merged,将立即执行同步操作
注意:
- /sync 命令可以指定同步到多个分支,仅最后一个 /sync 命令生效
- 如果创建的同步 PR 不正确,可通过向同步 PR 的源分支提交轻量级 PR 完善,或使用 /close 命令关闭


openLiBingCI
5月13日 评论:
5月13日 评论:
本PR中共发现代码检查告警抑制9处,请Committer检视合理性
本评论自动扫描PR中使用的开源代码检查工具(ruff、clang-tidy、CodeQL等)的屏蔽注释。
这些屏蔽注释会阻止开源代码检查工具对特定代码区域的检测,可能导致潜在问题被忽略。
| 文件路径 | 行号 | 屏蔽类型 | 代码片段 | 工具名称 |
|---|---|---|---|---|
| test/test_torch_npu_init.py | 257 | 行级屏蔽 | 253: """ 254: import torch_npu 255: import torch.distributed as dist 256: import torch.distributed.rpc as rpc 257: import torch.distributed.tensor # noqa: F401 258: from torch._dynamo.device_interface import get_interface_for_device 259: from torch._dynamo.backends.registry import _BACKENDS 260: from torch._inductor.codegen.common import device_op_overrides_dict 262: iface = get_interface_for_device("npu") 263: assert iface is not None |
flake8 |
| test/test_torch_npu_init.py | 383 | 行级屏蔽 | 378: assert hasattr(C, "_afd") is False 379: assert "torch_npu._afd" in sys.modules 380: assert "torch_npu._C._afd" not in sys.modules 382: try: 383: import torch_npu._C._afd # noqa: F401 384: raise AssertionError("import torch_npu._C._afd should fail") 385: except ModuleNotFoundError: 386: pass 388: for name in afd_ops: 389: assert hasattr(torch_npu._afd, name), ( |
flake8 |
| torch_npu/_init/core/ module_loader.py |
127 | 行级屏蔽 | 123: libhccl.so / libascendcl.so) into friendlier errors. 124: Must be called only after _C / required child submodules / torch.npu are ready. 125: """ 126: try: 127: import torch_npu.npu # noqa: F401 128: except ImportError as e: 129: from torch_npu.utils._error_code import ErrCode, pta_error 131: if "libhccl.so" in str(e): 132: if "ASCEND_OPP_PATH" in os.environ: 133: # Warning: key logs in the fault mode library!!! Don't make arbitrary modifications!!! |
flake8 |
| torch_npu/_init/core/ module_loader.py |
199 | 行级屏蔽 | 195: - AFD op bindings: torch.ops.npu.<afd_op> -> torch_npu._afd.<afd_op> 196: - custom ops import 197: - op-plugin registration / meta registration / generated docs side effects 198: """ 199: import torch_npu._afd # noqa: F401 200: import torch_npu.npu.aclnn # noqa: F401 201: import torch_npu.op_plugin 202: import torch_npu.optim # noqa: F401 203: from torch_npu.op_plugin.meta import _meta_registrations # noqa: F401 204: from torch_npu.utils import custom_ops # noqa: F401 |
flake8 |
| torch_npu/_init/core/ module_loader.py |
200 | 行级屏蔽 | 196: - custom ops import 197: - op-plugin registration / meta registration / generated docs side effects 198: """ 199: import torch_npu._afd # noqa: F401 200: import torch_npu.npu.aclnn # noqa: F401 201: import torch_npu.op_plugin 202: import torch_npu.optim # noqa: F401 203: from torch_npu.op_plugin.meta import _meta_registrations # noqa: F401 204: from torch_npu.utils import custom_ops # noqa: F401 205: from torch_npu.utils._afd_ops import initialize_afd_bindings |
flake8 |
| torch_npu/_init/core/ module_loader.py |
202 | 行级屏蔽 | 198: """ 199: import torch_npu._afd # noqa: F401 200: import torch_npu.npu.aclnn # noqa: F401 201: import torch_npu.op_plugin 202: import torch_npu.optim # noqa: F401 203: from torch_npu.op_plugin.meta import _meta_registrations # noqa: F401 204: from torch_npu.utils import custom_ops # noqa: F401 205: from torch_npu.utils._afd_ops import initialize_afd_bindings 207: importlib.import_module("torch_npu._op_plugin_docs") 208: if hasattr(torch_npu, "_op_plugin_docs"): |
flake8 |
| torch_npu/_init/core/ module_loader.py |
203 | 行级屏蔽 | 199: import torch_npu._afd # noqa: F401 200: import torch_npu.npu.aclnn # noqa: F401 201: import torch_npu.op_plugin 202: import torch_npu.optim # noqa: F401 203: from torch_npu.op_plugin.meta import _meta_registrations # noqa: F401 204: from torch_npu.utils import custom_ops # noqa: F401 205: from torch_npu.utils._afd_ops import initialize_afd_bindings 207: importlib.import_module("torch_npu._op_plugin_docs") 208: if hasattr(torch_npu, "_op_plugin_docs"): 209: delattr(torch_npu, "_op_plugin_docs") |
flake8 |
| torch_npu/_init/core/ module_loader.py |
204 | 行级屏蔽 | 200: import torch_npu.npu.aclnn # noqa: F401 201: import torch_npu.op_plugin 202: import torch_npu.optim # noqa: F401 203: from torch_npu.op_plugin.meta import _meta_registrations # noqa: F401 204: from torch_npu.utils import custom_ops # noqa: F401 205: from torch_npu.utils._afd_ops import initialize_afd_bindings 207: importlib.import_module("torch_npu._op_plugin_docs") 208: if hasattr(torch_npu, "_op_plugin_docs"): 209: delattr(torch_npu, "_op_plugin_docs") 211: initialize_afd_bindings() |
flake8 |
| torch_npu/_init/core/ optional_features.py |
32 | 行级屏蔽 | 28: Enable transfer_to_npu via environment variable 29: """ 30: transfer_to_npu_env = os.getenv("TORCH_TRANSFER_TO_NPU", "0") 31: if transfer_to_npu_env == "1": 32: from torch_npu.contrib import transfer_to_npu # noqa: F401 33: elif transfer_to_npu_env != "0": 34: raise ValueError( 35: f"Invalid value for TORCH_TRANSFER_TO_NPU: {transfer_to_npu_env}. " 36: "Only '0' or '1' is supported." 37: ) |
flake8 |


此处折叠了92条消息 查看更多
5月13日 添加了label:lgtm
openLiBingCI
5月13日 评论:
5月13日 评论:
本PR中共发现代码检查告警抑制9处,请Committer检视合理性
本评论自动扫描PR中使用的开源代码检查工具(ruff、clang-tidy、CodeQL等)的屏蔽注释。
这些屏蔽注释会阻止开源代码检查工具对特定代码区域的检测,可能导致潜在问题被忽略。
| 文件路径 | 行号 | 屏蔽类型 | 代码片段 | 工具名称 |
|---|---|---|---|---|
| test/test_torch_npu_init.py | 255 | 行级屏蔽 | 251: """ 252: import torch_npu 253: import torch.distributed as dist 254: import torch.distributed.rpc as rpc 255: import torch.distributed.tensor # noqa: F401 256: from torch._dynamo.device_interface import get_interface_for_device 257: from torch._dynamo.backends.registry import _BACKENDS 258: from torch._inductor.codegen.common import device_op_overrides_dict 260: iface = get_interface_for_device("npu") 261: assert iface is not None |
flake8 |
| test/test_torch_npu_init.py | 381 | 行级屏蔽 | 376: assert hasattr(C, "_afd") is False 377: assert "torch_npu._afd" in sys.modules 378: assert "torch_npu._C._afd" not in sys.modules 380: try: 381: import torch_npu._C._afd # noqa: F401 382: raise AssertionError("import torch_npu._C._afd should fail") 383: except ModuleNotFoundError: 384: pass 386: for name in afd_ops: 387: assert hasattr(torch_npu._afd, name), ( |
flake8 |
| torch_npu/_init/core/ module_loader.py |
127 | 行级屏蔽 | 123: libhccl.so / libascendcl.so) into friendlier errors. 124: Must be called only after _C / required child submodules / torch.npu are ready. 125: """ 126: try: 127: import torch_npu.npu # noqa: F401 128: except ImportError as e: 129: from torch_npu.utils._error_code import ErrCode, pta_error 131: if "libhccl.so" in str(e): 132: if "ASCEND_OPP_PATH" in os.environ: 133: # Warning: key logs in the fault mode library!!! Don't make arbitrary modifications!!! |
flake8 |
| torch_npu/_init/core/ module_loader.py |
199 | 行级屏蔽 | 195: - AFD op bindings: torch.ops.npu.<afd_op> -> torch_npu._afd.<afd_op> 196: - custom ops import 197: - op-plugin registration / meta registration / generated docs side effects 198: """ 199: import torch_npu._afd # noqa: F401 200: import torch_npu.npu.aclnn # noqa: F401 201: import torch_npu.op_plugin 202: import torch_npu.optim # noqa: F401 203: from torch_npu.op_plugin.meta import _meta_registrations # noqa: F401 204: from torch_npu.utils import custom_ops # noqa: F401 |
flake8 |
| torch_npu/_init/core/ module_loader.py |
200 | 行级屏蔽 | 196: - custom ops import 197: - op-plugin registration / meta registration / generated docs side effects 198: """ 199: import torch_npu._afd # noqa: F401 200: import torch_npu.npu.aclnn # noqa: F401 201: import torch_npu.op_plugin 202: import torch_npu.optim # noqa: F401 203: from torch_npu.op_plugin.meta import _meta_registrations # noqa: F401 204: from torch_npu.utils import custom_ops # noqa: F401 205: from torch_npu.utils._afd_ops import initialize_afd_bindings |
flake8 |
| torch_npu/_init/core/ module_loader.py |
202 | 行级屏蔽 | 198: """ 199: import torch_npu._afd # noqa: F401 200: import torch_npu.npu.aclnn # noqa: F401 201: import torch_npu.op_plugin 202: import torch_npu.optim # noqa: F401 203: from torch_npu.op_plugin.meta import _meta_registrations # noqa: F401 204: from torch_npu.utils import custom_ops # noqa: F401 205: from torch_npu.utils._afd_ops import initialize_afd_bindings 207: importlib.import_module("torch_npu._op_plugin_docs") 208: if hasattr(torch_npu, "_op_plugin_docs"): |
flake8 |
| torch_npu/_init/core/ module_loader.py |
203 | 行级屏蔽 | 199: import torch_npu._afd # noqa: F401 200: import torch_npu.npu.aclnn # noqa: F401 201: import torch_npu.op_plugin 202: import torch_npu.optim # noqa: F401 203: from torch_npu.op_plugin.meta import _meta_registrations # noqa: F401 204: from torch_npu.utils import custom_ops # noqa: F401 205: from torch_npu.utils._afd_ops import initialize_afd_bindings 207: importlib.import_module("torch_npu._op_plugin_docs") 208: if hasattr(torch_npu, "_op_plugin_docs"): 209: delattr(torch_npu, "_op_plugin_docs") |
flake8 |
| torch_npu/_init/core/ module_loader.py |
204 | 行级屏蔽 | 200: import torch_npu.npu.aclnn # noqa: F401 201: import torch_npu.op_plugin 202: import torch_npu.optim # noqa: F401 203: from torch_npu.op_plugin.meta import _meta_registrations # noqa: F401 204: from torch_npu.utils import custom_ops # noqa: F401 205: from torch_npu.utils._afd_ops import initialize_afd_bindings 207: importlib.import_module("torch_npu._op_plugin_docs") 208: if hasattr(torch_npu, "_op_plugin_docs"): 209: delattr(torch_npu, "_op_plugin_docs") 211: initialize_afd_bindings() |
flake8 |
| torch_npu/_init/core/ optional_features.py |
32 | 行级屏蔽 | 28: Enable transfer_to_npu via environment variable 29: """ 30: transfer_to_npu_env = os.getenv("TORCH_TRANSFER_TO_NPU", "0") 31: if transfer_to_npu_env == "1": 32: from torch_npu.contrib import transfer_to_npu # noqa: F401 33: elif transfer_to_npu_env != "0": 34: raise ValueError( 35: f"Invalid value for TORCH_TRANSFER_TO_NPU: {transfer_to_npu_env}. " 36: "Only '0' or '1' is supported." 37: ) |
flake8 |


ascend-robot
5月13日 评论:
5月13日 评论:
5月13日 合入了pull request
【合入来源】
【修改方案】
本 PR 对
torch_npu初始化链路进行重构,将原先集中在torch_npu/__init__.py中的初始化逻辑拆分到_init目录下的多个职责模块中,形成“顶层编排 + 子模块分阶段执行 + 内部能力统一收口”的结构。重构后,torch_npu/__init__.py不再承载大量具体业务初始化细节,只负责固定初始化时序。各类具体能力分别由_check_device_conflict、_load_core_modules、_register_components、_apply_patches、_enable_optional_features、_initialize_runtime_lifecycle等内部函数承接。一、核心修改
1. 重构
torch_npu/__init__.py顶层初始化入口重构后的初始化流程如下:
def _initialize(): _check_device_conflict() _load_core_modules() _register_components() _apply_patches() _enable_optional_features() _initialize_runtime_lifecycle()顶层入口主要负责:
__all__;import torch前关闭TORCH_DEVICE_BACKEND_AUTOLOAD,避免 PyTorch 后端自动加载导致循环依赖;torch_npu.utils.patch_getenv,用于捕获初始化阶段的环境变量访问;_autoload()作为 PyTorch 后端自动加载入口,用于恢复TORCH_DEVICE_BACKEND_AUTOLOAD。2. 新增
_init目录:目录结构如下:
3. 通过
_check_device_conflict()处理前置设备冲突检查_check_device_conflict():负责最早期的设备冲突检查,避免 NPU 与其他 accelerator 同时启用。该接口属于初始化内部逻辑,不作为 public API 暴露。4. 通过
_load_core_modules()统一管理核心模块加载、注册副作用和顶层 API 导出_load_core_modules()将原先散落在torch_npu/__init__.py中的模块导入、底层_C子模块准备、基础 runtime 支撑模块初始化、导入即注册副作用以及顶层 API 导出统一收口。该阶段主要负责:torch_npu初始化所需的核心模块;_Cchild submodules;_C准备完成后进行torch_npu.npu导入检查;torch_npu顶层 public API。具体包括:
_C子模块初始化:统一创建并注册_profiler、_distributed_c10d、_cd、_logging、_flops_count等_Cchild submodules,保证业务 Python 模块只消费这些子模块,不再各自创建。torch_npu.npu导入检查:在_C子模块完成准备后再检查torch_npu.npu导入状态,既保留对底层依赖缺失的友好报错,又避免_C未就绪时提前 importtorch_npu.npu导致循环导入。export_all将torch_npu顶层公开 API 统一导出到globals()和__all__中,保证 public API 行为与旧版兼容。HiFloat8Tensor、erase_stream、matmul_checksum等接口采用 lazy export,保证接口可见但不在 import 阶段立即加载对应模块,减少循环导入风险。torch.ops.npu下的公开算子导出到torch_npu顶层,并保留torch.<op>deprecated wrapper。_C._cd.DType中的 dtype 符号导出到torch_npu顶层。5. 通过
_register_components()统一管理框架集成注册_register_components()负责 backend 和 framework integration 注册,将原先散落在顶层入口中的 NPU backend、distributed、Dynamo、RPC、Inductor 等注册逻辑统一收口。通过该阶段统一收口后,框架集成注册逻辑不再散落在顶层__init__.py中,后续新增集成能力时可直接在 registry 目录下维护。该阶段主要负责:torch.npu设备模块和相关方法。6. 通过
_apply_patches()统一管理 patch 注册与执行引入集中式 patch 管理机制,统一收口原先散落在初始化入口中的 patch 逻辑。顶层入口
_apply_patches()负责触发 patch 发现、注册和执行,具体由PatchManager承接。_apply_patches()主要完成以下工作:PatchManager会自动扫描_init/patches下符合命名规则的 patch 模块。模块被导入后,内部 patch 会完成注册。PatchManager支持调整 patch group 执行顺序,便于测试或特殊场景扩展。PatchManager.run()统一处理,便于初始化失败和运行时异常场景的集中管理。7. 通过
_enable_optional_features()统一管理可选运行时能力将 sanitizer、交互式模式配置、
transfer_to_npu等可选能力统一收口到_enable_optional_features(),避免可选逻辑散落在顶层初始化入口。该阶段主要包括:具体说明:
TORCH_NPU_SANITIZER时启用;TORCH_TRANSFER_TO_NPU控制是否启用,对非法配置进行显式报错。8. 通过
_initialize_runtime_lifecycle()统一管理 runtime 生命周期_initialize_runtime_lifecycle()专门负责最终 C++ extension 初始化屏障和进程退出阶段的 shutdown hook 注册。该阶段主要包括:torch_npu._C._initExtension()完成最终 C++ extension 绑定。该阶段放在核心模块加载、框架注册、API 导出和 patch 执行之后,保证 Python 侧初始化准备完成后再进入最终 extension barrier。三、重构目的和收益
本次重构的目标是把
torch_npu初始化从“单文件集中式副作用堆叠”调整为“阶段化、组件化、可维护”的初始化框架。主要收益包括:torch_npu/__init__.py只保留初始化编排,不再堆叠大量具体 import、注册、patch 和 shutdown 逻辑。_C子模块和基础 runtime 支撑能力统一由_load_core_modules准备,降低循环导入和_C未就绪时提前访问的风险。模块加载、框架注册、API 导出、patch、可选功能、runtime 生命周期分别由不同接口承接。
各组件 patch 可以在自己的文件中维护,由
PatchManager自动发现和统一执行,减少顶层冲突。新增初始化能力时,只需放到对应处理的接口 或 patch group 中,不需要继续膨胀
__init__.py。初始化链路被拆成明确阶段,出现问题时可以快速判断是模块加载、注册、导出、patch、optional feature 还是 runtime lifecycle 阶段异常。
四、兼容性说明
本次重构保持以下兼容性:
import torch_npu行为保持兼容;__version__仍从torch_npu.version导出。五、PatchManager 机制说明
本 PR 引入
PatchManager,用于统一管理torch_npu初始化阶段的 patch 注册与执行。原先 patch 逻辑集中在torch_npu/__init__.py中,和初始化流程、模块导入、框架注册逻辑混在一起,导致顶层文件过重,也不利于各组件独立维护。本次重构后,patch 逻辑从顶层入口中解耦,由_apply_patches()作为顶层入口触发执行,具体注册、发现、排序、幂等保护由PatchManager管理。PatchManager主要支持以下能力:整体机制如下:
场景一:新增 torch_npu 内置 patch
如果新增的是
torch_npu内置 patch,例如 distributed patch、profiler patch、NPU API patch、warning patch、ASD patch 等,可以直接放到:torch_npu/_init/patches/目录下,并按 group 注册。示例:
from torch_npu._init.patches.patch_manager import PatchManager @PatchManager.register_patch("profiler") def apply_profiler_patch(): ...使用方式:
场景二:组件自行维护 patch module
如果某个组件自己的目录下新加了patch 文件,通过 patch module 注册机制接入。
示例:
PatchManager.register_patch_module("torch_npu.some_component.some_patches")组件自己的 patch 文件中仍然使用 group 注册:
from torch_npu._init.patches.patch_manager import PatchManager @PatchManager.register_patch("some_component") def apply_some_component_patch(): ...使用方式:
适用场景:
场景三:按 group 执行 patch,用于测试或后续按需使能
PatchManager支持按 group 执行 patch。当前默认初始化路径仍执行全部注册 patch,后续也可按需使能。示例:
PatchManager.apply_registered_patches("distributed")使用方式:
适用场景:
如果需要调整 patch group 顺序,也可以使用:
PatchManager.set_patch_order([ "monkey", "api", "distributed", ])适用场景:
【资料变更】
【接口变更】
【功能验证】
新增
TestTorchNpuBootstrap初始化专项测试,覆盖以下场景:test_01_import_order_compatibility验证
import torch_npu、import torch; import torch_npu、import torch_npu; import torch、重复import torch_npu等不同导入顺序保持兼容。test_02_import_state_snapshot验证
import torch_npu后的初始化状态,包括torch.npu注册、Tensor/Module.npu方法生成、_Cchild submodules 准备、旧版初始化副作用模块加载、非预期模块不 eager import、顶层关键属性可访问等。test_03_public_exports_snapshot验证顶层 public API 导出行为,包括 lazy Python APIs、
torch.ops.npupublic ops、deprecatedtorch.<op>alias、dtype symbols 等导出保持兼容。test_04_framework_registration_snapshot验证框架集成注册行为,包括 Dynamo NPU device interface、Dynamo backend、Inductor lightweight device op override、distributed backend、RPC backend 等注册保持生效。
test_05_runtime_lazy_init_semantics验证 import 阶段不触发 NPU runtime lazy init,查询类 API 不触发完整 runtime 初始化,真实 runtime API 和显式
torch_npu.npu.init()能正常触发 lazy init。test_06_component_behavior_snapshot验证关键组件行为保持兼容,包括
patch_getenv生效、ASD detector 兼容 API、AFD 通过torch_npu._afd暴露、torch_npu._C._afd不暴露、AFD ops 可访问等。test_07_distributed_patch_behavior验证 distributed patch 行为保持兼容,包括 distributed 内部函数替换、public API alias、rendezvous/launcher patch、FSDP 相关 patch 等。
新增测试用例本地验证通过。
【CheckList】