已合并
【API一致性任务】test: Add consistency validation cases for torch.QUInt4x2Storage.dtype on NPU (#3536) #44413
luoxiaoyan2024创建于 8月12日
【API一致性任务】test: Add consistency validation cases for torch.QUInt4x2Storage.dtype on NPU (#3536) #44413
已合并
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 5f16af66
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 环境下的一致性。测试覆盖了 dtype 恒为 torch.quint4x2、属于量化 dtype 集合(torch.quint8/torch.qint8/torch.qint32/torch.quint4x2),以及能够与 torch.quint8torch.qint8 明确区分等边界校验,补齐了官方测试套件中针对该存储类 dtype 属性的聚焦一致性用例。

主要改动

  • 新增测试文件 test/test_quint4x2_storage_dtype.py:包含完整的 BSD-3-Clause 许可证头与模块文档字符串,引入 torchTestCaserun_tests 依赖,文件共计新增 83 行。
  • 新增测试类 TestQUInt4x2StorageDtype:继承自 TestCase,作为 torch.QUInt4x2Storage.dtype 一致性验证的测试容器,支持后续按相同模式扩展其他量化存储类(如 QUInt8StorageQInt8Storage)的用例。
  • 新增 test_cpu_quint4x2_storage_dtype 方法:通过 hasattr 守卫检查构建是否包含 QUInt4x2Storage,随后使用 assertIs 校验 dtype 恒为 torch.quint4x2assertIn 验证其属于量化 dtype 集合,并通过 assertIsNot 确保与 torch.quint8torch.qint8 明确区分。
  • 新增 test_npu_quint4x2_storage_dtype 方法:通过 torch.npu.is_available() 守卫仅在 NPU 可用时执行,验证设备无关的类属性 torch.QUInt4x2Storage.dtype 仍为 torch.quint4x2;同时通过 hasattr 守卫检查 NPU 是否已注册 torch.npu.QUInt4x2Storage,若存在则额外校验其类属性 dtype、空存储实例 dtype 及存储大小为 0,确保未来 NPU 暴露该类时可自动扩展校验。
likedislike
不准确?
atomgit-bot
atomgit-bot
8月12日 评论:

代码审查

审查总结

  • 已审查文件test/test_quint4x2_storage_dtype.py

  • 发现问题

    • P2: 1 个(NPU 测试缺少 QUInt4x2Storage 存在性守卫)
    • P1: 0 个
    • P0: 0 个
    • P3: 0 个
  • 整体风险判断:低风险。该文件是一个新增的、自包含的测试用例,逻辑清晰,断言正确。唯一的问题是 NPU 测试方法与 CPU 测试方法之间的防御性守卫不一致——在极端构建配置下可能导致 NPU 测试异常失败而非优雅跳过。修复成本极低(增加两行守卫代码),不影响任何生产逻辑。

类型 数量
🔴 阻塞 0
🟡 建议 1

💬 仅评论

likedislike
不准确?
此处折叠了244条消息 查看更多
luoxiaoyan2024
1 天前 评论:

@chenrayray @li_jing_hw 打扰了:本 PR 已获 /lgtm 与 /approve,CI 流水线已通过,当前唯一阻塞是 2026-08-12 atomgit-bot 的一条内联检视线程(test/test_quint4x2_storage_dtype.py,P2:建议 NPU 用例补 hasattr 守卫)仍为未解决状态。该建议已在此前提交中采纳修复,但本人作为 fork PR 作者无目标仓库 push 权限,Web UI 与 API 均提示无权将该线程标记为解决。麻烦有权限的老师帮忙将该检视线程点「解决」,以便合并,非常感谢!

likedislike
群青世界成员
2 小时前 解决了最后一个问题
ascend-robotascend-robot成员
2 小时前 合入了pull request
ascend-robot
ascend-robot成员
2 小时前 评论:

Pull Request 已合并或已关闭。

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

likedislike
AtlasAccount
AtlasAccount成员
2 小时前 评论:
流水线 pytorch_gitcode_PR_multiVersion#15242 [ commitID:d0ebada6 ] 已完成
likedislike