AMCT amct_ops 自定义算子测试实战:从 ops_build.sh 构建到 HiFloat8/HiFloat4 cast 的 NPU 硬件验证
2026/9/18 2:44:27 网站建设 项目流程

AMCT amct_ops 自定义算子测试实战:从 ops_build.sh 构建到 HiFloat8/HiFloat4 cast 的 NPU 硬件验证

【免费下载链接】amctAMCT是CANN提供的昇腾AI处理器亲和的模型压缩工具仓。项目地址: https://gitcode.com/cann/amct

本文讲解 AMCT 仓库中tests/amct_ops测试套件的完整运行方法:如何用 ops_build.sh 编译 HiFloat4/HiFloat8 cast 与 SVDQuant 等 NPU 算子、以 staging 目录或 wheel 两种方式运行对应 unittest,以及使用 HiFloat8 dtype 冒烟脚本对原生 cast 与amct_opsfallback 路径做确定性硬件验证。读完后你可以独立在昇腾 NPU 机器上完成「构建算子 → 跑测试 → 判定硬件路径是否真正可用」的完整闭环,并理解每个测试背后的验证契约(round-trip 精度、shape/dtype/device 不变量、退出码语义)。

一、前置条件:先构建 amct_ops 算子包

tests/amct_ops中的所有测试都依赖已编译的amct_opsPython 包和算子.so文件,执行测试前必须先构建amct_ops。构建统一由 ops_build.sh 完成:

bash amct_ops/ops_build.sh [<op_name>] # 构建全部算子(默认 ascend910b / A2) bash amct_ops/ops_build.sh hifloat8_cast # 仅构建 hifloat8_cast bash amct_ops/ops_build.sh --soc ascend950 svd_quant # 指定 SOC + 指定算子

从脚本实现看,构建流程分为四步:加载 CANN 环境(要求ASCEND_HOME_PATH已设置)、按 SOC 编译各算子、把各算子的 Python 包与.so汇集到amct_ops/staging/目录、最后用pip wheel打包出dist/amct_ops-*.whl。其中两个关键细节直接影响测试环境:

  1. SOC 到 NPU 架构的映射:脚本支持三种 SOC,默认值为ascend910b(见 ops_build.sh#L61):

    --soc取值硬件NPU_ARCH说明
    ascend910b(默认)Ascend A2(910B1/B2/B3)dav-2201对应 x86 下的 A2 机型
    ascend910_93Ascend A3(910B4)dav-2201与 A2 共用 ISA,UB 大小由运行时平台 API 区分
    ascend950Ascend A5dav-3510dav-3510 指令集

    同时脚本按主机 CPU 架构选择 CANN 包目录:x86_64/amd64映射到x86_64-linuxaarch64/arm64映射到aarch64-linux,其他架构直接报错退出。

  2. SVDQuant 的平台约束svd_quant算子只在ascend950上构建——脚本中若目标 SOC 不是ascend950,会打印'svd_quant' operator builds for ascend950 socket only并将其加入跳过列表(见 ops_build.sh#L123-L128)。这意味着在 A2 机器上构建全量算子时,staging 中不会出现svd_quant子包,对应的test_svd_quant也就无法运行。

staging 目录的结构是「一个算子一个子包」:脚本把<op>/python/<pkg>/下的*.py<op>/build/下编译出的*.so一起拷贝到staging/amct_ops/<pkg>/,并以 ops_init.py 作为包入口__init__.py。按 ops_init.py 的文档,包内可用的子模块包括:

  • amct_ops.hifloat8_castencode_to_hifloat8(x)(FP16/BF16 → uint8)与decode_from_hifloat8(x, dtype=bfloat16)(uint8 → FP16/BF16),也可通过torch.ops.amct.encode_to_hifloat8/torch.ops.amct.decode_from_hifloat8访问;
  • amct_ops.hifloat4_casthifloat4_fake_quant(x, qdim=-1),在 NPU 上做 FP16/BF16 → HiFloat4 → FP16/BF16 的 fake-quant 往返,其中 HiFloat4 是 4-bit 块标度浮点,每 64 个元素共享一组 3 级 scale,qdim指定的维度长度必须是 64 的倍数,否则算子抛RuntimeError(见 hifloat4_cast/ops.py)。

二、方式一:使用 staging 运行(推荐开发使用)

开发调试阶段推荐直接指向 staging 目录运行,避免反复安装 wheel。在仓库根目录下执行:

bash amct_ops/ops_build.sh <op_name> PYTHONPATH=amct_ops/staging python3 -m unittest <test_module>

其中<op_name>amct_ops下的算子目录名(如hifloat8_casthifloat4_castsvd_quant),<test_module>tests.amct_ops下的 unittest 模块名,例如tests.amct_ops.test_hifloat8_cast

如果算子需要特定 SOC 或其他构建参数,按算子 README 或ops_build.sh --help补充对应参数。SVDQuant 由于仅支持ascend950,运行方式为:

bash amct_ops/ops_build.sh --soc ascend950 svd_quant PYTHONPATH=amct_ops/staging python3 -m unittest tests.amct_ops.test_svd_quant

注意 staging 模式下PYTHONPATH=amct_ops/staging这一行环境变量不能省略——unittest 中from amct_ops.hifloat8_cast import ...的导入正是通过这个路径命中的;而tests.amct_ops.test_*的模块名则要求从仓库根目录启动python3 -m unittest,使tests包可被导入(test_svd_quant.py内部通过from .quantize_ref import ...做相对导入,test_svd_quant.py#L16-L17)。

三、方式二:安装 wheel 后运行

需要长期验证或跨目录使用时,可将构建产物安装为正式 wheel:

bash amct_ops/ops_build.sh <op_name> pip install amct_ops/dist/amct_ops-*.whl python3 -m unittest <test_module>

SVDQuant 的 wheel 安装示例:

bash amct_ops/ops_build.sh --soc ascend950 svd_quant pip install amct_ops/dist/amct_ops-*.whl python3 -m unittest tests.amct_ops.test_svd_quant

安装 wheel 后无需再设置PYTHONPATHamct_ops作为已安装包直接可导入。两种方式在验证对象上没有差别,差别仅在于算子代码的加载位置(staging 源码目录 vs site-packages)。

四、测试环境要求与典型测试内容

运行测试前需满足以下环境要求:

  • 已 source CANN 环境变量,例如$ASCEND_HOME_PATH/set_env.sh(构建脚本本身也依赖该变量,未设置会直接报错退出,见 ops_build.sh#L104-L113);
  • 当前环境可用torchtorch_npu
  • 当前机器可访问 NPU,测试会调用torch.npu.set_device(0)绑定 0 号设备;
  • 特定算子可能有额外依赖或平台约束,例如test_svd_quant依赖已构建或已安装的 SVDQuant 自定义算子,且当前构建脚本仅在ascend950SOC 上构建该算子。

从测试代码看,各 unittest 模块验证的重点各有不同:

  • test_hifloat8_cast.py:验证encode_to_hifloat8/decode_from_hifloat8的 dtype 契约(输入仅接受 FP16/BF16,编码输出为 uint8,解码默认回到 bfloat16 且可指定 float16)、基础与随机的 round-trip 相等性、边界值(0.001、0.01、±1、±100 等十余个定点)的误差,以及特殊值编码表(+Inf→0x6F、-Inf→0xEF、NaN→0x80 等,见 test_hifloat8_cast.py#L24-L30)。
  • test_hifloat4_cast.py:将 NPU 上的hifloat4_fake_quant内核与纯 torch 的 CPU 参考实现hifloat4_fake_quant(来自 amct_pytorch/quantization/dtypes/hifp_impl.py)做逐元素对比,容差 1e-6;另含零输入块、非对齐维度抛错、以及 NaN/Inf 块「整块污染为 NaN 且后续 kernel 发射仍正常」的设备健康度回归测试。无 NPU 时该类整体跳过(@unittest.skipUnless(_npu_available(), ...))。
  • test_svd_quant.py:使用纯 PyTorch 的 MX4 量化参考 quantize_ref.py(实现 E2M1 组共享指数量化与反量化,含py_quantize_mx4/py_dequantize_mx4两个 oracle 函数),针对 Prefill/Decode、Rank 32/64/128 组合的大批量矩阵形状用例,验证 SVDQuant 自定义算子的量化结果与参考实现一致。

五、HiFloat8 dtype 冒烟验证

除 unittest 外,run_hifloat8_dtype_smoke.py 提供了一条针对 dtype 层的冒烟验证路径:用固定种子的 FP16/BF16 输入(覆盖零值、正负值、幂次值、边界值如 ±32768 与torch.finfo(dtype).tiny,外加 16 个 seed=2026 的随机数),对以下三条路径做 round-trip 验证:

  1. torch_npu 的原生 HiFloat8 cast;
  2. amct_opshifloat8_castfallback;
  3. 「原生优先、原生失败自动切换 amct_ops」的自动路由(对应 run_hifloat8_dtype_smoke.py#L103-L120 中_run_backend的 auto 分支)。

三种后端的运行命令:

# 仅验证 torch_npu 原生 HiFloat8 cast python3 tests/amct_ops/run_hifloat8_dtype_smoke.py --backend native # 仅验证 amct_ops hifloat8_cast PYTHONPATH=amct_ops/staging \ python3 tests/amct_ops/run_hifloat8_dtype_smoke.py --backend amct_ops # 原生优先,失败时自动尝试 amct_ops PYTHONPATH=amct_ops/staging \ python3 tests/amct_ops/run_hifloat8_dtype_smoke.py --backend auto

可通过--device npu:1指定其他设备(默认npu:0)。脚本对 FP16 与 BF16 各构造一份输入,检查输出 shape 未变、dtype 未变、device 未变、误差有限,输出包含以下契约与指标的 JSON:hardware_path_verifiedenvironment(CANN 路径、设备名、torch/torch_npu/amct_ops 版本)、每条结果的max_abs_error/mean_abs_error等(见 run_hifloat8_dtype_smoke.py#L123-L142)。

退出码语义(与 run_hifloat8_dtype_smoke.py#L192-L221 的实现一致):

  • 成功(所有契约通过):退出码0,JSON 中hardware_path_verified: true
  • shape、dtype 或 device 契约失败:退出码1hardware_path_verified: false
  • 缺少 NPU、torch_npuamct_ops或后端执行失败:向 stderr 输出错误 JSON 对象(requested_backend/hardware_path_verified: false/error),以非零状态退出(导入或运行时错误路径返回2)。

最后需要特别强调一条验证边界:仅通过py_compile--help或 CPU 单元测试不能证明硬件路径可用。在未于真实 NPU 环境执行上述命令之前,原生路径与amct_ops路径都应记录为「硬件路径未验证」(hardware path not validated)——这是该冒烟脚本被设计为「硬件验证判据」而非普通单测的原因。

六、快速核对清单

在实际排障时,可以按以下顺序快速定位问题:

  1. bash amct_ops/ops_build.sh --help或直接查看 ops_build.sh 头部注释,确认 SOC 与主机架构是否在支持范围内;
  2. 检查amct_ops/staging/amct_ops/下是否同时存在目标子包的*.py*.so(构建日志第 3 步会打印每个算子收集到的.so数量);
  3. 确认已source $ASCEND_HOME_PATH/set_env.sh,且torch.npu.is_available()为 True;
  4. 若只跑 HiFloat8 冒烟,优先用--backend auto观察 JSON 中实际命中的backend字段,再分别用native/amct_ops复现,以区分是原生 cast 还是 fallback 算子的问题;
  5. 中文/英文说明互为对照:中文版见 tests/amct_ops/README.md,本文对应的英文版为 tests/amct_ops/README_en.md。

【免费下载链接】amctAMCT是CANN提供的昇腾AI处理器亲和的模型压缩工具仓。项目地址: https://gitcode.com/cann/amct

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询