Operator Fusion 解决单点算子合并Graph Fusion 在更大范围做整图级别的融合。GE 图引擎收到 ATC 编译好的图后不是直接拿去执行——它先跑一遍图优化流水线常量折叠、算子替换、模式匹配、Buffer 复用把几百个节点的散装图压成几十个高质量的执行单元。ONNX 导出的原始图是算子粒度的。一个 Transformer Block 在 ONNX 里有十几个节点Reshape、Transpose、MatMul、Softmax、Add、LayerNorm。每个节点对应一个 Kernel Launch。Graph Compiler 的任务是在不改变计算语义的前提下把这些节点聚合——减少 Kernel 执行次数、减少中间 Tensor 的 DDR 搬运。GE 的图优化流水线四步走固定顺序第一步常量折叠。把编译期已知的 Shape 计算、常量运算直接算出结果删除对应节点。ONNX 里大量 Shape/Reshape/Gather 节点在这一步被消掉——一个 512 节点的 ResNet 图常量折叠后剩约 350 个。第二步算子替换。把通用 ONNX 算子替换成昇腾原生实现。ONNX 的 Softmax 换成昇腾优化的 SoftmaxV2利用了 Vector Unit 的快速 exp 指令MatMul 换成 GEMM 模板Cube Unit 原生 16×16 乘加。替换不改变语义但换了更高效的 Kernel。第三步模式融合。Graph Fusion 的核心步骤。GE 维护了一张融合规则表——哪些算子组合可以合并、合并成什么、合并的约束条件是什么。不是手写的大部分来自 ATC 编译器的自动推导。第四步Buffer 分配。融合后的图节点大幅减少但每个节点内部计算变复杂。GE 在这一步为每个融合算子分配 L1 Buffer决定哪些中间结果可以复用同一块 Buffer。图优化流水线 ONNX 原始图512 节点 ↓ 常量折叠 350 节点 ↓ 算子替换ONNX → Ascend Native 350 节点Kernel 变更 ↓ 模式融合Graph Fusion 核心 120 节点多算子合并 ↓ Buffer 分配 120 节点 L1 Buffer 规划 生命周期表模式融合的工作机制GE 的融合规则表里每条规则定义了一个算子序列 → 融合算子的映射。比如[LayerNorm, MatMul] → FusedLayerNormMatMul [MatMul, Add] → FusedMatMulAdd [MatMul, GeLU, MatMul] → FusedFFN [Softmax, MatMul] → FusedSoftmaxMatMulGE 遍历图在拓扑顺序上做子图匹配。匹配到一组可融合节点后检查三个约束无分支。中间算子非最后一个的输出不能被多方消费。Shape 兼容。算子之间的 Tensor Shape 必须完全匹配中间没有隐式 Broadcast。精度策略一致。融合链上的所有算子必须接受同一种精度策略——不能一半 FP32、一半 FP16。三个条件都满足GE 创建融合节点替换原来的算子链然后继续往下匹配。贪婪策略——能融就融碰到不满足条件的边界才停。融合图在 Runtime 上的执行融合后的图在 GE 里编译成.om文件。Runtime 加载.om时看到的不是原始 ONNX 算子而是融合后的执行单元。每个执行单元内部包含多个原始算子的计算逻辑——一次aclrtLaunchKernel完成全部运算。以 FusedFFNMatMul GeLU MatMul为例Runtime 看到的 FusedFFN 执行流程 1. aclrtLaunchKernel(FusedFFN, stream_3) 2. Kernel 内部 DDR → L1: 加载输入 Tensor 和权重 W1 Cube Unit: MatMul(input, W1) → L1 Buffer A Vector Unit: GeLU(L1 Buffer A) → L1 Buffer B Cube Unit: MatMul(L1 Buffer B, W2) → L1 Buffer C L1 → DDR: 写回最终输出 3. aclrtSynchronizeStream(stream_3)Runtime 完全看不到中间的 MatMul 和 GeLU——它只知道跑 FusedFFN输入 A 输出 C。中间在 L1 上发生了什么GE 和 Runtime 都不干预。Transformer 推理中的融合效果LLaMA-7B一个 Attention Block 的融合前后融合前14 个独立节点 Reshape_Q → Transpose_Q → MatMul_QK → Softmax → MatMul_SV → Transpose_O → Reshape_O → Add → LayerNorm → MatMul_FFN1 → GeLU → MatMul_FFN2 → Add → LayerNorm → 14 次 Kernel Launch Graph Fusion 后4 个融合节点 FusedAttention → FusedResidual → FusedFFN → FusedResidualNorm → 4 次 Kernel Launch14 次 Launch 变 4 次省 10 次aclrtLaunchKernel约 100μs 8 次中间 DDR 写回约 120μs。32 层累计省约 7ms。总推理延迟从 25ms 降到约 18ms。融合的边界不是融得越多越好。单 Kernel 指令长度超过 L1 指令 Cache64KB时Kernel 开始从 DDR 取指令——延迟从个位数 cycle 跳到上百 cycle。融合规则表里标注了每个融合模式的最大算子数——FusedFFN 最多容纳 5 个原始算子FusedAttention 最多容纳 6 个。超出上限的融合候选被自动回退。参考仓库GE 图引擎ATC 编译工具Runtime 运行时CANN 学习中心