MoE混合专家架构#
一句话答案#
MoE 把 Transformer 里的 FFN 层换成 N 个并列的”专家”FFN + 一个路由器,每个 token 只激活 top-k 个专家,于是总参数很大、每 token 的计算量却只相当于一个小模型——用”稀疏激活”换来同等算力下更高的模型容量。代价是:参数必须全部加载(省算力不省显存)、路由要做负载均衡、专家并行带来 all-to-all 通信,这也是 DeepSeek、Qwen3、Llama 4 等前沿模型都转向 MoE 的原因与难点所在。
核心要点
1. Dense vs MoE:改的是 FFN,不是注意力#
标准 Transformer Block = Attention + FFN(见 Transformer架构),其中 FFN 占了约 2/3 的参数。MoE 只动 FFN:把它复制成 N 份(专家 expert),前面加一个线性层做路由器 gating/router。每个 token 经路由器打分后只送进得分最高的 k 个专家,输出按路由权重加权求和。
h = Attention(x)
scores = softmax(W_g · h) # 每个专家一个分数
topk = TopK(scores, k) # 只选 k 个,其余专家不参与计算
y = h + Σ_{i∈topk} scores_i · Expert_i(h)plaintext注意力层、Embedding、LayerNorm 仍然是所有 token 共享的稠密部分;MoE 的”稀疏”仅指 FFN 按 token 条件激活。
2. 总参数 vs 激活参数#
| 模型 | 总参数 | 每 token 激活 | 专家配置(每层) |
|---|---|---|---|
| Mixtral 8x7B | ≈ 47B | ≈ 13B | 8 个专家选 top-2 |
| DeepSeek-V2 | 236B | 21B | 细粒度路由专家 + 共享专家 |
| DeepSeek-V3 | 671B | 37B | 256 个路由专家选 8 + 1 个共享专家 |
| Qwen3-235B-A22B | 235B | 22B | 128 个专家选 8;命名即”总 235B / 激活 22B” |
| Llama 4 Maverick / Scout | 400B / 109B | 17B / 17B | 128 / 16 个专家 |
| Kimi K2 | 1T | 32B | 384 个路由专家选 8 + 1 个共享专家,注意力用 MLA |
| Qwen3.5-397B-A17B | 397B | 17B | 512 个路由专家选 10 + 1 个共享专家,与 Gated DeltaNet 线性注意力混合 |
| DeepSeek-V4-Pro / Flash | 1.6T / 284B | 49B / 13B | Flash:256 个路由专家选 6 + 1 个共享专家;1M 上下文,MIT 协议开源 |
表中数字来自各模型官方模型卡/技术报告,新版本迭代快,以官方发布为准。
- 算力(FLOPs)≈ 激活参数:DeepSeek-V3 每 token 的计算量只接近一个 37B 稠密模型,训练/推理成本远低于同总量的稠密模型
- 显存 ≈ 总参数:671B 参数必须全部驻留,FP8 也要数百 GB,单卡放不下 → 这是 MoE 最反直觉的点:“省算力不省显存”
- Mixtral 8x7B 不是 8×7B=56B:注意力等非专家部分是共享的,所以 ≈ 47B 而非 56B
3. 路由机制与负载均衡#
- token-choice(主流):每个 token 自己选 top-k 专家;expert-choice:每个专家选固定数量的 token,天然均衡但不适合自回归解码。本文只点名,细节不展开
- 路由坍塌 routing collapse:训练早期某几个专家得分略高 → 被选得更多 → 训练得更好 → 得分更高,最终大量 token 挤进少数专家,其余专家”饿死”,容量浪费且负载不均
- 辅助损失 auxiliary loss(Switch Transformer / GShard 路线):加一项
α · N · Σ f_i · P_i(f_i = 分给专家 i 的 token 比例,P_i = 路由给 i 的平均概率),鼓励均匀分配;再配 capacity factor 限制单专家 token 上限,超出的 token 被丢弃(token dropping)。问题是 α 太大会伤主任务效果 - DeepSeek-V3 的无辅助损失负载均衡 auxiliary-loss-free:给每个专家加一个偏置 b_i 只参与 top-k 选择、不参与最终加权,每步统计负载——过载的专家 b_i 减、欠载的加。用”选谁”和”权重多少”解耦的方式把均衡压力从损失函数里拿掉,避免辅助损失干扰模型学习
- ST-MoE 的 router z-loss:惩罚路由 logits 过大,缓解训练不稳定/数值溢出
4. DeepSeekMoE:共享专家 + 细粒度专家#
- 细粒度专家 fine-grained:把每个大专家切成 m 个小专家,同时 top-k 也乘 m,激活参数量不变但”专家组合”的数量组合爆炸式增加,不同知识能分得更细
- 共享专家 shared expert:固定激活 1 个(或几个)专家,所有 token 都过,用来承接通用知识(语法、常识),让路由专家可以更专注各自领域,减少专家间的知识冗余
- 两者结合就是 DeepSeek-V2/V3 的 MoE 形态;和 注意力机制变体与位置编码 里的 MLA 一起,构成 DeepSeek 架构的两大支柱(MLA 压 KV Cache,MoE 压算力)
5. 专家并行与 all-to-all 通信#
参数太大放不下单卡,于是把不同专家放到不同 GPU/节点上——专家并行 Expert Parallelism(EP)。代价是每个 MoE 层都要做两次 all-to-all:先把 token 按路由结果发送到各专家所在的卡(dispatch),算完再收回来(combine)。
- 通信量与 k、序列长度成正比,跨节点带宽远低于 NVLink,很容易成为瓶颈
- 应对:限制每个 token 最多路由到 M 个节点(DeepSeek-V3 的 node-limited routing)、通信与计算重叠(DeepSeek 的 DualPipe + DeepEP 通信库)、把共享专家或热门专家复制到多卡
6. 推理特性,以及为什么 2024–2026 前沿模型转向 MoE#
- 显存悖论:推理要加载全部专家,但每个 token 只算一小部分。小 batch 时每个专家只分到很少 token,权重读取开销摊不薄(memory-bound 更严重);batch 越大,专家利用率越高,所以 MoE 在大吞吐服务场景更划算
- 专家 offload:本地部署时把专家权重放 CPU/SSD,按路由结果临时搬进 GPU(llama.cpp、KTransformers 等思路),用延迟换显存,适合 模型量化与本地部署 场景
- 量化友好:专家权重占比极大且每次只用一部分,对专家做低比特量化、对注意力等共享部分保精度是常见组合
- 更多通用推理优化(KV Cache、PagedAttention、连续批处理)见 LLM推理优化,MoE 在这些之上额外引入了 EP 和路由的调度维度
为什么前沿模型都转向 MoE: Scaling law 说”参数多、数据多”效果好,但稠密模型的算力成本随参数线性涨;MoE 让”参数量”和”每 token 算力”解耦——同样的训练预算可以买到大得多的模型容量。DeepSeek-V3 用约 2.8M H800 GPU 小时训出 671B 模型,验证了这条路的性价比;Qwen3/Qwen3.5、Llama 4、Kimi K2、DeepSeek-V4、Mixtral 等相继采用,开源旗舰已到万亿总参数、几十 B 激活的量级。硬件侧 HBM 容量增长(装得下更多参数)和高速互联(扛得住 all-to-all)也让 MoE 的工程成本变得可接受。
面试回答(2分钟版)
MoE 是把 Transformer 里的 FFN 层换成多个并列的专家网络加一个路由器,每个 token 经过路由器打分后只激活 top-k 个专家,其余专家不参与计算。这样做的核心收益是把”总参数”和”每 token 的计算量”解耦——比如 DeepSeek-V3 总参数 671B,但每个 token 只激活 37B,训练和推理的算力接近一个 37B 稠密模型,容量却大得多;Mixtral 8x7B 也是总量约 47B、激活约 13B。但要注意 MoE 省的是算力不是显存,推理时参数必须全部加载,所以单机放不下,要做专家并行,把专家分到不同卡上,每层要两次 all-to-all 通信,跨节点带宽容易成为瓶颈。第二个难点是负载均衡:如果不管,路由会坍塌到少数几个专家上。传统做法是加辅助损失鼓励均匀分配,再用 capacity factor 限流;DeepSeek-V3 用无辅助损失的方案,给每个专家一个只影响选择、不影响加权的偏置,动态调整,避免辅助损失干扰主任务。第三是结构设计,DeepSeekMoE 提出细粒度专家加共享专家:专家切小增加组合数,共享专家固定激活承接通用知识。推理侧,MoE 在小 batch 时专家利用率低,大吞吐场景更划算;本地部署可以把专家 offload 到 CPU。2024 年后前沿模型基本都转向 MoE,本质就是同样训练预算买到更大容量,DeepSeek-V3、Qwen3、Llama 4 都是例子。
追问与易错
追问方向:
- Mixtral 8x7B 为什么不是 56B? → 只有 FFN 被复制成 8 份,注意力、Embedding 等部分是共享的,所以总参数约 47B;每 token 选 top-2 专家,激活约 13B
- 推理 MoE 比同激活参数的稠密模型快吗? → FLOPs 相近,但显存必须放全部参数且小 batch 下各专家分到的 token 少、memory-bound 更重,单请求延迟未必更低;优势在大 batch 吞吐和同算力下的模型质量
- 负载均衡为什么不直接用辅助损失就好? → 辅助损失是和主任务目标打架的正则项,系数大了伤效果、小了不均衡;DeepSeek-V3 用专家偏置只改 top-k 选择、不改梯度路径,实验上效果更好
- 专家之间会”分工”成领域专家吗? → 观察到的更多是按 token/语法类型的分化而非按学科分化;共享专家的引入正是因为很多通用知识在各专家间重复,单独抽出来更高效
- 专家并行和张量并行怎么搭配? → 专家维度用 EP 切到不同卡,注意力等稠密部分用 TP/DP;EP 的 all-to-all 是额外通信,要靠通信-计算重叠和限制跨节点路由来压
- MoE 能做 LoRA 微调吗? → 可以,但路由器本身的训练很敏感,常见做法是冻结路由器只对专家/注意力加 LoRA,避免微调导致路由分布漂移
易错点:
- ❌ “MoE 总参数 671B 所以需要 671B 的算力” → 算力按激活参数 37B 算,显存按总参数算,两者分开
- ❌ “MoE 比同等激活量的稠密模型更省显存” → 恰恰相反,显存占用对应总参数,MoE 是省算力不省显存
- ❌ “每个 token 经过所有专家再加权” → 只经过 top-k 个,其余专家对该 token 的计算被完全跳过,这才是”稀疏”
- ❌ “MoE 是把注意力换成专家” → 标准 MoE 只替换 FFN,注意力层仍是稠密共享的