已合并
fix(foreach,lamb,scatter_list): ForeachAddc*List 补 Div 0ULP 精度档 + LambApplyOptimizerAssign 支持面订正 #10142
fix(foreach,lamb,scatter_list): ForeachAddc*List 补 Div 0ULP 精度档 + LambApplyOptimizerAssign 支持面订正 #10142
已合并
zl_hw创建于 18 天前
zl_hw成员
18 天前

描述

本 PR 包含三组修复,均由 TTK 三方精度比对(cross_check)跑批暴露的红灯定位而来。

1. ForeachAddcmulList / ForeachAddcdivList:补 Div 0 ULP 精度档(内核)

foreach/foreach_utils/op_kernel/arch35/foreach_addc_list_regbase.h 中的 Div 此前未指定 DivConfig,落到缺省 DivAlgo::INTRINSIC——该档在 dav-3510 上仅保真到 1 ULP。

  • 实测 fp32 用例 23689/524288(4.52%) 元素与正确舍入结果相差 1 ULP
  • 在 x1 与 scalars*(x2/x3) 几乎相消的点上,该偏差被放大成上千 ULP 的相对误差,cross_check 的 mare 判据因此报红(实测 mare 29.87 > L1 阈值 5.0)
  • 显式改用 DivAlgo::PRECISION_0ULP_FTZ_TRUE 后,输出与正确舍入结果逐位相同(0/524288)

仓内 20/22 处显式 Div 配置均选 0ULP 档,本文件此前漏配;兄弟算子 foreach_div_list_inplace 已修过同一问题。addcmul 走 Mul 分支不受影响;ComputeIntPath 的整数 Div 未改。

2. LambApplyOptimizerAssign:支持面订正(资料 + host 校验 + UT)

原 README 声明 grad 与 input3 均可小于 inputv/inputm 并向上广播,但底层 Ops::Base 广播模板的 DoDimensionCollapse 不支持对 In0(即 grad)做广播:

  • grad 为标量时 EnsureNotScalar 只抬到 {1}、不左补 1 对齐输出 rank → The 1 input's dim num is not same with output's dim num
  • grad 与输出同 rank 但某维为 1 → The 1 input's dim index is not same with out, and not 1
  • 实测支持面矩阵:grad 在任意单维广播均被拒;input3 支持 () / (1,) / (1,1,1) / (4,) / (1,3,4) / (2,1,4),仅 rank 大于输出时不支持

改动:

  • README 订正为「grad/inputv/inputm 三者 shape 必须完全相同,仅 input3 按右对齐 broadcast 规则向 inputv 对齐」
  • infershape 与 tiling 的 CheckInplaceShapeConstraint 同步改为严格等形,使非法组合在 host 阶段被清晰拒绝,而不是放行后到 tiling 阶段抛 E90003
  • infershape 三处 shape 校验统一改用结构化日志宏 OP_LOGE_FOR_INVALID_SHAPE(S)_WITH_REASON,与 tiling 侧口径一致
  • UT 同步更新:原 moment_shape_decides_output_shape 断言的是旧广播语义,已改为等形;新增 grad_smaller_than_moment_is_rejected 与 input3_broadcast_into_moment_is_accepted

3. 三方腿与资料订正(golden / docs)

  • foreach_add_list_inplace / foreach_sub_list_inplace 的三方腿改用两步拼接(_foreach_mul + _foreach_add),不再用 alpha= 的融合形式。融合形式是一次 FMA 舍入,与 CPU golden 的两步舍入序列不同,两者恒差 1 ULP:实测 107/107 例 |NPU−真值| + |三方−真值| 精确等于 1.0000 ULP,mare 恒为 1.000。分离后三个种子(0/1/7)各 20/20 全通过。
  • foreach_addcmul_list / foreach_addcdiv_list 的 golden 补 e2e 三方腿适配类 _TpE2e(TTK 按 torch 重载形参名 self/tensor1/tensor2/scalars 下发,与 def 注册名 x1/x2/x3/scalars 不同,直接复用 kernel 腿竞品类会抛 UnknownParamError);并标注这两个算子实际不具备 e2e 通路支持——aten::_foreach_addc{mul,div}.Tensor 在追踪期即抛 Expected scalars to be on CPU,torch.compile 建不了图,torchair converter 走不到,需手工给已安装的 torch_npu 补 meta 注册才能跑通,该补丁不在本仓、重装即失效,故不作为已交付通路。
  • ScatterList 资料补 maskOptional 取值范围,并修正 mask 维度列笔误(0-8 → 1 维);aclnnScatterMin 补索引取值范围;op_api_list 补 ForeachAddcmul/AddcdivList 的确定性说明。

关联的Issue

关联 Issue #5750 —— https://gitcode.com/cann/ops-nn/issues/5750

测试

  • LambApplyOptimizerAssign op_host UT:bash build.sh -u --ops=lamb_apply_optimizer_assign --soc=ascend950 → 14/14 PASSED(含 2 条新增用例)
  • Div 精度档位(JIT 在线编译,源码级 A/B):同用例同区间下,改前 23689/524288(4.518%)元素偏离正确舍入,改后 0/524288
  • 部署二进制验证(重新出包 + 部署,确认被测 == 当前源码):ForeachAddcdivList 在 kernel / aclnn / GE 图三条通路上 mare = mere = rmse = 1(即与 golden 逐位相同)
  • LambApplyOptimizerAssign 支持面矩阵(静态 GE 通路):grad 等形 + input3 降 rank 用例 PASS;grad 标量 / grad 含 1 维用例在 host 阶段被拒,报错文案为 Parameter grad of op1 has incorrect shape [1]. Reason: grad does not support broadcast and must have exactly the same shape as inputv/inputm
  • pre-commit:clang-format / ruff-check / ruff-format / codespell / trailing-whitespace / end-of-file-fixer 本地全部通过
  • ⚠️ 待补:foreach_addcdiv_list(1437 例)与 lamb_apply_optimizer_assign 泛化集回归正在跑批中,结果将补充到本 PR 评论

文档更新

  • optim/lamb_apply_optimizer_assign/README.md:输入/输出 shape 描述与《约束说明》改写
  • index/scatter_list/README.md、index/scatter_list/docs/aclnnScatterList.md:mask 取值范围与维度笔误订正
  • docs/zh/op_api_list.md:补 ForeachAddcmul/AddcdivList 确定性说明

类型标签

AI/Agent生成声明

likedislike
Pull Request已成功合入, 合并人@CANN-robot
(感谢 zl_hw 的贡献)
Zzl_hw成员
18 天前 创建了 pull request,commit 4cb0da2c
atomgit-bot
atomgit-bot
18 天前 评论:

变更摘要

本 PR 主要针对 foreach 系列算子测试资产中的三方腿(第三方对比实现)精度口径问题:原三方腿使用 torch._foreach_add / torch._foreach_sub 携带 alpha 参数的 FMA 单次舍入形式,而 NPU 内核实际是先 Muls 再 Add/Sub 的两次舍入,两者对 float64 真值的误差恒满足 1.0000 ULP 关系,导致 cross_check 的 mare 比值被抬到 8.6(阈值 5)而出现假红。改动将三方腿改为 _foreach_mul + _foreach_add/_foreach_sub 两步拼接,与 CPU golden 同口径,避免误报(NPU 相对误差约 1.07e-7,远低于 fp32 判据)。PR 标题还提及为 ScatterList 资料补充 mask 取值范围,但相应文件未附带补丁,此处不作展开。

主要改动

  • foreach_add_list_inplace golden 三方腿去融合化:在 tests/assets/golden.py 中将 _ForeachAddListInplaceCompose 的单次 torch._foreach_add(..., alpha=...) 调用拆为先 _foreach_mul 缩放、再 _foreach_add 的两步实现,与 CPU golden 的两次舍入口径保持一致
  • foreach_sub_list_inplace golden 三方腿去融合化:在 tests/assets/golden.py 中将 _ForeachSubListInplaceCompose 的单次 torch._foreach_sub(..., alpha=...) 调用同样拆为 _foreach_mul + _foreach_sub 两步,消除 FMA 单次舍入与内核两次舍入的精度差异
  • 消除 cross_check 假红:两步拼接后三方腿与内核误差同向(对 float64 真值恒满足 1.0000 ULP 关系),使 mare 比值回落到阈值 5 以内,同时以注释说明该改动并非内核精度短板,避免后续误判
likedislike
不准确?
atomgit-bot
atomgit-bot
18 天前 评论:

代码审查

✅ 未发现问题

likedislike
不准确?
CANN-robotCANN-robot成员
18 天前 添加了label:cann-cla/yes
CANN-robot
CANN-robot成员
18 天前 评论:

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)
docs ✅ 陈娇, 汤平川 (2/2) ✅ 陈娇 (1/1)
foreach ✅ 汤平川, 钱泽洪 (2/2) ✅ 钱泽洪, 汤平川 (2/1)
optim ✅ 汤平川, 钱泽洪 (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

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

likedislike
此处折叠了60条消息 查看更多
qianzehong成员
17 天前 评论:

/lgtm
/approve

likedislike
chenjiao成员
17 天前 评论:

/approve

likedislike
CANN-robotCANN-robot成员
17 天前 添加了label:lgtmapproved
CANN-robotCANN-robot成员
17 天前 关闭了关联的issue
CANN-robotCANN-robot成员
17 天前 合入了pull request