Closed
[Requirement|需求建议]: 新增 reduce_std_with_mean_v2 算子 #2908
GavinAdd on  Aug 27Closed at  Sep 19
Gavin
GavinCollaborators
Aug 27 Create

Thanks for sending an requirement! Please fill in the following template to help quickly solve your problem.

一、背景信息 (必填)

现有 reduce_std_with_mean(Two-Pass 方案)在 L2 层需先调用 l0op::ReduceMean 预计算均值,再经 Expand/BroadcastTo 广播后送入 ReduceStdWithMean kernel 计算方差——全程 2~3 次 kernel 启动,mean 张量需完整写/读/广播,引入大量额外 GM 流量;且在小数据量场景 kernel 启动开销占比高。本次新增算子 reduce_std_with_mean_v2 在 kernel 内用**分块 Welford(Chan 并行合并)**算法单遍扫描输入,同时产出均值和标准差/标准差倒数,消除中间 kernel 链与 mean 张量搬运。

二、价值/作用 (必填)

  • 单遍融合计算:一次 kernel 启动同时计算 mean 与 std(替代 ReduceMean+Expand+ReduceStdWithMean 三 kernel),数据只读一次 GM
  • 应用场景:torch.std_mean(统计标准差+均值)、BatchNorm 训练统计量(均值+标准差倒数)等归约统计类计算

三、设计方案 (必填)

3.1 使能方式(涉及哪些框架:如Aclnn直调、Pytorch训练等)
  • aclnn 两段式接口直调:aclnnStdMeanCorrectionV2(对应 torch.std_mean)、aclnnBatchNormStatsV2(对应 BatchNorm 统计量)
  • L0 单算子接口:l0op::ReduceStdWithMeanV2(含 two-stage 的 ReduceStdWithMeanV2Partial/ReduceStdWithMeanV2Merge)
3.2 总体设计

核心:分块 Welford——数据按行(非归约维)分块,块内两遍计算 tileMean 与 tileM2(Σ(x-tileMean)²),块间用 Chan 合并公式归并,数学上对任意分块精确。

对每行 m(归约维 R 连续):
    tileSum → tileMean(ReduceSum 树归约)
    diff² → tileM2(Sub/Mul/ReduceSum)
    Chan 合并: delta = tileMean - mean; mean += delta·R/count; M2 += tileM2 + delta²·R·(count-R)/count
    var = M2/max(0, count-correction); std = sqrt(var+eps)(或 1/std,invert)

按输入形态在 tiling 阶段选择三条执行路径:

串行(兜底)          :逐行 tile 循环 + 标量 Chan 合并
单 tile M 向量化(vectorize 路径) :R≤1920 且 32B 对齐且 M≥8——一次处理 M_tile 行,BlockReduceSum
                        多段归约 + 向量化 Chan 合并,摊薄每行固定开销
two-stage R 跨核      :M≤64 且 R>2048 且 32B 对齐——R 拆 K 段跨核归约(Partial)
                        + Chan 跨段合并(Merge),解决"M 小核闲置+行内串行"
3.2.1 算子支持的数据类型
  • fp16 / fp32 / bf16(输入输出 dtype 一致)
  • 数据格式:ND
  • 中间计算统一升 fp32 精度域,输出 Cast 回原 dtype(RNE 舍入,与 PyTorch 一致)
3.2.2 host侧设计
  • 参数校验(dtype/shape/dim/format)、空 tensor 处理、correction 边界(N≤correction 时输出 NaN/INF 语义)
  • 非最内层归约自动 Transpose 预处理、keepdim 逆转置输出
  • tiling:多核沿非归约维切分(blockFactor);UB 预算计算 ubLength/ubM;路径选择(串行/P1/two-stage)并下发 tiling 参数
  • two-stage 场景:host 依序调度 Partial(blockDim=K,各核归约 R 的一段,输出 partial 张量 [M,K,3])→ Merge(blockDim=min(M,核数),Chan 合并 → std/mean)
3.2.3 kernel侧设计
  • 串行路径:行循环 + R 维 tile 双缓冲(DataCopyPad + EnQue/DeQue 流水)
  • M 向量化路径(ProcessVectorized):批处理 [M_tile, R] 块,BlockReduceSum(vcgadd 多段归约)一次算 M_tile 行的 tileSum/tileM2,Chan 合并向量化(count 标量化)
  • two-stage 路径:Partial(strided GM 加载 R 段 + 逐行两遍 Welford → (n,mean,M2) 写 GM);Merge(读 K 三元组,Chan 公式跨核合并,数学精确)
  • 数值:fp32 计算域(fp16/bf16 Cast 无损升精度);输出 CAST_RINT(RNE 与 torch 对齐);UB 偏移 32B 对齐(上板硬要求)
3.3 支持硬件
  • Atlas A2 训练系列产品 / Atlas A2 推理系列产品(Ascend910B,DAV_2201)——已完成编译与精度/性能验证
  • 950(RegBase)路径仅在设计上保留,尚未验证

3.4 算子约束限制

  • 仅支持 ND 格式;输入维度 1~8 维
  • 仅支持 fp16/fp32/bf16(输入输出 dtype 一致)
  • 仅提供 aclnn 接口,暂不支持图模式(Graph Mode)
  • 归约维长度非 32B 对齐(如 R=7/9/15 等)时走串行路径,不启用向量化/跨核加速
  • two-stage 跨核仅对 M≤64 && R>2048 的场景启用(其他场景单 kernel 执行)
  • correction ≥ N 时按 PyTorch 语义输出 NaN/INF(由 host 侧处理)

💡 备注(选填)

likedislike
GavinGavinCollaborators
Aug 27 Added label: requirement
Gavin
GavinCollaborators
Aug 27 Comments:

/assign @gavinhhr

likedislike
CANN-robotCANN-robotCollaborators
Aug 27 Assign gavinhhr as responsible person
GavinGavinCollaborators
Aug 27 Associated pull request
songkai111Collaborators
Sep 19 Comments:

你好,由于该issue较长时间未贡献,我们将做issue关闭处理,如有需求请重新打开。

likedislike
Ssongkai111Collaborators
Sep 19 changed custom state from 进行中 to 已拒绝
Ssongkai111Collaborators
Sep 19 Close issue
CANN-robotCANN-robotCollaborators
12 days ago Added label: resolved