---
title: 【昇腾热点算子大解密】CANN创新MoE融合算子，巧用排序算法优化，计算性能实现近4倍提升-官方技术文章-昇腾社区
description: 在MoE模型中，每个输入（Token）会通过路由门控动态选择Top-K个专家对其进行处理。预先对Token进行重排（Permute）与反重排（Unpermute）的排序处理，使得属于同一专家的Token在内存中连续存储，可以有效降低通信消耗，提升训练吞吐。基于传统的排序算法，结合昇腾微架构特性，通过优化算法逻辑，以及将多个细粒度小算子融合，创新了具备重排与反重排功能的融合算子MoeTokenPer
keywords: CANN,MoE,昇腾热点算子,大解密,创新,融合算子,巧用排序算法优化,计算性能实现
url: https://www.hiascend.com/developer/techArticles/20250702-1?envFlag=1
section: (其他)
---

# 【昇腾热点算子大解密】CANN创新MoE融合算子，巧用排序算法优化，计算性能实现近4倍提升-官方技术文章-昇腾社区

URL: https://www.hiascend.com/developer/techArticles/20250702-1?envFlag=1
描述: 在MoE模型中，每个输入（Token）会通过路由门控动态选择Top-K个专家对其进行处理。预先对Token进行重排（Permute）与反重排（Unpermute）的排序处理，使得属于同一专家的Token在内存中连续存储，可以有效降低通信消耗，提升训练吞吐。基于传统的排序算法，结合昇腾微架构特性，通过优化算法逻辑，以及将多个细粒度小算子融合，创新了具备重排与反重排功能的融合算子MoeTokenPer
关键词: CANN,MoE,昇腾热点算子,大解密,创新,融合算子,巧用排序算法优化,计算性能实现

官方技术文章 [了解详情](https://www.hiascend.com/zh/developer/techArticles)

【昇腾热点算子大解密】CANN创新MoE融合算子，巧用排序算法优化，计算性能实现近4倍提升

【昇腾热点算子大解密】CANN创新MoE融合算子，巧用排序算法优化，计算性能实现近4倍提升

昇腾CANN算子开发性能调优

发表于: 2025/07/02

## MoE架构带来的专家负载均衡与通信优化挑战

在MoE模型中，每个输入（Token）会通过路由门控动态选择Top-K个专家对其进行处理。单一Token会被分配给少数专家，而不同专家接收到的Token数可能存在差异，导致部分专家过载而其他专家闲置。这种负载不均会引发两个关键问题：一方面，过载专家将成为计算瓶颈，降低整体训练效率；另一方面，闲置专家的算力无法被充分利用，也会造成计算资源浪费。除此以外，在分布式训练场景下，专家通常分布在不同的计算卡上，需根据路由结果AllToAll通信，将Token分发至专家所在的目标设备。若Token未按专家ID排序，通信时需为每个Token单独传输目标设备信息，这会导致通信效率大幅降低。

## 亲和昇腾微架构特性，创新优化排序算法

为应对上述挑战，我们会需要对Token进行重排（Permute）与反重排（Unpermute）的排序处理：首先将输入Token按专家ID进行重排操作，使得属于同一专家的Token在内存中连续存储；待专家计算完成后，再执行反重排操作，将计算结果还原至原始顺序并累加输出。

在专家并行的分层通信架构中，会涉及分别在外层和内层进行重排/反重排的排序操作。其中，外层处理跨专家组的Token排序，主要负责由专家编号区间构成的专家组之间的数据交互，处理跨机的分发与通信；内层处理单个专家组内部的Token排序，优化机内多卡间的分发与通信。值得注意的是，外层操作涉及将切片处理后的重排序列作为输出/输入，而内层操作则无需切片处理。基于这种设计差异，内层操作实质上可以看作是外层操作的特例，因此在性能优化时，我们只需重点考虑更具普适性的外层优化策略即可。

基于传统的排序算法，结合昇腾微架构特性，我们通过优化算法逻辑，以及将多个细粒度小算子融合，创新了具备重排与反重排功能的融合算子MoeTokenPermuteWithEP与MoeTokenUnpermuteWithEP，显著降低了内存搬运带来的性能损耗。新算法不仅简化了计算流程，也大幅提升了整体运算效率。这一优化方案通过算子融合有效减少了数据交互开销，充分发挥了硬件的并行计算能力，实现了端到端的性能跃升。

## 重排融合算子MoeTokenPermuteWithEP

在MoE模型的路由分发机制中，每个输入Token会被动态分配到K个不同的专家进行处理。比如以Token a、b、c为例：a被路由至专家3和1，b分配给专家4和2，c被分发至专家5和3。为优化计算效率，我们会将路由到同一专家的Token排序后聚合重组来降低通信开销。在本示例中，Token a和c都被分发到了专家3，因此需要将它们重新排序至相邻位置。

在传统实现方案中，重排操作采用小算子串行调用的处理逻辑：首先对专家索引通过Sort进行排序，随后根据专家组的起始索引进行Slice切片划分，接着通过FloorDiv将专家索引映射到对应的Token，最终按照排序后的Token索引通过Gather完成数据重排。然而，这种方案存在明显的性能瓶颈，由于FloorDiv算子必须在相对低效的AICPU上执行，严重制约了整体训练吞吐。

为此，我们对传统的重排实现方案进行了深度优化，创新性地提出了一种功能等价但性能更优的新方案。MoeTokenPermuteWithEP融合算子通过三大创新突破性能瓶颈：

(1) 双重排序机制：首轮排序专家序列（如[3, 1, 4, 2, 5, 3]→[1, 2, 3, 3, 4, 5]），获得位置索引sorted_indices = [1, 3, 0, 5, 2, 4]；次轮对sorted_indices再排序得到sorted_indices1 = [2, 0, 4, 1, 5, 3]，指示了排序后的Token位置索引；

(2) 智能索引拷贝：AICore并行加载Token数据后，基于sorted_indices1执行范围检查，校验后智能写出，完全规避FloorDiv计算；

(3) 计算流重构：将原本分散的排序、切片、映射操作融合为AICore上的高效循环计算。

相比传统重排实现，在MoeTokenPermuteWithEP融合算子运行时，每个vector核只需处理输入Token/probs/indices1的局部数据片段，并支持对输出空间的全局访问。由于全局地址偏移信息已预编码在索引中，在实现高效内存访问的同时，完全规避了FloorDiv计算，彻底消除了AICPU计算瓶颈和数据搬运开销，实现3.5倍的性能提升。

## 反重排融合算子MoeTokenUnpermuteWithEP

在专家处理完Token后，为了得到最终输出结果，我们还需要将同一Token分散在不同专家上的计算结果聚合，再将Token序列恢复至原始顺序，最后基于概率权重对同一Token的多个专家输出进行加权求和。为此，我们设计了与前述重排过程相对应的反重排机制。

在反重排机制中，每个专家分配到的Token会有对应的权重（probs），其序列长度与专家序列长度一致。传统实现方案中，probs首先需要基于sorted_indices位置索引，通过Gather操作进行排序，这样可以与排序后的Token序列保持对应。随后，将probs与专家输出对位相乘的结果写出至由FloorDiv处理后的位置索引，最终得到反重排后的Token输出。我们可以发现，对AICPU计算的依赖仍是一个性能瓶颈点，同时，在全局内存的累加操作也还有优化空间。

同样的，我们对反重排计算流程也进行了深度优化，MoeTokenUnpermuteWithEP算子通过三重创新实现突破：

(1) 双重排序机制：延续重排算子的优化思路，完全规避AICPU计算；

(2) 片上累加优化：在统一缓冲区（UB）内完成Gather和累加计算，避免全局内存（GM）访问，以缓存累加替代内存累加；

(3) 智能算子融合：通过算子融合，当probs非空时，直接在UB完成乘法和写出，节省完整GM读写周期。

实测表明，在probs非空场景下，MoeTokenUnpermuteWithEP融合算子相较传统反重排方案可实现3.8倍的性能提升，特别是在处理大规模专家网络时优势更为显著。

总体而言，经过深度优化的排序融合算子展现出显著的性能优势：相较于传统串行调用的排序方案，其计算性能实现了近4倍的突破性提升。这一优化成果也可以直接转化到模型训练效率上，使得MoE模型的整体训练吞吐量获得了3-6%的可观提升。

## 结语

结合MoE架构与昇腾硬件微架构特性的排序算法优化与融合算子设计，不仅能显著提升专家模型的训练效率，更是探索出了稀疏计算与分布式通信领域一条高效可行的技术路径，为MoE模型的规模化训练提供了坚实的技术支撑。

MoeTokenPermuteWithEP及MoeTokenUnpermuteWithEP算子功能通过CANN软件包使能，社区版资源下载地址：

https://www.hiascend.com/developer/download/community/result?module=cann [了解详情](https://www.hiascend.com/developer/download/community/result?module=cann)

算子接口定义为：

```cpp
aclnnStatus aclnnMoeTokenPermuteWithEpGetWorkspaceSize(const aclTensor *tokens, const aclTensor *indices,
    const aclTensor *probsOptional, const aclIntArray *rangeOptional, int64_t numOutTokens, bool paddedMode,
    const aclTensor *permuteTokensOut, const aclTensor *sortedIndicesOut, const aclTensor *permuteProbsOut,
    uint64_t *workspaceSize, aclOpExecutor **executor)

aclnnStatus aclnnMoeTokenPermuteWithEp(void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream)

aclnnStatus aclnnMoeTokenUnpermuteWithEpGetWorkspaceSize(const aclTensor *permutedTokens, const aclTensor *sortedIndices,
    const aclTensor *probsOptional, int64_t numTopK, const aclIntArray *rangeOptional, bool paddedMode,
    const aclIntArray *restoreShapeOptional, const aclTensor *out, uint64_t *workspaceSize, aclOpExecutor **executor)

aclnnStatus aclnnMoeTokenUnpermuteWithEp(void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream)
```

详细融合算子接口文档可参考昇腾社区API描述：

https://www.hiascend.com/document/detail/zh/canncommercial/81RC1/apiref/aolapi/context/common/aclnn_domains_fuse.md [了解详情](https://www.hiascend.com/document/detail/zh/canncommercial/81RC1/apiref/aolapi/context/common/aclnn_domains_fuse.md)

本页内容
