资讯动态

CANN ops-nn 仓库 EluGrad 算子深度解析:ELU 反向传播梯度计算与 NPU 图模式调用指南

发布时间:2026/9/18 18:14:57 来源:尧图企业网站定制
CANN ops-nn 仓库 EluGrad 算子深度解析ELU 反向传播梯度计算与 NPU 图模式调用指南【免费下载链接】ops-nn本项目是CANN提供的神经网络类计算算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-nnEluGrad 是 CANN 神经网络算子库 ops-nn 中 ELU 激活函数的反向传播梯度算子输入反向传播梯度grads与 ELU 前向输出activations输出y (min(activations, 0) 1) * grads支持 FLOAT、FLOAT16、BFLOAT16 三种数据类型与 ND 数据格式已适配 Ascend 950PR/950DT、Atlas A2/A3 训练与推理系列产品。本文以 activation/elu_grad/README.md 为核心骨架结合算子 IR 原型、Host 侧 Tiling、Kernel 侧 AscendC 实现、框架插件与测试用例完整讲解其数学原理、产品支持矩阵、参数约束、图模式调用方式与源码级实现机制帮助你快速理解并在自有推理/训练网络中正确接入该反向算子。产品支持情况EluGrad 算子在不同硬件产品上的支持情况如下表所示来源activation/elu_grad/README.md产品是否支持Ascend 950PR / Ascend 950DT√Atlas A3 训练系列产品 / Atlas A3 推理系列产品√Atlas A2 训练系列产品 / Atlas A2 推理系列产品√Atlas 200I/500 A2 推理产品×Atlas 推理系列产品√Atlas 训练系列产品√从工程配置看算子注册的 AICore 芯片配置与文档支持矩阵保持一致elu_grad_def.cpp 中通过this-AICore().AddConfig(ascend950, aicoreConfig)与this-AICore().AddConfig(ascend350, aicoreConfig)注册了ascend950与ascend350两种芯片型号CMakeLists.txt 中的set(SUPPORT_COMPUTE_UNIT ascend950 ascend350)也对应设置了两类计算单元的编译支持且两种芯片统一使用arch35目录下的 Tiling 实现set(SUPPORT_TILING_DIR arch35 arch35)。其中ascend950对应 Ascend 950 系列950PR/950DTascend350对应 Atlas A2/A3 系列产品所采用的芯片未注册Atlas 200I/500 A2对应的计算单元因此该推理产品不支持本算子。功能说明与计算公式算子功能EluGrad 对应 ELUExponential Linear Unit操作的反向传播梯度。在训练场景中前向计算得到 ELU 的输出activations反向传播时上游传入梯度gradsEluGrad 依据 ELU 前向函数的分段导数规则将二者合成为本层参数的梯度y用于继续向更浅层回传。计算公式文档给出的计算公式为$$ y (min(activations, 0) 1) * grads $$该公式的推导逻辑来自 ELU 前向函数的分段性质当activations 0时前向为线性恒等导数为 1此时min(activations, 0) 0公式退化为y grads当activations 0时前向为指数分支导数为activations 1此时min(activations, 0) activations公式即为y (activations 1) * grads。在 op_kernel/arch35/elu_grad_dag.h 的注释中同样写明// y (min(activation, 0) 1) * grads与文档公式完全一致。参数说明算子共包含两个输入与一个输出全部为必选REQUIRED参数均为 ND 数据格式具体如下来源activation/elu_grad/README.md并对照 elu_grad_def.cpp 与 elu_grad_proto.h 核实参数名输入/输出/属性描述数据类型数据格式grads输入对应 Elu 操作的反向传播梯度FLOAT、FLOAT16、BFLOAT16NDactivations输入与grads具有相同的类型、格式和形状对应 Elu 操作的输出值FLOAT、FLOAT16、BFLOAT16NDy输出公式中的输出张量同gradsND底层原型补充说明在算子 IR 原型 elu_grad_proto.h 中REG_OP(EluGrad)将两个输入与输出的 TensorType 统一声明为{FloatingDataType, DT_BF16}并明确注明grads与activations支持 1D~8D 的 ND 或 5HD 张量y与grads具有相同的类型、格式和形状。同时该原型标注算子与 TensorFlow 框架的EluGrad算子兼容。在算子定义文件 elu_grad_def.cpp 中实际注册支持的数据类型收敛为{ge::DT_BF16, ge::DT_FLOAT16, ge::DT_FLOAT}即 BFLOAT16、FLOAT16、FLOAT格式为FORMAT_ND与 README 参数表完全一致。约束说明原文档对 EluGrad 的约束说明为“无”。从源码实现看运行期仍有以下几类隐含校验需要在调用时保证满足来源elu_grad_tiling_arch35.cpp 中的CalcInputDtype、CalcOutputDtype、CheckShape数据类型约束grads、activations、y三者数据类型必须一致且只能是 FLOAT16、BF16 或 FLOAT输入与输出类型不一致、或类型超出支持范围例如 DT_DOUBLE时 Tiling 直接返回失败形状约束grads、activations与y的形状必须相同形状不一致时校验失败标量处理Tiling 侧通过EnsureNotScalar将标量形状视为长度为 1 的向量处理因此调用时无需为标量单独规避空张量从 Tiling 单元测试看空形状如{1, 0, 2, 64}会触发校验失败。上述约束在 tests/ut/op_host/arch35/test_elu_grad_tiling.cpp 中有对应的失败用例覆盖test_tiling_failed_dtype_input_output_diff_004输入输出类型不同、test_tiling_failed_inputs_dtype_diff_005两个输入类型不同、test_tiling_failed_empty_tensor_006空张量、test_tiling_failed_unsupport_type_007不支持的类型 DT_DOUBLE、test_tiling_failed_inputs_diff_shape_008与test_tiling_failed_input_output_diff_shape_009形状不一致。调用说明文档提供的调用方式为图模式GE Graph 构图运行示例代码为 examples/test_geir_elu_backward.cpp通过 算子IR 构图调用 EluGrad 算子。下面结合示例代码展开讲解。图模式调用的完整流程示例程序展示了通过 GEGraph Engine图模式运行 EluGrad 算子的标准步骤初始化 GE调用ge::GEInitialize(global_options)完成全局初始化其中global_options配置了{ge.exec.deviceId, 0}与{ge.graphRunMode, 1}分别指定执行设备号与图运行模式构建计算图创建ge::Graph graph(tc_ge_irrun_test)通过op::EluGrad(eluGrad1)创建单算子节点并用op::Data包装grads、activations两个输入占位算子后调用set_input_grads/set_input_activations与算子节点建立连接示例中使用GenOnesDataFloat32/GenOnesData生成全 2 的测试输入数据输入形状为{4, 2}设置图输入输出graph.SetInputs(inputs).SetOutputs(outputs)将占位算子集合设为图输入、EluGrad 节点设为图输出创建 Session 并运行ge::Session* session new Session(build_options)创建会话session-AddGraph(graph_id, graph, graph_options)将图加入会话随后session-RunGraph(graph_id, input, output)执行计算图并得到输出张量结果落盘与清理示例将输入输出按tc_ge_irrun_test_0008_npu_input_*.bin、tc_ge_irrun_test_0008_npu_output_*.bin命名写入文件打印每个输出元素最后调用ge::GEFinalize()完成资源释放。示例还演示了aclgrphDumpGraph将图结构 dump 到./dump目录以及通过GEGetErrorMsgV2/GEGetWarningMsgV2获取运行期错误与告警信息。核心构图代码片段如下摘自 examples/test_geir_elu_backward.cppint CreateOppInGraph(DataType inDtype, std::vectorge::Tensor input, std::vectorOperator inputs, std::vectorOperator outputs, Graph graph) { Status ret SUCCESS; // 自定义代码添加单算子定义到图中 auto eluGrad1 op::EluGrad(eluGrad1); std::vectorint64_t xShape {4, 2}; ADD_INPUT(1, grads, inDtype, xShape); ADD_INPUT(2, activations, inDtype, xShape); outputs.push_back(eluGrad1); // 添加完毕 return SUCCESS; }其中ADD_INPUT宏将输入封装为op::Data占位节点设置FORMAT_ND格式与 Host 侧 Placement生成全 2 的 FLOAT32 测试数据后绑定到 EluGrad 节点并注册为图的输入。示例默认以DT_BF16BFLOAT16作为输入数据类型。输入输出数据格式说明从示例的WriteDataToFile与GetDataTypeSize可以看出图模式运行后输入/输出以二进制文件形式落盘文件命名规则为tc_ge_irrun_test_0008_npu_input_index.bin与tc_ge_irrun_test_0008_npu_output_index.bin输出张量可通过Tensor::GetData()直接读取并按元素打印方便与期望结果比对。源码级实现解析算子定义Host 侧注册elu_grad_def.cpp 通过OP_ADD(EluGrad)注册算子关键配置包括输入/输出均为ParamType(REQUIRED)必选参数DataType支持DT_BF16、DT_FLOAT16、DT_FLOAT格式固定为FORMAT_NDDynamicCompileStaticFlag(true)表示按动态编译方式生成静态 tilingKeyDynamicRankSupportFlag(true)与DynamicShapeSupportFlag(true)支持动态 rank 与动态 shape对应 IR 原型中 1D~8D 的形状范围ExtendCfgInfo(opFile.value, elu_grad_apt)指向 Kernel 侧实现文件 elu_grad_apt.cpp。框架适配插件TensorFlow 映射framework/elu_grad_tf_plugin.cpp 通过REGISTER_CUSTOM_OP(EluGrad)完成框架适配.FrameworkType(TENSORFLOW)声明面向 TensorFlow 框架.OriginOpType(EluGrad)与.ParseParamsByOperatorFn(AutoMappingByOpFn)实现同名算子自动映射无需手工解析参数.ImplyType(ImplyType::TVM)声明算子由 TVM 图编译器实现。这与 IR 原型中“兼容 TensorFlow 算子 EluGrad”的说明相互印证。形状推断InferShapeelu_grad_infershape.cpp 直接复用广播形状推断工具InferShape4EluGrad调用InferShape4Broadcast。由于两个输入形状必须一致广播式推断的结果自然等于二者共同的形状输出y与输入形状保持一致。Tiling 计算Host 侧elu_grad_tiling_arch35.cpp 与 elu_grad_tiling_arch35.h 实现算子 Tiling流程如下TilingPrepareForEluGrad在编译准备阶段通过PlatformAscendC获取 AIV 核数coreNum与 UB 内存大小ubSize存入EluGradCompileInfoRunTiling依次执行CalcInputDtype、CalcOutputDtype、CheckShape完成类型与形状校验依据输出数据类型FLOAT16/BF16/FLOAT选择TPL_FP16/TPL_BF16/TPL_FP32模板参数调用elewiseBaseTiling.DoTilingEluGradDagT::OpDag生成 Elewise 逐元素类 Tiling 数据EleBaseTilingDataV2通过GET_TPL_TILING_KEY(scheMode, dType)生成 tilingKey 并设置SetTilingKey、SetBlockDim(tiling-blockNum)申请 16MBASCEND_WORKSPACE 16777216系统 workspace 写入tilingContext-GetWorkspaceSizes(1)。对应 Tiling 参数维度dim0、blockNum、ubFormer、blockFormer、ubLoopOfFormerBlock、ubTailOfFormerBlock等可在 Kernel 侧单元测试 tests/ut/op_kernel/test_elu_grad_apt.cpp 中看到直接赋值示例例如tilingDatafromBin-dim0 256; blockNum 1; ubFormer 1024; blockFormer 256等展示了 Host 侧 Tiling 数据与 Kernel 侧消费方之间的契约关系。Kernel 实现AscendC 算子elu_grad_apt.cpp 是算子入口通过模板参数schMode与dType实例化按dTypeTPL_FP16/TPL_BF16/TPL_FP32分别构造ElementwiseSchschMode, EluGradDaghalf/bfloat16_t/float::OpDagsch.Init(grads, activations, y)绑定输入输出全局内存地址sch.Process()驱动整条流水执行通过REGISTER_TILING_DEFAULT(EleBaseTilingDataV2)与GET_TILING_DATA_WITH_STRUCT从 GM 读取 Tiling 数据KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_AIV_ONLY)声明算子运行在 AIV 核上。计算图 DAG 定义Kernel 侧op_kernel/arch35/elu_grad_dag.h 以算子图DAG方式声明了 EluGrad 的完整计算流水逐节点对应计算公式OpCopyIn0/OpCopyIn1将gradsIn0、activationsIn1从 GM 拷入Cast0/Cast1将两个输入统一 Cast 为 float 中间精度参与计算OpCompareCompareuint8_t, float, COMPARE_MODE_LT将activations与常量 0.0 比较小于模式OpAddsAddsfloat对activations加常量 1.0OpMulsMulfloatgrads * (activations 1)OpSelectSelectuint8_t, float, SELECT_MODE_T_T依据比较结果选择activations 0时取(activations 1) * grads否则取grads与公式(min(activations, 0) 1) * grads等价OpResultCast结果 Cast 回原始数据类型TOpCopyOut写回输出y。MemCfg MemOptCfgMemLevel::LEVEL_2声明数据流经 L2 缓存进行访存优化。elu_grad_struct.hop_kernel/arch35/elu_grad_struct.h中通过ASCENDC_TPL_ARGS_DECL声明scheModeTPL_SCH_MODE_0/TPL_SCH_MODE_1与dTypeTPL_FP16/TPL_BF16/TPL_FP32的模板参数列表供 tilingKey 与 Kernel 模板实例化匹配。编译产物配置op_host/config/ascend950/elu_grad_binary.jsonascend350 下存在同名配置文件按(dtype, format, shape)维度声明了预编译 binary 的匹配规则三个op_list条目分别对应float16、float32、bfloat16三种数据类型格式均为ND形状为-2表示动态形状可匹配任意 shapeformat_match_mode为FormatAgnostic每条目声明bin_filename指向对应数据类型的编译产物如EluGrad_93b3f8e9594b4018902b635fff3a83c5对应 float16。该配置文件与 elu_grad_def.cpp 中声明的三种数据类型一一对应确保算子在运行期能够按输入数据类型命中正确的 binary。测试与验证EluGrad 在仓库中配有完整的 Host 侧与 Kernel 侧测试可用于验证算子正确性Kernel 单元测试tests/ut/op_kernel/test_elu_grad_apt.cpp以elu_grad0, TPL_FP32模板实例运行 256 元素、形状(256)的 float32 用例先通过 gen_data.py 生成输入与期望数据再调用 Kernel 得到输出output.bin后与 golden 数据比对数据生成脚本gen_data.py使用 numpy 在[-2, 2]区间随机生成grads与activations并按公式golden grads * torch.where(activations 0, 1, activations 1)计算 golden 值等价于 README 公式y (min(activations, 0) 1) * grads用法为python gen_data.py (128, 64) float32支持 float32 与 float16 两种 dtypeTiling 单元测试tests/ut/op_host/arch35/test_elu_grad_tiling.cpp以Ascend950平台信息CORE_NUM64、UB_SIZE245760 等模拟 Tiling 上下文覆盖 fp16/bf16/fp32 的 tilingKey分别为 3/5/7正确性并验证 6 类异常场景返回GRAPH_FAILED同时覆盖大 shape{1024,1024}与 1D shape{8192}用例Golden 脚本tests/assets/golden.py通过 TensorFlow 的gen_nn_ops.elu_grad生成基准输出从框架兼容性角度交叉验证本算子结果与框架插件 elu_grad_tf_plugin.cpp 的 TensorFlow 适配形成闭环。总结EluGrad 是 ops-nn 仓库中结构清晰、实现完整的 ELU 反向梯度算子文档明确了产品支持矩阵Ascend 950 系列与 Atlas A2/A3 训练、推理系列与参数契约两输入一输出均为 ND 格式的 FLOAT/FLOAT16/BFLOAT16源码则从 IR 原型、框架映射、形状推断、Tiling、AscendC Kernel 到 DAG 计算图逐层落实了y (min(activations, 0) 1) * grads的数学定义。需要将该算子接入训练网络时可参照 examples/test_geir_elu_backward.cpp 的图模式调用流程结合 elu_grad_binary.json 确认目标数据类型与预编译产物匹配并利用仓库内 Tiling 与 Kernel 单元测试完成正确性验证。【免费下载链接】ops-nn本项目是CANN提供的神经网络类计算算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-nn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价