§ 7.5 · Section

MoE · 专家混合

Mixture of Experts

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,混合专家——一个模型里养一群各有所长的专家,每次只叫醒最合适的几个干活)。三个词各自的意思:

还有两个必须先立起来的关键词,本篇会反复出现。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 亿……继续这样堆下去,会撞上三堵墙:

于是 Google 从 2017 年就开始琢磨的一个老想法——MoE——被翻出来重新扛旗:参数放着不用没关系,关键是每次前向传播只激活一小撮。这样模型"看起来"很大(容量足),但每次推理只花"小模型"的成本。

Analogy · 图书馆 vs 你的书桌

一座图书馆有 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 让"参数量"这个词一分为二,需要一次说清:

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 / 22020
Switch Transformer1.6T7B2048 / 12021
Mixtral 8x7B47B13B8 / 22023.12
Mixtral 8x22B141B39B8 / 22024.4
Qwen1.5-MoE-A2.7B14.3B2.7B60 / 42024.3
DeepSeek-V2236B21B160 / 6 + 2 shared2024.5
DeepSeek-V3671B37B256 / 8 + 1 shared2024.12
Grok-1 (xAI)314B~86B8 / 22024.3

你看得出趋势——专家数量在快速上升,从最早的 8 个逐渐增加到 256 个甚至几千个。专家越细分,每个"更专业",模型的知识密度就越高。DeepSeek-V3 的 256 位专家已经接近一支"综合科研院"的规模。

Analogy · 从社区诊所到三甲医院

Mixtral 8x7B 有 8 位专家——像一家社区诊所:内、外、妇、儿……分工粗,几位老大夫覆盖大部分场景。
DeepSeek-V3 有 256 位专家——像一家大型综合医院:不仅有心内科,还细分成心律失常科、心脏介入科、心衰科;不仅有神内,还有帕金森专科、癫痫专科、脑卒中专科……
专家越细分,每位专家越精,路由器(分诊台)也越难做——但服务上限就越高。这就是 MoE 规模化的路径。

关键难题 · 路由平衡问题

MoE 听起来完美,但工程上有个头疼的问题——路由塌方(Routing Collapse)。
想象一下:如果 Router 学着学着,发现"送到 3 号专家总是效果不错",就干脆一直把所有 Token 都送去 3 号——这样 3 号累死,其他 255 位专家没活干、参数白占显存。整个 MoE 退化成了一个密集小模型。

解决路由平衡问题,是 MoE 训练的核心工程挑战。常见手段:

Analogy · 不能所有病人都挂同一个科室

把路由塌方这件事放回医院场景,你会立刻明白它有多荒唐,也明白为什么必须人为干预。
事情是这样开始的。新来的分诊台护士经验不足,第一天随便分诊。恰好她分给呼吸科的几个病人恢复得都不错,于是她形成了一个印象:"呼吸科很靠得住。"
第二天,她分给呼吸科的病人更多了,呼吸科的医生也因为看得多、越看越熟练——反馈更好了。第三天,她把八成病人都送去了呼吸科。
一个月后的局面:呼吸科走廊排到楼梯口,医生连轴转、看病越来越糊;而眼科、骨科、皮肤科的医生一个月没接到病人,业务能力开始退化,反而更不敢派活给他们了。这形成了一个恶性循环:用得多的越用越强,用得少的越用越弱,最后 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 有一个不太被外行提及、但从业者深有体会的痛点:它训起来比稠密模型脆弱得多。原因可以归成四条,每一条都有生活里的对应。

业界的应对办法是一整套经验的堆叠:路由器用高精度、加梯度裁剪、给路由分数加一点随机噪声(防止过早锁定)、用更小的学习率、辅助损失系数细致调参、训练早期先当稠密模型热身再切换到稀疏……这就是为什么 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?答案不在某一项技术优势,而在三个层面同时指向了同一个方向。

再补一个视角上的转变,它可能比上面三条更根本。过去十年,深度学习的默认假设是"参数越多越好,而且每次都要全用上"。MoE 挑战的是后半句——它主张:参数的作用是"存放可能有用的知识",而不是"每次都必须参与运算"。从"全员到岗、全员出工"变成"全员到岗、按需出工",这个转变让"模型规模"和"运行成本"这两个长期绑死的量第一次可以分开调节。这是一个范式级别的松绑。

当然也要留一句清醒的话:MoE 不是终点,它只是"条件计算"这个更大方向上目前最成熟的一个形态。它还有明显的未解问题——显存占用没解决、路由仍然脆弱、专家分工不可控、端侧完全用不上。所以本篇末尾提到的那些更激进的方向(Attention 层也稀疏、层数动态决定、参数按需从内存换入显存)都在推进中。但可以肯定的是:从 2024 年往后,"总参数"和"激活参数"这两个数字会一起出现在每一份大模型规格表上,就像手机同时标"存储容量"和"运行内存"一样自然。

MoE 的历史 · 从 1991 到 2024

MoE 不是什么新概念——早在1991 年,Hinton 的学生 Jacobs 就提出了"Mixtures of Experts"的原型思想,用在传统神经网络里。但直到深度学习时代它才真正大放异彩:

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 只是"稀疏化"这个大方向的一个具体形态。围绕"参数很多但每次只激活一部分"这个思想,学术界还在探索更激进的方案:

2025 年之后,我们大概率会看到"万亿参数、百亿激活"成为主流大模型的默认配置——就像 2020 年"千亿参数"从奢侈变常态那样。

MoE 会不会让每位专家"专精一门"

很多人第一次听 MoE 会想:那 256 位专家是不是一位管数学、一位管代码、一位管诗歌、一位管医学?——实际情况没那么整齐
研究者对 Mixtral 和 DeepSeek 做了大量可视化分析,发现专家的分工是相当抽象的——它们不是按"话题"分,而是按更底层的"语言模式"分。有的专家专门处理数字类 Token,有的专家专门处理动词,有的专家专门处理句尾结构,有的专家专门处理代码里的括号缩进……分工存在,但不是我们直觉里那种"学科式分工"
这也解释了为什么单看某位专家没什么规律可言——它们是训练动态中自组织涌现的产物,不是人类概念体系的镜像。让专家真正"每人一门学科"是一条研究方向,但目前的主流 MoE 都还处于"隐性分工"阶段。

Recap · 收束

MoE 的口诀只有一句——"参数很多,激活很少"。它把 Transformer 里那个又大又贵的 FFN 层,换成了一堆专家 + 一个分诊台。总参数量可以疯狂堆到万亿,激活参数量却只有几百亿,成本大幅下降。
DeepSeek-V3、Mixtral、Qwen-MoE 三大代表证明了这条路——2025 年之后,几乎所有超大模型都会走 MoE。
到这里,第 7 章 Transformer 的五个核心概念——Attention、QKV、Multi-Head、Encoder/Decoder 派系、MoE——就全部讲完了。下一章我们会走进它最著名的应用场景:大语言模型(LLM)

☰ 主页
Xue Hai Wu Ya · § 7.5 · MoE