MoE:从多个 FFN 专家到稀疏激活

Router 如何选择专家,以及为什么参数量增加后计算量仍可控

Posted by Liu Mengxuan on September 21, 2026

普通 Transformer 的 FFN 只有一套参数,所有 token 都经过同一个变换。MoE(Mixture of Experts,混合专家)把这一个 FFN 换成多个专家,并让 Router 为每个 token 选择少数几个专家。

它想解决的是一个容量问题:模型可以拥有更多 FFN 参数,但单个 token 不必激活全部参数。

1. 从一个 FFN 到多个专家

普通结构是:

1
token 表示 x → 一个 FFN → 输出

MoE 结构是:

1
token 表示 x → Router → 选择专家 → 专家 FFN → 合并输出

i 个专家本身就是一个独立的 FFN:

$E_i(x)=\operatorname{FFN}_i(x)$

不同专家拥有不同的参数,因此可以学习不同的特征变换。这里的“专家”不是预先指定的人工类别,而是训练中逐渐形成的参数分工。

2. Router 如何给专家打分?

设有 n_experts 个专家,Router 用一个线性层产生分数:

$r(x)=xW_r$

其中:

1
2
3
x:   [d_model]
W_r: [d_model, n_experts]
r(x):[n_experts]

再经过 softmax 得到路由概率:

$p(x)=\operatorname{softmax}(r(x))$

例如 4 个专家的概率为:

1
[0.05, 0.60, 0.10, 0.25]

如果采用 Top-2 路由,就选择概率最高的 Expert 1 和 Expert 3。随后通常只对选中的权重重新归一化,使它们之和为 1。

3. 一个 token 怎样经过 MoE?

假设选中两个专家,归一化权重为 0.70.3

$y=0.7E_1(x)+0.3E_3(x)$

数据流是:

Router 为 token 选择两个专家,专家输出按路由权重加权合并

每个专家输出仍然是 [d_model],加权合并后可以继续进入下一层 Transformer。对一批 token 来说,Router 会产生一张路由表,把不同 token 分发给不同专家。

4. 为什么叫稀疏激活?

假设有 8 个专家,每个专家的参数量为 P,每个 token 只选择 Top-2:

1
2
总专家参数量:8P
单个 token 激活的专家参数量:2P

因此,模型的总参数容量随着专家数量增加,但每个 token 主要计算 2 个专家,而不是 8 个专家。

这不是说所有开销都变成原来的四分之一。Router、token 重排、容量管理、通信和专家的实际矩阵乘仍然需要计算;“稀疏”主要指专家 FFN 的选择性激活。

5. Token Dispatch 与 Combine

当不同专家位于不同 GPU 上时,MoE 会多出两次数据组织:

1
2
3
4
5
6
7
8
9
原始 token
    ↓ Router 选择专家
Token Dispatch:把 token 发到专家所在 GPU
    ↓
专家 FFN 批量计算
    ↓
Token Combine:按原位置取回并加权合并
    ↓
恢复原 token 顺序

专家并行(Expert Parallelism)通常需要 All-to-All:每张 GPU 把属于其他 GPU 专家的 token 发出去,同时接收发送给本地专家的 token。

这和前面 FFN 张量并行中的 AllReduce 不同:AllReduce 是大家对相同形状的部分结果求和,All-to-All 是每张卡与其他卡交换不同 token。

6. 为什么需要负载均衡?

Router 可能把大量 token 都送给同一个专家:

1
2
3
4
Expert 0:10%
Expert 1:75%
Expert 2:8%
Expert 3:7%

结果是 Expert 1 拥堵,其他专家却没有充分工作;同时,冷门专家得到的训练信号太少。

常见办法包括:

  • 辅助负载均衡损失:惩罚路由概率和实际 token 数过度集中。
  • 容量上限:给每个专家设置最多接收的 token 数,避免单个专家无限堆积。
  • 更换路由规则:例如让专家主动选择 token,以便控制每个专家的容量。

这些机制改变的是 token 如何分配,不改变“专家本身是 FFN”这一核心结构。

7. 把 MoE 放回 Transformer

一个 MoE Block 可以简化为:

1
2
3
4
5
6
7
8
9
10
11
输入
 ↓
Attention
 ↓
Router
 ↓
少数几个专家 FFN
 ↓
按路由权重合并
 ↓
残差输出

MoE 通常替换 FFN 子层,Attention 仍然负责 token 之间的信息交互。这样,Attention 提供上下文,Router 决定当前 token 使用哪些 FFN 参数,专家负责逐 token 加工。

一句话概括:MoE 用路由器把每个 token 送给少数 FFN 专家,以较低的单 token 计算量换取更大的参数容量;代价是路由、负载均衡和分布式通信。

参考资料