已关闭
[Requirement|需求建议]: 910b的apply_gradient_descent实现 #3429
zhaohujie创建于  6月18日关闭于  7月29日
zhaohujie
zhaohujie
6月18日 创建

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

Backgroud(背景信息)

ApplyGradientDescent 是梯度下降的单步参数原地(inplace)更新算子:

var = var - alpha * delta

ops-nn 仓库中已有 optim/apply_gradient_descent,但它仅支持 Ascend 950:

  • kernel(op_kernel/arch35/)、tiling(op_host/arch35/)、binary config(op_host/config/ascend950/)
    均只存在于 arch35 下;
  • op_host/apply_gradient_descent_def.cpp 中只声明了 AddConfig("ascend950");
  • scripts/kernel/binary_config/ascendc_config.json 中该算子的 compute_units 也只有 ["ascend950"]。

同时,当前 CANN 部署包在 ascend910b 上没有该算子可直调的同语义内置实现(aic-ascend910b-ops-info-*.json
中无该 OpType,也没有对应的 aclnn_apply_gradient_descent.h)。

问题:在 Ascend 910B(Atlas A2)上无法使用该算子 —— 既没有仓库内的原生 AscendC 实现,也没有可直调的内置
基线。该算子在 ascend910b 上存在实现空缺。

Origin(信息来源)

基础软件开发-agent tbe算子迁移

Benefit / Necessity (价值/作用)

  • 应用场景:ApplyGradientDescent 是训练侧最基础的 SGD 参数更新算子,被优化器 / 训练图直接使用。
    Atlas A2(ascend910b)是当前主流训练硬件,缺少该算子会导致相关训练图在 910B 上无法完整落图,或需回退到
    更慢的替代路径(如多算子分解)。
  • 价值:补齐后,910B 上可直接通过 aclnn 或图模式(GEIR)调用该算子,与已有的 Ascend 950 实现形成完整的
    芯片覆盖。
  • 外溢价值:optim/ 下其余 apply_* 系列算子(apply_adam、apply_adam_d、apply_momentum、
    apply_ftrl、apply_adagrad_d 等)当前同样只有 arch35 实现,本需求可作为该系列向 910B 扩展的先例与参考。

Design(设计方案)

在 experimental/optim/apply_gradient_descent_v2/ 下新增面向 ascend910b 的实现,OpType 取
ApplyGradientDescentV2(与顶层 ApplyGradientDescent 区分,避免在共享的 ascendc_config.json 中产生同名
重复条目;参考 experimental/activation/celu_v2 与顶层 activation/celu 的既有先例)。顶层
optim/apply_gradient_descent/ 不做任何改动
,仅作为语义真值参考。

op_kernel —— 经典(classic)AscendC 逐元素 kernel(伪代码)

// 多核:按 512B(256 元素)对齐,把总数据量均分到各 AIV 核
// 单核:按 UB tile 分批处理,TQue 双缓冲;alpha 为标量,Init 阶段一次性读入
for each UB tile:
    CopyIn(var_tile); CopyIn(delta_tile)                  // MTE2
    if dtype is fp16 / bf16:
        Cast(var_f32, var_tile); Cast(delta_f32, delta_tile)
        Axpy(var_f32, delta_f32, -alpha)                  // var - alpha*delta,融合 MAC
        Cast(out_tile, var_f32)
    else:                                                  // fp32
        Muls(delta_tile, delta_tile, alpha)
        Sub(out_tile, var_tile, delta_tile)
    CopyOut(out_tile -> var)                              // MTE3,原地写回
  • 中间计算统一在 fp32 完成(fp16/bf16 先 Cast 到 fp32、算完再 Cast 回原类型),保证精度。
  • dtype 经 TilingKey 分派:fp16 = 1 / fp32 = 2 / bf16 = 3。

op_host:算子 def(AddConfig("ascend910b"))+ elementwise infershape + tiling(多核切分 / UB tile 切分 /
尾块处理 / TilingKey 下发)+ config/ascend910b/ binary config。

对外接口:手写两段式 aclnn 调用路径 aclnnApplyGradientDescentV2GetWorkspaceSize +
aclnnApplyGradientDescentV2(含 L0);另提供 op_graph/ proto + graph_infer 支持图模式(GEIR)调用。

支持范围:dtype float16 / float32 / bfloat16,格式 ND,var 维度 1~8;alpha 为 1 元素标量 Tensor,
var.shape == delta.shape,三者同 dtype。

测试方案:UT(op_host tiling/infershape、op_api aclnn 含异常分支、op_kernel 走 CPU 孪生 ICPU_RUN_KF 跑
真实 kernel)+ ST(ATK 上板精度用例集,vs CPU/torch golden,覆盖 fp16/fp32/bf16 × 1D~4D 及标量 shape、含正 /
负 / 零 alpha)。

性能预期:该算子为 MTE2(GM 读)带宽受限型 —— 每元素读 var + delta、写 var,读带宽约为写的 2 倍。
大 shape 下应接近 HBM 读带宽上限,读流量不可约减;可优化空间主要在读突发对齐与减少与 MTE2 竞争的向量
指令
(例如 fp16/bf16 用一次 Axpy 取代 Muls+Sub)。

likedislike
zhaohujie
zhaohujie
6月18日 评论:

/assign @zhaohujie

likedislike
CANN-robotCANN-robot成员
6月18日 将 zhaohujie 设为负责人
chenqi317成员
7月2日 评论:

你好 请在issue上关联提交的pr
新增算子 建议上sig例会评审https://etherpad-cann.meeting.osinfra.cn/p/sig-ops-nn
请参考https://gitcode.com/cann/ops-nn/blob/master/CONTRIBUTING.md 提交代码贡献

likedislike
zhaohujiezhaohujie
7月12日 修改了issue 的描述
zhaohujiezhaohujie
7月12日 关联了pull request:chore(apply_gradient_descent): remove dev scaffolding, keep contribution only
CANN-robotCANN-robot成员
7月29日 关闭了 issue
CANN-robotCANN-robot成员
7月29日 添加了label:resolved