ascend-transformer-boost 激活算子(Activation)全解析:ActivationParam 参数模型、Runner 决策机制与逐元素执行管线
【免费下载链接】ascend-transformer-boost本项目是CANN提供的是一款高效、可靠的Transformer加速库,基于华为Ascend AI处理器,提供Transformer定制化场景的高性能融合算子。项目地址: https://gitcode.com/cann/ascend-transformer-boost
导读:本文以 CANN ascend-transformer-boost 仓库中的 activation 算子知识条目为骨架,完整讲解该复合激活算子的类型枚举与参数模型(include/atb/infer_op_params.h)、四类 Runner 的平台决策逻辑(src/ops/ops_infer/activation/)、SwiGLU 特有的 Shape 推导约束,以及底层逐元素 Kernel 的 dtype 分发机制(src/kernels/kernels/activation/)。读完本文,你将掌握在 Transformer 场景下如何通过ActivationParam正确创建 GELU、SwiGLU、Swish 等激活算子,理解其在昇腾 950 平台与推理产品上的不同执行路径,并能基于官方 demo(example/op_demo/activation/activation_demo.cpp)快速跑通一个最小示例。
一、算子定位:Tier-M 级复合激活算子
根据知识条目的元数据,activation 在 ascend-transformer-boost 算子体系中定位如下:
op: {name: "activation", category: "activation", tier: "M", type: "composite"} source: repo_path: "src/ops/ops_infer/activation/" kernel_path: "src/kernels/kernels/activation/" param_header: "include/atb/infer_op_params.h"- type: composite:它并非单一计算内核,而是一个复合(Composite)算子,内部聚合了 GELU、SiLU/Swish、SwiGLU、ReLU、Sigmoid、Log、FastGelu 等多种激活函数,由参数
activationType统一调度; - category: activation:归属于激活函数类,服务于 Transformer 中 FFN(前馈网络)的非线性层与注意力打分等场景;
- tier: M:属于中等级别的通用算子,源码分布在推理算子层与底层 Kernel 层两个目录;
- 顶层入口:该目录共 10 个文件,其中包含3 个 ACLNN Runner(
activation/gelu/swiglu_forward),分别对应 activation_aclnn_runner.cpp、gelu_aclnn_runner.cpp、swiglu_forward_aclnn_runner.cpp。
二、参数模型:ActivationParam 与 ActivationType 枚举详解
2.1 ActivationType:9 种激活类型
在 include/atb/infer_op_params.h 中定义了激活类型枚举,这是创建算子时最核心的字段:
| 枚举值 | 含义 | 说明 |
|---|---|---|
ACTIVATION_UNDEFINED = 0 | 未定义 | 默认值,创建算子时视为非法 |
ACTIVATION_RELU | ReLU 激活 | max(x, 0) |
ACTIVATION_GELU | GELU 激活 | 支持 tanh 近似与原始公式两种模式 |
ACTIVATION_FAST_GELU | FastGelu 激活 | 对每个元素做 GELU 近似计算,速度更快且保持较高精度 |
ACTIVATION_SWISH | Swish 激活 | 即 SiLU,x * sigmoid(scale * x),受scale参数控制 |
ACTIVATION_LOG | Log 激活 | 自然对数运算 |
ACTIVATION_SWIGLU_FORWARD | SwiGLU 正向 | 将输入沿指定维拆成两半做门控;Atlas 推理系列产品只支持 32 位对齐的数据 |
ACTIVATION_SWIGLU_BACKWARD | SwiGLU 反向 | 正向激活的反向求梯度,只支持 Atlas 800I A2 推理产品 |
ACTIVATION_FASTER_GELU_FORWARD | FasterGelu | 进一步简化后的 FastGelu,计算速度更快 |
ACTIVATION_MAX | 枚举最大值 | 非激活类型,用于范围校验 |
2.2 ActivationParam:四个可配置字段
struct ActivationParam { enum GeLUMode : int { TANH_MODE = 0, // 默认值,使用 tanh 估算 GELU NONE_MODE, // 使用原始 GELU 计算公式 }; ActivationType activationType = ACTIVATION_UNDEFINED; // 激活函数类型 float scale = 1.0f; // SWISH 激活函数的缩放参数 int32_t dim = -1; // SWIGLU 激活函数的分裂维度 GeLUMode geluMode = TANH_MODE; // GELU 计算模式 uint8_t rsv[8] = {0}; // 预留参数 };参数使用要点(均有源码校验依据):
- activationType 必须落在合法区间:
CreateOperation模板特化在创建算子时即校验activationType <= ACTIVATION_UNDEFINED || activationType >= ACTIVATION_MAX,非法值直接返回ERROR_INVALID_PARAM,见 activation_operation.cpp; - dim 仅对 SwiGLU 有效且只支持 -1:源码中
dim != -1时,SwiGLU 正向/反向会报 "only support splitting dim -1",其他激活类型则报 "does not support splitting dim"。即当前版本中 SwiGLU 固定沿最后一维分裂(dim = -1); - geluMode 控制近似精度:
TANH_MODE走 tanh 近似,NONE_MODE走原始公式。在 ACLNN 路径下该字段被转换为approximate参数传入底层(geluMode == NONE_MODE ? 0 : 1)。
三、Runner 决策机制:平台分支与四类执行器
知识条目第 3 点指出,该算子的执行器(Runner)有四种:ActivationAclnnRunner/GeluAclnnRunner/SwigluForwardAclnnRunner/ActivationOpsRunner。决策逻辑集中在 CreateRunner 中,核心是按平台类型分叉:
ASCEND_950 平台(昇腾 950) ├── ACTIVATION_SWIGLU_FORWARD → SwigluForwardAclnnRunner ├── ACTIVATION_GELU → GeluAclnnRunner └── 其余(SWISH/SIGMOID 等) → ActivationAclnnRunner 其他平台(含 310P 推理产品等) → ActivationOpsRunner3.1 ActivationOpsRunner:Kernel 图执行路径
这是非 950 平台的默认路径,继承自OpsRunner(见 activation_ops_runner.cpp):
- 构建一个单节点
kernelGraph_,节点 OpDesc 由RunnerUtil::GetActivationNodeOpDesc(param_)生成; - 普通激活类型输入输出均为 1 个 Tensor;
SWIGLU_BACKWARD特殊处理为2 个输入(y_grad、x); - 通过
REG_RUNNER_TYPE(ActivationOpsRunner)与REG_OP_PARAM(AsdOps::OpParam::Activation)注册到算子工厂。
3.2 三个 ACLNN Runner:昇腾 950 平台的算子库路径
在 950 平台上,激活函数直接复用 CANN 的 ACLNN 算子库,通过dlopen方式按需加载共享库符号:
- ActivationAclnnRunner:在 activation_aclnn_runner.cpp 中通过
MakeAdaptersByType按激活类型映射到aclnnFastGelu/aclnnGeluV2/aclnnLog/aclnnRelu/aclnnSigmoid/aclnnSwish六组GetWorkspaceSize + Execute函数指针对。Swish 的scale参数通过aclCreateScalar包装为aclScalar传入; - GeluAclnnRunner:专门封装
aclnnGeluV2,approximate由geluMode推导,加载失败时日志提示 "Consider upgrade CANN first!",见 gelu_aclnn_runner.cpp; - SwigluForwardAclnnRunner:封装 swiglu_forward 的 ACLNN 接口,加载失败仅打 WARN 日志并返回
ERROR_CANN_ERROR。
调用链小结:CreateOperation(参数校验)→ActivationOperation::CreateRunner(平台决策)→ RunnerSetup(构建 VariantPack / 获取 WorkspaceSize)→Execute(在指定 stream 上 launch 内核)。其中 ACLNN 路径遵循标准的xxxGetWorkspaceSize → aclrtMalloc → xxxExecute → aclrtSynchronizeStream流程。
四、输入输出约束与 Shape 推导(SwiGLU 特例)
在 activation_operation.cpp 中实现了严格的校验与推导逻辑:
常规激活(RELU/GELU/SWISH/SIGMOID/LOG 等)
- 1 输入 1 输出,输出 Shape 与输入完全一致(逐元素操作);
SetupCheckImpl要求输入输出dimNum与各维度完全相等。
SwiGLU Forward(正向)
- 输入沿
dim(固定 -1,即最后一维)拆成两半做门控,输出在分裂维上的尺寸为输入的一半(dims[splitDim] / 2); - 分裂维取值范围校验:
[-dimNums, dimNums-1]; - Atlas 推理系列(310P)产品约束:输入最后一维(hidden size)必须是32 的倍数,否则返回
ERROR_INVALID_TENSOR_DIM,对应源码中HIDDEN_SIZE_DIM_BASE = 32的判断(activation_operation.cpp)。
SwiGLU Backward(反向,仅 800I A2 推理产品)
- 2 个输入:
inTensor[0] = y_grad(梯度),inTensor[1] = x(正向时的原输入),输出 Shape 与inTensor[1]一致; - 约束
inTensor[1]在分裂维上的尺寸等于inTensor[0]的 2 倍(SPLIT_NUM = 2),其余维度相等; - 正向阶段
x = concat(x_a, x_b),反向梯度按门控公式回传,这正是 FFN 反向训练中 SwiGLU 的求导需求。
五、底层 Kernel:逐元素单阶段管道与 dtype 分发
知识条目第 4 点指出:activation 的计算管道是逐元素(element-wise)单阶段,部分变体支持量化和 dtype 转换。底层 Kernel 位于 src/kernels/kernels/activation/,按函数拆分为独立目录:
fast_gelu/ faster_gelu_forward/ gelu/ gelu_forward/ log/ relu/ sigmoid/ swish/ swiglu_forward/ swiglu_backward/ tiling/ activation_operation.cpp内核分发逻辑在 activation_operation.cpp 的GetBestKernel中实现:先按 activationType 分派,再按输出 dtype 选择具体 Kernel。从源码结构可归纳出的 dtype 支持矩阵(节选):
| 激活类型 | FLOAT32 | FLOAT16 | BF16 |
|---|---|---|---|
| RELU | ReluF32Kernel | — | ReluBF16Kernel |
| GELU | GeluF32Kernel/GeluApproxF32Kernel | GeluF16Kernel/GeluApproxF16Kernel | GeluBF16Kernel/GeluApproxBF16Kernel |
| FAST_GELU | — | FastGeluF16Kernel | FastGeluBF16Kernel |
| SWISH | — | SwishF16Kernel | SwishBF16Kernel |
| LOG | — | LogF16Kernel | LogBF16Kernel |
其中 GELU 的Approx变体对应param.approx != 0(即 tanh 近似模式),同时存在独立 tiling 文件(tiling/activation_tiling.cpp)用于在核间切分数据,契合"逐元素单阶段"的计算特征——每个输出元素只依赖对应的输入元素,无跨元素归约,因此天然适合 tiling 并行与向量化指令。
六、实战示例:创建并运行 GELU / SwiGLU 算子
仓库提供了可直接运行的官方示例 activation_demo.cpp,核心流程如下:
1. 创建算子(参数 + CreateOperation)
// GELU 示例:使用 FasterGelu 变体 atb::infer::ActivationParam opParam; opParam.activationType = atb::infer::ActivationType::ACTIVATION_FASTER_GELU_FORWARD; CHECK_STATUS(atb::CreateOperation(opParam, opPtr)); // SwiGLU 正向示例:沿最后一维分裂 atb::infer::ActivationParam opParam; opParam.activationType = atb::infer::ActivationType::ACTIVATION_SWIGLU_FORWARD; opParam.dim = -1; CHECK_STATUS(atb::CreateOperation(opParam, opPtr));2. 准备 Tensor 与 VariantPack:示例以[BATCH_SIZE=16, SEQ_LEN=1024, HIDDEN_SIZE=4096]的 FP32 张量为例,通过aclrtMemcpy将主机随机数([-100, 100))搬运到 device;SwiGLU 场景下输入 hidden 维需为 2 的倍数(正向输出为其一半)。
3. Setup 与 Execute 两阶段调用:
uint64_t workspaceSize = 0; CHECK_STATUS(op->Setup(variantPack, workspaceSize, context)); // 获取 workspace 大小 uint8_t *workspacePtr = nullptr; if (workspaceSize > 0) { CHECK_STATUS(aclrtMalloc((void **)(&workspacePtr), workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST)); } op->Execute(variantPack, workspacePtr, workspaceSize, context); CHECK_STATUS(aclrtSynchronizeStream(stream)); // 流同步等待 device 计算完成4. 资源释放:依次aclrtFree输入/输出 Tensor 与 workspace,最后atb::DestroyOperation(op)。这也是所有 ATB 算子统一的执行范式。
七、相关算子与扩展方向
知识条目第 5 点提示了 activation 的两个近邻算子,可作为继续深入的方向:
- swiglu_quant(激活 + 量化):位于 src/ops/ops_infer/swiglu_quant/,将 SwiGLU 激活与量化融合,是量化推理场景的典型融合模式;
- fast_gelu / faster_gelu(GELU 变体):底层 Kernel 见 src/kernels/kernels/activation/fast_gelu/ 与 src/kernels/kernels/activation/faster_gelu_forward/,通过多项式近似降低 GELU 计算开销,适用于对精度损失不敏感的 Transformer 推理链路。
八、源码导航速查
| 关注点 | 路径 |
|---|---|
| 参数结构与枚举定义 | include/atb/infer_op_params.h |
| 算子主实现(校验/Shape/Runner 决策) | activation_operation.cpp |
| 非 950 平台 Kernel 图 Runner | activation_ops_runner.cpp |
| 950 平台 ACLNN Runner(×3) | activation_aclnn_runner.cpp、gelu_aclnn_runner.cpp、swiglu_forward_aclnn_runner.cpp |
| 底层 Kernel 分发与 tiling | src/kernels/kernels/activation/ |
| 可运行示例 | activation_demo.cpp |
总结:activation 是 ascend-transformer-boost 中"参数统一、平台分流、内核分派"三层架构的典型代表——上层用ActivationParam统一描述九种激活语义,中层按昇腾 950 与非 950 平台在 ACLNN 与自研 Kernel 图两条路径间决策,底层按 dtype 分发到逐元素 Kernel。理解这条从参数到内核的完整链路,是继续阅读仓库内其他融合算子(如rms_norm、swiglu_quant、mla_preprocess)的最佳起点。
【免费下载链接】ascend-transformer-boost本项目是CANN提供的是一款高效、可靠的Transformer加速库,基于华为Ascend AI处理器,提供Transformer定制化场景的高性能融合算子。项目地址: https://gitcode.com/cann/ascend-transformer-boost
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考