已关闭
[Bug-Report|缺陷反馈]: arch35 三个算子的 tiling/内核缺陷(GNSQ UB 记账越界、MML C 轴上限、L2G SPLIT_D 槽位写穿) #4994
zl_hw创建于  8月22日关闭于  8月22日
zl_hw成员
8月22日 创建

Describe the current behavior / 问题描述

在 Ascend950PR 上对 arch35 三个算子做泛化验证时,发现三处内核/tiling 缺陷,均可稳定复现:

1. GroupNormSiluQuant:UB 记账越界,7 例全崩

geir 动静态双腿 7 例全部崩溃(设备侧 errcode 82 MTE2 写 UB 越界 / 341 VEC 访存 UB 越界 / 263 scalar 地址越界),其中 3 例入参完全合法(L1_014/L1_436/L1_481)。定位到四处独立缺陷:

  • SetPartialFallback 中 ubSize - meanAndRstd - gamma - beta - quantScale 无下溢保护。C=5408396 时 ubRemain 下溢为 2^64-21380096,processSize 被算成 2^61 级。
  • 同函数用 isLargeChannel && hasOptional 决定走 TILINGKEY_R_PARTIAL_LOAD_GENERALIZED(1120) 还是 1100,而 quantScale 能否整段常驻只取决于 C;大 C 且无 gamma/beta 时被错选进 1100。
  • MaybeSetSplitReduce 覆盖成 R_SPLIT_REDUCE(1140) 时不做 UB 预算校验,而 1140 内核按本核通道数常驻 gamma/beta(每通道 12B,且无 gamma/beta 时也照开),固定开销约 73KB,chanPerCore 上限约 15000;失败例 chanPerCore=169013 需 2.03MB。
  • host 的 couldFold 漏了 kernel isFold = hwNum <= NDDMA_SIZE || (!hasGamma && !hasBeta) 的后半个条件,「无 gamma/beta + 大 hwNum」档 kernel 按 fold 布局写 451KB,而 host 只预留 shapeC 个 fp32。

2. MultilabelMarginLoss:C 轴支持面窄于 A2

七块 UB buffer 全部随 C 线性增长且不参与分块,UB 253952B 换算出 C≈8000 上限,超过即 tiling 主动返回 GRAPH_FAILED。实测 C<=2842 全过、C>=1950000 全败。A2 侧由 TBE DSL 承担切分,对 C 无上限,故 A5 支持面窄于 A2。

3. L2NormalizeGrad:SPLIT_D 累加槽位写穿

kernel 的 accum 缓冲固定 SPLIT_D_MAX_CHUNKS(=256) 槽,而 FormerProcess 按 numChunks_ 直接 Duplicate/写槽。1 维 D=151000000 需约 37000 槽,当场写穿,设备报 errcode 341;host 侧无守卫。

Environment / 环境信息

  • 硬件:Ascend950PR(aclrtGetSocName() 返回 Ascend950PR_9579)
  • CANN:9.2.0(innerversion V100R001C12B071)
  • 仓库:cann/ops-nn,基线 commit bcd1ffb99
  • 验证工具:ops-test-kit(TTK)geir 通路,-d -b -c=false
  • OS/架构:Linux x86_64

Steps to reproduce the issue / 重现步骤

GroupNormSiluQuant(7 例原始用例,含 3 例完全合法入参)

ttk geir -i gnsq_fail7.csv -d -b -c=false --golden-mode Disable
# 用例特征:L1_014 = (2,4,28224) rank8 无 gamma/beta;
#           L1_436 = 大 C(shapeD=169013×coresPerGroup)走 1140;
#           L1_481 = C=5408396 走 1120 generalized

MultilabelMarginLoss(C 轴扫描)

# 固定 reduction/dtype,扫 C:2842 / 8000 / 12000 / 1950000
ttk geir -i mml_c_scan.csv -d -b -c=false --plugin loss/multilabel_margin_loss/tests/assets/

L2NormalizeGrad(超大 D)

# x/y/dy 均为 1 维 (151000000,),attrs = {'dim': [0], 'eps': 0.0001}
ttk geir -i l2g_bigd.csv -d -b -c=false --plugin norm/l2_normalize_grad/tests/assets/

Describe the expected behavior / 预期结果

  1. GroupNormSiluQuant:合法入参不应触发设备侧内存越界。tiling 侧的 UB 预算计算不应下溢;当解不出正的 processSize 时应干净返回 GRAPH_FAILED,而不是把 0/下溢值下发给内核。host 与 kernel 对 isFold 的判据应一致。
  2. MultilabelMarginLoss:C 轴不应存在 ≈8000 的隐含上限,支持面应与 A2 对齐。
  3. L2NormalizeGrad:D 不应受 SPLIT_D_MAX_CHUNKS 槽位数限制;超出时要么正确分组累加,要么在 host 侧显式拒收,不应写穿缓冲。

GroupNormSiluQuant(plog 设备侧错误码,多核同报)

L1_014 / L1_078 / L1_578 / L1_708 : errcode:(82)   MTE2 写 UB 越界
L1_036                            : errcode:(341)  VEC 访问 UB 越界
L1_436                            : errcode:(263) + (82)
L1_481                            : errcode:(263) + (81) + (341)
PassRate 0.00% (0/7)

op_host UT 打印的 tiling data(L1_436/L1_481,key=1140)反推:

processSize = 2305843009213661696  (= 2^61 级)
  ← count * hwNumAlign,count = maxReduceCount / hwNumAlign
  ← maxReduceCount = (ubRemain/4)/2
  ⇒ ubRemain = 18446744073688171520 (= 2^64 - 21380096)   ← uint64 下溢
21380096 + 253952 恰为 per-channel quantScale 预留(C 个 fp32 ≈ 21.6MB)

MultilabelMarginLoss

C = 2842      -> PASS
C = 12000     -> GRAPH_FAILED (tiling 主动拒收)
C = 1950000   -> GRAPH_FAILED

L2NormalizeGrad

l2g_dim0_1d_flo_n151000000 : ERROR: GEIR execution failed (rc=255)
  RunGraph failed: -1, EZ9999: Internal error!
  An error occurs on the device(chipId:0 ...)   ← 设备侧 errcode 341

Special notes for this issue / 备注

  • 三处缺陷均在同一批泛化验证中发现,修复补丁见关联 PR。
  • 缺陷 1 的四个成因相互独立,只修其中任一处仍会崩;其中「host/kernel 的 isFold 判据不一致」这一条与前三条的失效路径不同(前三条走 UB 预算,这条走 fold 布局)。
  • 缺陷 2 的 C 轴上限是 tiling 主动 GRAPH_FAILED,不是崩溃,但构成 A5 相对 A2 的支持面收窄。
  • 复现所用的三个算子交付回归集分别为 2881 / 1098 / 1018 例,均未覆盖到上述失败画像(GNSQ 交付集 rank 只到 5、C 上限 12288;L2G 交付集 1018 例全部显式传 dim),故这三处缺陷此前未被拦截。
likedislike
CANN-robotCANN-robot成员
8月22日 关闭了 issue
CANN-robotCANN-robot成员
8月22日 添加了label:resolved