MoE · 专家混合
2024 年 AI 圈最火的一个词,除了"推理模型",就是 MoE。DeepSeek-V3 用 6710 亿参数,却只激活 370 亿;Mixtral 有 8 位专家、每次只用 2 位;Qwen-MoE、豆包大模型、GPT-4 传言也是……"参数很多,每次只用一小撮"——这就是 MoE 的核心逻辑。它让"万亿参数"从奢侈品变成了消费品。
你感冒发烧,走进一家三甲医院。医院有 50 个科室、几百位专家——但你不需要每个专家都给你看一遍病。
分诊台护士看你一眼:喉咙红肿、发烧咳嗽——"呼吸科二楼"。
你直接去呼吸科,医生看诊。整个过程里,那 50 个科室里只有 1 个被"激活"了——皮肤科、骨科、眼科的医生此刻在休息、在看别的病人,你的诊断跟他们无关。
但如果病情复杂——比如老年人合并糖尿病——护士可能会说"呼吸科 + 内分泌科都看看",就激活了 2 个科室。
MoE 就是这套逻辑:模型有很多"专家",但每次输入只激活其中最相关的几个。
先把名字拆开 · MoE 到底是哪三个字
开篇先把这个缩写彻底说清,后面就顺了。MoE(Mixture of Experts,混合专家——一个模型里养一群各有所长的专家,每次只叫醒最合适的几个干活)。三个词各自的意思:
- Expert · 专家所谓专家,说白了就是模型里一个独立的小型子网络——具体来说,是一个前馈网络(FFN,那个"先撑开再压回"的加工车间,§7.4 讲过)。它不是一个有意识的"人",只是一堆参数。之所以叫专家,是因为训练之后它们确实各自擅长处理某类输入。
- Mixture · 混合所谓混合,说白了就是把被选中的几位专家的输出按权重加起来——不是"选一个用",而是"选几个,各占一定比例"。跟 §7.2 里注意力的加权求和是同一个思路。
- Gating / Router · 门控 / 路由器所谓路由器,说白了就是那个"决定这次该叫谁"的小网络。它是整个 MoE 的调度中心,也是最难训好的一环。医院里的分诊台护士就是它。
还有两个必须先立起来的关键词,本篇会反复出现。Dense Model(稠密模型/密集模型)——所谓稠密模型,说白了就是"不管什么输入,全部参数都得跑一遍"的传统模型,GPT-3、Llama-2-70B 都是这类。Sparse Model(稀疏模型)——所谓稀疏模型,说白了就是"参数很多,但每次只叫醒一小部分"的模型,MoE 就是稀疏模型最成功的形态。整篇的核心矛盾就一句话:稠密模型每次都把全院医生请来会诊,太贵;稀疏模型只叫该叫的那两位,便宜得多。
稠密模型的浪费 · 感冒也请全院会诊
把浪费说得再具体一点。假设你有一个 700 亿参数的稠密模型,你问它一句"今天星期几?"。它会做什么?它会把 700 亿个参数全部过一遍,包括那些专门负责理解 Python 语法的参数、那些存着莎士比亚十四行诗韵律的参数、那些懂蛋白质折叠术语的参数——全部参与这次计算,只为了回答一个"星期几"。
这就是稠密模型的结构性浪费:它没有"跳过无关部分"的能力。矩阵乘法是一个整体运算,你没法让它"只算这一块、跳过那一块"。用大白话说:你去医院看个感冒,规定是全院 50 个科室的医生每人都得给你看一遍并签字,然后把 50 份意见汇总成一张处方。眼科医生看你的喉咙,骨科医生也看你的喉咙,皮肤科医生也来看一眼——最后处方跟只让呼吸科医生看的结果差不多。
为什么以前大家忍了这个浪费?因为在参数量不大的时候,浪费的绝对值不高,而稠密结构简单、稳定、好训。可当参数冲到千亿、万亿,这个浪费就变成了不可承受的成本。于是"按需调用"从一个可选优化,变成了一个必选项。
一笔直观的账:同样"知识容量"的两种方案
【方案 A · 稠密 671B】
每生成 1 个 Token,需要过的参数:671,000,000,000
按经验公式,前向传播的浮点运算量 ≈ 2 × 参数量
= 1.34 万亿次浮点运算 / Token
【方案 B · MoE 671B,每次激活 37B(DeepSeek-V3 的实际配置)】
每生成 1 个 Token,需要过的参数:37,000,000,000
= 740 亿次浮点运算 / Token
比例:671 / 37 ≈ 18.1 倍
换成能感知的量:
假设生成一个 Token 稠密方案要 18 毫秒,MoE 方案只要 1 毫秒。
生成一篇 2000 字(约 3000 Token)的文章:
稠密:3000 × 18ms = 54 秒 ← 用户等到不耐烦
MoE :3000 × 1ms = 3 秒 ← 流畅
同样的一张 GPU、同样的一段时间,
MoE 方案能服务的用户数是稠密方案的十几倍。
这就是"为什么 DeepSeek 的 API 能定价到 GPT-4 的几十分之一"
在算力层面的全部答案。
为什么需要 MoE · 大模型太贵
2020 年 GPT-3 出来的时候,175B(1750 亿)参数已经把整个行业震住了——训练一次要几千张 A100,成本上亿美元。但两年后大家发现——要继续变强,参数还得继续涨。GPT-4 传言是万亿级别,Google 的 PaLM 是 5400 亿……继续这样堆下去,会撞上三堵墙:
- 显存墙1 万亿参数光加载就要 2TB 显存——单张 GPU 只有 80GB,得几十张卡拼起来才能跑一次推理。
- 算力墙生成一个 Token 就要过一遍整个模型——参数越多,每个 Token 越慢,用户等不起。
- 电费墙训练一次万亿密集模型的电费能买一栋楼——微软和 OpenAI 都在痛苦地扩数据中心。
于是 Google 从 2017 年就开始琢磨的一个老想法——MoE——被翻出来重新扛旗:参数放着不用没关系,关键是每次前向传播只激活一小撮。这样模型"看起来"很大(容量足),但每次推理只花"小模型"的成本。
一座图书馆有 100 万册书(相当于"总参数量");
但你写论文时,桌上同时只摊开 3 本书(相当于"激活参数量")。
你的知识存量是 100 万册的量级,但此刻的工作量只有 3 本书的重量。
MoE 让 AI 模型也拥有这种"图书馆式"的效率——存海量参数,用起来却只调最相关的那部分。
MoE 结构 · 把 FFN 层换成一堆专家
标准 Transformer 每一层有两个子模块:Attention + FFN(前馈网络)。FFN 是每层里参数最多的部分——占整个模型 60%~70% 的参数。
MoE 的做法是:把 FFN 从"一个大 FFN"换成"很多个小 FFN"——每个小 FFN 就是一位"专家"。同时新增一个叫 Router(路由器)的小神经网络,决定"这个 Token 该交给哪几位专家处理"。
1. Token 进入 MoE 层
每个 Token(词)先过完 Attention,然后进入 MoE 层。此时它的向量已经融合了上下文信息。
2. Router 打分选专家
Router 是一个小 MLP——输入 Token 的向量,输出 N 个分数(N = 专家数量)。
比如 8 个专家,Router 输出 8 个分数:[0.05, 0.62, 0.03, 0.08, 0.15, 0.02, 0.04, 0.01]。
3. Top-K 稀疏激活
只挑分数最高的 K 个专家(通常 K=2)——例子里就是第 2 位(0.62)和第 5 位(0.15)。
其他 6 位专家这次不干活——它们的参数放在显存里睡觉。
4. 加权合并输出
Token 分别送进第 2 和第 5 号专家,各得一个输出向量;
按 Router 给的权重(重新归一化后)加权相加,作为这一层的最终输出。
门控网络怎么选专家 · 分诊台护士的判断依据
路由器是整个 MoE 里最小、也最关键的部件。它小到什么程度?它就是一个单层线性变换,参数量只占整个模型的万分之几——但它决定了那 6710 亿参数里哪些被叫醒。分诊台护士全院工资最低,可她把病人分错了科室,后面所有名医都白搭。
它的工作方式简单得出人意料:
路由器的完整计算(假设 8 个专家,d_model = 512)
输入:一个 Token 的向量 x,512 个数字
第 1 步 · 打分(就一次矩阵乘法)
logits = x · W_gate W_gate 形状 [512, 8]
结果是 8 个原始分数,比如:
专家0: -1.2 专家1: 3.5 专家2: -0.8 专家3: 0.4
专家4: 2.1 专家5: -2.3 专家6: 0.9 专家7: -0.1
第 2 步 · Top-K 挑人(K=2,只叫两位)
排序后最高的两个是:专家1 (3.5) 和 专家4 (2.1)
其余 6 位这次不参与,一行代码都不为它们执行
第 3 步 · 只对选中的两个做 softmax(重新归一化)
e^3.5 = 33.12, e^2.1 = 8.17, 合计 41.29
专家1 权重 = 33.12/41.29 = 0.802
专家4 权重 = 8.17/41.29 = 0.198
(注意:是只在这两个之间分 100 分,
不是在全部 8 个之间分 —— 这一点很重要)
第 4 步 · 送进去算,再按权重合并
out = 0.802 × Expert1(x) + 0.198 × Expert4(x)
整个路由器的参数量:512 × 8 = 4096 个数
而每位专家的参数量:约 200 万个数
→ 路由器只占 8 位专家总参数的约 0.026%
一个万分之三大小的部件,掌管全部调度。
有几个设计细节值得说明,它们都不是随手定的。
第一,为什么先挑人再 softmax,而不是先 softmax 再挑人?因为要保证被选中专家的权重加起来正好是 1。如果先在 8 个之间 softmax,专家 1 拿 0.62、专家 4 拿 0.15,两个加起来只有 0.77,剩下 0.23 的"份额"被丢弃的专家带走了——那这个 Token 的输出会整体偏小、幅度不稳。相当于一笔预算分给五个部门,其中三个部门被取消了,剩下两个部门必须把全部预算分完,不能让 23% 的钱悬在空中。
第二,为什么是 Top-2 而不是 Top-1?Top-1 更省算力(Switch Transformer 就是 Top-1),但有一个隐患:路由是个"硬"决策,只选一个的话,梯度只能流向那一个专家,路由器学起来非常不稳——它没有机会比较"选 A 好还是选 B 好"。选两个,就有了对比,训练平稳得多。而 Top-2 相比 Top-1 只多一倍专家计算量,仍然远小于稠密。这就像做决策时至少听两个人的意见,你才能判断谁说得更靠谱;只听一个人,你连对错都无从判断。
第三,路由决策是"每个 Token 各自决定"的,不是"整句话统一决定"。这一点最容易误解。同一句话里,"请"这个字可能被路由到专家 3 和 7,"用"字可能去了专家 1 和 5,"Python"可能去了专家 12 和 40。一句 20 个字的话,在一层里可能唤醒了十几位不同的专家。而且模型有几十层,每层都重新路由一次——DeepSeek-V3 有 58 个 MoE 层,一个 Token 从头走到尾,前后经过的专家组合有几十种。所以不要把 MoE 想成"这次对话调用了 2 个专家",而应该想成"每一个字在每一层都被重新分诊了一次"。
核心概念 · 总参数 vs 激活参数
MoE 让"参数量"这个词一分为二,需要一次说清:
- 总参数(Total Params)模型全部权重的规模——决定"模型有多大的知识容量"。DeepSeek-V3 是 6710 亿。
- 激活参数(Active Params)处理一个 Token 时实际参与计算的参数量——决定"每次生成有多贵"。DeepSeek-V3 是 370 亿。
DeepSeek-V3 的经济学秘密就在这两个数字的比例——6710B ÷ 370B ≈ 18 倍——它拥有 671B 密集模型的知识容量,但推理成本只有 37B 密集模型的水平。这就是为什么 DeepSeek 定价能做到 GPT-4 的几十分之一。
"18 倍"这个比例还是有点抽象。我们把它换算成三个人人有感的量:训练花多少钱、推理多快、你调用 API 付多少钱。
【一】训练成本
DeepSeek-V3 官方论文披露的数字:
训练用了 2788 千 GPU 小时(H800)
按当时的租用市价 2 美元/GPU小时 计算
≈ 557.6 万美元
对比同期公开或推测的数据:
GPT-4(传闻) 约 6300 万 ~ 1 亿美元
Llama-3-405B(稠密)约 3000 万美元以上(Meta 用了 1600 万 GPU 小时)
也就是说:DeepSeek-V3 用了大约 1/10 甚至更低的成本,
训出了一个基准测试上与顶级闭源模型同档的模型。
MoE 不是唯一原因(还有 FP8 训练、MLA、多 Token 预测等),
但它是最主要的那个原因。
【二】推理速度(每秒能吐多少字)
影响生成速度的关键不是总参数,而是「每个 Token 要搬多少参数进计算单元」。
671B 稠密,FP8 精度 → 每 Token 要读 671 GB 参数
H100 显存带宽约 3.35 TB/s → 理论上限 5 Token/秒
671B MoE 激活 37B → 每 Token 只读 37 GB
→ 理论上限 90 Token/秒
90 对 5,差 18 倍。而 5 Token/秒是什么体验?
大约每秒吐出 3~4 个汉字,慢到你会怀疑网络断了。
90 Token/秒则是「比你阅读速度还快」的流畅体验。
【三】你付的 API 价格(2024 年底的公开定价,每百万 Token)
GPT-4o 输入 $2.50 输出 $10.00
Claude 3.5 输入 $3.00 输出 $15.00
DeepSeek-V3 输入 $0.27 输出 $1.10
差距约 10 倍。翻译成日常场景:
用 GPT-4o 处理一本 30 万字的书(约 45 万 Token)
输入成本 ≈ $1.13
用 DeepSeek-V3 处理同一本书
输入成本 ≈ $0.12 —— 不到一块钱人民币
MoE 让「用大模型处理海量文本」从奢侈行为变成了日常操作。
但必须马上补一句,否则你会得到一个错误印象:MoE 省的是算力,不省显存。这一点非常反直觉,也是很多人第一次接触 MoE 时最大的误区。我们下面单独用一节讲清楚。
MoE 的显存代价 · 专家全都得在场,只是不都发言
回到医院那个类比,现在要补上一个残酷的现实:虽然每次只叫两位医生看诊,但医院必须把全部 256 位专家都养着、都在班上、都占着办公室。因为你不知道下一个病人需要谁,谁都不能回家。
模型里也一样。那 6710 亿个参数必须全部加载到显存里,一个都不能少——因为路由器随时可能选中任何一位专家,来不及从硬盘上临时读取(硬盘比显存慢几千倍,读一次的时间足够生成好几百个 Token)。
DeepSeek-V3 的显存账(FP8 精度,1 参数 = 1 字节)
权重本身:671 GB
运行时还需要:KV Cache、激活值、通信缓冲区等,约 50~100 GB
────────────────────────────────
合计约 750 GB
一张 H100 有 80 GB → 至少需要 10 张卡,实际部署常用 16 张
按 H100 单卡约 25 万元人民币算 → 硬件成本约 400 万元
对比一个同等「激活参数」的稠密 37B 模型:
权重 37 GB → 一张 H100 就够,甚至一张 48G 的卡量化后也能跑
所以 MoE 的真实定位是:
✓ 省算力(每 Token 快 18 倍)
✓ 省电(同样的输出,耗电少一个数量级)
✗ 不省显存(该占的一分不少)
✗ 不适合端侧(手机哪来 671 GB 内存)
【一个精确的说法】
MoE 交换的是「显存换算力」:
用「多占显存」这件相对便宜的事,
换掉「每次都全算一遍」这件极其昂贵的事。
在数据中心里这笔交易非常划算 ——
因为显存可以靠多插卡解决,而延迟不能靠多插卡解决。
在手机上这笔交易完全不成立 ——
所以你手机里的模型(Phi-3、Qwen-1.8B)全是稠密的。
顺便解释一个常被问到的现象:为什么 Mixtral 叫 "8x7B" 却只有 47B 参数,而不是 56B?因为那个"8x"只作用在 FFN 部分,注意力层、词嵌入层这些是八位专家共用的,不需要复制八份。8 × 7 = 56 这个算法把共用部分重复算了八次。真实的构成是:共用部分约 5B + 八份专家 FFN 各约 5.3B = 47B。这个命名方式引起过不少误解,后来的模型(如 DeepSeek)就改成直接标"总参数/激活参数"了,清楚得多。
代表模型 · MoE 家族
| 模型 | 总参数 | 激活参数 | 专家数 / Top-K | 发布时间 |
|---|---|---|---|---|
| GShard (Google) | 600B | ~几十亿 | 2048 / 2 | 2020 |
| Switch Transformer | 1.6T | 7B | 2048 / 1 | 2021 |
| Mixtral 8x7B | 47B | 13B | 8 / 2 | 2023.12 |
| Mixtral 8x22B | 141B | 39B | 8 / 2 | 2024.4 |
| Qwen1.5-MoE-A2.7B | 14.3B | 2.7B | 60 / 4 | 2024.3 |
| DeepSeek-V2 | 236B | 21B | 160 / 6 + 2 shared | 2024.5 |
| DeepSeek-V3 | 671B | 37B | 256 / 8 + 1 shared | 2024.12 |
| Grok-1 (xAI) | 314B | ~86B | 8 / 2 | 2024.3 |
你看得出趋势——专家数量在快速上升,从最早的 8 个逐渐增加到 256 个甚至几千个。专家越细分,每个"更专业",模型的知识密度就越高。DeepSeek-V3 的 256 位专家已经接近一支"综合科研院"的规模。
Mixtral 8x7B 有 8 位专家——像一家社区诊所:内、外、妇、儿……分工粗,几位老大夫覆盖大部分场景。
DeepSeek-V3 有 256 位专家——像一家大型综合医院:不仅有心内科,还细分成心律失常科、心脏介入科、心衰科;不仅有神内,还有帕金森专科、癫痫专科、脑卒中专科……
专家越细分,每位专家越精,路由器(分诊台)也越难做——但服务上限就越高。这就是 MoE 规模化的路径。
关键难题 · 路由平衡问题
MoE 听起来完美,但工程上有个头疼的问题——路由塌方(Routing Collapse)。
想象一下:如果 Router 学着学着,发现"送到 3 号专家总是效果不错",就干脆一直把所有 Token 都送去 3 号——这样 3 号累死,其他 255 位专家没活干、参数白占显存。整个 MoE 退化成了一个密集小模型。
解决路由平衡问题,是 MoE 训练的核心工程挑战。常见手段:
- 负载均衡损失(Load Balancing Loss)额外加一个损失项,惩罚"某位专家被过度使用"——强制路由把工作量均摊。
- 容量因子(Capacity Factor)给每位专家设一个"每 batch 最多处理多少 Token"的上限——超了就丢给次优专家。
- 共享专家(Shared Expert)DeepSeek 的创新——留 1 位"什么 Token 都过一遍"的专家,处理通用知识;其他专家专攻细分领域。
- Expert Parallelism工程层面把不同专家放在不同 GPU 上,让路由能真的跨设备分发——这是训练超大 MoE 的硬件基础。
把路由塌方这件事放回医院场景,你会立刻明白它有多荒唐,也明白为什么必须人为干预。
事情是这样开始的。新来的分诊台护士经验不足,第一天随便分诊。恰好她分给呼吸科的几个病人恢复得都不错,于是她形成了一个印象:"呼吸科很靠得住。"
第二天,她分给呼吸科的病人更多了,呼吸科的医生也因为看得多、越看越熟练——反馈更好了。第三天,她把八成病人都送去了呼吸科。
一个月后的局面:呼吸科走廊排到楼梯口,医生连轴转、看病越来越糊;而眼科、骨科、皮肤科的医生一个月没接到病人,业务能力开始退化,反而更不敢派活给他们了。这形成了一个恶性循环:用得多的越用越强,用得少的越用越弱,最后 256 个科室退化成事实上的 1 个科室。
院长的干预手段就是下面要讲的负载均衡损失——他给分诊台立了一条硬规矩:"每个月各科室的接诊量偏差不得超过某个范围,超了扣你绩效。"护士为了自己的绩效,会主动把病人往冷门科室匀。这个规矩看起来很粗暴,甚至有时会让病人被分到不那么理想的科室,但它保住了整个医院的能力结构——宁可单次分诊略有偏差,也不能让 255 个科室荒废掉。
负载均衡损失与专家容量 · 惩罚公式加上"号满了怎么办"
"加个损失项惩罚不均衡"这句话有点玄,我们把它拆成能算的东西。所谓损失(Loss),说白了就是模型的"扣分表"——训练时模型的唯一目标就是让扣分越少越好,你往扣分表里加一条,它就会主动避开那条被扣分的行为。
负载均衡损失的核心思路(Switch Transformer 的写法)
对一个 batch 里的所有 Token,统计两个东西:
f_i = 实际被路由到专家 i 的 Token 比例(谁接了多少活)
P_i = 路由器给专家 i 的平均打分(谁被看好的程度)
辅助损失 = α × N × 求和( f_i × P_i )
其中 N 是专家数,α 是权重系数(通常 0.01)
为什么这个式子能促成均衡?看两个极端:
【完全均衡·8 个专家】
每个 f_i = 1/8 = 0.125,每个 P_i = 0.125
损失 = 0.01 × 8 × (8 × 0.125 × 0.125)
= 0.01 × 8 × 0.125 = 0.01
← 这是这个式子能取到的最小值
【完全塌方·全部涌向专家 3】
f_3 = 1.0,P_3 ≈ 1.0,其余全是 0
损失 = 0.01 × 8 × (1.0 × 1.0)
= 0.08
← 是均衡情形的 8 倍,模型会被狠狠扣分
所以梯度下降为了少扣分,会推着路由器把活儿摊平。
α = 0.01 这个数字也是权衡出来的:
太小 → 惩罚不够,还是会塌方
太大 → 路由器为了均衡而胡乱分配,把 Token 送给
不合适的专家,主任务效果下降
这就像给分诊台定 KPI:
考核太松,她还是只往一个科室送;
考核太严,她为了凑数把感冒病人送去骨科。
DeepSeek-V3 在这件事上做了一个很漂亮的改进,叫无辅助损失的负载均衡(Auxiliary-Loss-Free Load Balancing)。他们注意到辅助损失有个副作用:它跟主任务是"打架"的——一个要效果好,一个要分配平,两个目标互相拉扯,最终两边都要打折。
他们的替代方案是给每位专家加一个动态偏置项:谁最近接活太多,就在它的路由分数上悄悄减一点;谁太闲,就加一点。关键在于:这个偏置只影响"挑谁",不参与最终输出的权重计算,所以完全不干扰主任务的梯度。用大白话说:不再罚护士的绩效,而是在排班表上做手脚——把忙科室的号源调少一点,闲科室的号源调多一点。病人还是按病情分诊,只是号源的松紧被暗中调节了。这个改动看起来很小,但让 DeepSeek-V3 在保持均衡的同时避免了效果损失,是它训练成功的关键之一。
光有软性的惩罚还不够,训练时必须有个硬性的兜底机制,因为 GPU 有一个死板的要求:它需要提前知道每个专家要处理多少个 Token,才好分配显存。它不能接受"这个专家这批可能来 3 个也可能来 3000 个"这种不确定性。
于是有了专家容量(Expert Capacity)——所谓专家容量,说白了就是给每个科室每天的挂号数设一个上限。
容量的计算与"丢弃"的发生
容量 = 容量因子 × (这批 Token 总数 × K) / 专家数
举例:一批 4096 个 Token,8 个专家,Top-2,容量因子 1.25
平均每个专家该接:4096 × 2 / 8 = 1024 个
容量上限 = 1.25 × 1024 = 1280 个
(容量因子 1.25 意味着「允许比平均值多接 25%」,
这是留给不均衡的缓冲空间)
现在假设专家 3 特别热门,这批有 1500 个 Token 想去:
前 1280 个被接收,正常处理
后 220 个 —— 号满了,怎么办?
三种处理方式:
① Token Dropping(丢弃)
这个专家不处理它了,它的输出就靠残差直接跳过这一层。
相当于「今天挂不上号,你先回家,病历原样带走」。
—— Switch Transformer 的做法
② 转给次优专家
送去 Top-2 里的第二名,或者顺位第三名。
相当于「呼吸科满了,去感染科看看」。
③ 提高容量因子
把 1.25 调到 2.0,几乎不会满。
代价:显存占用几乎翻倍,且大量容量被浪费。
实测经验:
容量因子 1.0 → 丢弃率可能高达 10%+,效果明显受损
容量因子 1.25 → 丢弃率约 1%~3%,常用配置
容量因子 2.0 → 几乎不丢,但显存吃紧
一个重要区分:
训练时会丢弃(为了 batch 内的形状固定,便于并行)
推理时通常不丢弃(一次只处理少量 Token,可以灵活处理)
这也是「MoE 推理引擎需要专门实现」的原因之一。
"丢弃"这个词听着可怕,好像信息就没了——其实不至于。因为残差连接(§7.2 讲过的"原件留一份")在那儿兜底:被丢弃的 Token 只是这一层没被加工,它的原始信息完整地传到了下一层,下一层还有机会处理它。就像挂不上今天的号,明天还能来。所以少量丢弃对效果的影响是可接受的——但如果丢弃率飙到 10% 以上,就说明路由已经严重失衡,得回去调参了。
通信开销与专家并行 · 病人要跨楼跑
还有一个只在真实工程里才暴露出来的成本,纸上推导时完全看不见。256 位专家放不进一张卡,必须分散在几十张 GPU 上——这个做法叫 Expert Parallelism(专家并行,简称 EP):所谓专家并行,说白了就是把不同的科室开在不同的楼里。
问题随之而来:一个 Token 在第 1 号卡上算完注意力,路由器说"你该去 37 号专家",而 37 号专家住在第 5 号卡上。这个 Token 的向量必须通过网络从 1 号卡搬到 5 号卡,算完再搬回来。这就是"病人要跨楼跑"。
一次 MoE 层的通信过程(All-to-All 通信)
第 1 步 · Dispatch(分发)
每张卡把自己手上的 Token 按目标专家打包,
发给对应的卡。因为目标可能是任意一张卡,
所以是「所有卡对所有卡」都要发一次 —— All-to-All。
第 2 步 · 各卡上的专家计算(这一步是纯算力,很快)
第 3 步 · Combine(回收)
算完的结果再原路搬回原来的卡,
又是一次 All-to-All。
一层要做两次全局通信。DeepSeek-V3 有 58 个 MoE 层
→ 一次前向传播要做 116 次跨卡全局通信。
开销有多大?
卡内通信(NVLink):约 900 GB/s,还算快
跨机通信(InfiniBand):约 50~400 GB/s,慢得多
如果专家分散在多台机器上,通信可能占到
整层耗时的 30%~50% —— 也就是说 GPU 有近一半时间
在等数据搬运,而不是在算。
DeepSeek-V3 的应对(论文里的 DualPipe 方案):
把「通信」和「计算」重叠起来 ——
在等这一批 Token 搬运的同时,
先算上一批已经到位的 Token。
相当于医院搞了个「病人转运的同时,医生先看已经到的病人」
的流水线,让医生几乎不空等。
他们还专门限制了「每个 Token 最多跨 4 个节点」,
从算法层面给通信量上了个天花板。
这一节想传达的要点是:MoE 的账不能只算浮点运算。理论上省 18 倍算力,实际端到端可能只快 8 到 12 倍,差额就吃在通信上。这也是为什么 MoE 的成功高度依赖工程能力——同一个模型结构,通信调度做得好和做得差,训练成本能差一倍。DeepSeek 团队公开的那些工程细节(DualPipe、FP8 训练、跨节点限制)之所以被反复研究,原因就在这里:MoE 在论文上是个算法创新,在落地时是个系统工程问题。
MoE 的优点与代价
| 维度 | MoE 的优势 | MoE 的代价 |
|---|---|---|
| 推理成本 | 只激活一小部分——比同容量密集模型便宜 5~20 倍 | 但显存占用仍然是"总参数"——所以还是很吃卡 |
| 训练效率 | 相同算力下能训练更大的模型 | 路由不稳定,训练调参更难 |
| 模型能力 | 知识容量大,泛化面广 | 专家之间信息不共享,可能导致"割裂" |
| 部署难度 | —— | 需要专门的 MoE 推理引擎(vLLM、SGLang 都在跟进) |
但总的来说,MoE 是大模型进入"万亿时代"的经济学解药——没有 MoE,普通企业根本用不起万亿模型;有了 MoE,DeepSeek 才能把 API 价格打到白菜价。
共享专家与细粒度专家 · DeepSeek 的两个关键改动
从 Mixtral 的 8 位专家到 DeepSeek 的 256 位专家,不只是数字变大,中间有两个真正的设计突破。DeepSeek-V2 的论文把它们讲得很清楚。
改动一 · 细粒度专家切分(Fine-Grained Expert Segmentation)。所谓细粒度,说白了就是把几位"大而全"的专家,拆成很多位"小而专"的专家——同时按比例多选几位。具体做法是:把每位专家的规模缩到原来的四分之一,专家数量变成四倍,同时把 Top-2 改成 Top-8。激活的参数总量一分不变,但"专家组合"的可能性暴增。
为什么细粒度更好?—— 组合数的爆炸
【粗粒度】16 位大专家,每次选 2
可能的组合数 = C(16, 2) = 120 种
【细粒度】64 位小专家(每位是原来的 1/4),每次选 8
激活参数量:8 × (1/4) = 2 个大专家的量 —— 完全相同!
可能的组合数 = C(64, 8) = 4,426,165,368 种
≈ 44 亿种
120 种 vs 44 亿种,而成本一模一样。
【打个比方】
粗粒度像去餐厅点「套餐」——只有 120 种套餐可选,
你想吃的搭配可能压根没有。
细粒度像去自助餐台夹菜 —— 64 个菜品里夹 8 样,
吃的分量完全一样,但能配出的口味组合近乎无限。
想吃辣配甜?想吃素配汤?都能精确满足。
这就是"专家越细分,模型的知识密度越高"的数学根据:
同样的参数预算,能表达的"专业化路径"多了七个数量级。
改动二 · 共享专家隔离(Shared Expert Isolation)。所谓共享专家,说白了就是留出一到两位"不管什么病人都要过一遍"的全科医生,每个 Token 必定经过它们,另外再按路由挑几位专科医生。
为什么要这么设计?因为纯路由方案有一个隐藏的浪费:很多基础能力是所有 Token 都需要的——基本语法、常用词的含义、语序习惯。如果没有共享专家,那这些基础能力就得在 256 位专家里各存一份——256 份重复的基础知识,白占了大量参数。
用大白话说:如果医院没有全科医生,那么每个专科医生都必须自己掌握一套"量血压、测体温、看化验单"的基本功——256 份重复的基本功。设一个全科门诊统一处理这些,专科医生就能把全部精力用在自己的专业深度上。DeepSeek-V3 的最终配置是"1 位共享专家 + 256 位路由专家,每次激活共享 1 位 + 路由 8 位",正是这个思路的产物。这两个改动加起来,让 MoE 从"能用"变成了"好用",也是 DeepSeek 系列能在同等激活参数下超越竞品的结构性原因。
MoE 的训练不稳定性 · 为什么它比稠密模型难训
MoE 有一个不太被外行提及、但从业者深有体会的痛点:它训起来比稠密模型脆弱得多。原因可以归成四条,每一条都有生活里的对应。
- 难点一 · 路由是"硬"决策,梯度不连续Top-K 里那个"选谁不选谁"的动作是一刀切的,不可微分。路由分数从 2.09 变成 2.11,选择结果可能突然从专家 A 跳到专家 B,整个后续计算路径瞬间换了一条。相当于分诊台的判断从"内科多一点点"变成"外科多一点点",病人就被送去了完全不同的楼层——后续的治疗方案天差地别。这种不连续让优化过程非常颠簸。
- 难点二 · 富者愈富的正反馈前面讲过的路由塌方,本质上是一个自我强化的循环:被选中越多的专家训练越充分、表现越好、于是被选中更多。这类正反馈在优化里天生不稳定,一点初始随机偏差就可能被放大成完全的失衡,必须靠外力持续压制。
- 难点三 · 每位专家看到的数据量少得多256 位专家、Top-8,意味着平均每位专家只看到全部数据的 8/256 = 3.1%。稠密模型的每个参数都被 100% 的数据训练过;MoE 里每位专家只被约 3% 的数据训练过。数据一少,过拟合和欠训风险都上升。好比一个科室的医生一年只接 30 个病人,他的经验积累速度必然慢于每天看 30 个的全科医生。
- 难点四 · 数值不稳定,容易溢出路由分数经过 softmax,如果某个分数窜得特别高,会引发数值溢出(在低精度训练里尤其危险)。Switch Transformer 论文专门提到必须把路由器部分用 FP32 高精度计算,哪怕其他部分用 FP16/BF16——因为路由器一崩,整个模型就崩。这就像整栈系统里那个最小但最关键的服务,必须给它最高等级的保障。
业界的应对办法是一整套经验的堆叠:路由器用高精度、加梯度裁剪、给路由分数加一点随机噪声(防止过早锁定)、用更小的学习率、辅助损失系数细致调参、训练早期先当稠密模型热身再切换到稀疏……这就是为什么 MoE 的开源实现看起来不难,但真正训出一个好的 MoE 大模型只有少数团队做得到。结构可以抄,那几十条"踩过坑才知道"的工程细节抄不来。
MoE 与蒸馏 · 大专家团教出一个小全科
MoE 有一个很自然的搭档技术叫知识蒸馏(Knowledge Distillation)——所谓知识蒸馏,说白了就是让一个大模型当老师,教一个小模型模仿它的答案,从而把大模型的本事"浓缩"进小模型里。
为什么这两个技术特别配?因为它们各自的短板正好被对方补上:
| MoE 大模型(老师) | 蒸馏出的小稠密模型(学生) | |
|---|---|---|
| 能力上限 | 高——知识容量大 | 略低,但可以接近 |
| 显存需求 | 极高(几百 GB,必须多卡) | 低(几 GB,单卡甚至手机) |
| 部署场景 | 云端 API、数据中心 | 端侧、边缘设备、私有化部署 |
| 训练成本 | 高,但比同容量稠密低一个量级 | 很低(只需模仿老师的输出) |
| 角色定位 | 知识的"生产者" | 知识的"分发者" |
形成的完整链路是:先用 MoE 以较低成本训出一个能力极强的大模型,再用它生成大量高质量的训练数据(或直接对齐它的输出分布),蒸馏出一系列小的稠密模型,分发到各种设备上。用大白话说:先建一所拥有 256 位顶级专家的教学医院,让它培养出一批扎实的全科医生,再派到各个社区诊所去——社区诊所装不下 256 位专家,但一位受过顶级培训的全科医生足以应付九成日常需求。
DeepSeek-R1 是这个链路最著名的公开案例:他们用 R1(基于 671B MoE)生成的推理数据,蒸馏出了 1.5B 到 70B 一系列稠密小模型,其中 32B 的版本在数学推理上超过了当时的许多更大的模型。这条路径正在成为行业标配——旗舰模型走 MoE 追极限,衍生模型走稠密 + 蒸馏铺市场。你手机上跑的那个小模型,很可能就是某个 MoE 巨兽的"徒弟"。
为什么 MoE 成了扩容的主流路线 · 三个层面的必然
最后收一个总账。为什么 2024 年之后所有超大模型几乎清一色转向 MoE?答案不在某一项技术优势,而在三个层面同时指向了同一个方向。
- 层面一 · 缩放定律的算术要求缩放定律(Scaling Law)告诉我们:模型能力随参数量和数据量的增长而可预测地提升。要变强就必须变大,这是硬要求。但稠密模型的推理成本与参数量成正比——变大十倍,每个字都慢十倍。MoE 打破了这个绑定:容量可以随意涨,成本只随激活参数涨。这是唯一一条"能变大又不变慢"的路。
- 层面二 · 数据快用完了高质量文本数据是有限的,业界估计已经在耗尽的边缘。当数据不再是可以无限扩张的一边时,就得靠"更有效地存储和调用已有知识"来提升能力。稠密模型把所有知识揉在同一套参数里,彼此干扰(业内叫"知识冲突");MoE 让不同类型的知识分居在不同专家里,互不挤占——相当于从"一间大通铺"改成"很多个隔间",同样的建筑面积能住得更舒服、更专业。
- 层面三 · 经济账算得过来这是最现实的一条。API 是按量计费的生意,推理成本直接决定毛利率和定价空间。一个能力相同但推理便宜十倍的模型,在市场上是压倒性的优势。DeepSeek 用 MoE 把价格打到十分之一,直接引发了 2024 年那场全行业降价——这不是慈善,是结构性成本优势带来的定价权。只要商业模式是"按调用次数收钱",MoE 就永远有经济上的吸引力。
再补一个视角上的转变,它可能比上面三条更根本。过去十年,深度学习的默认假设是"参数越多越好,而且每次都要全用上"。MoE 挑战的是后半句——它主张:参数的作用是"存放可能有用的知识",而不是"每次都必须参与运算"。从"全员到岗、全员出工"变成"全员到岗、按需出工",这个转变让"模型规模"和"运行成本"这两个长期绑死的量第一次可以分开调节。这是一个范式级别的松绑。
当然也要留一句清醒的话:MoE 不是终点,它只是"条件计算"这个更大方向上目前最成熟的一个形态。它还有明显的未解问题——显存占用没解决、路由仍然脆弱、专家分工不可控、端侧完全用不上。所以本篇末尾提到的那些更激进的方向(Attention 层也稀疏、层数动态决定、参数按需从内存换入显存)都在推进中。但可以肯定的是:从 2024 年往后,"总参数"和"激活参数"这两个数字会一起出现在每一份大模型规格表上,就像手机同时标"存储容量"和"运行内存"一样自然。
MoE 的历史 · 从 1991 到 2024
MoE 不是什么新概念——早在1991 年,Hinton 的学生 Jacobs 就提出了"Mixtures of Experts"的原型思想,用在传统神经网络里。但直到深度学习时代它才真正大放异彩:
- 2017 · Sparsely-Gated MoEGoogle 的 Noam Shazeer 团队第一次把 MoE 融进大规模神经网络——用稀疏门控让专家"轮流上工",参数量突破 1000 亿。
- 2020 · GShardGoogle 首个真正的超大 MoE 语言模型——2048 个专家、600B 参数——但训练不稳定、路由问题严重。
- 2021 · Switch Transformer进一步简化路由——Top-1 激活(每个 Token 只走 1 位专家),把参数扩到 1.6 万亿。
- 2023 · Mixtral 8x7BMistral AI 开源了第一个"人人可用"的 MoE 大模型——8 位专家 Top-2 激活——一夜之间让 MoE 从"实验室玩具"变成"生产力工具"。
- 2024 · DeepSeek-V3中国团队把 MoE 玩到极致——671B 总参、37B 激活、256 专家 Top-8 + 共享专家——训练成本只有 GPT-4 的 1/10。彻底改写了"大模型经济学"。
Dense vs MoE · 什么时候该选 MoE
并不是所有模型都适合 MoE——它有自己的"甜蜜区"。什么时候该考虑 MoE?
| 场景 | Dense 更好 | MoE 更好 |
|---|---|---|
| 参数 < 10B | ✓ 简单直接 | 路由开销不值 |
| 参数 10B~100B | 还行 | ✓ 开始有优势 |
| 参数 > 100B | 推理太贵 | ✓ 唯一选择 |
| 端侧部署(手机) | ✓ 内存友好 | 显存占用不划算 |
| API 云服务 | 成本高 | ✓ 大幅省电 |
| 训练资源紧 | 参数少省事 | ✓ 相同算力更强 |
所以你看到市场上——端侧模型(Phi-3、Qwen-3B、Llama-3.2-1B)继续走 Dense 路线,云端旗舰模型(DeepSeek V3/V4 系、Mixtral、Kimi K2)全线转向 MoE。两条路线各有用武之地,谁也没吃掉谁。
更远的未来 · 稀疏之外还有什么
MoE 只是"稀疏化"这个大方向的一个具体形态。围绕"参数很多但每次只激活一部分"这个思想,学术界还在探索更激进的方案:
- Fine-grained Expert专家做得越来越小、越来越多——DeepSeek 用 256 位小专家取代 8 位大专家,知识密度更高。
- Shared Expert Isolation留一部分专家永远激活(处理通用能力),其他专家做细分领域——DeepSeek-V3 的关键创新。
- MoE + MLA + MTPDeepSeek-V3 三大创新的组合——把 MoE 和多头低秩、多 Token 预测结合,训练效率再翻倍。
- Conditional Computation终极目标——不只是 FFN 稀疏,Attention 层、每层深度都根据输入动态决定要不要用。目前还在研究阶段。
2025 年之后,我们大概率会看到"万亿参数、百亿激活"成为主流大模型的默认配置——就像 2020 年"千亿参数"从奢侈变常态那样。
MoE 会不会让每位专家"专精一门"
很多人第一次听 MoE 会想:那 256 位专家是不是一位管数学、一位管代码、一位管诗歌、一位管医学?——实际情况没那么整齐。
研究者对 Mixtral 和 DeepSeek 做了大量可视化分析,发现专家的分工是相当抽象的——它们不是按"话题"分,而是按更底层的"语言模式"分。有的专家专门处理数字类 Token,有的专家专门处理动词,有的专家专门处理句尾结构,有的专家专门处理代码里的括号缩进……分工存在,但不是我们直觉里那种"学科式分工"。
这也解释了为什么单看某位专家没什么规律可言——它们是训练动态中自组织涌现的产物,不是人类概念体系的镜像。让专家真正"每人一门学科"是一条研究方向,但目前的主流 MoE 都还处于"隐性分工"阶段。
MoE 的口诀只有一句——"参数很多,激活很少"。它把 Transformer 里那个又大又贵的 FFN 层,换成了一堆专家 + 一个分诊台。总参数量可以疯狂堆到万亿,激活参数量却只有几百亿,成本大幅下降。
DeepSeek-V3、Mixtral、Qwen-MoE 三大代表证明了这条路——2025 年之后,几乎所有超大模型都会走 MoE。
到这里,第 7 章 Transformer 的五个核心概念——Attention、QKV、Multi-Head、Encoder/Decoder 派系、MoE——就全部讲完了。下一章我们会走进它最著名的应用场景:大语言模型(LLM)。