Pull Request已成功合入, 合并人@ascend-robot
(感谢 Yhw050920 的贡献)变更摘要
本 PR 面向 Ascend NPU 完成了 torch.autograd.gradcheck 与 torch.autograd.profiler.emit_itt 两个 API 的一致性适配。核心思路是针对 NPU 不支持 float64 某些运算(如 linalg.vector_norm、mm、relu 等)以及缺少 Intel ITT 硬件支持的约束,通过补丁机制分别提供 CPU 回退计算路径和基于 torch_npu.profiler 的替代方案,并在 api_patches.py 中注册补丁使适配逻辑在初始化时自动生效。
主要改动
-
新增
torch_npu/utils/_gradcheck.py并注册补丁:提供了gradcheck_npu/gradgradcheck_npu包装函数,检测到输入含 NPU float64 张量时自动将数据和计算移至 CPU,并将内部_vec_from_tensor替换为在 CPU 上做归一化、再传回 NPU 的_vec_from_tensor_npu实现,通过_apply_gradcheck_patch()同时覆盖torch.autograd.gradcheck/gradgradcheck公共 API 引用。 -
新增
torch_npu/utils/_emit_itt.py并注册补丁:实现了 NPU 适配的emit_itt上下文管理器类,按"原生 ITT →torch_npu.profiler→ no-op 加警告"三级回退策略运行,通过线程局部变量_emit_itt_active强制不可重入,并在api_patches.py中将其直接赋值给torch.autograd.profiler.emit_itt。 -
在
torch_npu/_init/patches/api_patches.py中新增两个补丁函数:apply_gradcheck_patch()和apply_emit_itt_patch(),均通过@PatchManager.register_patch("api")注册,确保 NPU 初始化时自动应用上述适配逻辑。 -
新增测试文件
test/npu/test_gradcheck.py:覆盖gradcheck和gradgradcheck在 NPU 上的 fast/slow 模式、多输入、矩阵乘法、归约、relu、返回元组等 12 个场景,统一使用 float64 张量验证梯度正确性。 -
新增测试文件
test/npu/test_emit_itt.py:覆盖emit_itt的基本上下文管理、enabled=False的 no-op 行为、不可重入性检查、带模型的前向/反向执行、record_shapes=True以及原生 ITT 不可用场景共 6 个用例。


代码审查
Now I am confident in my findings. Let me provide the closing summary.
审查总结
已审查全部 5 个变更文件,结果如下:
| 文件 | 审查结果 |
|---|---|
test/npu/test_emit_itt.py |
无问题 |
test/npu/test_gradcheck.py |
无问题 |
torch_npu/_init/patches/api_patches.py |
无问题 |
torch_npu/utils/_emit_itt.py |
3 个问题(P1 ×1, P2 ×2) |
torch_npu/utils/_gradcheck.py |
1 个问题(P3 ×1) |
按优先级统计:
- P1:1 个 —
_emit_itt_active.active线程局部标志在原生 ITT 初始化失败时泄漏,导致线程中 profiling 永久不可用 - P2:2 个 — NPU fallback 路径过度宽泛地静默吞掉所有异常;
__exit__中原生 ITT 清理抛异常时跳过状态重置 - P3:1 个 —
_gradcheck.py中未使用的import warnings
整体风险判断: 此变更的核心逻辑(gradcheck CPU fallback、emit_itt NPU 适配)设计合理,测试覆盖基本完备。主要风险集中在 _emit_itt.py 的错误处理路径上——线程局部标志的泄漏问题(P1)在生产环境中可能因一次偶然的 ITT 初始化失败导致该线程后续所有 profiling 功能永久失效,建议优先修复。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 1 |
| 🟡 建议 | 3 |
⛔ 需要修改


/approve


Pull Request 已合并或已关闭。
If you want to solve this problem, you can click here to do it in the FAQs.




【合入来源】
关联Issue:
【修改方案】
本 PR 属于 Torch-NPU API 一致性对齐任务,面向 torch.autograd.gradcheck 与 torch.autograd.profiler.emit_itt 完成 v2.7.1 版本的测试用例补齐。
API 功能说明
torch.autograd.gradcheck
gradcheck(func, inputs, *, eps=1e-6, atol=1e-5, rtol=1e-3, ...) -> bool
通过小有限差分计算数值梯度并与分析梯度比较,验证自动微分实现的正确性。是 PyTorch 官方提供的梯度验证工具函数,默认使用 float64 精度以保证数值稳定性。
torch.autograd.profiler.emit_itt
emit_itt(enabled=True, record_shapes=False)
上下文管理器,使每个 autograd 操作发出 ITT 范围标注,用于 Intel VTune Profiler 性能分析。
用例完整性说明
torch.autograd.gradcheck
经检索 PyTorch 官方仓库(v2.7.1),对 test/ 目录执行了检索:
grep -rn "def test.gradcheck" test/test_autograd.py --include=".py"
检索结论:PyTorch 官方已包含 test_gradcheck_single_input 等一系列独立聚焦测试用例。
Ascend NPU 不支持 float64 的 linalg.vector_norm、dot、mm、relu 算子,因此 fast_mode 无法直接在 NPU 上运行。按任务文档场景一规范,在 slow_mode 下对 NPU 支持的 float64 运算编写测试用例,覆盖单输入、多输入、返回元组、二阶梯度等场景。
torch.autograd.profiler.emit_itt
PyTorch 官方在 test/test_autograd.py 中包含 test_profiler_emit_itt 测试用例,带以下装饰器:
@unittest.skipIf(not torch.profiler.itt.is_available(), "ITT is required")
def test_profiler_emit_itt(self, device):
a = torch.tensor([1, 2, 3], dtype=torch.float32, device=device)
with emit_itt():
a.add(1.0)
Ascend NPU 上 torch.profiler.itt.is_available() 返回 False,用例被自动跳过。
检索结论:上游用例在 NPU 上无法直接运行,需通过 test_upstream patch 适配并新增独立测试。
具体修改内容
本 PR 新增 2 个测试文件,修改 1 个 test_upstream patch:test_upstream/test/test_autograd.py.patch:
test/npu/test_gradcheck.py(9 个测试方法)
test/npu/test_emit_itt.py(3 个测试方法)
【资料变更】
不涉及。
torch.autograd.gradcheck、torch.autograd.gradgradcheck、torch.autograd.profiler.emit_itt 在 v2.7.1 版本文档中均已收录,无需补充。
【接口变更】
不涉及。
【功能验证】
测试命令:
python test/npu/test_gradcheck.py -v # Ran 9 tests OK
python test/npu/test_emit_itt.py -v # Ran 3 tests OK
测试截图
【CheckList】
结论
torch.autograd.gradcheck 和 torch.autograd.profiler.emit_itt 在 v2.7.1 版本 NPU 环境下通过测试用例补齐,功能与 PyTorch 官方行为一致。