ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CANN ops-nn BatchNorm 算子深度解析:训练/推理双模式实现与图模式调用实战指南

CANN ops-nn BatchNorm 算子深度解析:训练/推理双模式实现与图模式调用实战指南 人工智能算子库深度学习CANNAscend【免费下载链接】ops-nn本项目是CANN提供的神经网络类计算算子库实现网络在NPU上加速计算。项目地址https://gitcode.com/cann/ops-nn点击查看免费下载本文以 CANNCompute Architecture for Neural Networks神经网络算子库 ops-nn 中的 BatchNorm 算子为对象系统讲解其在 NPU 上的批量归一化计算原理、训练与推理两种工作模式下的输入输出语义、全部可配置参数并结合算子 IR 定义、Shape 推导、Tiling 计算与 Kernel 实现源码给出通过算子 IR 构图GEIR方式在昇腾硬件上调用该算子的完整可运行样例。读完本文你将掌握 BatchNorm 算子的参数语义、训练/推理差异、源码级实现路径以及如何基于 算子 IR 定义 完成一次真实的图模式调用。产品支持情况根据 README 文档 的官方声明BatchNorm 算子对以下产品系列均提供支持产品是否支持Ascend 950PR 950DT 系列产品√Atlas A3 系列产品√Atlas A2 系列产品√Atlas 200I/500 A2 推理产品√Atlas 推理系列产品√Atlas 训练系列产品√从源码的 AICore 配置来看batch_norm_def.cpp 中为ascend950与ascend350两代昇腾芯片注册了 AI Core 算子配置OpAICoreConfig而 op_kernel/batch_norm_apt.cpp 中对应的arch35目录存放了内核实现这与上表所列产品系列Ascend 950 系列、Atlas A3/A2 系列均基于相应芯片架构相互印证。功能说明与计算公式算子功能BatchNorm 算子对一个批次batch的数据执行批量归一化处理。归一化之后生成的数据其统计结果为0 均值、1 标准差即y (x - E(x)) / sqrt(Var(x) ε) * γ β。具体而言均值E(x)与方差Var(x)需要在算子内部计算得到ε是一个极小的浮点数用于防止分母为 0 的情况γscale与βoffset是可学习的仿射参数。计算公式$$y \frac{(x - E(x))}{\sqrt{Var(x) ε}} * γ β$$其中各符号含义如下符号含义E(x)输入 x 的均值算子内部计算Var(x)输入 x 的方差算子内部计算ε极小浮点数防止除零对应属性epsilon默认1e-4fγ缩放权重对应输入scaleβ偏置对应输入offset训练与推理两种模式从 算子 IR 定义注释 可以确认BatchNorm 通过属性is_training区分两种工作模式两种模式的计算路径与输入要求有本质差异训练模式is_trainingtrue默认算子内部计算当前批次的均值与方差用于归一化并同步更新运行时均值/方差moving mean/variance为后续推理阶段保存统计量。推理模式is_trainingfalsemean与variance变为必选输入直接使用训练阶段保存的统计量做归一化不再计算批次统计量。这一语义在 op_host/batch_norm_def.cpp 中得到印证mean与variance两个输入在 OpDef 中均被声明为OPTIONAL可选其是否必填取决于运行模式。参数说明以下参数表完整继承自 README 文档并结合 算子 IR 定义 与 OpDef 注册 补充了数据类型约束与默认值来源。输入参数参数名输入/输出/属性描述数据类型数据格式x输入进行批量归一化的输入张量对应公式中的x。shape 维度至少是 2D。FLOAT32、FLOAT16、BFLOAT16NCHW/NHWC/NCDHW/NDHWC/NDscale输入进行批量归一化的权重对应公式中的γ。一个 1D 张量shape 与输入 x 的维度 C 相同如果输入 x 是 ND 格式shape 与输入 x 的第 2 维度相同。FLOAT32NDoffset输入进行批量归一化的偏置值对应公式中的β。一个 1D 张量shape 与入参 scale 保持一致。FLOAT32NDmean可选输入训练场景训练期间动量更新前的均值为可选输入推理场景推理期间使用的均值为必选输入对应公式中的E(x)。一个 1D 张量shape 与入参 scale 保持一致。FLOAT32NDvariance可选输入训练场景训练期间动量更新前的方差为可选输入推理场景推理期间使用的方差为必选输入对应公式中的Var(x)。一个 1D 张量shape 与入参 scale 保持一致。FLOAT32ND属性Attribute参数名输入/输出/属性描述数据类型数据格式epsilon可选属性添加到方差中的小值以避免除以零对应公式中的ε。默认值为1e-4f。FLOAT32-data_format可选属性指定输入 x 的数据格式支持NHWC、NCHW、NDHWC、NCDHW。默认值为NHWC。STRING-is_training可选属性标记是否训练场景true表示训练场景false表示推理场景。默认值为true。BOOL-exponential_avg_factor可选属性训练期间用于更新动量平均值的因子。默认值为1.0f。FLOAT32-以上四个属性的默认值在 算子 IR 定义 中通过REG_OP的ATTR宏逐一登记.ATTR(epsilon, Float, 1e-4f) .ATTR(data_format, String, NHWC) .ATTR(is_training, Bool, true) .ATTR(exponential_avg_factor, Float, 1.0f)同时在 OpDef 注册 中保持一致其中exponential_avg_factor的默认常量定义在文件头部DEFAULT_EXPONENTIAL_AVG_FACTOR 1.0。输出参数参数名输入/输出/属性描述数据类型数据格式y输出表示批量归一化后的输出结果对应公式中的y。数据类型、数据格式、shape 与输入 x 保持一致。FLOAT32、FLOAT16、BFLOAT16NCHW/NHWC/NCDHW/NDHWC/NDbatch_mean输出训练模式当前批次的均值推理模式等于输入 mean。一个 1D 张量shape 与入参 scale 保持一致。FLOAT32NDbatch_variance输出训练模式当前批次的方差推理模式等于输入 variance。一个 1D 张量shape 与入参 scale 保持一致。FLOAT32NDreserve_space_1输出为梯度计算预留。训练模式等于输出 batch_mean推理模式等于输入 mean。一个 1D 张量shape 与入参 scale 保持一致。FLOAT32NDreserve_space_2输出为梯度计算预留。训练模式保存 inv_var1/sqrt(epsilon variance)用于反向梯度计算中重用推理模式等于输入 variance。一个 1D 张量shape 与入参 scale 保持一致。FLOAT32NDreserve_space_3输出一个只包含一个元素的一维张量仅出于与 TensorFlow 兼容的目的而存在数据无意义。shape 为[1]。FLOAT32ND类型约束细节IR 定义中通过DATATYPE宏声明了两个类型模板——T1作用于x与y支持{DT_FLOAT, DT_FLOAT16, DT_BF16}T2作用于scale、offset、mean、variance及全部统计量输出固定为{DT_FLOAT}。也就是说即使输入x是 FLOAT16/BFLOAT16所有的通道级参数scale/offset/mean/variance以及batch_mean、batch_variance、reserve_space_*输出一律以 FLOAT32 参与计算这与 batch_norm_infershape.cpp 中InferDataType的实现完全一致。动量更新语义源码级补充关于exponential_avg_factor与训练模式下动量统计量的更新IR 定义注释 给出了明确的更新公式new_mean (1 - factor) * old_mean factor * batch_meanmean输入在训练模式下作为动量均值的初始化起点当提供该输入时用于初始化动量均值未提供时从 0 开始variance输入在训练模式下作为动量方差的初始化起点未提供时从 1 开始在 Kernel 实现 中可以看到训练路径会根据useRunningMeanVar即是否传入 mean/variance决定是否计算oneSubMomentum 1 - momentum并在CalculateRuningMeanVarVF中完成动量均值和动量方差的更新训练模式下batch_variance的计算还带有Bessel 校正无偏估计besselCorrectionFactor reduceNum / (reduceNum - 1)见 batch_norm_full_reduce.h这一点与 PyTorch 等框架在训练时使用无偏方差的口径一致。约束说明根据 README 文档BatchNorm 算子无额外约束。可以理解为只要输入满足上表列出的数据类型、shape 维度和数据格式组合例如 4D 张量使用 NCHW/NHWC5D 张量使用 NCDHW/NDHWC任意维度使用 ND即可正常调用。图模式调用方式BatchNorm 算子支持图模式调用通过算子 IR 构图方式调用 BatchNorm 算子即直接基于 算子 IR 定义 中的op::BatchNorm构造计算图再交由 GEGraph Engine完成构图、编译与执行。调用方式样例代码说明图模式调用test_geir_batch_norm.cpp通过算子 IR 构图方式调用 BatchNorm 算子。样例整体流程test_geir_batch_norm.cpp 演示了一次完整的 GEIRGraph Engine Intermediate Representation调用其执行流程为调用ge::GEInitialize(global_options)初始化 GE设置ge.exec.deviceId0、ge.graphRunMode1创建ge::Graph计算图图名tc_ge_irrun_test在CreateOppInGraph中通过宏快速声明输入占位算子、常量算子并接入op::BatchNorm(batchNorm_1)为 BatchNorm 算子设置输入/输出 TensorDesc、属性并加入图创建ge::Session通过session-AddGraph(graph_id, graph, graph_options)将图加入会话通过aclgrphDumpGraph将图 dump 为 txt 便于检查通过session-RunGraph(graph_id, input, output)执行图将输入/输出数据写为.bin文件并逐元素打印输出结果通过GEGetErrorMsgV2/GEGetWarningMsgV2获取运行期错误与告警信息最后GEFinalize收尾。构图核心代码解读样例中的构图入口函数CreateOppInGraph定义了如下张量 shape 与属性源码位于 test_geir_batch_norm.cppauto batchNorm_1 op::BatchNorm(batchNorm_1); std::vectorint64_t xShape {2, 3, 4, 5}; // 输入 x4DN2, H3, W4, C5 std::vectorint64_t channelShape {5}; // scale/offset/mean/variance通道维度 std::vectorint64_t oneShape {1}; // reserve_space_3单元素 ADD_INPUT(1, x, inDtype, xShape); ADD_INPUT(2, scale, inDtype, channelShape); ADD_INPUT(3, offset, inDtype, channelShape); ADD_INPUT(4, mean, inDtype, channelShape); ADD_INPUT(5, variance, inDtype, channelShape); ADD_OUTPUT(1, y, inDtype, xShape); ADD_OUTPUT(2, batch_mean, inDtype, channelShape); ADD_OUTPUT(3, batch_variance, inDtype, channelShape); ADD_OUTPUT(4, reserve_space_1, inDtype, channelShape); ADD_OUTPUT(5, reserve_space_2, inDtype, channelShape); ADD_OUTPUT(6, reserve_space_3, inDtype, oneShape); ADD_INPUT_ATTR(epsilon, 1e-4f); ADD_INPUT_ATTR(data_format, NHWC); ADD_INPUT_ATTR(is_training, true); ADD_INPUT_ATTR(exponential_avg_factor, 1.0f);其中x使用 4D shape{2, 3, 4, 5}对应data_formatNHWC时 N2、H3、W4、C5通道数为 5scale、offset、mean、variance均为长度为 5与通道数一致的 1D 张量六个输出中y与x同 shapebatch_mean/batch_variance/reserve_space_1/reserve_space_2与scale同 shapereserve_space_3为[1]四个属性均使用默认值即epsilon1e-4f、data_formatNHWC、is_trainingtrue、exponential_avg_factor1.0f。宏ADD_INPUT内部通过op::Data构造输入占位算子并调用GenOnesDataFloat32将输入初始化为全 2 的 FLOAT32 数据ADD_CONST_INPUT则通过op::Const构造常量输入。这种宏封装的方式便于扩展更多输入规模是理解 GEIR 构图的良好起点。输出数据核对样例在RunGraph成功后会遍历所有输出将输出数据写入./tc_ge_irrun_test_0008_npu_output_*.bin并逐元素打印。由于输入数据为常量全 2且训练模式下batch_mean即为当前批次的均值读者可通过输出与手工计算公式代入互相印证算子的正确性。底层实现原理源码级扩展BatchNorm 算子在 ops-nn 仓库中的完整实现链路为算子 IR 定义 → Shape/DataType 推导 → Tiling 计算 → Kernel 内核执行下面依次展开。1. 算子 IR 定义op_graph/batch_norm_proto.h 使用REG_OP(BatchNorm)宏完成算子原语注册声明了 5 个输入其中mean、variance为OPTIONAL_INPUT、6 个输出与 4 个属性并约束了T1/T2的数据类型集合。这部分直接决定算子对外暴露的接口语义也是图模式调用op::BatchNorm的编译依据。2. Shape 与 DataType 推导op_host/batch_norm_infershape.cpp 实现InferShape与InferDataTypey的 shape 直接继承x*yShape *xShapebatch_mean、batch_variance、reserve_space_1、reserve_space_2的 shape 直接继承scalereserve_space_3固定为gert::Shape({1})数据类型推导中y与x同类型其余五个统计量输出固定为DT_FLOAT。该推导逻辑在 tests/ut/op_host/test_batch_norm_infershape.cpp 中有对应的单测覆盖构造 x shape{2,3,4,5}、scale shape{5}校验输出 0 为[2, 3, 4, 5]、输出 1 为[5]、输出 5 为[1]与推导实现一一对应。3. Tiling 计算多核切分op_host/arch35/batch_norm_tiling.cpp 注册了Tiling4BatchNorm与TilingPrepare4BatchNormTilingPrepare阶段从平台信息中获取 AIV 核数coreNum、UB 内存大小ubSize、UB 块大小blockSize与向量寄存器长度vectorLength用于后续的切分决策具体的切分实现分布在 op_host/arch35 目录下的多个文件中覆盖FullReduce、Welford 在线算法、BlockSplitR按通道分块、RA多核归约等多种策略从 Kernel 入口 batch_norm_apt.cpp 可以看到不同策略通过TILINGKEY进行标识如TILINGKEY_FULL_REDUCE200000、TILINGKEY_WELFORD_REDUCE300000、TILINGKEY_INFER910000等Tiling 阶段选定的策略会在运行时通过TILING_KEY_IS分发到对应的 Kernel 实现类。4. Kernel 内核实现op_kernel/batch_norm_apt.cpp 定义了 AI Core 内核入口batch_norm按 TilingKey 分发到 11 种实现类可归纳为两大族训练族BatchNormFullReduce、BatchNormWelford、BatchNormBlockSplitR、BatchNormRAFullReduce、BatchNormRAWelford、BatchNormRARBlockSplitR等负责批次均值/方差计算含 Welford 在线更新与 Bessel 校正、动量统计量更新以及归一化后输出y推理族BatchNormInfer、BatchNormInferLastChannel、BatchNormInferLastChannelContinuousA、BatchNormInferLastChannelSmallA、BatchNormInferSmallAB1等直接使用输入的 mean/variance 完成归一化。以训练路径的 batch_norm_full_reduce.h 为例其ProcessUB流程清晰展示了内核的计算管线CopyInX将x按块从全局内存GM搬运到统一缓冲区UBCalculateMeanVarVF在 UB 中计算当前批次的均值与方差生成batch_mean与batch_rstd其中 rstd 即1/sqrt(epsilon variance)CopyInGammaBeta/CopyInRunningMeanVar加载scale、offset及动量均值/方差CalculateRuningMeanVarVF完成动量均值和方差的更新CalculateNormalizeVF执行y (x - batch_mean) * batch_rstd * gamma beta通过EnQue/DeQue双缓冲队列DOUBLE_BUFFER2实现数据搬移与计算的重叠最后CopyOutY写回全局内存。此外batch_norm_base.hbatch_norm_base.h中针对 FLOAT32/FLOAT16/BFLOAT16 提供了统一的加载/存储模板FLOAT16/BFLOAT16 数据先经Cast提升为 FLOAT32 参与运算输出时再降回原精度这也印证了计算在 FLOAT32 精度下完成的实现事实。5. 二进制配置文件op_host/config/ascend950/batch_norm_binary.json以及 ascend350 版本为每种输入数据类型 × 数据格式组合声明了独立的 kernel 二进制文件例如BatchNorm_bfloat16_NCDHW、BatchNorm_float16_NCHW、BatchNorm_float32_NHWC等共覆盖 bfloat16/float16/float32 三种输入类型与 NCDHW/NCHW/NHWC/NDHWC/ND 多种格式组合。配置中的format_match_modeFormatFixed/FormatDefault进一步约束了输入输出格式的匹配规则是算子编译期选核kernel binary 选择的直接依据。总结BatchNorm 是神经网络训练与推理中最基础的归一化算子之一。在 CANN ops-nn 算子库中它通过 算子 IR 定义对外接口以is_training属性区分训练计算批次统计量 更新动量与推理使用输入统计量两种模式通过 Shape 推导、Tiling 多核切分 与 AI Core Kernel 构成完整的编译-执行链路开发者可参照 test_geir_batch_norm.cpp 以图模式快速完成算子验证并可通过 单测 与 ST 用例 深入核对推导与执行结果。赞分享人工智能算子库深度学习CANNAscend【免费下载链接】ops-nn本项目是CANN提供的神经网络类计算算子库实现网络在NPU上加速计算。项目地址https://gitcode.com/cann/ops-nn点击查看免费下载相关推荐CANN ops-nn GatherV2 算子深度解析从计算原理到 aclnn/图模式双调用实战CANN ops nn GatherV2 算子深度解析从计算原理到 aclnn/图模式双调用实战 GatherV2 是 CANN ops nn 算子库中实现「人工智能算子库深度学习CANNAscendCANN ops-nn SigmoidFocalLoss 算子深度解析原理、参数、源码实现与 GE 图模式调用CANN ops nn SigmoidFocalLoss 算子深度解析原理、参数、源码实现与 GE 图模式调用 SigmoidFocalLoss 是 CANN人工智能算子库深度学习CANNAscendCANN ops-nn SoftplusGrad 算子深度解析Softplus 反向传播原理与图模式调用实战CANN ops nn SoftplusGrad 算子深度解析Softplus 反向传播原理与图模式调用实战 SoftplusGrad 是 CANN ops桌面应用系统编程上一篇mp-html表格渲染原理如何在小程序中完美显示复杂表格下一篇探索高效邮件管理的未来NeoMutt 开源项目创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表