已合并
fix(norm): 补齐 RmsNormQuant 参数校验与可选输出推导 #10865
fix(norm): 补齐 RmsNormQuant 参数校验与可选输出推导 #10865
已合并
raoliang_sac创建于 9月20日
raoliang_sac成员
9月20日

描述

修复 Ascend 950/RegBase 上 RmsNormQuant 系列的参数校验遗漏、错误分类和可选输出推导问题。合并原扫描整改与返回码/日志整改;不修改 kernel 计算、tiling key 或 AddRmsNormQuant V1/V2 产品代码。

问题、原因与效果

  • 本 PR 先前提交已包含:V1 非一维 scale 只记录错误却继续执行;V3 标量 x/y 缺少最小维度检查;V2/V3 缺省 scales2 时 y2 仍推导完整形状的修复。V2/V3 通过 GetOptionalInputShape(INPUT_SCALE2_IDX) != nullptr 判断第二路是否实际提供:标量 scales2=[] 仍有非空 shape 对象,因此按已提供处理并推导 y2=x.shape;只有真正未提供 scales2 时才使用 y2=[1] 占位。
  • 本轮补充:非法二维 gamma/beta 在 reshape 后才失败,以及 V3 部分非法 dtype、shape 组合到下层才失败,最终被包装为 561103 内部空指针错误。TTK 基于原 PR 提交 3fce33f2c 部署实测 34 条此类输入返回 561103;改为在 RegBase API 层检查并返回 161002。
  • 这不是把所有内部错误统一改成参数错误:真正的内部构建失败仍保留原错误处理;必选 nullptr 仍为 161001,空 Tensor 为 161002。V3 可选 offset/beta 和未请求的 rstd 保留合法空值语义。
  • 保留 gamma/beta 的 [H]、[1,H] 合法组合、scale 长度 1/H、INT32 打包 INT4 和有效 rstd 的形状约定;当 x 为一维时,rstd 保留 [1] 和标量两种历史表示;原生 GEIR 的多轴归一化能力不套用 ACLNN 的末轴限制。
  • 修正 V1 offset 日志误写成 scale 的文本,以及共用 RegBase tiling 支持类型日志漏写 INT4。没有据此宣称发现合法输入的数值计算错误。
  • 补充整改 RmsNormQuantV2/V3 的 zero_points2 单独提供场景:旧代码已经拒绝该组合,但使用内部错误上报,并在外层重复记录相同原因。改为 EZ0037 用户参数错误,明确提供 zero_points2 时必须提供 scales2;去掉外层重复日志,仍返回 GRAPH_FAILED,不新增限制、不放宽支持范围。此规则不套用到支持该组合的 AddRmsNormQuant V1/V2。
  • TTK 进一步复现了 V3 原有 GEIR 功能缺陷:output_rstd=false 时 InferDataType 不写必需输出 rstd 的 dtype,初始 DT_UNDEFINED 导致 GE EZ3002 拒绝执行。改为始终推导 DT_FLOAT,只补输出元数据,不开启 rstd 计算;原先错误断言“false 时不应写 dtype”的 UT 同步纠正。
  • 两条 aclnnRmsNormQuantV3GetWorkspaceSize 边界对照确认:offset 为标量、以及 H=1 时 beta 为标量,修改前 ACLNN 实现返回成功,修改后依公开接口的形状约束返回 161002;合法 H=1 的 [1]、[1,1] norm 参数前后均通过。这两条属于 ACLNN 非法输入校验遗漏,不混记为 561103 分类修正。

每个文件的修改、目的及前后效果

文件 修改前的问题 → 修改及效果
norm/rms_norm_quant/op_host/op_api/aclnn_rms_norm_quant.cpp 原 scale rank 日志后遗漏返回,补 return false;本轮仅 RegBase 提前拒绝首维不为 1 的二维 gamma/beta、非法 scale 长度,将用户形状错误从 561103 纠正为 161002;修正 offset dtype 日志主体。
norm/rms_norm_quant/tests/ut/op_host/op_api/test_aclnn_rms_norm_quant.cpp 增加 scale rank、二维首维、scale/offset 形状负向 UT;覆盖合法二维组合及 scale 模式、必选 nullptr、910B/910_93 原预处理行为。
norm/rms_norm_quant/docs/aclnnRmsNormQuant.md 补全 950 gamma/beta、scale、offset 类型和返回码说明,明确 INT32 打包输出的形状例外,避免把产品差异写成所有平台通用约束。950 空 Tensor 的错误条件并入 161002 返回码表,不重复解释修复历史;明确 gamma、beta 均支持 [H] 或 [1,H],两者维度数不要求相同。非 950 的 scale=[1] 约束并入对应产品的 dtype 说明,删除重复产品列表。
norm/rms_norm_quant_v2/op_host/rms_norm_quant_v2_infershape.cpp 无 scales2 时 y2 原先仍推导为 x;改为通过 GetOptionalInputShape(INPUT_SCALE2_IDX) != nullptr 判断可选输入是否存在,真正缺省时推导 [1] 无效占位,标量 scales2=[] 仍识别为已提供并推导 x 形状。
norm/rms_norm_quant_v2/tests/ut/op_host/test_rms_norm_quant_v2_infershape.cpp 补缺省 scales2 与标量 scales2=[] 的 y2 推导断言,分别验证 [1] 占位和 y2=x.shape 分支。
norm/rms_norm_quant_v2/op_host/rms_norm_quant_v2_tiling_regbase_base.cpp 输出类型检查已支持 INT4,但错误原因列表漏写,补齐支持类型日志;zero_points2 单独提供原先以内部错误上报且重复记录,改用 OP_LOGE_FOR_INVALID_ARGUMENT_WITH_REASON 上报 EZ0037,并删除外层重复日志。拒绝条件、GRAPH_FAILED、tiling 计算及 GEIR shape 能力不变。
norm/rms_norm_quant_v2/op_graph/rms_norm_quant_v2_proto.h 原图原型未明确缺省第二路的输出语义;补充 y2 无效占位约定。
norm/rms_norm_quant_v2/README.md 简要同步 y2 缺省场景,不堆入 ACLNN 详细校验规则。
norm/rms_norm_quant_v3/op_api/aclnn_rms_norm_quant_v3.cpp 原最小 rank、dtype/组合、beta 及输出形状检查不完整;保留原 PR 的最小 rank 修复,本轮仅 RegBase 增加完整的所述 dtype/shape 检查,非法输入返回 161002;仅 outputRstd=true 校验 rstd。x 为一维时兼容标量 rstd,二维及以上 x 不适用此特例,dtype、空 Tensor、空指针检查不变。
norm/rms_norm_quant_v3/tests/ut/op_api/test_aclnn_rms_norm_quant_v3.cpp 分别断言标量 x/y;补 dtype、shape、INT4/INT32 打包负向,合法 dtype 组合、rank 边界、可选空指针和不启用 rstd 时的占位正向。另新增 3 个 UT / 37 组参数检查,覆盖一维 scalar/[1]、三种 x dtype、H=1/16、二维/三维 x 拒绝 scalar、错误 dtype/空输出及未启用 rstd 的占位。
norm/rms_norm_quant_v3/docs/aclnnRmsNormQuantV3.md 将已补检查的用户参数错误由 561103 调整为 161002;整除/比例错误改为“或者”,明确空 Tensor、打包形状及 rstd 生效条件,参数名与公开接口对齐;补充一维 x 对应标量 rstd 的合法形状,秩范围改为 0-8,返回码表同步这一例外。
norm/rms_norm_quant_v3/op_host/rms_norm_quant_v3_infershape.cpp 通过非空可选输入 shape 指针区分 scales2 缺省与标量:缺省时推导 y2=[1],未知秩分支也保留占位;标量 scales2=[] 及其他已提供形状均推导 y2=x.shape。另修复 output_rstd=false 时 rstd 的 dtype 未设置导致 GE 拒绝的问题,始终推导 FLOAT,不改变是否计算 rstd。
norm/rms_norm_quant_v3/tests/ut/op_host/test_rms_norm_quant_v3_infershape.cpp 覆盖 scales2 缺省、标量 []、普通形状及未知秩分支;纠正原 false 场景错误的 dtype 期望;从初始 UNDEFINED 验证 5 种 dst_type × true/false 和属性缺省的完整输出类型推导。
norm/rms_norm_quant_v3/tests/ut/op_host/test_rms_norm_quant_v3_tiling.cpp 新增 1 个 UT,覆盖 output_rstd 开/关 × scales2 有/无 × zero_points2 有/无,共 8 种组合,断言 zero_points2-only 拒绝、其余组合成功;V2 既有 mismatch UT 同时回归。
norm/rms_norm_quant_v3/op_graph/rms_norm_quant_v3_proto.h 同步 y2 占位语义,使图原型与 InferShape 一致。
norm/rms_norm_quant_v3/README.md 简要同步 y2 占位约定。

兼容性边界

  • 本轮新增 dtype/shape 检查只在 IsRegbase() 分支调用;不改 A2/A3 原有预处理和计算路径。
  • zero_points2 日志整改仅在 V2/V3 的 RegBase tiling 路径生效;两者入口已通过 IsRegbaseSocVersion() 限定平台,不修改 A2/A3 路由及行为,也不改 kernel。
  • 整个 PR 原有 V1 scale rank 修复属于共用检查,因此 A2/A3 的非法非一维 scale 也会由放行变为拒绝;不能将整个 PR 表述为对所有 A2/A3 输入完全无变化。合法输入行为不应改变,UT 验证与实机验证分别列出。
  • PR 不包含 ST、TTK 用例、框架修改、日志或构建产物;这些测试资产保存在工作目录 TTK 和任务证据目录。

关联的Issue

关联的Issue:#6248

Fixes #6248

测试

以下为 2026-09-20 已完成的回归记录;2026-09-21 与 2026-09-23 的增量验证单列在本节末尾,不将旧回归算成本次重新执行。使用工作目录的 TTK(add_ops_onto_master,f78078fb)和 CANN 9.2.0,950 实机;构建最多 -j8,所有 TTK 模式显式 --pc=1,批次串行。按 CSV 原始结果及真实返回码逐条核验,不以 runner exit=0 代替测试通过。

  • 69 条负向 API 前后对照全部符合预期:34 条 561103→161002,原 24 条 161002、11 条 161001 保持;另 2 条 aclnnRmsNormQuantV3GetWorkspaceSize 标量边界为 0→161002。记录真实 GetWorkspaceSize 返回码,不用 TTK N/A 冒充 PASS。
  • 本 PR 先前提交的 V1 非一维 scale、V3 标量 x/y 共 3 条扫描负向已做“修改前放行、修改后 161002”的 TTK 对照;原始证据保留,与本轮 69+2 条返回码整改分别记录,不重复归为本轮新增修复。
  • 74 条合法输入前后均 74/74 PASS;合法 H=1 的 2 条输入前后均 PASS;另补 12 条非均匀 leading-one gamma/beta 输入,覆盖 x rank 1/2/3、beta rank 1/2 和 half/BF16/float,固定 seed=11027,旧/新 API 前后各 12/12 PASS。三组共 88 条合法场景前后均通过,有效输出精度达标比例 100%;未请求输出为 SUPPRESSED,无百分比。
  • 最终 UT:op-host 51/51、op-api 39/39。V1/V3 API 行覆盖率分别 88.5%、97.5%,V3 推导文件 94.9%;函数覆盖率分别 93.3%、92.3%、100%,未采集分支覆盖率。
  • 新增原生 kernel 58/58、GEIR 58/58 全部 PASS,有效输出精度达标比例 100%。覆盖多轴归一化、单/双路、rstd 开关、INT8/INT4/HIFLOAT8/FP8 E5M2/FP8 E4M3FN;GEIR rstd=false 旧代码失败→修复后通过的原始日志保留。
  • GEIR 6 条非法形状全部按预期拒绝,错误为 EZ0010(参数形状错误),分别指出 scales1/x、scales1/zeroPoints1、gamma/x 的不匹配,不计入精度 PASS。
  • 既有四套 ACLNN 各 500/500 PASS,共 2000 条,Add shape 20/20 PASS。Rms 两套有效输出精度达标比例 100%,Add 两套为 99.4791666667%~100%。Add 的现有 CSV 设置 ptol=0.01(最多 1% 元素可超 1 LSB),本轮未调整;不能把 PASS 等同于每个元素都 ≤1 LSB,旧回归也存在该现象。
  • 既有四套 kernel 各 500 条全部执行:RmsNormQuantV2 为 370 PASS/130 未匹配,RmsNormQuantV3 为 340/160,AddRmsNormQuant 为 352/148,AddRmsNormQuantV2 为 360/140。1422 个已注册 dtype 组合全部 BINARY_MATCH 且精度 PASS,有效输出比例 100%;578 条未匹配均为当前 950 OpDef 未注册的 dtype 组合,保留 BINARY_MATCH_FAILURE/FAIL 原始结果,不算 PASS。
  • 旧 aclnnRmsNormQuantV2 资产 1 条为 OP_API_NOT_FOUND,不算精度 PASS;950 的公开 V2 计算入口是 aclnnRmsNormQuant,已由其 500 条回归覆盖。
  • 定向完整包构建通过;后续 dtype 修复用 --jit -j8 重编主机库,部署新 proto 并保留已验证的 API/tiling/kernel,实际加载路径已核对。整个 PR 15 文件基础检查/OAT 通过;未执行全仓本地 CI,未将跳过的全文件 clang-format 声称为通过。

截至 2026-09-20,既有全量及新增 kernel/GEIR 批次合计 4143 条记录:3558 条精度 PASS、578 条未注册 binary 组合、6 条预期拒绝、1 条不可用 API。上述 71 条返回码对照及 88 条合法输入前后对照另行统计,不重复堆入通过数。当时用例资产为 18 个 CSV、4244 行;资产行数也不等于通过数。最终自动核验覆盖资产 SHA256、完整行数、真实返回码、注册组合匹配和精度状态,全部符合上述预期。

本轮将 TTK Golden 对 ACLNN 二维 gamma 的归一化轴修正为公开接口的末轴语义,并增加 6 条 CPU 回归,相关 Golden/量化比较 CPU 测试共 45 PASS;没有放宽精度容差。GEIR 的原生多轴能力保留,不能复用 ACLNN 的轴限制。

上一版 GEIR runner 的 rc=-11 已定位到本机 Python 日志任务查询问题,可用不依赖 CANN 的最小程序复现;结合 TTK 的栈限制设置,仅在任务启动环境内处理。GEIR 能真正执行后又复现上述 V3 dtype 产品缺陷,并完成修复后 58 条正向回归;没有将产品缺陷归咎于环境,也没有把绕过 runner 崩溃本身算作算子通过。

2026-09-21,提交 b5ff65c07 的 zero_points2-only 日志整改补测:

  • 修改前为 313ed0c99 对应已部署产物,修改后重新以 --pkg -j8 构建相关算子包并部署到同一工作目录 CANN;包内和实际加载的 tiling 库 SHA256 一致。API/proto 库 SHA256 与修改前一致。
  • 新增 2 个本地 TTK CSV:3 条非法组合、9 条合法组合,不进入本 PR。使用相同固定输入前后对照,所有批次显式 --pc=1。
  • GEIR 3 条非法组合覆盖 V2、V3 output_rstd=false/true:前后均拒绝。修改前错误文本由 CheckOptionalInput/GetShapeAttrsInfo 重复记录,GE 对外为 E90003;修改后明确报 Invalid_Argument(EZ0037),指出 zero_points2 存在时缺少 scales2,且删除外层重复日志。负向 CSV 保留 EXEC_FAILURE,不算精度 PASS、没有精度百分比。Golden 不支持非法组合而报 TypeError 的原始记录也保留;拒绝结论来自其后实际 GEIR 执行的 tiling/RunGraph 日志,不来自 Golden 失败。
  • 合法组合覆盖单路、仅 scales2、scales2+zero_points2,分别运行 V2、V3 rstd 开/关。GEIR 修改前 9/9、修改后 9/9 PASS;kernel binary 修改前 9/9、修改后 9/9 BINARY_MATCH 且精度 PASS。有效输出精度达标比例均为 100%,INT8 按绝对误差不超过 1 LSB 且 ptol=0 判断,rstd 使用 atol/rtol=1e-4;未请求输出为 SUPPRESSED。kernel 的 tilingKey、匹配 kernel 名保持一致,TTK 输出的越界检查通过;不据此宣称逐位一致。
  • 此次重新执行 UT:op_host 52/52、op_api 39/39;新增 V3 UT 含 8 种组合,V2 既有 mismatch UT 通过。最终 16 个 PR 文件的基础检查/OAT 通过;新增 UT 范围格式化完成,全文件 clang-format 为跳过。未重新执行旧 4143 条批次,也未执行全仓本地 CI;本次共 36 条正向执行记录及 6 条预期拒绝记录,单独统计。
  • 该非法第二路组合属于原生 V2/V3 图接口,公开 aclnnRmsNormQuant / aclnnRmsNormQuantV3 只有单路 scale/offset,无法直接传入该组合;本次用 GEIR 检查拦截和日志,同时回归 API UT,不伪造对应 ACLNN 实机测试。

2026-09-21,提交 520c75e4b 的一维 x / 标量 rstd 兼容补测:

  • TTK 对照确认:相同 x=[16]、rstd=[] 场景,旧 API 成功,PR 增加严格 shape 校验后返回 161002,本次修复恢复成功;y/rstd 的有效输出精度达标比例均为 100%。仅调整 RegBase ACLNN 的 shape 判断,不修改 kernel、tiling 或 A2/A3 路径。
  • 增量 ACLNN 库编译成功;API UT 42/42 通过,包括新增 3 个 UT / 37 组参数检查。
  • 新增 41 条 TTK 定向用例已保存于工作目录用例库:32 条正向 PASS,有效输出精度达标比例 100%;9 条非法输入均真实返回 161002,保留 TTK N/A,不算精度 PASS。未请求的 rstd 标记 SUPPRESSED。
  • 先完成原有 500 条回归;随后将原有资产与历次补充资产纳入统一入口,于 2026-09-21 20:46–20:50 重新执行累计 640 条 V3 ACLNN 用例(7 份输入 CSV):580 条正向全部 PASS,GetWorkspaceSize/执行均返回 0,有效输出精度达标比例均为 100%;60 条负向全部符合真实返回码预期,其中 55 条 161002、5 条 161001,均不进入执行阶段,不计入精度 PASS。640 条包含前述 500 条和本次 41 条,不重复累计。
  • 累计入口保存在工作目录 TTK 的 examples/regression/rms_norm_quant_v3_950_aclnn.py:自动收集同族输入 CSV 中的 V3 用例,排除结果 CSV,检查重名/禁用/负向预期缺失,记录逐例来源及源文件 SHA256;新增问题用例继续沉淀到 TTK,不进入产品 PR。
  • 实测通过指定 API 动态库隔离此次 API 改动,使用同一工作目录 CANN 的 host/kernel;动态库依赖已核对为真实 CANN 库而非构建 stub。未重新执行 kernel/GEIR 全量或全仓本地 CI。

2026-09-23,提交 879de1f52 的标量 scales2 与 A3 兼容性补测:

  • V2、V3 InferShape UT 均显式传入标量 scales2=[],验证 GetOptionalInputShape(INPUT_SCALE2_IDX) 返回非空 shape 指针,y2 推导为 x 形状;缺省 scales2 的独立用例仍推导 [1] 占位。
  • 950 实机 TTK GEIR 定向 4/4 PASS,所有命令显式 --pc=1:V2 覆盖二维/三维 x,V3 覆盖 output_rstd=false/true。V2 两个输出均为 100%;V3 未请求 rstd 时为 SUPPRESSED,请求 rstd 时三个输出均为 100%。这组实测确认标量不会被误判为缺省输入。
  • A3 (Ascend910_9362) 使用同一提交独立编译、刷入任务专用 CANN/vendor 后,RmsNormQuant 合法 ACLNN 矩阵 22/22 PASS,每条有效输出精度达标比例均为 100%;覆盖 FLOAT16/BFLOAT16、INT8/INT4、rank 1/2/3/4/8、H=1 及多组 epsilon。非法二维 scale 返回 161002。未修改 kernel,A3 合法计算路径未见回归;A2 未实机执行,其结论仍来自与 A3 共用的非 RegBase V1 API 路径审计。

文档更新

两份 ACLNN 说明补齐上述返回码和约束;V2/V3 README 与图原型同步 y2 占位约定。

类型标签

AI/Agent生成声明

likedislike
Pull Request已成功合入, 合并人@CANN-robot
(感谢 raoliang_sac 的贡献)
Rraoliang_sac成员
9月20日 创建了 pull request,commit a894da8e
CANN-robotCANN-robot成员
9月20日 添加了label:cann-cla/yes
CANN-robot
CANN-robot成员
9月20日 评论:

CLA Signature Pass

raoliang_sac, thanks for your pull request. All authors of the commits have signed the CLA. 👍

likedislike
CANN-robot
CANN-robot成员
9月20日 评论:

Thanks for your pull-request.
The full list of commands accepted by me can be found at here.
You can get sig-info at here.
You can self-configure the PR merge rules for this repository. For more details, please refer to Here.
For more, you also can visit HICANN.


PR Approval Progress

✅ Congratulations! All modules have met the lgtm and approve requirements.

Module Approval Details

module lgtm status approve status
*/*/README.md ✅ 陈娇, 钱泽洪, 陈展熹 (3/2) ✅ 陈娇 (1/1)
*/*/docs/acl*.md ✅ 陈娇, 钱泽洪, 陈展熹 (3/2) ✅ 陈娇 (1/1)
*/*/op_graph/*_proto.h ✅ 陈展熹, 汤磊, 钱泽洪 (3/2) ✅ 汤磊 (1/1)
norm ✅ 钱泽洪, 陈展熹 (2/2) ✅ 陈展熹, 钱泽洪 (2/1)

💡 Tip:

  • Committer can comment /approve or /lgtm
  • Commenting /approve implies both code review (lgtm) and intent to merge (approve)

CLA Signature Pass

raoliang_sac, thanks for your pull request. All authors of the commits have signed the CLA. 👍

likedislike
CANN-robotCANN-robot成员
9月20日 将zengjuan,u010470851,chaotang233,kevin_huang1234,crystalhu,yangyang016,fanqirui,gitee-duhuiping,wangrui_,renruhai,su-yueming,zhajianqing123,tang-lei01,yourealize,chenqi317,wang-xing001,liubo75,tangweiwei2,gitcode-chenjiao,chenxingyu18,liujie12345678,pingchuantang,Chen_HaoWen,qianzehong,wangyongguang,fengying555682,caiwenwen,yanglu-1设为评审人
此处折叠了95条消息 查看更多
CANN-robot
CANN-robot成员
9月28日 评论:

The MR can not be merged, because of CodeReview discussion not resolved

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

likedislike
Rraoliang_sac成员
9月28日 解决了最后一个问题
CANN-robotCANN-robot成员
9月28日 关闭了关联的issue
CANN-robotCANN-robot成员
9月28日 合入了pull request
CANN-robot
CANN-robot成员
9月28日 评论:

Pull Request 已合并或已关闭。

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

likedislike