已关闭
[RFC]: 移除 unsupport API 拦截补丁 #3682
zhounan创建于  8月5日关闭于  26 天前
zhounan成员
8月5日 创建

RFC:移除 unsupport API 拦截补丁并整体删除 npu_intercept.py

状态(Status): -
作者(Authors): @周楠
创建日期(Created): 2026-08-11
更新日期(Updated): 2026-08-11
相关 Issue/PR: https://gitcode.com/Ascend/pytorch/pull/43782


1. 概述

1.1 简介

移除 torch_npu 对 6 个 PyTorch 模块方法(nn.Module.share_memorytorch.jit.ScriptModule.add_module / bfloat16 / register_buffer / register_parameter / register_module)的 monkey-patch 拦截机制,并整体删除torch_npu/utils/npu_intercept.py。其中仍被使用的 CANN 包检测逻辑(_cann_package_check()cann_pytorch_version_map迁移torch_npu/_init/registry/registry_manager.py(其唯一调用点所在)。

1.2 动机

image.png
屏幕截图 2026-08-11 162632.png

  1. 拦截前提已失效(share_memory / bfloat16):该补丁(commit 217f26d6d,2023-08)
    最初用于在 torch_npu 尚不支持某些 API 时抛出明确的 "xxx is not supported in npu."。
    自 commit 967ed515b(2025-07,IPC 内存通信)起 torch_npu 已支持 Tensor.share_memory_,且 ScriptModule.bfloat16() 在 NPU 2.13 实测可用。
  2. 错误消息不具有必要性:ScriptModule 的修改限制(add_module / register_parameter等)是通用 PyTorch 限制(CPU / GPU 上同样抛错,已实测),与设备无关。反而可能在正常构造时会报错。
    屏幕截图 2026-08-12 144756.png
  3. 模块整体清空:拦截机制删除 + CANN 检查迁出,CANN 检查本属 registry 初始化职责, 故将_cann_package_check()cann_pytorch_version_map迁移torch_npu/_init/registry/registry_manager.py

1.3 目标

  • 目标:
    1. 删除拦截机制(unsupport_api.py 整文件、npu_patches.py 注册、相关测试);
    2. _cann_package_check()cann_pytorch_version_map 迁入
      registry_manager.py(行为零变化,调用点改为本地调用);
    3. 整体删除 torch_npu/utils/npu_intercept.py
    4. 保持必要行为不变:ScriptModule 修改类操作仍被拒绝(由原生 torch 保证);
      share_memory / bfloat16 在 NPU 上恢复可用;

2. 用例分析

用例 受影响功能 关键要求
NPU 模块调用 model.share_memory() 共享内存 正常执行:返回 self、参数保持 NPU、storage 可共享(与 CUDA no-op 语义一致)
NPU scripted 模块调用 .bfloat16() 精度转换 正常执行,参数 dtype 实际转为 bfloat16
尝试修改已 script 的模块(add_module / register_*) 模块不可变性 仍必须报错(由原生 torch 保证),不得破坏脚本模块一致性
import torch_npu(CANN 检查) 环境/版本校验 迁移后行为不变:路径存在性检查、缺失时 warning/Exception、版本匹配警告文案一致

DFX 要求:可维护性(删除死代码与误导性错误消息、模块职责归位)、兼容性(不改变原生
torch 对 ScriptModule 的保护语义、CANN 检查行为不变)、可测试性(测试改为验证真实行为)。

3. 方案设计

3.1 总体方案(迁移 + 删除范围)

torch_npu/_init/registry/registry_manager.py(迁入 CANN 检查):

  • 新增模块级 import:import osfrom torch_npu.utils.collect_env import get_cann_version
    from torch_npu.utils._error_code import ErrCode, pta_error
  • 新增 cann_pytorch_version_map_cann_package_check() 定义(自 npu_intercept.py
    原样搬迁);
  • _register_npu_backend() 中删除 from torch_npu.utils.npu_intercept import _cann_package_check
    改为直接调用本地 _cann_package_check()
  • 导入顺序已验证安全:torch_npu.__version__torch_npu/__init__.py:44 定义,
    _register_components():52 才调用;registry_manager 顶部已 import torch_npu

torch_npu/utils/unsupport_api.py(整个文件删除):

  • unsupported_Tensor_api = {}(空 dict,包装零个方法,死代码);
  • unsupported_nn_api(6 个条目:share_memory / add_module / bfloat16 /
    register_buffer / register_parameter / register_module)。

torch_npu/utils/npu_intercept.py(整体删除):

  • 拦截机制:_create_wrap_func_is_tensor_npu_supported
    _is_module_parameters_supported_apply_wrap_func_to_modules
    _add_intercept_methods → 删除;
  • CANN 检查:_cann_package_check()cann_pytorch_version_map 及依赖
    ostorch_npuget_cann_versionErrCode/pta_error)→ 迁入
    registry_manager.py

torch_npu/_init/patches/npu_patches.py(删除注册):

  • 删除 apply_npu_intercept_patch 函数(@PatchManager.register_patch("npu") 注册)。

测试更新:

  • test/npu/test_unsupport_api.py:删除 6 项 *_runtimeerror 拦截测试;
    test_Module_share_memory_runtimeerror 改为断言 NPU 上正常执行;
  • test/jit/test_script_module.pyTestScriptModuleShareMemory.test_share_memory_on_npu_raises
    改为断言 NPU 上正常执行;TestScriptModuleMetadata 的 2 项 raise 测试删除。

3.2 技术选型

方案 结论
整机制删除 + CANN 检查迁入 registry_manager(本提案) ✅ 推荐:拦截前提已失效;CANN 检查归位其唯一调用点所在模块,职责内聚,npu_intercept.py 可整体清空
整机制删除 + utils下新增一个cann_package_check.py ❌ 不推荐:没有必要,registry_manager.py为唯一调用
保留 npu_intercept.py 承载 CANN 检查 ❌ 不推荐:模块语义是"API 拦截",承载环境检查属职责错位;文件随拦截删除而失去存在意义

3.3 功能与影响

删除/迁移后:

  • nn.Module.share_memory():返回 self、参数保持 NPU、storage.is_shared()=True
  • ScriptModule.bfloat16():无异常,参数 dtype 实际变为 bfloat16
  • ScriptModule.add_module / register_module:原生 RuntimeError: Cannot re-assign modules in a ScriptModule with non-scripted module...
  • ScriptModule.register_parameter / register_buffer:原生 AttributeError: cannot assign parameter/buffer before Module.__init__() call
  • CPU 模块行为不变;
  • GPU上已验证

性能:删除纯 Python 包装层,无编译/算子开销差异,每次调用省去一层 wrapper(无回退);
CANN 检查无性能影响。

3.4 安全隐私与 DFX

  • 可靠性:ScriptModule 不可变性由原生 torch 保证,不存在绕过保护的风险(GPU 同样拒绝,
    已实测)。
  • 兼容性:拦截错误消息不再出现;依赖该字符串的调用方需适配(见第 5 节)。
  • 可维护性:npu_intercept.py 整体删除,CANN 检查归位 registry 初始化,职责清晰。
  • 可测试性:测试改为断言真实行为(可用 API 正常执行、不可变 API 抛原生错误)。

3.5 编程与调用设计

纯内部删除/迁移,无对外 API 变更:相关函数均为私有(下划线)且 npu_intercept.__all__ = []
torch.nn.Module / ScriptModule 方法签名与调用方式不变。无编程手册变更。

4. 测试设计

4.1 A/B 测试

原有测试:

测试 baseline candidate
test/npu/test_unsupport_api.py 13 passed 7 passed, 6 failed
test/jit/test_script_module.py(ShareMemory/Metadata 类) 11 passed 8 passed, 3 failed

candidate 的 9 项失败全部为原拦截 raise 测试:

  • share_memory / bfloat16:不再抛错(功能可用)——预期行为变更
  • add_module / register_module:原生 RuntimeError(消息不同);
  • register_parameter / register_buffer:原生 AttributeError(类型不同)。

4.2 官方用例对照

官方用例 位置 实测结果
test_module_share_memory@onlyPRIVATEUSE1,NPU ) test/test_torch.py 削减前 PASS / 削减后 FAIL(被拦截抛错)——保留拦截补丁会使官方用例失败,删除后通过
test_share_memory(CPU storage shared 语义) test/test_nn.py 削减后 PASS
test_jit.py 中与3个本修改相关的官方报错( Cannot re-assign ...)测试用例全部通过

4.3 gpu行为一致性验证

检查了torch.nn.Module.share_memory() 以及 ScriptModule调用'add_module/register_buffer/register_parameter/register_module'的行为一致性。

4.4 registry_manager正常运行

5. 缺点和风险

6. 现有技术

  • 上游 PyTorch:nn.Module.share_memory 委托 Tensor.share_memory_(CUDA 为 no-op);
    ScriptModule 在 torch.jit._script 中限制模块变更(原生抛错),与设备无关。
  • 项目自身先例:967ed515b 在 IPC 支持落地后删除 Tensor 层拦截条目,证明"能力支持后
    删除拦截"是既定模式;registry_manager 已集中 backend / distributed / dynamo 注册,
    CANN 检查归位与其设计一致。
likedislike
Zzhounan成员
8月5日 关联了看板:FrameworkPTAdapter 版本issue看板
ascend-robotascend-robot成员
8月5日 添加了label:feature
TorchNPU-BotTorchNPU-Bot成员
8月5日 添加了label:bot-triaged
TorchNPU-Bot
TorchNPU-Bot成员
8月5日 评论:

检测到当前 issue 已关联 PR,自动添加标签:bot-triaged

likedislike
Zzhounan成员
28 天前 修改标题为 “[RFC]: NPU Intercept Patch 可以削减”,原标题为“[Feature]: NPU Intercept Patch 可以削减”
此处折叠了24条事件消息 查看更多
Zzhounan成员
25 天前 issue状态由 TODO 改变为 DONE