15. MoE 的专家并行(Expert Parallelism)怎么做?为什么 MoE 训练特别难?

整理 MoE 训练的 EP 设计、负载均衡与通信优化。

简单回答

Expert Parallelism(EP)是把 MoE 模型里的专家(experts)切到不同 GPU 上。每个输入 token 经过 router 选择 top-k 个专家,token 要被发送到对应专家所在的 GPU 计算,结果再发回来。EP 的核心通信是 AllToAll——每张卡把要发给其他卡的 token 一次性交换出去。MoE 训练特别难的原因有三:负载不均衡(router 可能把大部分 token 路由到少数热门专家,其他专家闲置)、AllToAll 通信成本高且不稳定、训练稳定性差(router 的 gating 容易塌缩到只用几个专家)。DeepSeek-V3、Mixtral、Qwen-MoE 等模型在这条路上都做了大量工程优化。

详细解释

MoE 是什么、为什么需要 EP

MoE(Mixture of Experts)是把 transformer 的 FFN 层换成 多个并行的 FFN 专家 + 一个 router。每个 token 进来后 router 选择 top-k 个专家(典型 k=2 或 k=4),只让这 k 个专家计算。

数学上看:

正常 FFN:    output = FFN(x)
MoE FFN:    output = Σ gate_i(x) · Expert_i(x), 只对 top-k 专家求和

收益是 参数总量大但激活参数少——比如 DeepSeek-V3 总参数 671B 但每个 token 只激活 37B。模型容量大但推理成本低。

但 MoE 模型的总参数往往是几百 B 到 1T,单卡甚至单机都放不下所有专家。所以必须把专家分到不同 GPU 上——这就是 Expert Parallelism。

EP 的基本机制

假设有 8 个 GPU 和 8 个专家,最简单的 EP=8 配置是每张 GPU 放一个专家。

forward 时一个 batch 的 token 在所有 GPU 上都有(DP 视角)。每个 token 经 router 选择 top-2 专家,假设 token A 选了专家 3 和专家 5,token B 选了专家 1 和专家 5。

这时每张卡都需要做:

  • 把自己持有的 token 中要去其他专家的 token 打包发出
  • 收到要交给本地专家的 token
  • 本地专家计算
  • 把计算结果按原路发回

这个"按目的地路由 + 计算 + 按原路返回"的过程,就是 AllToAll 通信。每个 forward + backward 至少 4 次 AllToAll(forward 来回 + backward 来回)。

EP 通常和其他并行组合:

  • DP × EP × TP × PP,形成 4D 并行
  • 或 DP × EP × TP × PP × SP 5D 并行

DeepSeek-V3 训练时用的是这种多维并行。

AllToAll 通信的痛点

AllToAll 是 EP 的核心也是瓶颈:

通信量大。每个 token 的 hidden state(几 KB)要发出再收回。一个 batch 里几千个 token 经过几十层 MoE,累计通信量惊人。

对网络拓扑敏感。AllToAll 要求所有 GPU 之间两两通信,不像 AllReduce 那样可以走树状结构高度优化。InfiniBand 的 bisection bandwidth 是关键约束。

和 GPU 的算力不平衡。AllToAll 通信时 GPU 算力闲着——不像 AllReduce 可以和计算重叠那么自然。MoE 训练里 AllToAll 占总时间 30-50% 是常见的。

业界的优化主要几方面:

Topology-aware All2All:根据物理拓扑分层做 AllToAll——先在机内 NVLink 域做局部 AllToAll,再跨机做。比一刀切的全局 AllToAll 快几倍。

通信和计算重叠:把 AllToAll 拆成几个 phase 和不同部分的计算交错执行。难做但能恢复 20-30% 算力。

EP 维度限制在机内:把 EP 限定在 NVLink 域(≤ 8)。专家数多时同一组 GPU 持有多个专家,token 跨组时才走 IB。这样把 AllToAll 限定在高带宽域内。DeepSeek-V3 训练时的策略就接近这个。

负载均衡是核心难题

理想情况下每个专家处理同样数量的 token——这样 GPU 利用率最高、通信最均衡。但 router 是模型自己学的,没人保证它会均匀分配。

实际中常见的失败模式是 router collapse——router 学到只把 token 路由给少数几个"热门"专家,其他专家从来收不到 token。这些冷门专家的参数永远没机会更新,等于浪费。

为了缓解,所有 MoE 模型都加了某种 load balancing loss

Auxiliary Loss(Switch Transformer 提出)

L_balance = α · N · Σ_i f_i · P_i

其中 f_i 是专家 i 实际收到的 token 比例,P_i 是 router 对专家 i 的平均门控概率。这个 loss 鼓励两者乘积均匀,间接约束负载均衡。但这个 loss 本身和主训练目标有冲突,权重 α 难调。

DeepSeek 的 Bias-only 方案:DeepSeek-V3 提出不用 auxiliary loss,而是给 router 的输出加一个可学习的 bias,专门用来调节负载均衡:

score_i = router_logit_i + bias_i

bias_i 不通过梯度更新,而是在每个 step 后根据"专家 i 收到的 token 是否过多"手动调整——多了就 -ε,少了就 +ε。这个机制比 auxiliary loss 干扰主训练目标小。

Capacity Factor:给每个专家设一个 capacity 上限——最多收 (tokens × top_k × cf / num_experts) 个 token。超出的 token 被 drop(直接跳过这一层)或 reroute 到其他专家。这个机制保证最差情况下 GPU 不会因为单个专家过载而成瓶颈,但有 token drop 副作用。

训练稳定性

MoE 训练比 dense 模型不稳定得多。常见问题:

Router 输出 logits 过大:导致 softmax 很尖,几乎只用 1 个专家。常见对策是给 router logits 加 z-loss(惩罚 logits 数值过大)。

专家间 capability 不平衡:训得久了某些专家变得"全能"专门接管,其他专家退化。和 router collapse 互相加强。

梯度爆炸:MoE 的稀疏激活让梯度方差大。需要更小心的 learning rate warmup、grad clipping。

Fine-tuning 的特殊挑战:MoE 模型 SFT 时 router 容易在小数据集上过拟合,把 token 全路由到几个专家。需要冻结 router 或加约束。

Expert Capacity 和 Token Dropping

设 capacity factor 决定每个专家能容纳的 token 上限。cf = 1.0 意味着完全均衡时刚好够用,但实际不均衡时会有 token 被 drop。cf = 1.25 留一些 buffer。cf = 2.0 几乎不会 drop 但显存浪费多。

Token drop 的影响:被 drop 的 token 在这一层等价于 identity(直接跳过 FFN)。少量 drop(< 5%)影响小,多了就显著掉点。

DeepSeek-V3 训练时用了 无 drop 的策略——保证所有 token 都被处理。代价是 capacity 要设得大些,显存占用高。

推理时的 EP

训练 EP 是为了塞下大模型,推理 EP 是为了 吞吐——同样的硬件配置下 MoE 的活跃参数少所以推理快。

推理时的挑战是 batch 内 token 的目的地高度发散——一个 batch 里几百个 token 可能要发到几乎所有专家,AllToAll 通信量大。优化思路:

  • Expert sharding 把热门专家复制到多张卡,分担流量
  • Token packing 把连续多个 token 的目的地排序后批量发送
  • 用更高带宽的 NVLink 域做 EP,避免跨机

DeepSeek 在 R1/V3 推理时把 EP 大量复制(同一专家在多机器上有副本),用 redundant expert deployment 提升吞吐。

主流 MoE 模型对比

Mixtral 8×7B / 8×22B:8 专家,每 token 激活 2。结构相对简单,社区开源生态成熟。

DeepSeek-V3 / V2:256 个专家(V3)+ 共享专家。专家数极多但每个专家小,激活更稀疏。在效果和成本上是公开 MoE 中最好的之一。

Qwen2-MoE:Qwen 团队的 MoE 实现,和 Mixtral 思路接近。

GShard / Switch Transformer / GLaM:早期 Google 的 MoE 工作,奠定了 EP 和 capacity factor 的基础设计。

各家在专家粒度(粗 vs 细)、共享专家、router 设计、负载均衡机制上都有不同选择,是 MoE 当前的活跃研究领域。

面试时可以这样答

Expert Parallelism 是把 MoE 模型的专家分到不同 GPU 上,每个 token 经 router 选 top-k 专家后被发送到对应 GPU 计算再发回来。核心通信是 AllToAll。EP 通常和 DP/TP/PP 组合形成 4D 或 5D 并行,DeepSeek-V3 用的就是这种。

AllToAll 是 EP 的瓶颈——通信量大、对网络拓扑敏感、和算力不平衡难重叠。MoE 训练里 AllToAll 占总时间 30-50% 常见。优化主要是 topology-aware 分层 AllToAll、通信计算重叠、把 EP 限定在机内 NVLink 域。

负载均衡是核心难题。router 自己学的不保证均匀,常见 router collapse——只用几个热门专家其他闲置。常见对策有 auxiliary loss(鼓励 token 分布均匀,但和主目标冲突)、DeepSeek 的 bias-only 方案(给 router logits 加可学习 bias 不过梯度而是按统计调整)、capacity factor 限制每个专家的 token 上限超出就 drop 或 reroute。

训练稳定性问题包括 router logits 过大需要 z-loss 抑制、专家间能力不平衡、梯度方差大需要更小 lr 和 grad clip、SFT 时 router 容易过拟合到小数据集。

Token drop 是个实际权衡——cf=1.25 留 buffer 偶尔 drop,cf=2.0 几乎不 drop 但显存浪费。DeepSeek-V3 用了无 drop 策略保证所有 token 被处理。

推理时 EP 是为吞吐,挑战是 batch 内 token 目的地分散导致 AllToAll 量大。优化是 expert sharding 复制热门专家、token packing 批量发送。DeepSeek 推理时用 redundant expert deployment 提升吞吐。

主流 MoE 模型 Mixtral 是 8 专家 top-2 的简单结构,DeepSeek-V3 用 256 个细粒度专家加共享专家是最复杂也最高效的开源方案之一。

常见追问

  1. DeepSeek 的 bias-only 负载均衡为什么比 auxiliary loss 好?bias 调整的步长怎么定?
  2. Top-1 routing(Switch Transformer)和 Top-K routing 各自的 trade-off 是什么?
  3. MoE 模型推理时怎么做 batching?token 路由不一致让 batch 处理变复杂。