MoE 训练与专家并行
DeepSeek-V3、Qwen-MoE、Mixtral 把 MoE 推成了主流架构,「MoE 怎么训、怎么并行、怎么保证专家负载均衡」成了训练岗的高频深挖点。本文承接 MoE 混合专家模型 的架构介绍,聚焦工程侧:路由与负载均衡、辅助损失、容量因子与 token 丢弃、专家并行(EP)与 AllToAll 通信、DeepSeekMoE 的细粒度+共享专家设计。并行通信基础见 AI 训练集群与网络通信。
面试先背这几句话
- MoE 用稀疏激活换「大参数量、小激活算力」:总参数很大,但每个 token 只激活 Top-K 个专家。
- 训练最大难题是负载均衡:路由器容易把 token 都送给少数专家,导致「专家坍缩」,其余专家训不到。
- 解决靠辅助损失(auxiliary/load-balancing loss) 或 无辅助损失的偏置调整(DeepSeek 的 aux-loss-free)。
- 专家并行(EP)把不同专家放到不同 GPU,token 路由靠 AllToAll 通信——这是 MoE 特有且易成瓶颈的通信模式。
- DeepSeekMoE 两个关键设计:细粒度专家(切更小更多)+ 共享专家(每个 token 都过,学通用知识)。
一、MoE 训练为什么特殊
稠密模型每个 token 走全部参数;MoE 每个 token 只走 Top-K 专家(如 8 选 2)。这带来三个训练特有问题:
- 路由是离散/不可导的:选哪个专家是 argmax/TopK,梯度不能直接穿过「选择」这个动作——靠对被选专家的 gating 权重加权来间接回传。
- 负载不均衡:路由器是学出来的,训练早期容易形成「马太效应」——热门专家越来越热,冷门专家收不到 token、学不到东西、进一步没人选,最终专家坍缩。
- 通信模式变了:专家分布在不同卡上时,token 要被「发到对应专家所在的卡、算完再收回来」,引入 AllToAll。
二、路由与负载均衡 ★
2.1 路由器(Router / Gating)
对每个 token,router 是一个小的线性层 + softmax,输出对各专家的分数,选 Top-K:
$$g = \text{softmax}(x \cdot W_g), \quad \text{选 TopK 专家,按 } g \text{ 加权求和输出}$$
2.2 负载均衡损失(Auxiliary Loss)
经典方案(GShard/Switch Transformer):加一个辅助损失,惩罚「token 分配不均」。直觉是让每个专家被选的比例和分给它的路由概率都趋于均匀:
$$L_{aux} = \alpha \cdot N \cdot \sum_{i=1}^{N} f_i \cdot P_i$$
其中 $f_i$ 是分到专家 $i$ 的 token 占比,$P_i$ 是路由给它的平均概率。$\alpha$ 太大伤模型质量,太小压不住不均衡,是个需要调的权衡。
2.3 无辅助损失均衡(DeepSeek aux-loss-free)★
DeepSeek-V3 提出不用辅助损失,改为给每个专家维护一个可动态调整的偏置项:某专家过载就调低它的偏置(少被选),欠载就调高。好处是不引入与主任务冲突的额外梯度,避免辅助损失损害模型质量。这是近年 MoE 的一个重要工程改进,面试提到会加分。
2.4 容量因子与 token 丢弃
- 专家容量(capacity):每个专家每个 batch 最多处理的 token 数 =
容量因子 × 平均负载。 - token 丢弃(dropping):超出容量的 token 被丢弃(不经该专家,走残差直连)。容量因子小 → 丢得多、省算力但伤质量;大 → 少丢但浪费算力和显存。
- 推理时通常不丢(或用更大容量),训练时容量因子是吞吐与质量的权衡旋钮。
三、专家并行(Expert Parallelism, EP)★
当专家太多放不进一张卡时,把不同专家分到不同 GPU:
token 在各卡上产生 → 按路由结果 AllToAll 分发到专家所在卡
→ 各卡专家计算
→ AllToAll 收回到原来的卡 → 继续后续层- 两次 AllToAll:一次分发(dispatch)、一次收集(combine)。这是 MoE 训练/推理的特有通信开销,token 越多、专家越分散,通信越重。
- 和其他并行组合:EP 常和 DP/TP/PP 组成复杂的多维并行。EP 通信量大,通常也希望放在高带宽域内。
- 负载不均的连锁反应:如果专家负载不均,热门专家所在卡成为瓶颈,其他卡空等——所以负载均衡不仅关乎质量,也直接影响 EP 的吞吐(木桶效应)。
面试点:MoE 的 AllToAll 和稠密模型的 AllReduce 是不同通信原语;MoE 训练把「计算省下来的钱」部分花在了「通信」上,工程上要靠通信-计算重叠、分组路由等手段抵消。
四、DeepSeekMoE 的关键设计
DeepSeek 系列把 MoE 做到 SOTA,两个标志性设计(见 DeepSeek 专题):
- 细粒度专家(Fine-grained):把专家切得更小、数量更多,Top-K 也更大。好处是专家组合数爆炸增长,专业化程度更高、知识分得更细。
- 共享专家(Shared Expert):设置 1~2 个所有 token 都必过的共享专家,负责学「通用/共性知识」,让路由专家专注差异化知识,减少冗余。
配合 aux-loss-free 均衡、MLA 压 KV Cache,构成了 DeepSeek-V3 的高性价比配方。
五、MoE 的推理与部署挑战
- 显存 vs 算力错配:MoE 参数巨大(要全部加载进显存)但每 token 激活少,显存压力远大于算力压力,部署成本主要在显存/多卡。
- 批处理下的专家利用:一个 batch 里 token 被路由到各专家,专家利用率取决于 batch 内 token 分布;小 batch 时很多专家「空转」。
- EP 推理:大 MoE 推理也用专家并行 + AllToAll,vLLM/SGLang 等已支持(见 推理框架对比)。
- 量化:MoE 权重量化收益大(省显存),但要注意专家间敏感度差异。
六、常见坑与调参经验
- ❌ 辅助损失权重过大 → 为了均衡牺牲质量;过小 → 专家坍缩。要监控专家负载分布这个指标。
- ❌ 容量因子设置不当 → 丢 token 太多或显存爆。
- ❌ 忽视 router 的训练稳定性 → 早期路由抖动大,可用 router z-loss 稳定 logits。
- ❌ EP 通信没和计算重叠 → AllToAll 成为吞吐瓶颈。
- ✅ 监控每个专家的 token 命中数、路由熵,及时发现坍缩。
高频追问
- MoE 相比稠密模型省的是什么?代价是什么? 省的是激活算力(每 token 只走 Top-K 专家),代价是显存(参数全量加载)和通信(AllToAll)以及训练不稳定(负载均衡)。
- 什么是专家坍缩,怎么解决? 路由马太效应导致少数专家垄断 token、其余训不到;解决靠负载均衡辅助损失,或 DeepSeek 的无辅助损失偏置调整。
- 负载均衡辅助损失怎么起作用? 惩罚 token 分配比例与路由概率的不均匀,鼓励各专家被均匀选择;权重 α 是质量与均衡的权衡。
- DeepSeek 的 aux-loss-free 是什么,好在哪? 用每专家可调偏置动态均衡负载,不引入与主任务冲突的额外梯度,避免辅助损失损害模型质量。
- 专家并行的通信是什么?和稠密模型有何不同? EP 用两次 AllToAll 分发/收集 token,稠密模型是 AllReduce 同步梯度;AllToAll 是 MoE 特有瓶颈。
- 容量因子和 token 丢弃是什么? 每专家有处理上限(容量因子×平均负载),超出的 token 被丢弃走残差;是吞吐/显存与质量的权衡。
- DeepSeekMoE 的细粒度专家和共享专家分别解决什么? 细粒度提升专业化与组合表达力;共享专家承载通用知识、减少路由专家的冗余。
- MoE 部署为什么贵? 参数全量占显存但激活少,显存/多卡成本高,且小 batch 时专家利用率低、AllToAll 通信开销大。