ARTICLE DETAIL

资讯详情

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

CANN ascend-transformer-boost Elewise 逐元素算子深度解析:参数配置、InferShape 推导与 Runner 分发机制

CANN ascend-transformer-boost Elewise 逐元素算子深度解析:参数配置、InferShape 推导与 Runner 分发机制 CANN ascend-transformer-boost Elewise 逐元素算子深度解析参数配置、InferShape 推导与 Runner 分发机制【免费下载链接】ascend-transformer-boost本项目是CANN提供的是一款高效、可靠的Transformer加速库基于华为Ascend AI处理器提供Transformer定制化场景的高性能融合算子。项目地址: https://gitcode.com/cann/ascend-transformer-boostElewise 是 CANN ascend-transformer-boost 加速库中最基础也最高频的一类算子集合它在一个 Operation 中统一承载了 19 种逐元素element-wise计算涵盖 Cast、Add、Mul、Sin/Cos/Tanh、逻辑比较以及量化/反量化等场景广泛用于 Transformer 模型的激活、归一化前后处理和量化部署环节。本文以仓库中的 Elewise 知识条目及其路由文件为主线结合 参数头文件、Operation 实现、Ops Runner 与 使用示例 等源码证据帮助你完整掌握 Elewise 的参数语义、平台约束、形状推导规则和底层执行路径从而在实际业务中正确配置并高效使用该算子。Elewise 是什么一个 Operation十九种逐元素计算在 ascend-transformer-boost 中Elewise 是一个OperationBase派生类见 elewise_operation.h通过枚举字段elewiseType区分具体的计算语义。其官方定义位于 infer_op_params.h常用的逐元素数值计算集合。ELEWISE_ADD、ELEWISE_MUL、ELEWISE_REALDIV、ELEWISE_SUB 计算类型将会对输入进行广播后再进行指定操作。输入 x、y 对应维度的对应值要求相同或至少其中一个为 1。Elewise 家族共定义 20 个枚举值含ELEWISE_UNDEFINED哨兵与ELEWISE_TYPE_MAX边界值可按输入数量划分为三类类别输入数类型一元运算1ELEWISE_CAST类型转换、ELEWISE_MULS乘标量、ELEWISE_COS、ELEWISE_SIN、ELEWISE_NEG取反、ELEWISE_QUANT量化、ELEWISE_LOGICAL_NOT、ELEWISE_DYNAMIC_QUANT动态量化、ELEWISE_TANH二元运算2ELEWISE_ADD、ELEWISE_MUL、ELEWISE_REALDIV、ELEWISE_LOGICAL_AND、ELEWISE_LOGICAL_OR、ELEWISE_LESS、ELEWISE_GREATER、ELEWISE_SUB、ELEWISE_EQUAL三元运算3ELEWISE_QUANT_PER_CHANNEL逐通道量化、ELEWISE_DEQUANT_PER_CHANNEL逐通道反量化输入/输出数量的映射关系在 elewise_operation.cpp 中通过inTensorNumTable表驱动实现一元运算输入 1 个 tensorELEWISE_ADD等二元运算输入 2 个 tensor量化类三元运算输入 3 个 tensor。输出方面除ELEWISE_DYNAMIC_QUANT外其余类型均输出 1 个 tensor而动态量化输出 2 个非对称量化时输出 3 个。ElewiseParam 参数结构详解Elewise 的全部配置收敛在atb::infer::ElewiseParam结构体中共 4 个字段和 2 个内嵌子结构字段类型默认值说明elewiseTypeElewiseTypeELEWISE_UNDEFINED计算方式必须显式指定且不能取边界值quantParamQuantParam见下量化非每通道所需参数mulsParamMulsParam见下向量乘值所需参数outTensorTypeaclDataTypeACL_DT_UNDEFINED指定类型转换Cast输出的数据类型QuantParam内嵌结构包含三个实际参数inputScalefloat默认1.0f量化的步长用于ELEWISE_QUANT非每通道量化场景代码中会原样透传给底层AsdOps::OpParam::Elewise的inputScaleasymmetricbool默认false动态量化是否使用非对称量化false表示对称量化true表示非对称。它直接决定ELEWISE_DYNAMIC_QUANT的输出 tensor 数量非对称时额外输出 zero pointinputOffsetint默认0量化的偏移度同样透传给底层内核参数。MulsParam内嵌结构仅包含一个实际参数varAttrfloat默认0.0f向量乘的值作用于ELEWISE_MULS类型实现y x * varAttr的逐元素标量乘法。注意ELEWISE_DYNAMIC_QUANT不支持非对称量化以外的限制以及ELEWISE_QUANT/ELEWISE_DEQUANT_PER_CHANNEL的平台约束详见下文平台适配与使用约束。源码文件地图与推荐阅读顺序Elewise 的算子层实现集中在src/ops/ops_infer/elewise/目录共 10 个文件知识路由文件.agent/knowledge/routing/elewise.md给出了每个文件的角色定位#文件角色1aclnn_ascend_quant_runner.cppACLNN RunnerAscend 950 逐通道量化2aclnn_ascend_quant_runner.hACLNN Runner 接口3aclnn_dynamic_quant_runner.cppACLNN RunnerAscend 950 动态量化4aclnn_dynamic_quant_runner.hACLNN Runner 接口5elewise_aclnn_runner.cppACLNN Runner通用逐元素6elewise_aclnn_runner.hACLNN Runner 接口7elewise_operation.cppOperation 定义InferShape / Runner 分发8elewise_operation.hOperation 定义头文件9elewise_ops_runner.cpp原生 Ops Runner10elewise_ops_runner.h原生 Ops Runner 接口按路由文件建议的阅读顺序可先读elewise_operation.h掌握输入输出数量和 InferShape 签名再读elewise_operation.cpp理解CreateRunner()的决策逻辑之后按需深入三个 ACLNN Runner 或原生elewise_ops_runner.cpp的调用链。算子层对应的底层 Kernel 目录为 src/kernels/kernels/elewise参数头文件为 include/atb/infer_op_params.h。平台适配与使用约束CreateOperation模板特化elewise_operation.cpp在创建 Operation 时会做一系列平台与参数校验这些约束在实际使用中必须满足动态量化与逐通道量化仅在 Ascend 950 上走 ACLNN当平台为ASCEND_950且类型为ELEWISE_DYNAMIC_QUANT或ELEWISE_QUANT_PER_CHANNEL时会分别加载AclnnDynamicQuantRunner、AclnnAscendQuantRunner对应的 aclnn 函数加载失败则报 Load aclnn function failed, please check your CANN version.。逐通道反量化仅支持 Atlas 800I A2 推理产品ELEWISE_DEQUANT_PER_CHANNEL在非 910B 平台直接返回ERROR_INVALID_PARAM日志提示 Elewise dequant only support Atlas 800I A2 inference product。非每通道量化仅支持 910B 与 Ascend 950ELEWISE_QUANT在其他产品系列上不支持。动态量化不支持非对称ELEWISE_DYNAMIC_QUANT与quantParam.asymmetric true组合会被直接拒绝Elewise dynamic quant doesnt support asymmetric。类型合法性elewiseType必须处于ELEWISE_UNDEFINED与ELEWISE_TYPE_MAX之间否则报 Please enter the correct elewiseType。通用 ACLNN 加载创建任何 Elewise Operation 前都会调用ElewiseAclnnRunner::LoadMethod()预加载 aclnn 函数。此外构造函数的opIniTableelewise_operation.cpp展示了不同平台下的内核配置名差异310B 平台为ELEWISE_CAST、ELEWISE_MULS、ELEWISE_ADD、ELEWISE_MUL选择带Atlas200I500A2后缀的内核配置Ascend 950 平台为ELEWISE_QUANT、ELEWISE_DYNAMIC_QUANT选择Ascend950后缀配置非对称动态量化还会追加Asymmetric后缀。这也意味着同一份 API 参数在不同硬件系列上会自动路由到不同的底层内核实现。InferShape 推导逻辑输出形状与类型如何确定Elewise 的 InferShape 在 elewise_operation.cpp 中按类型分派到不同的推导函数是理解该算子行为的关键单输入类型MULS/COS/SIN/NEG/LOGICAL_NOT/TANH输出 shape 与输入完全一致仅需拷贝inTensorDescs[0]。ELEWISE_CAST类型转换默认行为是 FP32 与 FP16 互转——输入为ACL_FLOAT时输出ACL_FLOAT16否则输出ACL_FLOAT若显式指定outTensorType则仅允许ACL_FLOAT16、ACL_FLOAT、ACL_INT32、ACL_INT64、ACL_BF16五种目标类型。ELEWISE_QUANT量化非 Ascend 950 平台要求输入最后一维按 32 对齐lastDim % 32 0且输入必须为 FP16输出为 INT8Ascend 950 平台放宽为 FP32/FP16/BF16 均可输出 INT8 或outTensorType指定的类型。二元运算与广播ELEWISE_ADD、ELEWISE_MUL、ELEWISE_REALDIV、ELEWISE_SUB、ELEWISE_LESS、ELEWISE_GREATER、ELEWISE_EQUAL走InferShapeCommon规则为两输入 dtype 必须一致输出维数为两者较大者从尾维度逐位对齐两个维度要么相等、要么其一为 1即标准广播语义否则报 cannot broadcast this dim。比较类LESS/GREATER/EQUAL输出 dtype 固定为ACL_INT8ELEWISE_LOGICAL_AND/ELEWISE_LOGICAL_OR在公共推导基础上同样将输出固定为ACL_INT8。ELEWISE_DYNAMIC_QUANT逐行动态量化输入维度数必须 ≥ 2输出 0 为量化后的 INT8 数据输出 1 为 scaleFP32维数减一非对称时输出 2 为 zero point。形状推导之外还有严格的维数上限校验InferShapeCheckDynamicQuant/InferShapeCheckDynamicQuant310P平台输入 dtype最后一维上限Atlas 800I A2910BFP1626624Atlas 800I A2910BBF167552其他 Atlas 推理产品310PFP164096同时InferShapeImplDynamicQuant支持通过outTensorType指定 FP8 输出ACL_HIFLOAT8、ACL_FLOAT8_E5M2、ACL_FLOAT8_E4M3FN。量化类 InferShape 校验Ascend 950 上的ELEWISE_QUANT_PER_CHANNEL要求 IN_TENSOR_1 要么所有维度为 1要么其尾部维度与 IN_TENSOR_0 完全一致且 IN_TENSOR_1 与 IN_TENSOR_2 的 shape 相同IN_TENSOR_2 允许为空 tensor见GetEmptyInTensorPermissionselewise_operation.cpp。Runner 分发机制四条执行路径的选择逻辑CreateRunner()elewise_operation.cpp是 Elewise 的执行入口分发器其决策顺序为Ascend 950 ELEWISE_DYNAMIC_QUANT→AclnnDynamicQuantRunnerAscend 950 ELEWISE_QUANT_PER_CHANNEL→AclnnAscendQuantRunnerAscend 950 其他常见类型CAST、MULS、COS、SIN、ADD、LESS、MUL、GREATER、REALDIV、LOGICAL_NOT、QUANT、SUB→ElewiseAclnnRunner其余所有情况含 910B、310B 等平台→ 原生ElewiseOpsRunner。也就是说Ascend 950 上 Elewise 全面走 ACLNN 加速接口而老平台则回退到库内自研内核路径。ElewiseAclnnRunner、AclnnDynamicQuantRunner、AclnnAscendQuantRunner三个 ACLNN Runner 负责 Workspace 计算与aclnnXXXAPI 的调用封装对应 elewise_aclnn_runner.cpp、aclnn_dynamic_quant_runner.cpp、aclnn_ascend_quant_runner.cpp这解释了知识条目中 Runner: ops_runner / aclnn_runner 的双通道设计。OpsRunner 内核图构建原生执行链路当走原生路径时ElewiseOpsRunnerelewise_ops_runner.cpp会构建一个单节点 KernelGraphSetIntensor根据GetIntensorSize()与 Operation 侧同一张输入数量表把输入按 1/2/3 个 tensor 挂载到节点inTensorsSetOuttensor将ElewiseParam翻译为AsdOps::OpParam::Elewise动态量化按asymmetric决定输出 2 或 3 个 tensorELEWISE_MULS透传varAttrELEWISE_QUANT透传inputScale/inputOffset此时varAttr置 0ELEWISE_CAST通过GetOutTensorType把aclDataType映射为 Mki 的TensorDType支持 INT8/FLOAT/FLOAT16/INT32/INT64/BF16节点描述统一为{0, ElewiseOperation, elsewiseParam}并通过REG_RUNNER_TYPE(ElewiseOpsRunner)与REG_OP_PARAM(AsdOps::OpParam::Elewise)完成注册。对应地src/kernels/kernels/elewise 目录下按子算子组织了内核实现add、sub、mul、muls、realdiv、cast、cos、sin、tanh、neg、quant、dynamic_quant、logical_and/not/or、less、greater、equal、simple_broadcast广播通用内核以及tiling目录与 ElewiseType 枚举一一呼应便于按需深入某个具体计算的 Kernel 细节。快速上手ELEWISE_MUL 最小示例仓库提供了可直接编译运行的示例 example/op_demo/elewise/elewise_demo.cpp核心流程展示了创建 Elewise Operation 的标准姿势#include ../demo_util.h using namespace atb; using namespace std; const int VECTOR_SIZE 4; // 向量的大小 const float INIT_VALUE 2.0f; // 向量的初始值 // 准备 atb::VariantPack 中的所有输入 tensor atb::Status PrepareInTensor(atb::Context *contextPtr, aclrtStream stream, atb::SVectoratb::Tensor inTensors) { uint32_t dim0 2; uint32_t dim1 2; // 创建两个 2x2 的 FP16 tensor初始值均为 2.0 std::vectorfloat tensormul0(VECTOR_SIZE, INIT_VALUE); atb::Tensor tensorMul0; CHECK_STATUS(CreateTensorFromVector(contextPtr, stream, tensormul0, ACL_FLOAT16, aclFormat::ACL_FORMAT_ND, {dim0, dim1}, tensorMul0)); std::vectorfloat tensormul1(VECTOR_SIZE, INIT_VALUE); atb::Tensor tensorMul1; CHECK_STATUS(CreateTensorFromVector(contextPtr, stream, tensormul1, ACL_FLOAT16, aclFormat::ACL_FORMAT_ND, {dim0, dim1}, tensorMul1)); inTensors {tensorMul0, tensorMul1}; // 按顺序放入输入 tensor return atb::ErrorType::NO_ERROR; } // 创建 ELEWISE_MUL 的 Operation并设置参数 atb::Status PrepareOperation(atb::Operation **op) { atb::infer::ElewiseParam mulParam; mulParam.elewiseType atb::infer::ElewiseParam::ElewiseType::ELEWISE_MUL; return atb::CreateOperation(mulParam, op); }main中的执行流程与仓库其他算子示例一致aclInit→aclrtSetDevice→atb::CreateContext→aclrtCreateStream→ 创建 Operation → 填充VariantPack.inTensors/outTensors→op-Setup()计算 workspace →op-Execute()执行并可用atb::CreateOperation返回的 Operation 指针复用多次。换用其他计算类型时只需修改mulParam.elewiseType并按照上文的输入数量表补充对应数量的 tensorELEWISE_MULS需额外设置mulsParam.varAttr量化类需设置quantParam字段。测试覆盖如何验证 Elewise 正确性Elewise 在仓库测试体系中覆盖全面可作为自测与回归参考Kernel 级测试tests/apitest/kernelstest/elewise 下包含 11 个 Python 用例覆盖各类逐元素计算的精度验证高层算子测试tests/high_level_test/ElewiseOperation 下包含 9 个 CSV 用例、1 个 Python 用例与 1 个 C 用例CSV 中定义了输入 shape、dtype、参数组合与期望输出可对照学习每种elewiseType的合法参数范围算子注册自检src/ops/ops_infer/elewise 中elewise_operation.cpp的REG_OP_PARAM与CreateOperation模板特化共同保证参数解析、JSON 序列化GetParamJson与符号检查链路的完整性。小结Elewise 是理解 ascend-transformer-boost 算子工程化的极佳样本它以单一ElewiseParam参数结构覆盖 19 种逐元素语义通过elewiseType表驱动统一输入输出数量、InferShape 与内核配置选择并在不同硬件平台上自动分流到 ACLNN 或原生 Kernel 路径。掌握本文的参数表、平台约束与 Runner 分发规则后你便能在 Transformer 模型的算子编排中准确选用合适的 Elewise 类型并快速定位形状推导或平台适配类问题。【免费下载链接】ascend-transformer-boost本项目是CANN提供的是一款高效、可靠的Transformer加速库基于华为Ascend AI处理器提供Transformer定制化场景的高性能融合算子。项目地址: https://gitcode.com/cann/ascend-transformer-boost创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表