AI-Workshop 文献分享 #20 — MoE:零基础详细讲义(路由、稀疏激活与多 GPU 部署)
分享人:ltw | 日期:2026-08-22
主题:MoE(Mixture of Experts,混合专家模型)零基础详解 —— 从 Dense FFN 到稀疏专家,路由机制、负载均衡与多 GPU 部署成本
本讲义独立介绍 MoE(Mixture of Experts,混合专家模型),重点回答四个问题:
- MoE 为什么能扩大模型容量?
- 路由器怎样为每个 token 选择专家?
- 稀疏激活为什么不等于没有代价?
- MoE 在训练和多 GPU 部署中有哪些难点?
先记住一句话:
MoE 让模型储备许多套参数,但每个 token 只运行当前需要的少数几套。
1. 从 Dense FFN 到 MoE:为什么要引入专家?
1.1 注意力和 FFN 分别负责什么?
Transformer 层通常先用注意力交换 token 之间的信息,再用前馈网络加工每个 token 的特征:
可以简单理解为:
注意力负责“从其他 token 搬来相关信息”,FFN 负责“在当前位置加工这些信息”。
例如处理“苹果公司发布手机”中的“苹果”时,注意力会把“公司”“发布”“手机”等上下文线索汇集到“苹果”的向量中;FFN 再把这些线索组合成更容易被后续层使用的特征。
“苹果”的原向量
↓ 注意力:读取上下文
带有“公司、发布、手机”等线索的向量
↓ FFN:组合并转换特征
更符合当前语境的新向量
这里变化的是 token 的向量表示,不是 token 本身。
1.2 FFN 改变特征,不减少 token 数量
假设输入有 4 个 token,隐藏维度是 4096。典型 FFN 会分别处理每个 token:
每个 token:4096 维 → 更大的中间维度 → 4096 维
整个序列: 4 个 token → 4 个 token
“先扩展再投影回来”发生在单个 token 的特征维度上,并不是把一句话压缩成更少的 token。
1.3 Dense FFN 的容量与计算绑定在一起
Dense 模型中,所有 token 都使用同一套完整 FFN 参数:
每个 token → 同一个完整 FFN → 新向量
扩大 FFN 可以增加模型容量,但每个 token 都必须运行扩大的网络,计算量也会同步上升。
MoE 要打破的正是这种绑定:
模型总共拥有很多专家
但每个 token 只运行少数专家
2. MoE 的完整数据流:路由、计算、合并
在 Transformer 中,每个专家通常就是一套独立的 FFN:
不同专家拥有不同参数,因此会把同一个输入加工成不同的候选表示。
一次 MoE 计算可以拆成五步:
当前 token 向量 x
↓ 1. 路由器给所有专家打分
专家分数 z
↓ 2. 选择 Top-K
被选中的专家集合 T(x)
↓ 3. 只运行这些专家
多个候选向量 fₑ(x)
↓ 4. 按路由权重加权求和
MoE 输出向量 y
↓ 5. 送入后续网络层
2.1 路由输入是上下文化的 token 向量
设隐藏维度为 \(d\),当前 token 进入 MoE 层时的向量为:
这个 \(x\) 通常已经经过注意力,包含当前上下文信息。因此,同一个词出现在不同句子中可能得到不同路由结果;同一句话里的不同 token 也可能选择不同专家。
2.2 路由器给所有专家打分
假设共有 \(E\) 个专家,路由器使用可训练矩阵:
计算全部专家的原始分数:
其中第 \(e\) 个分数为:
因此,\(z\) 是包含 \(E\) 个分数的向量,不是单个分数。\(W_r\) 的每一行都可以理解为一种可学习的匹配规则。
2.3 Top-K 只选择少数专家
路由器从全部分数中选出最高的 \(K\) 个:
如果:
它只表示专家 2 和专家 4 被选中。数字 2、4 是专家编号,类似员工工号,不能拿来计算专家权重。
路由器:需要给所有专家计算轻量分数
专家 FFN:只运行入选的 K 个
昂贵的专家计算只发生在少数路径上,这就是稀疏激活。
2.4 为入选专家计算合并权重
可以对入选专家的分数做 Softmax:
满足:
具体实现也可能先对全部分数做 Softmax,再选 Top-K,或使用其他归一化方式。关键逻辑不变:选择依据来自路由分数,不来自专家编号。
2.5 合并专家输出
被选中的专家分别运行后,按路由权重加权求和:
这不是拼接向量,而是对同维度向量逐项加权相加。因此:
MoE 不改变 token 数量,通常也不改变隐藏维度;它改变的是当前 token 实际经过的参数路径。
2.6 Dense FFN 与 MoE 的根本区别
Dense FFN
每个 token → 固定运行同一套完整参数 → 输出
MoE
每个 token → 动态选择少数专家参数 → 加权合并 → 输出
Dense 的计算路径固定;MoE 的计算路径由输入决定。
3. 用一个 Top-2 例子走完整流程
假设某个 MoE 层有 4 个专家,路由器对当前 token 输出:
第一步:选择专家
Top-2 选择分数最高的专家 2 和专家 4:
专家 2:原始分数 z₂ = 3.1
专家 4:原始分数 z₄ = 2.7
第二步:计算权重
第三步:运行并合并专家
完整过程是:
x
↓
z = [1.2, 3.1, 0.4, 2.7]
↓ Top-2
专家 2、专家 4
↓ 归一化
权重 0.60、0.40
↓ 运行专家并加权求和
y = 0.60f₂(x) + 0.40f₄(x)
专家不等于固定职业
不要机械地把专家理解成“数学专家”“代码专家”或“中文专家”。训练后可能出现专业化,但这种分工通常是隐式且分布式的:
- 一个专家可能偏向某些语言、语法或上下文特征;
- 一种能力可能由多个专家共同承担;
- 同一个专家也可能处理多种在人类看来不同的任务。
“专家”首先是结构名称,不保证具有清晰的人类职业标签。
4. MoE 为什么能做到“大容量、低激活”?
假设共有 \(E\) 个专家,每个专家有 \(P_e\) 个参数,完成一次专家前向计算的成本记为 \(C_e\)。
专家总参数量近似为:
如果每个 token 只激活 \(K\) 个专家,专家部分的单 token 计算近似为:
当 \(K\ll E\) 时,总参数容量主要随 \(E\) 增长,而单 token 的专家计算主要随 \(K\) 增长。这种“根据输入决定运行哪些参数”的方式称为条件计算。
总容量:由全部 E 个专家共同提供
单次计算:只使用其中 K 个专家
如果一个模型有 896 个路由专家,而每个 token 选择 16 个,那么路由专家数量上的激活比例约为:
但这不表示整个模型只使用 1.8% 的计算量。一次完整前向还包括注意力、共享专家、路由器、归一化、输出层、数据搬运和通信。
需要区分:
总参数量 模型一共储存多少参数
激活参数量 当前 token 实际使用多少参数
实际运行成本 计算、内存访问和通信共同产生的成本
MoE 主要降低的是激活专家计算,而不是按同样比例消除全部运行成本。
5. 路由专家与共享专家怎样分工?
很多 MoE 同时包含两类专家。
路由专家
只有被 Top-K 选中时才运行
主要提供条件化、差异化的处理能力
共享专家
所有 token 都会经过
主要承接普遍、基础的处理模式
可以类比为:
共享专家 = 所有项目都会使用的公共基础部门
路由专家 = 根据当前任务临时调用的专业团队
若模型包含共享专家,一次 MoE 输出可以教学化地写成:
真实架构可能使用多个共享专家或不同的缩放、合并方式,但基本分工相同。
6. 路由器怎样学习?为什么会负载失衡?
6.1 路由器与专家共同训练
训练时:
- 路由器根据 token 向量选择专家;
- 入选专家的输出参与模型预测;
- 预测误差通过连续的路由权重和相关训练目标影响专家与路由器;
- 专家逐渐适应被分配到的输入,路由器也逐渐调整分配方式。
理想情况下会形成:
相似输入被送往相似专家
→ 专家逐渐擅长这些输入
→ 路由器更准确地选择这些专家
但某些专家可能因早期略占优势而持续获得更多 token,最终形成少数热门专家垄断流量的路由坍缩。
6.2 负载失衡会造成什么?
假设 1000 个 token 需要分配给 4 个专家。
理想情况
专家 1:250 专家 2:250
专家 3:250 专家 4:250
失衡情况
专家 1:700 专家 2:180
专家 3:100 专家 4:20
这会造成:
- 热门专家成为整批计算的瓶颈;
- 冷门专家样本不足,难以训练充分;
- 热门专家可能超过设备容量;
- 其他设备空闲等待,整体吞吐下降。
若批次中有 \(T\) 个 token,每个 token 选择 \(K\) 个专家,共有 \(E\) 个专家,平均专家负载为:
常见治理方法包括:
- 加入负载均衡辅助损失;
- 调整路由分数或动态偏置;
- 为每个专家设置容量上限;
- 对溢出 token 做丢弃、缓存或重路由;
- 复制热点专家;
- 优化批次内 token 的打包与调度。
目标不是消灭专业化,而是在专家分工、训练稳定性和硬件利用率之间取得平衡。
7. Top-K 之外,路由还要解决什么?
7.1 每个 token 选择几个专家?
较小的 K:计算和通信更少,但可用专家组合更少
较大的 K:组合能力更强,但计算和通信更高
Top-1 只运行一个路由专家;Top-2 或更大的 \(K\) 可以融合多个专家输出。不存在脱离模型规模和硬件条件的统一最优值。
7.2 专家满载后怎样处理?
设备通常会给专家设置容量。如果某个专家收到的 token 过多,可以:
- 丢弃溢出路由;
- 改派到次优专家;
- 延后或分批处理;
- 提高容量,但承担更多内存和延迟。
7.3 训练和推理路由是否完全相同?
训练阶段可能加入噪声、辅助损失或探索机制,避免路由过早固化;推理阶段通常更强调确定性、吞吐和延迟。
所以,MoE 路由并不只是一个孤立的 TopK 操作,而是一整套训练与执行策略。
8. MoE 在多 GPU 上为什么难?
大型 MoE 通常无法把全部专家放在一张 GPU 上,只能把专家分布到多台设备:
GPU 1:一组专家
GPU 2:另一组专家
GPU 3:更多专家
……
一个 token 可能需要跨设备往返:
token 当前所在 GPU
↓ dispatch:发送到入选专家所在 GPU
远端专家执行 FFN
↓ combine:返回并合并专家输出
原计算流程继续运行
批次中的不同 token 会被发往不同设备,通常形成 all-to-all 通信。实际耗时近似为:
理论 FLOPs 降低,并不保证端到端延迟按相同比例降低。
如果 batch 很小、设备互联较慢或负载严重不均,通信和调度可能抵消稀疏计算带来的收益。
9. MoE 的收益、代价与总结
MoE 得到了什么?
- 在不同比例增加单 token 专家计算的前提下扩大总参数容量;
- 让不同 token 使用不同参数路径;
- 使专家有机会形成一定程度的专业化;
- 在合适条件下,提高单位计算预算对应的模型容量。
MoE 没有免费解决什么?
- 全部专家权重仍需存储、加载或分布式承载;
- 路由器可能发生坍缩和负载失衡;
- 跨设备 dispatch、combine 和 all-to-all 带来通信成本;
- 小 batch 或单请求推理不一定获得理想延迟;
- 训练、部署和故障排查都比 Dense 模型复杂。
最后用一条数据流记住 MoE:
上下文化 token 向量 x
→ 路由器计算专家分数
→ Top-K 选择少数路由专家
→ 入选专家分别加工 x
→ 按路由权重合并输出
→ 得到同维度的新向量 y
MoE 用“更多可选参数、较少激活参数”扩大模型容量;它节省的是单 token 的专家计算,不会自动消除权重存储、通信和调度成本。
10. 自测题
- Dense FFN 和 MoE 的计算路径有什么根本区别?
- 为什么路由器的输入是上下文化向量?
- 专家编号、路由分数和合并权重有什么区别?
- Top-K 为什么能实现稀疏激活?
- 为什么专家激活比例不能直接视为完整模型的 FLOPs 比例?
- 共享专家和路由专家分别承担什么作用?
- 路由坍缩为什么会同时影响模型质量和硬件效率?
- 为什么 MoE 的理论计算优势不一定能同比转化为推理延迟优势?
11. 参考答案
- Dense FFN 为所有 token 固定运行同一套完整参数;MoE 根据每个 token 的向量动态选择少数专家。
- 上下文化向量已经包含当前语境,因此路由器可以根据 token 此时的实际含义选择专家。
- 专家编号只表示选中了谁;路由分数表示匹配程度;合并权重由入选专家的分数归一化得到。
- 路由器只运行分数最高的少数专家,未入选专家不执行昂贵的 FFN 计算。
- 完整模型还包括注意力、共享专家、路由器、归一化、输出层以及通信和调度成本。
- 共享专家处理普遍基础模式;路由专家提供输入相关的条件化和差异化能力。
- 热门专家会成为计算瓶颈,冷门专家又会因为样本不足而训练不充分。
- 多 GPU 通信、token 调度、负载等待和内存访问可能抵消部分稀疏计算收益。