DeepEP Ascend 拆解:DeepSeek MoE 通信库搬上国产昇腾

DeepSeek 将 MoE 专用通信库 DeepEP 移植到国产昇腾 NPU,API 不变、引擎全换,POC 阶段 8 卡 Dispatch 带宽达 373-375 GB/s。
DeepEP Ascend 是 DeepSeek 将其 MoE(混合专家)通信库移植到华为昇腾 NPU 的开源项目。MoE 架构每次推理只激活少数专家,但专家分散在多张卡上,需要两次跨卡搬运:Dispatch(把 Token 派给对应专家)和 Combine(收回计算结果并加权合并)。DeepEP Ascend 的公开 API 与 NVIDIA 版完全对齐,Python 层代码几乎无需修改,底层则从 NCCL/NVLink/CUDA 全面替换为 HCCL/UB/Ascend C。核心优化包括:FP8 压缩将数据量砍半、defer epilogue 机制让通信与 shared expert 计算重叠、cached handle 复用路由元数据。当前为 POC 阶段数据,8 卡 Dispatch 带宽 373-375 GB/s,扩展到 EP128 后带宽下降,Combine 部分仍在优化,建议等 Q3 商用 HDK 发布后再用于生产环境。
MoE 为什么需要专门的通信库
想象一个 AI 模型里养着 256 个「专家」,每个只精通一小块领域。来一个 Token(模型眼里的一小段文字,大约半个词),由一个「路由」(router)扫一眼,选出最对口的 6 个专家起来干活,剩下的 250 个继续歇着——这就是当下大模型最火的 MoE(Mixture of Experts,混合专家)架构。
相比传统大模型「全科医生」式的全参数激活,MoE 换成了一群专科医生:只激活被选中的少数专家,又快又省。但省钱的代价是通信变麻烦。一张卡塞不下 256 个专家,假设用 8 张卡、每张住 32 个,那么被摇中的 6 个大概率分散在好几张卡上。于是每个 MoE 层都要做两次跨卡搬运,而 DeepEP 正是为解决这件事而生。
DeepSeek广告 把这套通信库搬上了国产昇腾 NPU(AI 专用芯片,干着与 GPU 类似的活),在 GitHub 上开源,名为 DeepEP Ascend。本文据 B 站 UP 主的拆解视频,把它的核心机制梳理一遍。
All-to-All 通信是分布式训练与推理中最昂贵的通信模式之一。与 AllReduce(所有节点把同一份数据汇总再广播)不同,All-to-All 要求每张卡向其他每张卡分别发送不同的数据块,通信量随卡数平方级增长,且很难用简单的树形或环形拓扑优化。MoE 架构天然产生 All-to-All 需求:路由决策在每张卡上独立完成,但被选中的专家分散在各处,必须把 Token 精确投递到对应卡,算完再取回,没有任何捷径可绕。这也是为什么 NCCL 的通用 ncclAlltoAll 在 MoE 场景下往往不够用——它不理解「专家对齐」「FP8 压缩」「defer epilogue」这些业务语义,而 DeepEP 正是在这层语义上做了深度定制。
两次搬运:Dispatch 派单与 Combine 收答案
MoE 层的跨卡通信由两个对称操作组成。第一次叫 Dispatch(派单),跟外卖平台给骑手派单是一个意思:你的 Token 在 0 号卡,命中的专家在 135 号卡,Dispatch 就把数据派过去。有个节能细节——如果 6 个专家里有两个住在同一张卡,那张卡只收一份数据,一个地址一张面单,快递只跑一趟。
第二次叫 Combine(收答案):专家在各自卡上算完,按原路把结果送回 0 号卡,再按路由权重(router 给每个专家打的话语权分量)加权求和,拼成这个 Token 的最终输出。两次加起来,就是一次 All-to-All 通信,相当于全班同学同时互相传纸条,每个人都给所有人发、也从所有人收。

算一笔账:每张卡 16384 个 Token,每个 Token 是 7168 个数的长串,一个数 2 字节,还要复印 6 份——一次 Dispatch 单张卡就要搬 1.4GB。好在 FP8(一种精度更低但体积更小的数据格式)能把这个量砍到一半。
API 对齐 NVIDIA,底层引擎全换
DeepEP Ascend 不是从零写的。它的公开 API(代码与库打交道的窗口)与 NVIDIA 版 DeepEP 完全对齐——EP Buffer、Dispatch、Combine,连 defer epilogue 这类参数都一字不差。你在 NVIDIA 卡上写的代码搬到昇腾上,Python 层基本不用改,但底下全换了:
- NVIDIA 版:走 NCCL,卡内用 NVLink,跨节点用 RDMA,内核用 CUDA 写;
- 昇腾版:走 HCCL(华为自家通信库),卡内用 UB,跨节点靠 HCCL/HCCN 的 URMA 引擎,内核用 Ascend C 写。
同一份菜谱,厨房从燃气灶换成了电磁炉,火候得重新练。具体差异有三处:其一,NUM_SMS 在 NVIDIA 版指 GPU 小核心数,昇腾版指 AI Core 数(卡里真正干活的小车间);其二,昇腾版必须用展开式布局(Dispatch Expand);其三,昇腾版目前是单一通信域,所有卡都在一个能直接通话的圈里。

还有个有意思的设计:两边的设备内核都不是预制菜,而是现场编译。DeepEP 装包只装 host 端(CPU 那头,负责指挥),kernel(跑在加速卡上的小程序)第一次跑才现场编译,编完记在缓存里,下次直接用。目前真正就绪的是 EP 这套跨卡派单机制,PP、bucket、ngram 等其他分工方式 API 先占坑、实现还在施工。
RDMA(Remote Direct Memory Access,远程直接内存访问)是跨节点高速通信的关键技术。它允许一张卡的网卡直接读写另一台服务器上显存或内存中的数据,完全绕过目标服务器的 CPU,延迟可低至微秒级。NVIDIA 生态中常用 InfiniBand 网络搭配 RDMA;昇腾版的对应实现是 URMA(Unified RDMA Abstraction)引擎,华为将其封装在 HCCL/HCCN 栈中。URMA 与 RDMA 的设计哲学一致——SGE(Scatter-Gather Entry)描述数据在哪、SQE(Send Queue Entry)发出传输指令、网卡硬件自主完成搬运,CPU 只负责下令,不参与数据搬运本身。这套机制使得 Dispatch 的「发令枪」步骤得以在不经过 CPU 的情况下完成跨卡数据投递。
Dispatch 的三步与 FP8 压缩
Dispatch 内部分三步。第一步列队:Token 来了先看面单(topk_idx,去拿哪几个专家),做一次「影分身」分成 6 份,每个专家一份(展开式布局),再按专家重新排队。排队时还会把每队人数补齐到 128 的倍数,叫 expert alignment——因为后面接手的 grouped GEMM(矩阵乘法)只吃 128 对齐的输入,空位拿零填上。
第二步发令枪:内核先数人头,统计每个专家分几个 Token、每张卡收几个,填好发货清单(SGE 写货在哪、送到哪,SQE 发指令),URMA 引擎直接把数据送到对面卡预留的货架上,全程不经过 CPU,CPU 只负责喊「开始」。
第三步打扫战场:货到齐后 epilogue 内核把数据摆成最终样子,顺手画一张「藏宝图」(receive source metadata),记录每个格子的货来自哪个 Token、哪张面单——Combine 原路返回全靠这张图。路由没变时还能用 cached handle 偷懒,直接复用上次的藏宝图,省掉重新数人头。

关于 FP8 压缩:Token 数据从 BF16 压成 FP8 E4M3,体积砍半,但每个 Token 塞一张「说明书」(scale 因子)跟着一起走,到对面照着还原。测试里拿 FP8 结果与参考答案逐项对过,Dispatch 这一环验证通过——但 README 没写端到端对模型精度的影响,这点不替它吹。
FP8 E4M3 是一种 8 位浮点格式,用 4 位表示指数、3 位表示尾数,可表示的数值范围远小于 BF16(16位),因此直接截断会引入显著误差。实际工程中通常配合per-token 或 per-tensor 的 scale 因子使用:先找到这批数据的最大绝对值,算出缩放比例,把原始数乘以比例后再转成 FP8;接收端拿到 scale 因子后做反向缩放还原。DeepEP 在每个 Token 旁边附带一个 scale 因子(即文中所说的「说明书」),属于 per-token 量化粒度,还原精度优于整批共用一个 scale 的方案。这也是为什么 FP8 并不是无损压缩——scale 因子本身占额外空间,且量化误差对最终模型精度的影响需要端到端验证,目前 README 只覆盖了 Dispatch 单环节的数值对齐。
计算与通信重叠:先上车后补票
打扫战场里藏着个讲究。默认情况下 Dispatch 当场办完,CPU 得干等对面喊「人到齐了」。设了 defer epilogue 后玩法就变了——先上车后补票:Dispatch 只管开车搬运,把补票(epilogue 打扫)推迟到真正需要数据时,即调用 event.current_stream.wait 的那一刻。
中间的空档用来干什么?README 给的标准写法是 Dispatch 先行,然后去算 shared expert(所有 Token 都要去的公共食堂,跟通信无关),正好贴近等待的空档,算完再 wait 补票。这样通信和计算严丝合缝叠在一起。一句话:晚的只是补票那一步,车一秒没晚点。注意数据在 current_stream.wait 之后、销毁之前别碰。
Combine 的加量不加价
Combine 是 Dispatch 的反向操作,多了一步算总分。专家算完后照着藏宝图把 6 份答案送回老家,按 top-k weights 加权求和。算总分时还能顺手做「加量不加价」:shared expert 的输出直接当 bias(出锅前固定加的一勺底料)加进来,由 epilogue 收尾那趟车顺路烧上,一次性加完,省掉单独再跑一趟加法。

实测带宽与需要谨慎的地方
回到开场问题:既然是对称的两次搬运,为什么 8 卡实测 Dispatch 能到 373–375 GB/s,Combine 只有 345–347 GB/s?README 给了答案——Combine 多了算总分的开销,而且 URMA 引擎跟 HBM(卡上的高速大仓库)抢路走,卡数越多差距越大。EP128 时 Dispatch 掉到 313–320,Combine 掉到 272–278,Combine 这部分仍在优化中。
测试环境为昇腾 950DT、CANN 9.2.0,每卡 16384 个 Token,hidden 7168,256 专家 top6,32 个 AI Core,Dispatch 跑 FP8、Combine 跑 BF16。EP 从 8 扩到 128,带宽随之下降;EP 不超过 32 时,Dispatch 能到物理 payload 带宽上限的 90–95%。
三句谨慎提醒:
- 这是 POC 版数据。用概念验证版 HDK(华为给开发者的软硬件套件)测出,不是正式发行版。README 自己推荐等 Q3 商用 HDK(大约发版时间看华为)再用于生产。
- 计时不完整。只算了 enqueue 和 drain,最后的 epilogue 没算,别直接拿来推端到端性能。
- Combine 仍在优化,华为固件改进也在路上——是「在路上」而非「已交付」。
EP(Expert Parallelism,专家并行)是 MoE 模型特有的并行维度,与常见的数据并行(DP)、张量并行(TP)、流水线并行(PP)并列。EP 的含义是:把不同专家分配到不同卡或节点上,每张卡只持有一部分专家的权重,Token 根据路由结果被派送到对应卡。EP 规模(EP8、EP32、EP128)即参与专家并行的卡数。EP 规模越大,每张卡承载的专家越多可节省单卡显存,但 All-to-All 的通信跳数和延迟也随之上升——这正是文中带宽随 EP 扩大而下降的根本原因。实际部署时,EP 规模需在显存容量、通信带宽与计算效率之间取得平衡,EP 不超过 32 时 Dispatch 能保持接近物理上限的 90–95% 效率,是一个有参考价值的工程经验数据。
小结
DeepEP Ascend 的价值一句话概括:把 DeepSeek 那套「派单 + 收答案」的 MoE 通信机制原样搬到了昇腾卡上——API 不变,引擎全换,为国产卡攻克了大模型推理的通信这一关。目前它是 POC 阶段的成果,带宽数据可作参考而非承诺,等商用 HDK 出来值得再复测一版。但对国产 AI 芯片生态而言,这种与 NVIDIA 生态 API 对齐、底层自研实现的路线,意义不容小觑。
相关推荐

智能体底座(Harness)比模型本身更关键:YC深度解析Agent架构演进
YC在Harness Night分享会上提出:决定智能体能力的关键不是模型本身,而是外层的Harness底座。本文梳理从GPT-2到自改进Harness的演进,解析Prime Agent、OpenJarvis、QM三大实践及Agent架构设计要点。

用n8n搭建LinkedIn线索抓取与丰富化自动工作流
一套基于n8n的LinkedIn线索抓取与丰富化自动工作流:只需填写职位、地点、行业和公司规模,系统即可自动生成含专业邮箱和验证状态的客户名单并写入Google表格。本文解析其流程、输出字段与合规注意事项。

SageMaker HyperPod:跨团队共享GPU集群的隔离与公平性实践
Amazon SageMaker HyperPod 推出跨团队共享GPU集群的参考架构,通过IAM Identity Center认证、Kubernetes命名空间隔离、Task Governance公平调度和成本分摊,实现算力安全共享与费用透明化。