已合并
test(fx): add NPU test cases for torch.fx.GraphModule APIs [v2.9.0] #39584
test(fx): add NPU test cases for torch.fx.GraphModule APIs [v2.9.0] #39584
已合并
冬阳创建于 6月30日
冬阳
6月30日

【合入来源】

https://gitcode.com/Ascend/pytorch/issues/1856
https://gitcode.com/Ascend/pytorch/issues/2482

Fork: gcw_IDzXRVNw/pytorch_npu
分支: test/fx-graphmodule-api-v2.9.0 → Ascend/pytorch:v2.9.0
关联 Issue: https://gitcode.com/Ascend/pytorch/issues/1856

【修改方案】

本 PR 为用户提供的任务 issue #1856 的交付。社区用例情况:

  • 已在 PyTorch 官方社区 pytorch/test/test_fx.py 下逐一搜索 GraphModule.codeGraphModule.graph 等 API,确认上游不存在针对这些属性的独立测试用例(仅作为辅助断言在其他测试中引用),因此自行编写测试用例。

一、API 功能说明

torch.fx.GraphModule 是 PyTorch FX 框架的核心输出类,将 fx.Graph 转化为可执行的 nn.Module,并通过 Python 代码生成实现 Python-to-Python 变换。本次验证的 10 个 API 均为纯 Python 图操作,与底层计算设备完全解耦:

  • torch.fx.GraphModule:nn.Module 子类,持有 fx.Graph 并自动生成 Python forward 代码,是 FX Python-to-Python 变换的基础
  • torch.fx.GraphModule.__init__:从 Module/dict 根对象和 Graph 构造 GraphModule,自动拷贝图中引用的属性和子模块
  • torch.fx.GraphModule.add_submodule:在指定路径添加子模块,自动创建中间占位 Module
  • torch.fx.GraphModule.code:只读 property,返回从 Graph 生成的 Python 源码字符串
  • torch.fx.GraphModule.delete_all_unused_submodules:遍历 Graph 节点收集引用,删除未使用的子模块
  • torch.fx.GraphModule.delete_submodule:删除指定路径的子模块,路径无效或为非 Module 时返回 False
  • torch.fx.GraphModule.graph:property (getter/setter),获取底层 Graph 或设置新 Graph(setter 自动触发 recompile)
  • torch.fx.GraphModule.print_readable:生成可读的模块源码打印输出
  • torch.fx.GraphModule.recompile:从 Graph 重新编译forward()方法,返回 PythonCode 对象
  • torch.fx.GraphModule.to_folder:将模块导出到文件夹(含 module.py、state_dict.pt、init.py)

上述 API 的实现特征:全部定义在 torch.fx.graph_module.GraphModule 上,torch_npu 未做任何覆盖/重写。所有 API 操作对象为 Python 对象(Graph、Node、Module 层级、字符串),不涉及 Tensor 计算或硬件算子。

二、测试文件 test_fx_graph_module_api.py 用例完备性说明

API 全路径 验证类型 核心测试用例 验证覆盖场景 验证完整性结论
torch.fx.GraphModule 间接验证 通过 test_init_from_moduletest_init_from_dict 验证 1. 类可正常导入和实例化 2. 作为 nn.Module 子类行为正确 通过 init 测试隐式覆盖,验证完全完整
torch.fx.GraphModule.__init__ 直接验证 test_init_from_moduletest_init_from_dicttest_init_sets_class_nametest_init_raises_on_bad_type 1. Module根对象拷贝子模块 2. Dict根对象赋值属性 3. 自定义class_name 4. 非法root类型抛异常 覆盖三种根对象类型+异常路径,验证完全完整
torch.fx.GraphModule.add_submodule 直接验证 test_add_submodule_root_leveltest_add_submodule_nestedtest_add_submodule_overwrite_fails_on_non_module 1. 根级添加 2. 嵌套路径自动创建中间Module 3. 非Module属性阻塞路径返回False 覆盖正常+异常路径,验证完全完整
torch.fx.GraphModule.code 直接验证 test_code_returns_stringtest_code_contains_forwardtest_code_contains_op_namestest_code_consistent_after_recompile 1. 返回值类型 2. 包含forward函数 3. 包含算子名 4. 多次recompile一致性 覆盖类型/内容/一致性,验证完全完整
torch.fx.GraphModule.delete_all_unused_submodules 直接验证 test_delete_all_unused_removes_orphanstest_delete_all_unused_preserves_used 1. 删除孤立模块 2. 保留图中引用的模块 覆盖删除+保留双向验证,验证完全完整
torch.fx.GraphModule.delete_submodule 直接验证 test_delete_submodule_existingtest_delete_submodule_nestedtest_delete_submodule_nonexistenttest_delete_submodule_non_module 1. 删除已存在模块 2. 删除嵌套模块 3. 路径不存在返回False 4. 路径指向非Module返回False 覆盖2正常+2异常路径,验证完全完整
torch.fx.GraphModule.graph 直接验证 test_graph_getter_returns_graphtest_graph_getter_has_nodestest_graph_getter_is_consistenttest_graph_setter_reassigns_graphtest_graph_setter_triggers_recompiletest_graph_setter_forward_workstest_graph_setter_raises_on_non_graphtest_graph_setter_preserves_lint 1. getter返回Graph实例 2. graph含placeholder/output节点 3. 重复访问一致性 4. setter更新内部引用 5. setter触发recompile 6. setter后forward正确 7. 非法类型抛AssertionError 8. lint通过 覆盖getter(3)/setter(5)全部路径,验证完全完整
torch.fx.GraphModule.print_readable 直接验证 test_print_readable_returns_stringtest_print_readable_contains_child_code 1. 返回字符串含class/forward 2. 包含子GraphModule代码 覆盖输出格式+嵌套场景,验证完全完整
torch.fx.GraphModule.recompile 直接验证 test_recompile_returns_python_codetest_recompile_preserves_forward 1. 返回PythonCode对象 2. recompile后forward计算结果不变 覆盖返回类型+功能正确性,验证完全完整
torch.fx.GraphModule.to_folder 直接验证 test_to_folder_creates_filestest_to_folder_module_file_content 1. 创建module.py和__init__.py 2. 生成文件为合法Python 覆盖文件生成+内容验证,验证完全完整

【结论】所有用例覆盖 API 的基础功能、异常行为、接口存在性、以及 NPU 设备场景,34 个测试用例完整覆盖昇腾 NPU 适配所需的最小功能集。

三、昇腾 NPU 适配说明

本次 GraphModule 相关 API 在昇腾 NPU 上的验证采用如下方式,符合硬件适配要求:

  • 所有 10 个 API 均为纯 Python 框架层图操作(操作 Graph/Node/Module 层级对象和字符串),与底层 CPU/GPU/NPU 计算硬件完全解耦,无需任何 NPU 特定代码适配
  • 测试文件包含专用 TestFxGraphModuleOnNpu 类(3 个测试用例),显式将模块和张量迁移到 NPU 设备(npu:0),验证在真实 NPU 环境下 codegraphrecompileforward 全部正常工作
  • torch_npu 未对任何 GraphModule API 进行覆盖/重写,所有 API 行为与 PyTorch 上游完全一致

【结论】本测试文件的设计合理,可充分保证 GraphModule 在昇腾 NPU 环境下的功能正确性与可用性。

【资料变更】

文档变更已在 v2.7.1 分支的 PR 中合入,本 PR 仅提交测试文件。

【接口变更】

不涉及

【功能验证】

  • 测试文件路径:test/fx/test_fx_graph_module_api.py
  • 测试环境:torch 2.7.1+cpu + torch_npu 2.7.1.post4 + NPU 910B3 + CANN 8.5.0
  • 本地验证结果(完整运行日志):
root@hostname:/tmp# python test/fx/test_fx_graph_module_api.py -v
test_code_consistent_after_recompile ... ok
test_code_contains_forward ... ok
test_code_contains_op_names ... ok
test_code_returns_string ... ok
test_graph_getter_has_nodes ... ok
test_graph_getter_is_consistent ... ok
test_graph_getter_returns_graph ... ok
test_graph_setter_forward_works ... ok
test_graph_setter_preserves_lint ... ok
test_graph_setter_raises_on_non_graph ... ok
test_graph_setter_reassigns_graph ... ok
test_graph_setter_triggers_recompile ... ok
test_init_from_dict ... ok
test_init_from_module ... ok
test_init_raises_on_bad_type ... ok
test_init_sets_class_name ... ok
test_code_and_graph_on_npu ... ok
test_forward_on_npu ... ok
test_recompile_on_npu ... ok
test_print_readable_contains_child_code ... ok
test_print_readable_returns_string ... ok
test_recompile_preserves_forward ... ok
test_recompile_returns_python_code ... ok
test_add_submodule_nested ... ok
test_add_submodule_overwrite_fails_on_non_module ... ok
test_add_submodule_root_level ... ok
test_delete_all_unused_preserves_used ... ok
test_delete_all_unused_removes_orphans ... ok
test_delete_submodule_existing ... ok
test_delete_submodule_nested ... ok
test_delete_submodule_non_module ... ok
test_delete_submodule_nonexistent ... ok
test_to_folder_creates_files ... ok
test_to_folder_module_file_content ... ok

----------------------------------------------------------------------
Ran 34 tests in 2.316s
OK

【结论】执行测试用例后,34 passed,所有测试用例在 NPU 环境下执行通过。GraphModule 核心 API 在 NPU 上验证正确。

【CheckList】

likedislike
Pull Request已成功合入, 合并人@ascend-robot
(感谢 冬阳 的贡献)
冬阳
6月30日 创建了 pull request,commit d4a566ac
冬阳
6月30日 关联了issue:【Ascend for PyTorch训练营 API一致性任务】补齐测试用例、API功能对齐、补齐文档(4),torch.fx.GraphModule API 补齐 — 分析报告
ascend-robotascend-robot成员
6月30日 添加了label:ascend-cla/yes
ascend-robot
ascend-robot成员
6月30日 评论:

CLA Signature Pass

gcw_IDzXRVNw, thanks for your pull request. All authors of the commits have signed the CLA. 👍

likedislike
此处折叠了89条消息 查看更多
ascend-robotascend-robot成员
7月2日 删除了label:ci-pipeline-running
ascend-robotascend-robot成员
7月2日 添加了label:ci-pipeline-passed
ascend-robot
ascend-robot成员
7月2日 评论:
流水线 PR-pipeline_pytorch#40644 [ commitID:9a9ccdce ] 已完成
>>>代码风格自动修复执行成功(无修复内容)
阶段 任务名 状态 详情
编译构建 Build_X86 >>>
Build_ARM >>>
Build_LibTorch_x86 >>>
Build_LibTorch_ARM >>>
Build_X86_torchair 🛑 >>>
Build_ARM_torchair 🛑 >>>
patch_test 🛑 >>>
恶意代码检查 Antipoison >>>
编码安全与规范检查 CodeCheck >>>
check_error >>>
CodeCheck_lintrunner >>>
开源片段检查 SCA >>>
开发者测试 UT_X86_Part_01 🛑 >>>
UT_X86_Part_02 🛑 >>>
UT_ARM_A3_Part_01 🛑 >>>
UT_ARM_A3_Part_02 🛑 >>>
UT_ARM_A2_Part_01 >>>
UT_ARM_A2_Part_02 >>>
UT_ARM_A2_Part_03 >>>
UT_inductor_Part_01 🛑 >>>
UT_inductor_Part_02 🛑 >>>
UT_inductor_Part_03 🛑 >>>
UT_inductor_Part_04 🛑 >>>
UT_DIST_ARM_Part_01 🛑 >>>
UT_DIST_ARM_Part_02 🛑 >>>
UT_DIST_ARM_Part_03 🛑 >>>
UT_DIST_ARM_Part_04 🛑 >>>
UT_ARM_A2_Select_Part_01 >>>
UT_ARM_A2_Select_Part_02 >>>
流水线 PR-pipeline_pytorch >>>
此流水线已支持下列评论快捷指令,仅PR创建者和白名单成员[wujinyuan1, huangjingwei, liangsongwei, yashi999, culechan, Dring, wuyouqi1, L1919_snow, qq_52711437, WhiteNight12, nomiz, xiu_21, ffmh, wanglijun55, hss-shuai, husichao, smallsilly, lanshaozuishuai, jimmyisme1, lzy0920232, alpha-junh, Sunshine_Youngster, wei_zhuoyi, zhangyihuiben, zyw-hw, zzzkeke, rmch, yangch0324, LucciC, AACAES, renyujin, wjlflyer, senzhen-town, pengjingyou, qsc97, limuan, yule100, xiaoqi-zhou, kuhn7, chenxingying, hanye02, zichun_ye, anyrenwei, kkjocker, wangzili121, Lu_G, yvjc, puddingfjz, HandsoemLemon, bigprestigee1, huawuyi, zhenyu10, dairenjie, du-jin-hang, zou-jieyu, adelaideliu, TrHan, wanlinan, Windwindzzz, pengqihw, kisnwang, yuheng_wang, honghao_wang, jizewei, zhangguoguang, sunyu-xuan, chenrayray, hbhu_bin, liujunzhu, c_34, LiNuoh, maoyuanpeng1, zzhongmin, zhaoyu65, bellatan, jiabaolin, zhuofanshen, wencaiwen, lu_zhuge, caoshuyang, molly12, lyx324521, LQ1206, gitcode-chenjiao, cai-weiwei1989, CHDong, ogqin, yuanlipingGit, xuqinglin1, lqz2, zouwei1, chaoluoa, paradox325, jackzhang1116, yaoyao, akh, yujiacheng, dengjie0116, Hubert11111, Shine_Ws, wslhj555, longqiand, OYtao666, JiaqingQiang, luyyyy, Kingbelial, zhanghaiyu0101, wenxp1018, yanliu-luoluo, ksun_sekiro, liyong328, wgzheng, tangky, vivi_is_coding, aoiaoisola, weixin_44494597, wangmengmengwang65667, hid57809721, qq_35468730, comeonup, C547032, gcw_m5OQChA4, yao_yao_ling_xian, cnnbwcy, szqfes_12, cora_19, cann_lilin, can, shawnylee233]评论有效
  • compile、compile_inductor、compile_torchair : 运行流水线
  • retry : 重试流水线所有失败子任务
  • retry <任务名> : 仅重试指定失败子任务
  • stop : 停止流水线
likedislike
ascend-robotascend-robot成员
7月2日 合入了pull request
ascend-robot
ascend-robot成员
7月2日 评论:
流水线 pytorch_gitcode_PR_multiVersion#11714 [ commitID:9a9ccdce ] 已完成
likedislike