已合并
【API一致性任务】test: Add consistency validation cases for torch.QUInt4x2Storage.dtype on NPU (#3536) #44412
luoxiaoyan2024创建于 8月12日
【API一致性任务】test: Add consistency validation cases for torch.QUInt4x2Storage.dtype on NPU (#3536) #44412
已合并
luoxiaoyan2024创建于 8月12日
8月12日

欢迎加入社区,感谢您对社区的贡献 🎉!

torch.QUInt4x2Storage.dtype 一致性验证用例 说明

关联 issue:https://gitcode.com/Ascend/pytorch/issues/3536
提交分支:api-3536-v2.7.1(目标 base:v2.7.1)
改动文件:test/test_quint4x2_storage_dtype.py(新增,96 行)

环境信息

验证在 Ascend 910B3 NPU 服务器的 CANN 8.5.1 容器中进行,torch_npu 分别安装于 PyTorch 2.7.1 / 2.11.0 / 2.12.0 三个版本;并按社区最新验收要求在 Ascend 950PR(CANN 9.1.0)环境补充验证(见「运行验证(Ascend 950PR)」);终端运行截图见文末「运行验证」说明与本地交付物。

使用场景及问题

来源任务:https://gitcode.com/Ascend/pytorch/issues/3536

对应 API:torch.QUInt4x2Storage.dtype

torch.quint4x2 是 4-bit 无符号整数量化数据类型(每字节打包 2 个元素),其底层连续存储由 torch.QUInt4x2Storage 承载。API 一致性验收要求该存储类的 dtype 类属性稳定返回 torch.quint4x2,且需在 NPU 环境下验证其取值与 CPU 一致(设备无关)。官方未对该属性建立聚焦的一致性断言,因此需在 test/ 补齐自包含用例。

API 功能

torch.QUInt4x2Storage 是支撑量化数据类型 torch.quint4x2 的底层存储类(Storage)。quint4x2 表示每个元素 4 bit、每字节打包 2 个元素的无符号整数量化类型;QUInt4x2Storage 负责以字节数组形式承载这类量化张量的连续存储。

torch.QUInt4x2Storage.dtype 是该存储类的类级只读属性,返回该存储所承载的量化数据类型,取值恒为 torch.quint4x2。该属性特性:

  • 无入参、只读:不可通过赋值修改;返回值是数据类型对象 torch.quint4x2 自身(identity 一致,is 比较为真)。
  • 设备无关:CPU 与 NPU 环境下取值一致,不随加速器变化。
  • 类 / 实例均可访问:既可通过类 torch.QUInt4x2Storage.dtype 访问,也可通过实例 torch.QUInt4x2Storage().dtype 访问,二者取值相同。

PyTorch 官方用例及完整性

在 PyTorch 官方 test/ 目录中检索(master / v2.7.1 / v2.11.0 / v2.12.0),QUInt4x2Storage / quint4x2 仅在量化相关用例中作为被量化张量的底层存储被间接触及,没有针对 storage.dtype 取值与量化 dtype 集合归属的聚焦一致性断言:

test/test_quantization.py / test/test_type_promotion.py :quint4x2 仅在量化流程中被引用
test/ :0 处独立断言 QUInt4x2Storage.dtype is torch.quint4x2

因此,社区对 QUInt4x2Storage.dtype 的「取值正确性 + 量化 dtype 归属 + 边界区分」覆盖不充分,需新增自包含一致性用例。

NPU 适配分析(含分类判定)

QUInt4x2Storage.dtype 是设备无关的类级只读属性,其取值不依赖任何 NPU kernel 或设备特定代码路径;当前 NPU 未单独注册 torch.npu.QUInt4x2Storage 类(curated NPU storage 列表仅覆盖数值 / bool / bfloat16 类存储),昇腾环境导入 torch_npu 后其行为与 CPU 完全一致。本接口无需修改 TorchNPU 实现、无需 NPU 适配 patch。

因此,本 API 归类为 1.2②:PyTorch 官方社区用例覆盖不充分,且涉及硬件相关存储类接口 → 在 test/ 目录新增一致性验证用例补齐(非修改源码 patch)

新增用例设计(功能一致标准覆盖)

新增 test/test_quint4x2_storage_dtype.py,按 API 功能一致标准以等价类 / 边界值覆盖(无数值计算、无入参):

  • 取值正确性torch.QUInt4x2Storage.dtype is torch.quint4x2;且与空存储实例 .dtype 一致。
  • 量化 dtype 集合归属assertIn{quint8, qint8, qint32, quint4x2}
  • 边界区分assertIsNotquint8 / qint8,避免与相邻量化 dtype 混淆。
  • 设备无关一致性:CPU 与 NPU 环境取值一致(torch.npu.is_available() 守卫);若 NPU 注册 torch.npu.QUInt4x2Storage 额外校验其 .dtype.size()

两个用例 test_cpu_quint4x2_storage_dtype / test_npu_quint4x2_storage_dtype 均带 hasattr 守卫,缺失该存储类的构建会优雅跳过而非报错。

运行验证

验证环境:

操作系统:Ubuntu 22.04.5 LTS
系统架构:aarch64
昇腾硬件:Ascend 910B3,8 卡,Health 为 OK
npu-smi:24.1.0
CANN:8.5.1
Python:3.10(torch_2.7.1 / torch_2.11.0 / torch_2.12.0 验证环境)

在 NPU 环境实跑 python test/test_quint4x2_storage_dtype.py -v,三个版本(2.7.1 / 2.11.0 / 2.12.0)均 Ran 2 tests ... OK,CPU 用例与 NPU 守卫用例实际执行(非跳过)

PyTorch torch-npu 检查项 失败 错误 结果
2.7.1+cpu 2.7.1.post8 2 用例(CPU + NPU 守卫) 0 0 PASS
2.11.0+cu130 2.11.0 2 用例(CPU + NPU 守卫) 0 0 PASS
2.12.0+cu130 2.12.0 2 用例(CPU + NPU 守卫) 0 0 PASS

三个版本(2.7.1 / 2.11.0 / 2.12.0)终端输出一致,完整日志如下:

========== torch 2.7.1 (torch.QUInt4x2Storage.dtype) ==========
$ /root/miniconda3/envs/torch_2.7.1/bin/python /tmp/test_quint4x2_storage_dtype.py -v   # torch 2.7.1+cpu / torch_npu 2.7.1.post8
test_cpu_quint4x2_storage_dtype (__main__.TestQUInt4x2StorageDtype) ... /tmp/test_quint4x2_storage_dtype.py:51: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly.  To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage()
  self.assertIs(torch.QUInt4x2Storage.dtype, torch.quint4x2)
ok
test_npu_quint4x2_storage_dtype (__main__.TestQUInt4x2StorageDtype) ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.028s

OK

========== torch 2.11.0 (torch.QUInt4x2Storage.dtype) ==========
$ /root/miniconda3/envs/torch_2.11.0/bin/python /tmp/test_quint4x2_storage_dtype.py -v   # torch 2.11.0+cu130 / torch_npu 2.11.0
test_cpu_quint4x2_storage_dtype (__main__.TestQUInt4x2StorageDtype) ... /tmp/test_quint4x2_storage_dtype.py:51: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly.  To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage()
  self.assertIs(torch.QUInt4x2Storage.dtype, torch.quint4x2)
ok
test_npu_quint4x2_storage_dtype (__main__.TestQUInt4x2StorageDtype) ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.026s

OK

========== torch 2.12.0 (torch.QUInt4x2Storage.dtype) ==========
$ /root/miniconda3/envs/torch_2.12.0/bin/python /tmp/test_quint4x2_storage_dtype.py -v   # torch 2.12.0+cu130 / torch_npu 2.12.0
W0819 01:32:34.165000 32618 root/miniconda3/envs/torch_2.12.0/lib/python3.10/site-packages/torch/_native/cutedsl_utils.py:55] CuTeDSL operators require optional Python packages `nvidia-cutlass-dsl` and `apache-tvm-ffi`; missing optional dependency `nvidia_cutlass_dsl` (importlib.util.find_spec(nvidia_cutlass_dsl) failed)
test_cpu_quint4x2_storage_dtype (__main__.TestQUInt4x2StorageDtype) ... /tmp/test_quint4x2_storage_dtype.py:51: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly.  To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage()
  self.assertIs(torch.QUInt4x2Storage.dtype, torch.quint4x2)
ok
test_npu_quint4x2_storage_dtype (__main__.TestQUInt4x2StorageDtype) ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.284s

OK

verify_quint4x2_all.png

运行验证(Ascend 950PR 补充验证)

按社区最新验收要求,另在 Ascend 950PR 环境实跑同一用例文件 test/test_quint4x2_storage_dtype.py 取证(该环境当前安装 torch_npu 2.12.0;.dtype 为设备无关类属性,跨版本行为一致):

操作系统:Ubuntu 22.04.5 LTS
系统架构:x86_64
昇腾硬件:Ascend 950PR,1 卡,HBM 128G,Health 为 OK
npu-smi:25.7.rc1.6
CANN:9.1.0
Python:3.10.12
torch / torch_npu:2.12.0+cu130 / 2.12.0

实跑结果:Ran 2 tests ... OK,CPU 用例与 NPU 用例实际执行(非跳过)

环境 torch torch-npu 检查项 失败 错误 结果
Ascend 950PR 2.12.0+cu130 2.12.0 2 用例(CPU + NPU) 0 0 PASS
$ python3 test_quint4x2_storage_dtype.py -v   # 950PR: Ascend950PR / CANN 9.1.0, torch 2.12.0+cu130 / torch_npu 2.12.0
test_cpu_quint4x2_storage_dtype (__main__.TestQUInt4x2StorageDtype) ... /tmp/q4x2_950pr/test_quint4x2_storage_dtype.py:51: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly.  To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage()
  self.assertIs(torch.QUInt4x2Storage.dtype, torch.quint4x2)
ok
test_npu_quint4x2_storage_dtype (__main__.TestQUInt4x2StorageDtype) ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.003s

OK

verify_quint4x2_950pr.png

950PR 验证结论与 910B3 三版本一致:torch.QUInt4x2Storage.dtype 在两种昇腾硬件(910B3 / 950PR)与 CANN 8.5.1 / 9.1.0 下取值均为 torch.quint4x2,设备无关性成立。

资料检查

torch.QUInt4x2Storage 为标准量化 storage 类、非私有接口、非缺失 API,依 §2 不纳入 native_apis 资料补齐;其所属量化模块在资料中已有收录。本次新增一致性用例不改变支持状态,无需提交资料 PR。

结论

检查项 结论
TorchNPU 环境可验证目标 API(.dtype 取值一致)
接口行为在 NPU 上与 CPU 一致(设备无关)
PyTorch 官方有聚焦 / 完整的 .dtype 一致性用例
需要修改 TorchNPU API 实现
需要新增 NPU 适配 patch
需要在 test/ 新增一致性验证用例
需要补充正式资料

欢迎加入社区,感谢您对社区的贡献 🎉!

likedislike
Pull Request已成功合入, 合并人@ascend-robot
(感谢 luoxiaoyan2024 的贡献)
Lluoxiaoyan2024
8月12日 创建了 pull request,commit c3bd4964
Lluoxiaoyan2024
8月12日 关联了issue:【社区任务】7月社区任务第四期-Ascend for PyTorch API 一致性开发(54)
atomgit-bot
atomgit-bot
8月12日 评论:

变更摘要

本 PR 新增测试文件 test/test_quint4x2_storage_dtype.py,为 torch.QUInt4x2Storage.dtype 属性补充一致性验证用例。该用例分别在 CPU 和 NPU 环境下校验 QUInt4x2Storagedtype 恒为 torch.quint4x2,并确认其属于量化 dtype 集合(quint8/qint8/qint32/quint4x2)且能与 quint8qint8 明确区分,旨在解决 #3536 中 NPU 端该属性缺少聚焦测试覆盖的问题。

主要改动

  • 新增 TestQUInt4x2StorageDtype 测试类:继承自 torch.testing._internal.common_utils.TestCase,作为 QUInt4x2Storage.dtype 一致性测试的容器。
  • 新增 test_cpu_quint4x2_storage_dtype 用例:通过 hasattr 守卫检查 QUInt4x2Storage 是否存在,随后使用 assertIs 确认 dtypetorch.quint4x2,使用 assertIn 验证其属于已知量化 dtype 集合,并使用 assertIsNottorch.quint8torch.qint8 做边界区分。
  • 新增 test_npu_quint4x2_storage_dtype 用例:通过 torch.npu.is_available() 守卫 NPU 环境,核心校验设备无关的 torch.QUInt4x2Storage.dtype 仍为 torch.quint4x2;同时以 hasattr(torch.npu, "QUInt4x2Storage") 条件守卫,在 NPU 未来注册该存储类后自动扩展校验其类属性 dtype 及空实例的 dtypesize()
  • 新增模块级文档字符串:说明了测试目的、NPU 当前未注册 torch.npu.QUInt4x2Storage 的背景,以及按相同模式扩展到其他量化存储类(如 QUInt8StorageQInt8Storage)的扩展方向。
  • 使用 assertIs / assertIsNot 进行精确身份断言:在对 dtype 属性做等值判断时采用身份比较而非值比较,确保返回的是同一个 torch.dtype 单例对象。
likedislike
不准确?
atomgit-bot
atomgit-bot
8月12日 评论:

代码审查

✅ 未发现问题

likedislike
不准确?
此处折叠了244条消息 查看更多
AtlasAccountAtlasAccount成员
1 天前 删除了label:ci-pipeline-running
AtlasAccountAtlasAccount成员
1 天前 添加了label:ci-pipeline-passed
AtlasAccount
AtlasAccount成员
1 天前 评论:
流水线 PR-pipeline_pytorch#67354 [ commitID:9a3b0981 ] 已完成
>>>代码风格自动修复执行成功(无修复内容)
阶段 任务名 状态 详情
编译构建 Build_X86 ✅ COMPLETED >>>
Build_ARM ✅ COMPLETED >>>
Build_X86_torchair ⚪ IGNORED >>>
Build_ARM_torchair ⚪ IGNORED >>>
patch_test ⚪ IGNORED >>>
Build_X86_213 ⚪ IGNORED >>>
Build_ARM_213 ⚪ IGNORED >>>
恶意代码检查 Antipoison ✅ COMPLETED >>>
编码安全与规范检查 codecheck_pre-commit ✅ COMPLETED >>>
check_error ✅ COMPLETED >>>
lintrunner ✅ COMPLETED >>>
开源片段检查 SCA ✅ COMPLETED >>>
开发者测试 UT_ARM_A3_Part_01 ⚪ IGNORED >>>
UT_ARM_A3_Part_02 ⚪ IGNORED >>>
UT_ARM_A2_Part_01 ✅ COMPLETED >>>
UT_ARM_A2_Part_02 ✅ COMPLETED >>>
UT_ARM_A2_Part_03 ✅ COMPLETED >>>
UT_inductor_Part_01 ⚪ IGNORED >>>
UT_inductor_Part_02 ⚪ IGNORED >>>
UT_inductor_Part_03 ⚪ IGNORED >>>
UT_inductor_Part_04 ⚪ IGNORED >>>
UT_DIST_ARM_Part_01 ⚪ IGNORED >>>
UT_DIST_ARM_Part_02 ⚪ IGNORED >>>
UT_DIST_ARM_Part_03 ⚪ IGNORED >>>
UT_DIST_ARM_Part_04 ⚪ IGNORED >>>
UT_ARM_A2_Select_Part_01 ⚪ IGNORED >>>
UT_ARM_A2_Select_Part_02 ⚪ IGNORED >>>
UT_inductor_Part_213 ⚪ IGNORED >>>
流水线 PR-pipeline_pytorch ✅ COMPLETED >>>
此流水线已支持下列评论快捷指令,仅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, fanglanyue0916, hhz0, LiNuohang, taohuoquan, Jesse, WSs_321, SCh_zx]评论有效
  • compile、compile_inductor、compile_torchair : 运行流水线
  • retry : 重试流水线所有失败子任务
  • retry <任务名> : 仅重试指定失败子任务
  • stop : 停止流水线
likedislike
ascend-robotascend-robot成员
1 天前 合入了pull request
AtlasAccount
AtlasAccount成员
1 天前 评论:
流水线 pytorch_gitcode_PR_multiVersion#15199 [ commitID:9a3b0981 ] 已完成
likedislike