跳到主要内容

专家路由——把稠密模型改成 MoE

这一章讲三件事: 为什么「每个 token 都动用全部参数」是浪费、三种动态推理怎么省;怎么把一个稠密模型改造成双专家 MoE 并让路由器学会分诊;以及怎么把第七章特化好的模型直接移植进来当专家——连训练都省一半。 这是全书最后一站:前面所有技术的产物——剪过的模型、特化过的专家——在这里被组装成一个会「按 token 分诊」的系统。

1. 这一章讲什么

稠密模型有个天生的浪费:不管在回答「巴黎是哪国首都」还是「五十页报告的逐条分析」,每个 token 都跑完同样的全部参数——它是按最难的情况设计的架构,而多数输入用不着1。动态推理让模型在运行时决定「算什么、跳过什么、把谁送去哪」。三种思路里,本章只深讲最成熟的 Mixture of Experts(MoE,专家混合):Mistral 用 Mixtral 8x7B 证明了它能出实验室,DeepSeek 又把它推向「许多小专家」的细粒度形态2

它在全书链条里的位置: 它是终点站,也是装配车间——第 07 章那个临床抽取专家,本章会被整个移植进 MoE 当器官用。

2. 顶层全景

三种动态推理( 本章只做第三种 )
早退:信心够了就提前出层(看 logits 集中度)
丢词:无关 token 逐层淘汰(看注意力权重,直接省 KV cache)
MoE:每个 token 路由到最合适的专家(可训练的线性路由器)

MoE 块 = 专家 × N + 路由器(一个 Linear 层)
原书的造法(sparse upcycling):
专家 0 = 原 MLP,冻结,保通用
专家 1 = 原 MLP 的拷贝,可训,学领域
路由器 = 从零训的 Linear(hidden → N)

图说:三种动态推理共同的短板是与 vLLM/TGI 这类
标准推理引擎不兼容——MoE 是其中唯一已获广泛支持的[^3]。

3. 核心原理

3.1 先立骨架:MoE 块怎么替换 MLP

MoE 块由三件套组成:专家(各自独立处理)、路由器(一个线性层,把每个 token 的隐状态投成每个专家一个分数)、组合前向(按路由器的比例混合输出)3。原书在 SmolLM2-1.7B-Instruct 上做最小改造:专家 0 就是原 MLP(权重原封不动、冻结),专家 1 是原 MLP 的深拷贝(可训练),只动 13-23 层——深层表示最抽象,特化最见效;全改的话 T4 显存也受不了4

这种「复制已训练权重来填专家、不从随机开始」的做法有正式名字:sparse upcycling,行话叫稀疏升级;稀疏(不是每个部件都随时动用,只在需要时才用一部分)是它省力的根源——给机器一个领跑优势5

冻结后的账:全模型 2,265,069,568 参数,可训的只有专家 1 加 11 个路由器,24.44%6

3.2 路由器的第一课:噪声防塌缩

双专家起步时权重完全相同,路由器怎么分都「对」——于是随机波动造成初始偏好,受宠的专家拿到更多梯度、变得更好,路由器更宠它,另一个专家彻底断粮。必须人为打断这个死循环:训练期给路由器的 logits 加高斯噪声(幅度 0.35),逼它在前几轮把两个专家都试一遍,给专家 1 长出本事的时间7

配套的两个工程细节:softmax 要在 FP32 里算(fp16 下会出退化值,把某个专家的贡献直接清零)8;训练数据必须是临床题和通用对话混装再打乱——只喂临床数据,路由器就没有「别的类」可学;不混洗,它会先学会全送一边、再费劲反学习9

3.3 主走查:一张路由表里看懂分诊

走查对象:训练好的双专家 MoE,第 23 层的路由权重(原书实测,soft routing 下每个 token 两个权重加和为 1)。

输入 A:"What's the most significant building in Barcelona?"
What → 通用 0.514 / 临床 0.486
Barcelona → 通用 0.606 / 临床 0.394
(整句温和偏向通用专家,没有任何临床信号)

输入 B:"Patient is a 67-year-old male with chronic pain"
Patient → 通用 0.517 / 临床 0.483 ← 还在观望
old → 通用 0.465 / 临床 0.535 ← 开始转向
with → 通用 0.380 / 临床 0.620 ← 最高点
chronic → 通用 0.469 / 临床 0.531
pain → 通用 0.548 / 临床 0.452 ← 又回来了!

图说:分诊不是「临床词去临床专家」的查表——
是随上下文累积逐渐倾斜的连续过程[^11]。

两个从这张表里长出来的关键认知。第一,路由器看的是累积上下文,不是词本身:「Patient」这个最像临床的词反而留在通用专家;把 prompt 改成「chronic back pain」,「pain」就搬家去临床专家——同一个词,换个邻居,换边站10第二,诚实的一句:「临床专家」是叫着方便——没有直接证据证明它的权重真的长出了临床专门表示;能验证的只有「它用临床数据训练过、路由器爱把临床 token 送给它」11

3.4 软路由与硬路由:同一套权重,两种性格

soft routing(上面的走查)每个 token 让两个专家都跑、按权重混合——有特化,但激活了全部权重。真正的 MoE 效率来自选择性激活:总容量很大,每个 token 只激活少数专家,推理成本不随之爆炸12

换硬路由不需要重新训练——权重原封不动,只换推理分支:路由器对每个 token 做 argmax 二选一,用布尔掩码把 token 分给两个专家各跑各的,结果写回原位(零初始化的输出张量+掩码当写入索引,顺序不乱)13

结果:Barcelona 全部 token 一边倒(通用 1.0/临床 0.0),不再有中间值;合规率与 soft 完全相同,97.5%——同样的成绩,只跑一个专家14。更有意思的是行为差异:同一个问题,基模型答四句、soft 版两句、hard 版一句,匹配的文本完全一样——唯一变的是模型决定何时停;一个假说是新专家学的是 JSON 这种「闭环生成」,输出齐了就收15

通用能力呢?五项基准里四项不降反升(ARC-Easy +0.17pp 到 LAMBADA +4.37pp),只有 PIQA 微降——特化没有伤害通用行为,甚至整体变好16

3.5 移植:第七章的专家直接上岗

真正的省法在这节。第七章已经训好一个临床抽取模型——它的 MLP 可以整个挖出来,当专家 1 直接移植,省掉从零特化这一步。为此把 MoE 类升级成参数化的 TrainableTopKMoE:专家数量(num_experts)和每 token 激活数(top_k)都成了配置;推理时 topk 选专家、只在选中的之间重新归一化,没分到 token 的专家直接跳过——真正省计算的只有那一行「专家只处理分给自己的那部分 token」,其余全是后勤17

移植后的训练分两相(数字为本章的高光):

阶段训什么可训参数占比学习率结果
只训路由器(24 个,全部层的)0.0034%1e-3合规 90%
加训移植专家的尾部 6 层(18-23)10.35%路由器降到 1e-6,专家 1e-5合规 100%

为什么不能只训路由器?移植来的 MLP 当年是与微调过的注意力并肩工作的;现在对面换成了原装注意力,信息分布对不上——作者称之为「不同步」。解法不是重训专家(那浪费第七章),而是把最贴输出、对表示漂移最敏感的尾部六层轻微再训一轮,让它适应新邻居18。这轮移植还有一个诚实注脚:这次不用加噪声防塌缩——移植的专家已经充分分化,路由器无从塌起19

4. 作者的判断与证据

给了证据的: 路由表、合规率、两阶段训练的全部数字来自可复现 notebook;置换验证(掩码写回、one_hot 记录)代码原书附上。

论文侧(两篇,各撑一半):

  • Sparse Upcycling(Komatsuzaki 等,2022):升级版模型胜过同算力的稠密版和从零训的 MoE,成本约为稠密预训练的一半(40%-60%,因模型而异)。注意本书不是它的复刻——本书冻结专家 0、给路由器加噪声;原论文试过加噪声但结论是「小了没用、大了有害」,而且它没冻结过任何专家20。冻结的代价书里也点了:冻结的专家不会适应,路由器训过头可能不再给它送信息21;
  • Mixtral of Experts(Jiang 等,2024):32 块每块 8 专家取 top-2,总参 46.7B、每 token 只激活 12.9B——追平 Llama 2 70B。本书的双专家 2.9B 是同一套逻辑的微缩版。Mixtral 还贡献了一个反直觉发现:作者们预期按领域分诊(数学归一个专家、代码归另一个),实测 token 分布几乎与领域无关,只有句法特化(Python 的 self、缩进符稳定去同一个专家)——「路由器学的是结构,不是领域语义」。本书的情形不同:一边是冻结的通用、一边是移植的临床专家,路由器必须学会领域分诊才有用武之地22

5. 边界与局限

  • 「通用能力变好」基于单次实验,书里自己说样本小、不能下强结论;PIQA 的下降说明并非全无代价。
  • top_k=1 与 top_k=2 在本书任务上成绩相同,专家调度的真实收益要在专家更多、任务更杂时才显形;三专家的练习(再加一个代码专家)留在实验室节。
  • 移植要求两边「门当户对」:供体的注意力与受体的不一致时要补训,补多少层是经验数(本书 6 层);作者自嘲——现实中你捡到的模型 99.99% 不可能只训过 MLP23
  • 动态推理与标准推理引擎的兼容性仍是软肋,MoE 相对最成熟,但 vLLM 对自定义 MoE 结构的支持仍在演进中24

6. 可带走的

  1. MoE 的本质是「把 MLP 换成分诊台」:专家干活、路由器分诊、组合前向混合;
  2. sparse upcycling:复制已训练权重当专家,不从随机开始;
  3. 双专家同权重起步必塌缩:训练期给路由器 logits 加噪声(约 0.35)逼它探索;
  4. 路由看上下文不看词:同一个词换个邻居换边站——评估 MoE 别按词表猜路由;
  5. 软硬路由是同一套权重的两种 forward,合规率可以完全一样,差异藏在「何时停笔」;
  6. 移植现成专家,先只训路由器(0.0034% 参数),不够再补训专家尾部;
  7. 注意力不同步是移植的头号坑:供体微调过注意力,受体没有——尾部六层轻补;
  8. 冻结专家有政治风险:路由器训过头会断它的粮;
  9. 别把领域分诊当成 MoE 的默认行为:Mixtral 实测只有句法特化——分诊能力是要设计出来的。

7. 原文地图

主题原书章原文位置
Mixtral 与 DeepSeek 背景9 Dynamic routing with Mixture of Expertstext/38-ch09-9-dynamic-routing-with-mixture-of-experts.txt:35(搜「Mixtral 8x7B」)
稠密模型的恒定成本9.1 Dynamic inference techniquestext/39-ch09-01-9-1-dynamic-inference-techniques.txt:7(搜「hardest case」)
三种动态推理9.1 Dynamic inference techniquestext/39-ch09-01-9-1-dynamic-inference-techniques.txt:25(搜「early exiting」) · text/39-ch09-01-9-1-dynamic-inference-techniques.txt:55(搜「does the right thing」) · text/39-ch09-01-9-1-dynamic-inference-techniques.txt:61(搜「custom implementations」)
三件套与 sparse upcycling9.2 Implementing and evaluating a two-expert MoEtext/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:19(搜「combined forward pass」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:49(搜「sparse upcycling」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:30(搜「13 through 23」)
噪声防塌缩9.2 Implementing and evaluating a two-expert MoEtext/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:127(搜「0.35」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:184(搜「collapse toward a single expert」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:190(搜「degenerate values」)
数据混装与训练细节9.2 Implementing and evaluating a two-expert MoEtext/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:406(搜「smoltalk」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:465(搜「unlearn」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:394(搜「24.44%」)
路由表走查9.2 Implementing and evaluating a two-expert MoEtext/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:745(搜「0.6060」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:786(搜「0.6196」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:794(搜「0.55」)
硬路由与合规率9.2 Implementing and evaluating a two-expert MoEtext/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:830(搜「binary decision」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:931(搜「preallocated」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1085(搜「chronic back pain」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1106(搜「97.5%」)
诚实注脚与行为差异9.2 Implementing and evaluating a two-expert MoEtext/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1098(搜「for convenience and clarity」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1176(搜「decides to stop」) · text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1195(搜「+4.37」)
移植与两阶段训练9.7 Reusing a fine-tuned model as an experttext/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:59(搜「transplant」) · text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:220(搜「no risk of the router collapsing」) · text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:251(搜「compute is actually saved」) · text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:408(搜「0.0034%」) · text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:473(搜「desynchronization occurs」) · text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:585(搜「99.99% chance」)
upcycling 论文9.11 From paper to practicetext/42-ch09-11-9-11-from-paper-to-practice.txt:7(搜「Komatsuzaki」) · text/42-ch09-11-9-11-from-paper-to-practice.txt:25(搜「initial dense pretraining cost」) · text/42-ch09-11-9-11-from-paper-to-practice.txt:37(搜「Gaussian noise」) · text/42-ch09-11-9-11-from-paper-to-practice.txt:43(搜「stop sending it information」)
Mixtral 论文与句法特化9.11 From paper to practicetext/42-ch09-11-9-11-from-paper-to-practice.txt:55(搜「12.9B active parameters」) · text/42-ch09-11-9-11-from-paper-to-practice.txt:67(搜「router learns structure」) · text/42-ch09-11-9-11-from-paper-to-practice.txt:67(搜「distinguish between domains」)
动手练习:三专家 MoE(再加一个代码专家)9.14 Hands-on labtext/43-ch09-14-9-14-hands-on-lab.txt:7(搜「three experts」)

Footnotes

  1. 出处:「9.1 Dynamic inference techniques」第 7 段(text/39-ch09-01-9-1-dynamic-inference-techniques.txt:7,搜「hardest case」)。

  2. 出处:「9 Dynamic routing with Mixture of Experts」第 35 段(text/38-ch09-9-dynamic-routing-with-mixture-of-experts.txt:35,搜「Mixtral 8x7B」)。

  3. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 7-19 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:16,搜「linear layer」)。

  4. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 30 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:30,搜「13 through 23」)与第 260 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:260,搜「out-of-memory」)。

  5. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 49 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:49,搜「sparse upcycling」)。

  6. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 387-394 行(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:394,搜「24.44%」)。

  7. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 127 行(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:127,搜「0.35」)与第 184 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:184,搜「collapse toward a single expert」)。

  8. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 190 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:190,搜「degenerate values」)。

  9. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 406 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:406,搜「smoltalk」)与第 465 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:465,搜「unlearn」)。

  10. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 1085 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1085,搜「chronic back pain」)。

  11. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 1098 段的 NOTE(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1098,搜「for convenience and clarity」)。

  12. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 806-812 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:806,搜「soft routing」;text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:812,搜「without inference cost growing」)。

  13. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 830 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:830,搜「binary decision」)与第 913-943 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:931,搜「preallocated」)。

  14. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 1031 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1031,搜「There is no ambiguity」)与第 1106 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1106,搜「97.5%」)。

  15. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 1176 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1176,搜「decides to stop」)与第 1176 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1176,搜「closed-ended generation」)。

  16. 出处:「9.2 Implementing and evaluating a two-expert MoE」第 1189-1195 段(text/40-ch09-02-9-2-implementing-and-evaluating-a-two-expert-moe.txt:1195,搜「+4.37」)。

  17. 出处:「9.7 Reusing a fine-tuned model as an expert」第 53 段(text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:53,搜「top_k」)、第 196 段(text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:196,搜「renormalized」)与第 251 段(text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:251,搜「compute is actually saved」)。

  18. 出处:「9.7 Reusing a fine-tuned model as an expert」第 473 段(text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:473,搜「desynchronization occurs」)、第 498 段(text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:498,搜「10.35%」)与第 579 行(text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:579,搜「100.0%」)。

  19. 出处:「9.7 Reusing a fine-tuned model as an expert」第 220 段(text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:220,搜「no risk of the router collapsing」)。

  20. 出处:「9.11 From paper to practice」第 25 段(text/42-ch09-11-9-11-from-paper-to-practice.txt:25,搜「initial dense pretraining cost」)与第 37 段(text/42-ch09-11-9-11-from-paper-to-practice.txt:37,搜「Gaussian noise」)。

  21. 出处:「9.11 From paper to practice」第 43 段(text/42-ch09-11-9-11-from-paper-to-practice.txt:43,搜「stop sending it information」)。

  22. 出处:「9.11 From paper to practice」第 55 段(text/42-ch09-11-9-11-from-paper-to-practice.txt:55,搜「12.9B active parameters」)、第 67 段(text/42-ch09-11-9-11-from-paper-to-practice.txt:67,搜「router learns structure」)与第 67 段(text/42-ch09-11-9-11-from-paper-to-practice.txt:67,搜「distinguish between domains」)。

  23. 出处:「9.7 Reusing a fine-tuned model as an expert」第 585 段(text/41-ch09-07-9-7-reusing-a-fine-tuned-model-as-an-expert.txt:585,搜「99.99% chance」)。

  24. 出处:「9.1 Dynamic inference techniques」第 67 段(text/39-ch09-01-9-1-dynamic-inference-techniques.txt:67,搜「most mature」)。