Skip to content

MoE (Mixture of Experts)

This content is not available in your language yet.

把 Transformer 中本来”密集”的 FFN 层换成 N 个并列的小 FFN(专家)+ 一个路由器,每个 token 只激活其中 Top-K 个专家。总参数量大幅增长,但每个 token 的计算量几乎不变

标准 Transformer 的 FFN 对每个 token 都走全部参数 —— 但显然,处理”它”和处理”傅里叶变换”用不到同一批权重。MoE 把这种条件计算显式建模出来:

  • N 个 expert 专门化,路由器学会”该把这个 token 送给谁”
  • 推理时只激活 K 个 expert(通常 K=1 或 2)→ 算力没变
  • 但模型容量是 N×FFN

代价:显存被全部 N 个专家占着(推理时也要加载),路由会带来负载不均衡。

设 token 表示 hRdh \in \mathbb{R}^d,N 个专家 E1,,ENE_1, \dots, E_N,路由器 g(h)=softmax(Wrh)RNg(h) = \text{softmax}(W_r h) \in \mathbb{R}^N

y=iTopK(g(h))gi(h)Ei(h)y = \sum_{i \in \text{TopK}(g(h))} g_i(h) \cdot E_i(h)

伪代码:

scores = router(h) # [B, T, N]
topk_v, topk_i = scores.topk(K) # 选 K 个专家
y = 0
for k in range(K):
expert_out = experts[topk_i[..., k]](h)
y += topk_v[..., k:k+1] * expert_out

工程难点是负载均衡:如果路由总把 token 送给少数热门专家,那些专家算力爆炸而其他闲置。常见做法是加 auxiliary loss 惩罚路由分布偏差。

DeepSeek 自己的 MoE 实现(DeepSeekMoE)有两个关键创新:

  1. 细粒度专家:把每个传统专家再拆成 m 个更小的专家,N 增大但单专家变小,路由更精细。
  2. 共享专家(shared experts):留几个专家强制每个 token 都走,捕捉通用知识;其他才是路由专家。
模型总参数激活参数路由专家数 / 共享Top-K
DeepSeek-V2236B21B160 / 26
DeepSeek-V3671B37B256 / 18

V3 还干掉了传统 auxiliary loss,改用 bias-based loss-free balancing(给路由 logits 加可学习偏置,监控历史负载实时校准),避免 aux loss 对主任务的干扰。