CANN 平台 SuperKernel 算子二进制融合:模型图调度优化原理、开启方式与 LongCat-Flash 实战
2026/9/18 9:36:30 网站建设 项目流程

CANN 平台 SuperKernel 算子二进制融合:模型图调度优化原理、开启方式与 LongCat-Flash 实战

【免费下载链接】cann-recipes-infer本项目针对LLM与多模态模型推理业务中的典型模型、加速算法,提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-infer

本篇围绕 cann-recipes-infer 仓库中的 SuperKernel 技术文档展开,系统讲解这一面向模型计算图的调度优化技术:它的二进制融合原理、四类算子级优化与两类网络级优化机制,以及如何在npugraph_ex和 GE 图模式两种后端中实际开启。读完本文,你将掌握 SuperKernel 融合范围的标定方法,并能结合仓库中 LongCat-Flash 优化样例理解“按分核与分流范围标定多个 SuperKernel”的工程实践。

1. 背景:调度层面还剩多少性能空间

提升 LLM 推理性能通常会叠加多种手段:

  • 算子级优化:算子融合、通信-计算重叠、Weight 预取等;
  • 网络执行优化:Continuous Batching、Pipeline Parallelism 等。

但这些手段主要作用于算子内部或任务编排,模型调度层面仍有明显空间:在图模式下,即使已经做了算子融合,也受融合规则限制,融合覆盖范围有限;融合后的算子之间仍需逐个调度执行,存在调度开销与等待时间。SuperKernel 正是针对这一层的优化——通过更彻底的任务调度,进一步压缩计算过程中的等待时间。

SuperKernel 的核心思想是:基于计算图中算子的先验信息(算子类型、前后序依赖关系等),结合即时编译(JIT)能力,突破传统算子融合规则的限制,把网络中的多个算子编译为一个 SuperKernel 整体调度执行,从而显著降低算子间调度开销。

2. 原理:算子二进制融合

SuperKernel 是一种算子二进制融合技术。它与源码融合不同,聚焦于内核函数(Kernel)的二进制调度优化:基于已编译的二进制代码创建一个超级 Kernel 函数(SuperKernel),把多个其他内核函数作为子函数来调用。

相比单算子逐个下发,SuperKernel 带来三方面收益:

  1. 减少调度开销:降低任务调度的等待时间和调度开销;
  2. 利用 Task 间隙资源:进一步摊薄算子启动开销;
  3. 编译期全局视野:编译阶段可获取全部子算子的先验信息,从而实施更深层次的算子级与网络级优化。

下图展示了融合前后的算子序列变化(以 MoE 计算子图为例):

从源码结构看,这种“按依赖切分融合段”的行为在实现层有明确体现:编译器按算子执行顺序依次识别可融合性,遇到不可融合算子(如 TBE 算子)时就切段(详见约束章节)。

2.1 算子级优化

SuperKernel 编译期拿到的是二进制 Kernel及其依赖关系,因此优化必须建立在二进制语义之上。文档列出了四类典型优化:

2.1.1 ICache Preload 优化

SuperKernel 执行时,运行系统通常只预取入口点的指令,子 Kernel 的代码段往往无法被硬件预取机制捕获,导致指令缓存(ICache)命中率下降,产生 ICache Miss。

ICache Preload的解法是:在当前子 Kernel 执行完毕前,以2KB 对齐方式,提前将下一个子 Kernel 的代码段预取进 ICache。指令加载延迟被隐藏在当前子 Kernel 的执行过程中,后续算子的 ICache Miss 随之减少。

2.1.2 Early-Start 优化

常规调度要求前序算子全部完成后才启动后续算子。但观察指令构成可以发现并发机会:

  • 多数前序算子的末尾指令是 MTE(Memory Transfer Engine,内存传输引擎)数据搬运指令;
  • 后续算子的起始指令通常是与输入数据无关的初始化标量指令。

两类指令分属不同计算单元,具备并发条件。Early-Start 的做法是在前序算子的搬运指令前插入Set 同步点,在后续算子的初始化指令后插入Wait 同步点,让两个子算子的部分指令重叠执行。

2.1.3 同步优化

为保证执行顺序正确,SuperKernel 在各子算子调度之间会插入全核同步。对于 Kernel Type 为Mix 1:2(1 个 Cube 核对应 2 个 Vector 核)的混合类型算子,完整的全核同步需要等待所有 AI Core 的 Vector 核与 Cube 核都到达同步点——开销并不小。

由于编译时能够识别每个子算子的 Kernel Type,SuperKernel 可以定制同步范围:例如连续两个 Vector 算子之间,只需执行全 Vector 核同步即可。通过细粒度控制同步范围,可显著降低子算子间的同步开销。

2.1.4 子 Kernel 复制

多核系统下,多个计算核心执行同一段代码时会并发访问同一指令地址,在共享 L2 Cache 层面形成串行化访问队列,引发资源争用,削弱多核并行的性能增益。

SuperKernel 的解法是将子 Kernel 代码复制多份,不同核心按核 ID 映射到不同物理地址执行,从而缓解同一指令地址的争用,提升算子执行效率。

2.2 网络级优化

2.2.1 Tiling 下沉与 Weight 预取

SuperKernel 支持基于内存语义的NotifyWait事件,以此适配两类典型网络级场景:

  • Tiling 下沉:Tiling 下沉算子指 Tiling 计算依赖前序算子的输出结果;为避免主机与设备间频繁交互,这类 Tiling 计算被部署在 AICPU 上执行。SuperKernel 融合它时需要区分两种情况:
    • 若融合的是其前序算子:前序算子执行完成后,通过Notify事件通知 AICPU 启动 Tiling 计算;
    • 若融合的就是 Tiling 下沉算子本身:需先通过Wait事件等待 AICPU 完成 Tiling 计算,再执行 Device 侧计算。
  • Weight 预取:借助 CMO(Cache Management Operation)任务调用专用硬件单元SDMA,把权重数据提前加载到 L2 Cache。SDMA 与 AI Core 的协作正是通过内存语义的Notify/Wait事件实现的。

这一点在仓库代码中有直接呼应:LongCat-Flash 样例中与 SuperKernel 协同使用的npu_prefetch权重预取逻辑,同样依赖 Event 与独立 Prefetch 流完成 SDMA 搬运与计算的重叠(见 模型实现)。

2.2.2 双流并发融合

在通过多流实现 Cube/Vector 并发之后,如果 SuperKernel 转换时不感知依赖关系、仅按执行顺序处理,SuperKernel 内部执行会退化为串行,性能收益不及预期。

解决方式:

  1. 将算子按类型分类
  2. 在 SuperKernel 内部按 Cube 和 Vector 的不同特性分配执行队列
  3. 结合流的属性和 Event,精准插入同步点,实现 Cube 与 Vector 的高效并发执行。

该小节整理自 graph-autofusion 项目的能力描述,具体实现与能力以对应版本源码和文档为准。

3. 实现方式:两种后端如何开启

当前 SuperKernel 特性通过PyTorch 图模式开启,主要支持npugraph_ex后端和GE图模式两种方式。

3.1 npugraph_ex 后端

npugraph_ex后端中,SuperKernel 融合能力通过torch.compileoptions参数配置,设置super_kernel_optimize=True即可开启:

compiled_model = torch.compile( model, backend="npugraph_ex", # 省略部分参数 options={ "static_kernel_compile": True, "super_kernel_optimize": True, # 省略部分参数 }, )

其中,super_kernel_optimize=True表示开启 SuperKernel 融合优化。

如需进一步控制融合范围,可通过范围标定接口手动圈定:

torch.npu.super_kernel_scope_begin(scope_name: str) torch.npu.super_kernel_scope_end(scope_name: str)

super_kernel_scope_begin/end标定的范围内,满足条件的算子将参与 SuperKernel 融合。

仓库内的 编译工具函数 展示了这套配置在真实推理框架中的组装方式:从推理配置的custom_params中读取开关,并一并传入编译选项——

enable_superkernel = model_config.custom_params.get("enable_superkernel", False) if exe_mode == "npugraph_ex": compile_options = { "frozen_parameter": True, "static_kernel_compile": enable_static_kernel, "super_kernel_optimize": enable_superkernel, "super_kernel_optimize_options": {"dcci_disable_on_kernel": [".*"]} } ... compiled = torch.compile(model_forward, dynamic=enable_dynamic_graph, fullgraph=True, backend="npugraph_ex", options=compile_options)

从源码结构看,这里除了文档提到的super_kernel_optimize外,还额外设置了super_kernel_optimize_options中的dcci_disable_on_kernel选项用于按 Kernel 正则控制 DCCI 行为,属于仓库对编译选项的进一步工程化配置。

3.2 GE 图模式后端

在 GE 图模式中,SuperKernel 通过 TorchAir 提供的作用域接口进行标定,并配合 TorchAir 的CompilerConfig开启。用户需要先分析模型脚本中可被融合的算子范围,再使用torchair.scope.super_kernel标定融合区域,with语句块内的算子会被融合为一个 SuperKernel 计算。

接口形式:

with torchair.scope.super_kernel(scope: str, options: str = ''): ...

参数说明:

  • scope:当前上下文中算子融合后的 SuperKernel 名称。相同的scope表示属于同一个融合范围,由用户指定;
  • options:SuperKernel 的编译选项。

示例:

import torchair with torchair.scope.super_kernel("super_kernel_0"): y = op1(x) z = op2(y)

上述示例中,op1op2位于同一个super_kernel_0作用域内,满足融合条件时会被融合为一个 SuperKernel。scopeNone时,该作用域内的算子不进行 SuperKernel 融合。

仓库为这一用法封装了带开关的上下文管理器,见 superkernel_scope:

def superkernel_scope(enable: bool, scope: str, options: str = None): if enable: return tng.scope.super_kernel(scope, options) else: return FakeContextManager()

这样同一份模型代码可以在“开启/关闭 SuperKernel”两种配置下运行,无需修改模型结构,便于做 A/B 对比。

4. 实战样例:LongCat-Flash 中的 SuperKernel 标定

以仓库中的 LongCat-Flash 模型优化样例 为例。该样例在不同流上采用了不同的分核策略,按照分核与分流的范围在整网中共标定了三个 SuperKernel

对应源码中的标定位置清晰可查:

(1)每层解码器标定的三段作用域。在 multi_stream_forward 中,每层被划分为三段 SuperKernel 范围:

# scope_{layer}_part1:输入 LayerNorm + 第一组注意力(含 O 投影) with superkernel_scope(self.enable_superkernel, f"scope_{self.layer_idx}_part1", ""): hidden_states, residual = self.input_layernorm0 attn_ret = self.self_attn[0].forward_page_attention_absorb(...) ... # scope_{layer}_part2_moe:独立 MoE 流上的 FFN(配合 limit_core_num 限制核数) with limit_core_num(True, self.aic_num1, self.aiv_num1): with superkernel_scope(self.enable_superkernel, f"scope_{self.layer_idx}_part2_moe", ""): shortcut_mlp_output = self.mlp(hidden_states_norm, is_prefill, cur_topk_list=cur_topk_list) # scope_{layer}_part2_main:主计算流上的第二组 MLP 与注意力 with limit_core_num(not self.enable_afd, self.aic_num2, self.aiv_num2): with superkernel_scope(self.enable_superkernel, f"scope_{self.layer_idx}_part2_main", ""): ...

(2)AFD(Attention/FFN 解耦)部署下的独立 FFN 子图。在 FFNModel.forward 中,decode 阶段每层 MoE 计算被整层包进一个作用域:

for i in range(self.moe_layer_num): ... else: with superkernel_scope(self.enable_superkernel, f"scope_{i}_moe", ""): hidden_states, gmm2_out, gmm2_event = self.layersi # 层间在独立预取流上执行 npu_prefetch,预取下层 router 权重与 w13 权重 if i < self.moe_layer_num - 1: with npu_stream_switch(on_stream, self.npugraph_prefetch_stream): ... npu_prefetch(self.enable_prefetch, self.layers[i + 1].mlp.router.classifier.weight.data, ...) npu_prefetch(self.enable_prefetch, self.layers[i + 1].mlp.experts.w13_weight.data, ...)

(3)配置入口。开关通过推理配置文件的custom_params控制,例如 longcat_flash_densetp8_ep128_gegraph_mtp_eplb_w8a8.yaml:

model_config: exe_mode: "ge_graph" # ["eager", "npugraph_ex", "ge_graph"] ... custom_params: enable_multi_streams: 1 # [0, 1, 2] enable_prefetch: True # [False, True] enable_superkernel: True # [False, True]

仓库中对这一能力的适用性还有明确的源码级防护与版本限制说明,实践时需注意:

  • 从 模型入口 看,eager模式不支持 cache compile 与 superkernel;LongCat-Flash 的npugraph_ex分支当前也不支持 superkernel(开启会直接抛出ValueError),因此该样例中 SuperKernel 实际运行在ge_graph模式下;
  • LongCat-Flash README 说明:当前 CANN 软件版本下,SuperKernel 标记范围内的部分算子尚不支持完全融合,该限制将在后续社区版本中解决。因此实际收益取决于所用 CANN 版本对范围内算子的融合覆盖程度。

5. 约束与注意事项

开启 SuperKernel 前,需确认以下约束(源自文档约束章节):

  • 切段规则:编译器按网络中算子的执行顺序依次识别可融合性。若遇到 TBE(Tensor Boost Engine)等不可融合算子,会将其前面已识别的连续可融合算子组成一段 SuperKernel,同时跳过该不可融合算子,继续向后识别并组成下一段 SuperKernel;
  • 通信算子支持范围:目前支持 SuperKernel 融合的通信类算子包括 AllReduce、ReduceScatter、AllGather 和 AlltoAll;
  • 静态编译前置依赖:在npugraph_ex图模式下,开启 SuperKernel 融合优化时需要同时开启静态 Kernel 编译功能(对应 3.1 节示例中的static_kernel_compile: True);
  • GE 图模式要求静态图:且with语句块内不支持断图
  • 功能取舍:开启 SuperKernel 融合优化后,将禁用算子 Data Dump功能,调试手段需相应调整。

6. 小结

SuperKernel 把“逐算子调度”升级为“按融合段整体调度”,通过 ICache Preload、Early-Start、细粒度同步与子 Kernel 复制等算子级手段,叠加 Tiling 下沉、Weight 预取、双流并发等网络级手段,系统性压缩图模式下的调度开销。仓库提供了完整的落地参照:executor中 superkernel_scope 封装 与 npugraph_ex 编译选项组装 展示了两种后端的开启路径,LongCat-Flash 样例 则演示了在真实 MoE 推理模型中按分核/分流范围标定多个 SuperKernel、并与权重预取流协同工作的完整工程实践。

【免费下载链接】cann-recipes-infer本项目针对LLM与多模态模型推理业务中的典型模型、加速算法,提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-infer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询