已合并
fix: route internal-format copy_ to native path and guard NPUStorageDesc access #44450
fix: route internal-format copy_ to native path and guard NPUStorageDesc access #44450
已合并
wuyouqi1创建于 10 天前
wuyouqi1
wuyouqi1成员
10 天前

【合入来源】

如有社区issue,请关联issue链接
请勿携带内部流程信息(需求链接、问题单、内部issue等)

关联 issue:https://gitcode.com/Ascend/pytorch/issues/2629

【修改方案】

前置pr为:https://gitcode.com/Ascend/pytorch/pull/40289 实现了修改点中的第一点。
本pr为以下修改点的第二点和第三点:

一、Ascend950 NZ 序列化 / D2H / 打印支持

  • copy_ 增加 internal_format_opapi: True,内部格式 tensor 进入 op_api 路径;
  • aclnn 格式转换归一化:NZ_C0 变体归一化为 FRACTAL_NZ,≥4 字节类型补 FLOAT16 additionalDtype;
  • 序列化 FORMAT_INFO 增加 NZ_C0 格式名,支持 C0 变体文件兼容加载;
  • 私有格式 tensor 的 __repr__ 补丁:先 .cpu() 触发 d2h + 格式转换再打印。

二、copy_ 内部格式路由修复

aclnnInplaceCopy 按 base format 布局写入,会损坏内部格式存储,在 copy_ 入口按平台分流:

  • A2/A3:任一输入为内部格式时回退原生 copy_(原生路径自行处理格式转换),base format 保持 aclnn 路径;
  • Ascend950:仅支持 device-to-host —— d2h 先 NZ→ND 转换再走 aclnn,h2d/d2d 遇内部格式报错。

实现细节:入口使用 IsOpInputBaseFormat 判断(legacy 加载的 from_blob tensor 视作 base format、不读 desc,legacy load 恢复可用);d2h 分支保留 IsBaseFormatType(legacy 保存命中第三部分拦截并抛异常)。

三、GetNpuStorageImplDesc 异常值拦截

legacy 序列化的 _write_file/_set_from_file 使用 at::from_blob 产生 plain c10::StorageImpl tensor,读取 desc 越界("unknown format type:<垃圾值>")。GetNpuStorageImplDesc 增加动态类型检查(typeid == NPUStorageImpl),不满足时抛清晰异常:legacy 序列化保存 NPU tensor 不支持,请改用新版 zipfile 序列化。

【资料变更】

不涉及

【接口变更】

不涉及

【功能验证】

新增用例

  • test/npu/test_serialization_format.pyTestCopyFormat(A2/A3:6 格式 × h2d/d2h + 6×6 d2d 全组合);TestCopyFormatAscend950(A5:base 对照、NZ d2h 遍历 fp16/bf16/i8/i32、NZ h2d/d2d 断言报错)

修复前 → 修复后

场景 修复前 修复后
A2/A3 内部格式 copy(ND→NZ / NZ→ND / NZ→NZ) FAIL(静默损坏 / CANN 报错) PASS(回退 native)
A5 NZ d2h PASS PASS(NZ→ND cast 后走 aclnn)
A5 NZ h2d / d2d CANN 报错 清晰报错 "not supported on Ascend950"

验证结果

  • A2A3 CI用例验证pass
  • A5运行CI用例结果如下:
# python test_serialization_format.py
s.[W814 10:14:44.341577560 OptionRegister.cpp:95] Warning: Current device only support allow_internal_format=False, the requested value True is invalid and has been reverted to False. (function operator())
...stensor([[-0.1117, -0.4966,  0.1631,  ..., -1.6592, -1.8770,  0.7373],
        [ 0.9258,  0.9248,  0.1825,  ..., -0.5845,  0.9077,  0.4849],
        [-0.2632, -0.5435, -1.6406,  ...,  2.1074, -0.9932,  1.4082],
        ...,
        [-1.2881,  1.3672,  0.1176,  ...,  0.1048, -1.2842,  0.6128],
        [ 1.0059, -0.3564,  0.5537,  ...,  1.5078, -1.5625, -0.9580],
        [-0.2183, -0.9858, -0.8320,  ..., -0.8965, -2.1719, -0.2754]],
       dtype=torch.float16)
tensor([[-0.4004, -2.3750, -0.2139,  ...,  0.6875, -0.4141, -1.8359],
        [-0.2969,  1.0547,  0.0659,  ...,  0.5430, -0.2002,  0.5039],
        [-0.3945, -0.4844, -1.0078,  ...,  1.7266,  0.2930, -0.4062],
        ...,
        [-2.0625,  0.3613, -0.1099,  ..., -0.2109, -0.5664,  0.9922],
        [ 1.1953, -0.7109,  1.3828,  ...,  1.3125, -0.5039,  1.3359],
        [ 0.5430,  0.5625, -0.0708,  ...,  1.0234,  0.5156,  0.2910]],
       dtype=torch.bfloat16)
tensor([[ 1, -1, -1,  ...,  0,  0,  0],
        [ 0,  1,  0,  ...,  0, -1, -1],
        [ 0,  0, -1,  ...,  0,  1,  0],
        ...,
        [ 1,  0,  0,  ...,  1,  0,  0],
        [ 0,  0,  1,  ...,  0, -1,  0],
        [ 0,  1,  0,  ...,  0, -2,  0]], dtype=torch.int8)
tensor([[ 0,  0,  0,  ...,  0,  0,  0],
        [ 0, -1, -1,  ...,  1,  0, -1],
        [ 0,  0,  1,  ...,  0,  0,  1],
        ...,
        [-1,  1, -2,  ..., -2,  0,  0],
        [ 1,  0, -1,  ...,  0,  0,  0],
        [ 0,  0,  2,  ..., -1,  0,  1]], dtype=torch.int32)
.Warning: The current version of the file storing weights is old, and it is relanded due to internal bug of torch and compatibility issue. We will deprecate the loading support for this type of file in the future, please use newer torch to re-store the weight file.
.Warning: The current version of the file storing weights is old, and it is relanded due to internal bug of torch and compatibility issue. We will deprecate the loading support for this type of file in the future, please use newer torch to re-store the weight file.
.
----------------------------------------------------------------------
Ran 9 tests in 59.626s

OK (skipped=2)

【CheckList】

PR提交人对以下CheckList自检项进行全量自检,自检通过或不涉及,均修改 [ ] 为 [x]

likedislike
Pull Request已成功合入, 合并人@ascend-robot
(感谢 wuyouqi1 的贡献)
wuyouqi1wuyouqi1成员
10 天前 创建了 pull request,commit 86f6d913
atomgit-bot
atomgit-bot
10 天前 评论:

变更摘要

此PR是一个编排类(chore)变更,主要针对 NPUNativeOpApiFunctions::copy_ 进行两项调整:一是为 A2/A3 芯片增加回退分支,使其走 native copy_ 路径而非 op_api 路径;二是回退此前 D2H(设备到主机)拷贝场景中的 NZ→ND 格式转换保护,简化拷贝逻辑。此外附带一个测试文件的空白行格式微调。

主要改动

  • A2/A3 回退分支:在 NPUNativeOpApiFunctions::copy_ 入口处新增 c10_npu::IsAclnnOnly() 判断,非纯 ACLNN 模式(A2/A3)直接调用 NPUNativeFunctions::copy_ 回退至 native 实现,仅 A5 继续走 op_api 路径
  • 回退 D2H 格式保护:删除 copy_ 中 D2H 路径的 NZ→ND 格式转换逻辑(原先通过 FormatHelper::IsBaseFormatType 判断并使用 FormatCastHelper::ApplyBaseFormatTensorBy 做显式格式转换),改为直接将原始 src 传入 copy_d2h_baseformat_opapi
  • 测试文件格式微调:在 test/distributed/test_send_recv.py 中新增一个空行,无功能影响
likedislike
atomgit-bot
atomgit-bot
10 天前 评论:

代码审查

✅ 未发现问题

likedislike
ascend-robotascend-robot成员
10 天前 添加了label:ascend-cla/yes
此处折叠了287条消息 查看更多
chujinjin成员
5 天前 评论:

/approve

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

Pull Request 已合并或已关闭。

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

likedislike
ascend-robot
ascend-robot成员
5 天前 评论:
流水线 pytorch_gitcode_PR_multiVersion#14098 [ commitID:5e4a4aa6 ] 已完成
likedislike