Ch 02 · DeepSeekMoE 与 MTP
第一部分 · 架构 · 02

DeepSeekMoE 与 MTP — V3 留下的两件遗产

DeepSeekMoE 与 Multi-Token Prediction 仍是 V4 的脊梁;但 MoE 的细节被改了五处,每一处都对应一个具体的"V3 时代撞过的墙"。

名词速通 · 一分钟看懂这两件遗产

DeepSeekMoE + MTP = V3 留给 V4 的两根脊梁

FFN 层的稀疏激活骨架 + 训练信号致密化的辅助头。两者在 V3 上验证过,V4 完全保留主体,只在 MoE 的5 个细节上动刀以适配新规模(384 专家 / 1M 序列)。

MoE(Mixture-of-Experts,专家混合)
把单个 dense FFN 拆成 $N$ 个并行专家,每个 token 由路由器 (router) 打分选 top-$k$ 个专家激活。总参数大、激活参数小 —— 模型容量上去但单步算力没涨。
DeepSeekMoE(Dai 2024)
DeepSeek V2/V3 时代定下的 MoE 三件套:① 细粒度专家(256 个小专家替代 8 个大专家)+ ② 共享专家(1 个 always-active 专家承通用能力)+ ③ aux-loss-free 负载均衡(不靠 loss 项,靠每个专家的动态偏置 $b_i$ 调节)。
aux-loss-free 负载均衡
传统 MoE 在 loss 里加一项"惩罚不均衡",会和主任务竞争。V3 改成给每个专家维护一个偏置 $b_i$,根据"被分配到的 token 数 vs 期望"在线调整 —— 不动主 loss、闭环平衡专家。
MTP(Multi-Token Prediction,多 token 预测)
主模型旁挂一个轻量 head,让它同时预测未来第 2、3、… 个token(不止下一个)。同一份 hidden state 给多份梯度,训练信号密度 ×D,且强迫 hidden state 编码更长程语义。V3 验证有效,V4 完全沿用,只调权重 schedule。
Hash Routing(Roller 2021)
不学习路由,按 token id 的 hash mod 专家数直接派单。用在前 3 层 MoE,避开"早期 router 没学好就抖"的问题,又享受 MoE 稀疏激活红利。
一句话定位:V3 已经做对的不动;V4 只在 5 个被新规模暴露的细节上补漏 —— 打分函数、序列内均衡、路由通信预算、前几层路由方式、MTP 权重 schedule。
DeepSeek-V4 整体架构:Embedding → CSA/HCA + Pre/Post-Block Mixing + Residual Mixing → DeepSeekMoE → MTP → Prediction Head
图 2-1 · DeepSeek-V4 整体架构(Transformer Block × $L$)。 底部 Embedding 上来后,每个 block 内部分两段:先进 CSA / HCA(Ch04 / Ch05 讲),输出经 Pre-Block / Post-Block MixingResidual Mixing 三个 mapping(也就是 Ch03 mHC 的三套 $\tilde A / \tilde B / \tilde C$)回到主 highway;再走第二段 DeepSeekMoE,同样经过一组 mixing 才合流。block 堆叠 $L$ 次后,顶部 Prediction Head 出 LM Loss,旁路 MTP Modules 出 MTP Loss(多 token 预测,本章 §3 / §4 讲)。 这张图就是后续 Ch03 / 04 / 05 的"目录索引"——三套 Mixing 是 mHC,左下 CSA / HCA 块就是新 attention,DeepSeekMoE 块是从 V3 继承下来的。 来源:DeepSeek-V4 技术报告 §2 Architecture,Figure 2,p. 6。

1. 先看 V3 的 DeepSeekMoE 干了什么

MoE 的标准做法:FFN 层不再是单一稠密网络,而是 $N$ 个并行专家 $\{E_1, \ldots, E_N\}$。每个 token 由路由器打分,选出 top-$k$ 个专家激活。原始 GShard 用 $N=8$、$k=2$,专家间隔很粗。

DeepSeekMoE(V2/V3)做了三个关键改造,这些 V4 完全继承:

  • 细粒度专家:把 $N=8$ 个大专家切成 $N \cdot s = 64$ 个小专家(每个尺寸缩到 $1/s$),同时把 $k$ 也乘以 $s$。同样总激活参数下,专家组合数指数级增加
  • 共享专家:另设 1 个 always-active 专家承担"通用知识",让路由专家专注差异化能力。
  • aux-loss-free 负载均衡:见上方名词速通。不动主 loss,闭环调控全局负载。
DeepSeekMoE 三段式演进:传统 Top-2 → +Fine-grained Expert Segmentation → +Shared Expert Isolation
图 2-2 · DeepSeekMoE 的三段式演进。 (a) Conventional Top-2:原始 GShard 风格,$N$ 个大专家、Router 选 $K=2$。专家粒度粗,组合数有限。 (b) +Fine-grained Expert Segmentation:每个专家切成更小的 $2N$ 个,对应把 $K$ 翻倍到 $4$ —— 同样的总激活参数下,专家组合数指数级增加。 (c) +Shared Expert Isolation(DeepSeekMoE):在细粒度基础上额外抽出 1 个 always-on 共享专家(绿色块)承担"通用知识",剩余 $K=3$ 个 routed expert 专注差异化能力。 V4 在 (c) 的基础上把规模拉到 384 routed + 1 shared,核心结构没变。 来源:外部论文 Dai et al. 2024《DeepSeekMoE: Towards Ultimate Expert Specialization》Figure 2。V4 报告 §2.1(p. 7)通过引用 (Dai et al., 2024) 复用此架构。
数值演练 细粒度专家的"组合数指数增长"具体多大? GShard:$\binom{8}{2} = 28$ 种组合。 DeepSeekMoE V3(256 专家、激活 8):$\binom{256}{8} \approx 4.1 \times 10^{14}$。 V4-Pro(384 专家、激活 9):$\binom{384}{9} \approx 8.5 \times 10^{17}$ —— 比 GShard 多 16 个数量级。 组合数 ≈ 模型可表达的"专家分工模式数",这就是细粒度的红利来源。

V4 的总专家数从 V3 的 256 涨到 384,激活专家从 8 涨到(Pro)9 / (Flash)8,总参数从 671B 涨到 1.6T。规模一上来,V3 的几个 trick 开始显出毛刺,于是 V4 在 5 个细节上动了刀。

2. 改动 ① 路由打分:Sigmoid → Sqrt(Softplus)

V3 的做法:路由 logits 经过 $\text{Sigmoid}(\cdot)$ 得到打分,再做 top-$k$ 选择和重新归一化。

它哪里不够

  • Sigmoid 上界是 1,logits 大到一定程度就饱和。当模型确信"这个 token 应该去专家 #42"时,logit 可能是 8、12、20 —— 但 Sigmoid 都吐 ≈1,不再有区分度。
  • 专家数从 256 → 384,"top-9 专家间的细微优劣"更重要。Sigmoid 在饱和区梯度趋零,路由器学不到"这个专家比那个稍强一点"。

V4 改成

$$ s_i \;=\; \sqrt{\, \mathrm{Softplus}(\ell_i)\,} \;=\; \sqrt{\,\log(1 + e^{\ell_i})\,} $$
📖 公式白话翻译

这条公式是"两层活塞"

  1. 下层 Softplus:$\log(1+e^{\ell_i})$ —— 把任意 logit 推到 $(0, +\infty)$,没有上界,logit 越大 score 越大,绝不饱和。logit 极小时趋零,自动屏蔽弱专家。
  2. 上层 sqrt:把 Softplus 的"线性尾巴"压成"平方根尾巴",给一个软上界 —— score 仍单调上升,但增长率随 $\ell$ 越来越慢。

没有上层 sqrt 的话,单个超强专家的分数会把其他专家在归一化后挤到接近 0,等同于"硬选 1 个专家",丢掉了多专家协作。无上界解决饱和、软上界保多专家协作 —— 缺一不可

Demo · 三种打分函数在 logit ∈ [-4, 12] 上的对比
交互
0 1 2 3 4 -4 0 4 8 12 logit ℓ score s Sigmoid(V3,上界 1,饱和) Softplus(无上界,线性尾) √Softplus(V4,软上界)

把滑条拉到 ℓ=8 看三个读数:Sigmoid≈1.000(已饱和、梯度近零),Softplus≈8.000(无界),√Softplus≈2.83(软上界、仍可区分)。 两个专家的 logits 一个 8 一个 12,Sigmoid 都给 ≈1 看不出谁强;√Softplus 分别给 2.83 和 3.46,仍保留区分度

3. 改动 ② 序列内 balance loss:补 aux-free 在长序列上的盲区

V3 的 aux-loss-free 是怎么工作的

$$ \tilde{s}_i = s_i + b_i, \qquad b_i \leftarrow b_i + \alpha \cdot \big(\bar{f}^{*} - \bar{f}_i\big) $$

$b_i$ 是专家 $i$ 的动态偏置,$\bar{f}_i$ 是过去 $T$ 步内被分给专家 $i$ 的 token 比例,$\bar{f}^* = k/N$ 是均匀目标比例。如果 $i$ 被分得太少,$b_i$ 上调,下一步打分就提升一点 —— 不动主 loss,闭环调控全局负载

它在 V4 规模上撞墙:$b_i$ 的更新粒度是跨步全局的。但 V4 的训练序列动辄 64K~1M 长,同一条序列内可能强烈偏好某些专家(比如一篇 Python 长文档全程偏向 code 专家)。aux-free 看不到这种"序列内偏置"—— 它只知道"过去 1024 步全局均衡",对单序列内 6× 的不均衡袖手旁观。

具体例子 一条 256K 的 Python 训练序列、384 专家。理想分配:每个专家 $\sim 256\text{K} \times 9 / 384 = 6000$ 个 token-激活次。 实际:5 个 code-相关专家可能各拿 36000 次(6×),其余 379 个专家平均拿 5400 次。 aux-free 的统计窗口看的是跨序列平均:1024 步乘 256K → 全局尺度上 code 专家被均摊回去,看起来是均衡的。 于是 aux-free 不会调偏置,但单条序列内的 5 个 code 专家已经被严重过载 —— GPU expert parallelism 因此抖动。

V4 加了什么

$$ \mathcal{L}_{\text{seq-bal}} \;=\; \beta \sum_{i=1}^{N} f_i^{(\text{seq})} \cdot p_i^{(\text{seq})} $$
📖 公式白话翻译

这条 loss 是"在单序列尺度对 router 罚一下不均衡"

  • $f_i^{(\text{seq})}$ = 这条序列里被分给专家 $i$ 的 token 比例(离散的统计值,不可微);
  • $p_i^{(\text{seq})}$ = 这条序列里 router 给专家 $i$ 的平均概率(可微,梯度从这里走);
  • 两者相乘求和:如果某个 $i$ 已经分得太多($f_i$ 大),且 router 还在给它高概率($p_i$ 大),loss 就大,反向传播会让 router 降它的 $p_i$

aux-free 管全局,seq-bal 管局部,两层互补 —— 这是 V4 在长序列时代的必要补丁。$\beta$ 取 $10^{-4}$ 量级,仅作"温和提示",不喧宾夺主。

4. 改动 ③ 取消"路由目标节点上限"

V3 的限制:每个 token 路由的专家最多落在 $M$ 个不同的硬件节点上(V3 取 $M=4$)。这是为了控全节点 all-to-all 通信成本 —— 通信节点越多越贵。

它的代价:当 token 真正"想去"的 top-9 专家分布在 5 个节点时,第 5 个节点的专家被强行替换成"次优 + 同节点"专家。路由质量被通信预算扭曲

数值演练 384 专家均匀分布在 32 个节点(每节点 12 专家)。token 选 top-9 时,"最理想 9 个专家恰好都在 4 个节点"的概率非常低(远低于 1%)。 也就是说:V3 的 $M=4$ 限制对绝大多数 token 都生效,被强制替换的"次优专家"占比可能高达 30%+。 V4 取消上限后,路由质量回到模型实际想要的分布,代价由下层 MegaMoE all-to-all 优化(Ch07)兜住。

V4 的解法:直接取消上限,让 token 路由到任何专家。代价由 Ch7 的 MegaMoE + DualPipe + 通信压缩承担 —— 基础设施够便宜了,所以模型层不需要再做这种妥协。这就是架构与系统协设:上层不给下层让步,下层兜住成本。

5. 改动 ④ 头几层 Dense FFN → Hash-Routed MoE

V3 的做法:前 1~3 层用 Dense FFN(不做 MoE),后面才开始 MoE。常见的稳定性套路:早期层负责低级特征,路由器还没学好,强行 MoE 容易抖。

它的浪费:Dense FFN 在大模型里参数密度低 —— 早期层用了同样的 GPU 算力,却没享受 MoE 的"激活稀疏 + 总参数高"红利。

V4 改成 Hash Routing(Roller 2021)

$$ \text{expert}(t) \;=\; \mathrm{hash}(\mathrm{token\_id}(t)) \bmod N_{\text{hash}} $$
📖 公式白话翻译

路由不学,由 token id 直接哈希到一个专家:

  • 不需要梯度训练 router → 没有"早期 router 抖"问题;
  • 哈希在统计上均匀 → 天然负载均衡,不需要 aux-free / seq-bal;
  • 仍享受 MoE 的稀疏激活红利。

关键洞察:学习型路由的不稳定主要发生在前 1-2 层,因为这些层的 hidden state 还没成型,路由器拿到的特征噪声大。Hash 路由用"反正这层学不了好路由"的事实,干脆放弃学习 —— 是"知道哪里不该学"的典型应用。前 3 层用 Hash MoE,后续层用学习型 MoE。

6. MTP(Multi-Token Prediction):为什么完全不动

MTP 模块的工作机制:在主模型旁边接一个轻量 head $h_{\text{MTP}}$,让它预测未来第 2、3、… 个 token(不止下一个)。损失为:

$$ \mathcal{L}_{\text{MTP}} \;=\; \sum_{j=2}^{D} \alpha_j \cdot \mathrm{CE}\big(\hat{y}_{t+j},\; y_{t+j}\big), \quad \alpha_j \to 0\ \text{as}\ j\ \text{增大} $$
📖 公式白话翻译

三件事:

  • 预测多个未来 token:$\hat y_{t+j}$ 是从位置 $t$ 出发预测未来第 $j$ 个;
  • 逐个算交叉熵:$\mathrm{CE}(\cdot)$ 是常规 LM loss;
  • 越远权重越低:$\alpha_j$ 随 $j$ 增大递减,远 token 监督信号弱(毕竟越远越难预测)。

同一份 hidden state 给 $D$ 份梯度,训练信号密度 $\times D$;同时强迫 hidden state 编码"未来一段语义弧线",而不只是"下一个词"。

V4 的 MTP loss 总权重维持 0.3,学习率衰减阶段降到 0.1。降权重的逻辑是:

  • 训练前期 hidden state 不稳,MTP 提供致密梯度有助于快速塑形;
  • 训练后期主 loss 已经在精修,MTP 的"远 token 监督"开始与主目标产生小幅冲突 —— 降权让主 loss 主导。

因此 V4 完全不改 MTP 模块本身,只调权重 schedule —— 已经被 V3 反复验证、没有失效模式被暴露的组件,就不要动

7. 五处改动的汇总

组件V3 行为V4 行为对应解决的具体问题
路由打分SigmoidSqrt(Softplus)384 专家间饱和区无区分度
负载均衡仅 aux-freeaux-free + 序列内 balance loss长序列内单序列偏置 aux-free 看不见
路由节点上限$M=4$取消路由质量不再被通信预算扭曲
前几层 FFNDenseHash-Routed MoE避免学习型路由早期不稳,又享受 MoE 红利
MTP 模块权重 0.3权重 0.3,衰减期降 0.1主 loss 后期减少 MTP 干扰
把整章压成一句话

V3 的 MoE 主体被完整继承,但 V4 在 5 个细节上"补漏": 打分函数换成不饱和的 Sqrt(Softplus)、加序列内 balance、取消通信驱动的路由限制、把 dense 早层换成 hash MoE、MTP 权重做 schedule。 每一处改动都对应一个 V3 时代被新规模(384 专家、1M 序列)暴露出来的具体毛刺。