MoE 的稀疏艺术:1.6 万亿参数的模型,为什么每个 token 只唤醒 49B
从路由公式出发把 MoE 拆开讲透:门控与归一化的分步推导、专家容量与丢 token 的关系、辅助损失的梯度含义及其副作用、DeepSeek 无辅助损失偏置调整的机理与超参、细粒度与共享专家的参数账、节点受限路由与 all-to-all 通信量估算,以及 V4 为什么又把节点限制取消掉。所有具体数字都标注官方一手来源,可逐条核对。
一、先说直觉:1.6 万亿的仓库,每次只搬 49B 的货
不严谨地说,稠密(Dense)模型每读一个 token,就把这一层所有参数都过一遍;MoE(Mixture of Experts,混合专家)把 FFN 子层换成一大排并行的小 FFN,再加一个路由器(Router),每个 token 只过其中几个。于是两件事被解耦了:总参数量决定”仓库有多大”,激活参数量决定”每次搬多少货”。
三组官方数字摆在一起,直觉就出来了:
- DeepSeek-V3:671B 总参数,每 token 激活 37B(官方模型卡与技术报告摘要口径)
- DeepSeek-V4-Pro:1.6T 总参数,每 token 激活 49B(官方模型卡与技术报告摘要口径)
- Mixtral 8x7B:46.7B 总参数,每 token 只用 12.9B(Mistral 官方博客口径)
顺手算一下量级:,也就是 V3 的总参数是激活参数的约 18 倍;V4-Pro 的 ,约 33 倍。这个倍数不是”效率提升了几倍”,而是知识容量与单 token 计算成本的脱钩比例——它是架构选择的结果,不是训练技巧的结果。
但”脱钩”不是白拿的。仓库大了,货物就要从不同货架搬过来:MoE 的代价几乎全部出现在通信和负载均衡这两个词上。本文按下面的顺序展开,由浅入深:
直觉(本节)→ 符号约定 → 一层的参数账 → 门控公式逐变量拆解 → softmax 与归一化的分步推导 → 负载均衡为何致命 → 辅助损失的梯度含义与副作用 → 无辅助损失的偏置调整 → 细粒度/共享专家/节点受限路由 → 通信量估算 → 方案对照表 → 工程含义 → 边界与未解 → 小结。
二、术语与符号约定
先把记号定下来,后面所有公式都用这套符号。术语与符号约定表如下:
| 符号 | 含义 | 本文出现的取值 |
|---|---|---|
| 模型隐藏维度(残差流宽度) | V3 / V4-Pro:7168;V4-Flash:4096 | |
| 单个专家的中间维度 | V3:2048;V4-Pro:3072;V4-Flash:2048 | |
| 路由专家(routed expert)数量 | V3:256;V4-Pro:384 | |
| 共享专家(shared expert)数量 | V3、V4 均为 1 | |
| 每个 token 激活的路由专家数 | V3:8;V4:6 | |
| 节点受限路由允许的最大目标节点数 | V3:4(V4 已取消该限制) | |
| 一个序列 / 一个 batch 里的 token 数 | 视上下文长度而定 | |
| 第 个 token 送进 FFN 的输入表示 | 维度 | |
| 第 个路由专家的质心向量(可学习) | 维度 | |
| token 与专家的亲和度分数(affinity score) | 标量 | |
| 门控权重(gating value),乘在专家输出上 | 标量,未选中时为 0 | |
| 专家 的路由偏置项(只影响选谁,不影响权重) | V3、V4:初值 0(一手出处是该方法的提出工作 Wang et al. 2024a 的 Algorithm 1「Initialize for each expert」;V3 报告正文未逐字给出) | |
| 偏置更新速度(bias update speed) | V3、V4:0.001 | |
| 均衡辅助损失的权重系数 | V3、V4:0.0001 | |
| 分给专家 的 token 比例(离散统计量) | 标量 | |
| 路由器给专家 的平均概率(连续可导量) | 标量 |
术语上有一处容易混:“激活参数”指的是每个 token 前向一次真正参与计算的参数,不是”被缓存到显存的参数”。MoE 推理时全部专家权重都要装着(否则无法路由到它),但每 token 只有激活的那部分参与乘加。所以”总参数量”影响显存占用,“激活参数量”影响算力与延迟,这两个账必须分开算。
| 术语 | 含义 | 常见误解 |
|---|---|---|
| 路由专家 | 被路由器按分数挑选、只服务部分 token 的专家 | 误以为”某些专家专管数学/法律”,见第十三节的实测反例 |
| 共享专家 | 所有 token 都会经过的专家,用于承载通用知识 | 误以为它是”兜底专家”或”恒等映射” |
| 专家容量 | 单个专家一次前向允许处理的 token 上限 | 误以为容量是”显存上限”,它其实是并行切分的形状约束 |
| 专家并行(EP) | 把不同专家放到不同 GPU 上的并行方式 | 误以为和模型并行一样只切权重,EP 每层都要 all-to-all |
| 路由崩塌 | 少数专家吸走绝大多数 token 的退化状态 | 误以为只影响速度;它同时让大量参数得不到训练 |
记号上还有两个坑必须提前说清,否则读论文时一定会撞上:
- 同一个字母 在不同论文里指不同东西。 本文统一用 表示模型隐藏维度、 表示专家中间维度;但 V4 报告在通信量公式里写的 与 ,那个位置的 实际对应的是专家中间维度(V4-Pro 取 3072,故 ),而不是模型隐藏维度 7168(同一份报告在描述模型结构时又用同一个 指隐藏维度 7168,属符号复用;别与本文的 混——本文的 是专家中间维度)。第十节会把这一步的解释写全,这里先埋一个提示。
- “第几层开始是 MoE”有两种口径。 V3 是”前 3 层为稠密 FFN,其余 58 层为 MoE”,对应
config.json的first_k_dense_replace: 3;V4 则是”所有 Transformer 块都用 MoE 层,只有前 3 个 MoE 层改用 Hash 路由”。两者都写”3”,说的不是同一件事——算参数账时差一层就会差出十几个 B。
三、把 FFN 换成”专家团”:一层里到底算什么
DeepSeek-V3 技术报告的式 (12) 给出了这一层的完整形式:第 个 token 在第 层的输出等于残差加上共享专家的输出,再加被选中的路由专家输出的加权和。
三个符号分别对应三件事: 个共享专家对所有 token 一视同仁地参与( 时就是一个固定分支), 个路由专家的求和里只有 个 不为零(稀疏性就体现在这里),而残差项 保证这条路是”加一层”而不是”换一层”。
先算参数量,因为它决定了”容量”这个词到底有多大。 一个 SwiGLU 风格的专家由三个矩阵构成(gate、up、down),参数量是 。代入 V3 的配置:
一层里 256 个这样的专家,加上 1 个共享专家:
V3 有 61 层,其中前 3 层是稠密 FFN、后 58 层是 MoE 层(官方报告:除前三层外全部替换为 MoE 层),于是路由专家总参数量是
再算激活的那一份:每 token 激活 8 个路由专家 + 1 个共享专家,即 每层,乘以 58 层得
下面这张账把 V3 的 671B / 37B 拆开(数字是我按官方 config.json 的字段逐项相乘的结果,不是报告原文的表格):
| 组成 | 每层参数量 | 层数 | 合计 | 每 token 激活 |
|---|---|---|---|---|
| 路由专家(256 × 44.04M) | 11.27 B | 58 | 653.9 B | 23.0 B |
| 共享专家(1 × 44.04M) | 44.0 M | 58 | 2.55 B | 含在上行 |
| 稠密 FFN(3 × 7168 × 18432) | 396.4 M | 3 | 1.19 B | 1.19 B |
| MLA 注意力(含低秩压缩投影与解耦 RoPE 的 = 7168 × 64 = 0.46 M) | 187.6 M | 61 | 11.44 B | 11.44 B |
| 词嵌入与输出头等 | — | — | 约 1.85 B | 约 0.9 B |
| 合计 | — | — | 约 670.9 B(官方口径 671 B) | 约 36.5 B(官方口径 37 B) |
两边都对得上官方口径,误差来自未被计入的 MTP 模块与各类 Norm。这张表顺手回答了一个常见问题:MoE 到底”省”在哪里——省在每 token 只碰 8 个专家;而它”贵”在哪里——653.9B 的路由专家权重必须全部驻留显存。
还有个细节值得记住:稠密层的 FFN 中间维度是 18432,专家是 2048,比值恰好是 9。换句话说 DeepSeek-V3 的”专家”只有标准 FFN 宽度的约九分之一,这就是”细粒度专家”的量化含义,第九节会讲为什么把它切细是有收益的。
四、门控公式逐变量拆解
路由要解决两个独立的问题:选谁(离散决策)和选中后给多大权重(连续权重)。DeepSeek-V3 把这两步拆得很清楚。
第一步,给每个专家算亲和度分数。V3 用的是 sigmoid,而不是经典做法里的 softmax:
逐变量看: 是这个 token 的表示(维度 7168), 是专家 的可学习质心向量(同维度),点积衡量”这个 token 跟这个专家的方向有多合”。sigmoid 把结果压进 ,但它不做跨专家归一化——这一点是 V3 相对 V2 的改动,官方措辞是”V3 用 sigmoid 计算亲和度分数,并对被选中的分数做归一化以得到门控值”。
第二步,Top-K 硬选择。只有落在前 名的分数才保留,其余直接置零:
第三步,在被选中的那 K 个之间重新归一化,得到真正乘在专家输出上的门控权重:
注意分母里包含所有 项,但由于未被选中的项是 0,实际只对 Top-K 求和。V3 的 config.json 里 norm_topk_prob: true 对应的就是这一步;同文件里 routed_scaling_factor: 2.5 则是把这些归一化后的权重再乘一个固定缩放系数(官方实现细节,非报告正文公式)。
为什么必须归一化,而不是”选完直接用原始分数”? 因为 sigmoid 不保证被选中的 个分数之和是 1。如果直接用原始分数当权重,那么模型的输出尺度会随”这次选中了哪几个专家”漂移:选中 8 个高分专家时输出被放大,选中 8 个低分专家时被缩小。把权重归一化到和为 1,等于让”专家输出的加权平均”这件事在尺度上稳定下来,路由器只需要负责”分配比例”,不用同时负责”控制总增益”。
路由与专家并行的数据流可以用下面这张图概括:
flowchart LR
tok["token 表示 u_t"] --> score["路由打分 s_i = 亲和度"]
score --> sel["Top-K 选择 + 归一化得到 g_i"]
sel --> disp["Dispatch: 按专家 all-to-all 分发 (FP8)"]
disp --> eA["节点 0 上的被选专家"]
disp --> eB["节点 1 上的被选专家"]
eA --> comb["Combine: all-to-all 回收 (BF16)"]
eB --> comb
comb --> out["h_t 等于 u_t 加专家输出加权和"]这张图说明了什么:稀疏性只省下”专家内部的计算”,省不掉”把 token 送到专家那里”这一步。图中 Dispatch 与 Combine 是两次跨设备通信,它们的存在与 成正比。后面第十节算通信量时,就是沿着这条链路的每一段累加。(图中的 FP8 / BF16 精度标注与”节点 0 / 节点 1”这类部署细节分别是第十节与第九节 9.3 的话题,这里先把数据流画出来。)
五、Top-K 门控的 softmax 与归一化:分步推导
上一节的 V3 是 sigmoid 版本。要理解它的取舍,得先看清更常见的 softmax 版本是怎么写的——Mixtral 论文给了一个很干净的写法:
把 代进 softmax 意味着 ,于是”被淘汰的专家权重为 0”这件事是被自动做掉的。分四步推导一遍:
第 1 步:打分。 是 token 表示, 是路由矩阵, 给出 维 logits( 是专家数)。这一步是纯线性的,没有非线性变换。
第 2 步:Top-K 掩码。 保留前 大,其余置 。这一步是不可导的离散选择——掩码本身没有梯度。
第 3 步:softmax。 对掩码后的 logits 做 softmax。因为被淘汰项是 ,分母只剩被选中的 项,得到的就是”在被选中集合上重新归一化”的权重,和 V3 的式 (13) 在做同一件事。
第 4 步:加权求和。 输出是 ,即被选中专家输出的加权和。
softmax 版本和 sigmoid 版本的关键差别在耦合性:softmax 的分母包含所有被选中专家,任何两个专家的分数变化会互相影响(这个专家分数涨了,那个专家的权重就会被压低);sigmoid 是逐专家独立打分,不存在这种”此消彼长”的强制竞争。
那么从 softmax 换到 sigmoid 的动机是什么?这里要分清两件事,因为最常见的误读就出在这里:
- V3 报告本身没有给动机。 它对这件事只有一句话:“Slightly different from DeepSeek-V2, DeepSeek-V3 uses the sigmoid function to compute the affinity scores, and applies a normalization among all selected affinity scores to produce the gating values.”(译述:与 V2 略有不同,V3 用 sigmoid 计算亲和度分数,并对被选中的分数做归一化得到门控值。)报告只陈述了做法。
- 给出经验依据的是 V3 引用的 Wang et al. 2024a(arXiv:2408.15664)。 该文(V3 的无辅助损失均衡策略正出自这里)在实验设置里写明:“we choose sigmoid instead of softmax as the gating function , since we find that the sigmoid baseline performs better than the softmax baseline”——这是一条实测结论,不是理论证明。它的附录 C.1 进一步给出量化对比:在负载均衡程度相近时,softmax 门控的困惑度更高,且”对负载失衡更敏感”;附录 C.2 则点出真正的原因——“Adjusting the per-expert bias for the softmax gate is more challenging due to the normalization property of softmax, which makes the score gap between two experts sensitive to the scores of other experts”(译述:softmax 门控下逐个专家调偏置更难,因为 softmax 的归一化性质让两个专家之间的分数间距对其他专家的分数敏感)。
顺带纠一个流传很广的说法:“softmax 会把亲和度排序拉伸扭曲”在技术上不成立——softmax 是单调函数,单调变换不改变大小关系,Top-K 选出的是同一批专家。真正的差别有两处:一是门控权重的耦合(softmax 下改一个专家的分数会改变其他所有被选中专家的权重,sigmoid 逐专家独立);二是均衡偏置的敏感度(softmax 的归一化让间距受他人影响,偏置迭代更难收敛)。V3 仍在被选中的集合内做一次归一化,是为了拿回尺度稳定性——这一点与选择用什么打分函数是两件事。
还有一个演化值得记下来:DeepSeek-V4 把亲和度函数从 sigmoid 换成了 Sqrt(Softplus(·))(V4 技术报告原文:“we change the activation function that computes the affinity scores from Sigmoid(·) into Sqrt(Softplus(·))”)。Sqrt(Softplus) 在负半轴不会被压到接近 0,梯度比 sigmoid 更平缓,代价是分数不再有 的上界——这属于”训练稳定性优先于打分可解释性”的取舍,V4 报告没有给出该改动的消融,属于需要读者自己上机验证的部分。
六、负载均衡为什么致命:专家容量、溢出与丢 token
如果路由器”偏心”,少数专家被选中绝大多数 token,后果不是”慢一点”,而是下面四件事同时发生:
- 同步等待:专家并行下每层有 all-to-all 通信,所有设备要等最慢的那个。一个热点专家 = 一个 straggler,拖住整个集群。
- 容量溢出丢 token:并行切分要求张量形状静态可算,每个专家能收的 token 数是有限的,超出的 token 不会被任何专家处理。
- 参数浪费:冷门专家长期收不到 token,梯度接近 0,那部分参数事实上没被训练。
- 路由崩塌:越是被偏爱的专家训练越充分、分数越高,形成正反馈。
第 2 条是最容易被忽略、也最容易算清楚的一条。Switch Transformer 给出了专家的固定容量:
它的含义是:容量不是显存决定的,而是”把 batch 平均切开再留点冗余”决定的。论文的配图描述得很直白——若 token 分发不均,某些专家就会溢出,超出容量的那部分 token “不会在这一层被处理”(论文用一张示意图说明分流不均与溢出的对应关系;颜色细节不可从文本核验,这里不描述)。把容量系数调大能缓解溢出,但它同时按比例增加计算与通信(因为多出来的槽位要 padding)。
由此可以推出一条工程直觉:丢 token 率不是”均衡做得好不好”的副产品,而是”均衡策略与容量系数共同决定”的量。Switch Transformer 的经验结论是”保证较低的丢 token 率对稀疏专家模型的扩展很重要”;ST-MoE 论文给出的实验配置是训练时容量系数 1.25、评估时 2.0——评估放大系数,本质是一种”评估期宁可浪费算力也不丢 token”的选择。
DeepSeek-V3 在这里做了一个很”强硬”的选择:训练和推理都不丢 token(报告原话:由于有效的负载均衡策略,V3 在完整训练过程中保持了良好的负载均衡,因此训练期间不丢弃任何 token;推理阶段也实现了部署策略来保证负载均衡)。这是无偿的结论吗?不是——它的前提正是下一节的偏置调整。“不丢 token”是负债均衡策略成功之后才能说的一句话,而不是一个独立的设计选项。
另一种均衡动机来自组合数:细粒度切分会把”可选专家组合数”放大到离谱的程度(第七节末尾给具体数字),组合空间越大,路由器越容易在某几个组合上堆积——这既提高了表达能力上限,也提高了失衡的概率。
还可以把”容量为什么不能一味调大”写成一个更直白的不等式。设专家数为 、每步 token 数为 、容量系数为 ,则每层的总处理槽位是
也就是**“槽位总量”只跟容量系数成正比**: 时槽位数刚好等于 token 数,任何不均衡都会导致溢出; 时有一半槽位是空的,这些空槽照样要占住张量形状、照样要做矩阵乘与通信。所以调大 不是在”买保险”,而是在按比例买算力浪费。真正把丢 token 率压到 0 的同时不让 膨胀的办法只有一个:让分布本身变平——这正是从第七节到第八节要走的路线。
七、辅助损失:定义、梯度含义与它的副作用
7.1 经典写法与梯度
Switch Transformer 的辅助损失(式 4)是这一路线的原点:
其中两项分别是”实际分配比例”和”路由器意愿比例”:
梯度含义要说清楚,否则很容易误读这个损失在做什么。 论文自己点明了:目标函数可以被求导,因为 向量是可导的,而 向量不可导。也就是说,辅助损失实际传播的梯度只作用在 (路由器给出的概率)上, 在这里扮演的角色更像一个系数——它是”当前分配现状”的度量,反向传播时被当作常量。
于是这个损失的语义是:“对已经被分到很多 token 的专家,主动压低路由器给它的概率。” 不是”惩罚专家的计算量”(那个量本身不可导),而是”惩罚路由器对热门专家的偏好”。
论文还解释了为什么外乘一个 :均匀路由时 ,乘 让损失在专家数变化时保持同一量级。论文全篇取 (原话:足够大以保证负载均衡,又足够小而不至于压过主交叉熵目标)。
7.2 DeepSeekMoE 的两级版本
DeepSeekMoE 把辅助损失拆成两级,理由很实在:要做到”算力均衡”其实不需要”专家均衡”。
专家级均衡损失(式 12–14):
设备级均衡损失(式 15–17)把专家按部署位置分组 ,在组的粒度上要求均衡:
论文给出的实践口径是:专家级系数取小(只用来防路由崩塌),设备级系数取大(用来真正压计算瓶颈)——因为对专家级施加过严的约束会损害模型性能,而设备级才是吞吐的真正约束。
7.3 副作用:均衡约束会杀死专家分工
辅助损失的代价不是”多一项要调的超参”,而是它把均衡约束加到了每个序列上。V3 报告的 4.5.3 节把这个区别讲得很透:
- 无辅助损失的偏置法作用在 batch 粒度(每一步在全 batch 上监控负载)
- 序列级辅助损失作用在 sequence 粒度(要求每个序列内部也均衡)
后者是更严的约束:它不允许专家按领域分工。报告的原话是,batch 粒度的均衡”不强制在每个序列内部均衡,这种灵活性让专家能更好地在不同领域上分工”。
这不是定性推测,报告给了两组实测验证损失(validation loss,越低越好):
| 模型规模 | 序列级辅助损失 | 无辅助损失(偏置法) | batch 级辅助损失 |
|---|---|---|---|
| 1B MoE | 2.258 | 2.253 | 2.253 |
| 3B MoE | 2.085 | 2.080 | 2.080 |
读法是:“无辅助损失”与”batch 级辅助损失”打平,“序列级辅助损失”稳定落后。结论并不是”辅助损失有害”,而是”辅助损失的粒度错了才有害”——这条区分比”用不用辅助损失”更有解释力。
另一条来自 ST-MoE 的经验补充了”辅助损失还能干什么”:它提出的 router z-loss 不是为均衡,而是为数值稳定性——
其中 是 token 数, 是专家数, 是送进路由器的 logits。它的作用是把 logits 的绝对值压小,从而减少指数运算的舍入误差。论文明确比较过另一条路(收紧 update clipping):两者都能让 3 次训练全部稳定,但 update clipping 显著损害质量。这条经验对今天仍有意义——“能稳住训练”的方案有很多,能稳住且不掉分的很少。
八、无辅助损失的偏置调整:DeepSeek-V3 的做法
V3 的做法是:不动损失函数,动路由的排序键。给每个专家配一个偏置项 ,只在选择时加进去(这套机制的一手出处是 V3 引用的 Wang et al. 2024a,V3 报告式 (16)–(17) 与训练配方沿用了它,并给出了偏置更新速度 的两段取值):
报告特意强调了一句关键的实现边界:偏置项只用于路由,乘在专家输出上的门控值仍然来自原始亲和度 。把这一步拆成三句话:
- 选谁:按 排序取 Top-K。
- 权重多大:按 归一化(式 13、19、20 的那套)。
- 偏置怎么调:每一步在全 batch 上统计专家负载,步骤结束时,过载的专家 减 ,欠载的加 :
其中 是专家 在这一步收到的 token 数, 是均衡目标(均分时应有的 token 数)。
为什么这样能绕开辅助损失的副作用? 因为偏置是一个前向计算中被当作常量的可调参数,它不在损失函数里,因此不会把”均衡”这个目标写进梯度。路由器学到的依然是”这个 token 更像哪个专家”,均衡则由外部的 迭代来兜——梯度信号与均衡目标彻底解耦。
代价是引入了一个新的失效模式:偏置是按 batch 统计量逐 step 迭代的,它只能看见”这一批里谁忙”,看不见”某个序列里谁忙”。这正是 V3 仍保留一个”极轻量”的互补序列级损失的原因(式 17,,与 Switch 的 差了整整两个数量级)。
超参上有一个很能说明设计意图的细节:V3 把偏置更新速度 设为 0.001,只在前 14.3T token 期间生效,最后 500B token 直接置 0.0。我的读法是:训练早期需要主动拉平负载、把冷门专家”扶起来”参与训练;训练后期路由格局已经成型,继续动偏置反而干扰模型收敛,于是干脆关掉(这是对参数设计的解读,报告本身没有对该安排给出消融)。
V4 沿用了同一套机制, 仍为 0.001、均衡损失权重仍为 0.0001。但 V4 在稳定性上承认了一个更棘手的事实:loss spike 与 MoE 层的 outlier 稳定相关,而路由机制本身会加剧 outlier。它给出的两条工程手段是 Anticipatory Routing(用历史参数 计算路由索引、当前参数 算特征,把两者的同步更新解耦)与 SwiGLU Clamping,并明确写出”对其底层机理的完整理论理解目前仍是开放问题”。
该方案的已知作用范围也说清楚:V3 报告给的是”训练全程负载均衡 + 评测上普遍更好”的对比结果,并没有给出”推理期流量分布变化时偏置是否仍然有效”的线上数据。而推理期的失衡风险是 V3 报告自己点出来的:§4.5.3 在对比序列级/批级/无辅助损失三条路线时写道,batch 粒度的均衡方法虽然评测更好,但有两条潜在的效率挑战:“(1) load imbalance within certain sequences or small batches, and (2) domain-shift-induced load imbalance during inference”(译述:① 某些序列或小 batch 内部的负载失衡;② 推理期因领域漂移导致的负载失衡)。报告对第 ① 条的回答是”训练框架的大规模专家并行 + 数据并行保证了 micro-batch 足够大”,对第 ② 条的回答是部署侧的冗余专家方案(§3.4)。
这一点值得强调口径:它是整类 batch 粒度均衡方法(无辅助损失偏置与批级辅助损失都在内)共同的代价,不是偏置项独有的缺陷;而且 V4 报告全文没有再出现这个表述,只在序列级均衡损失处提到”避免单个序列内的极端失衡”(“to avoid extreme imbalance within single sequences”)。读者若看到把这句话归给 V4 的二手解读,可以直接对照两份报告的原文。
九、细粒度专家、共享专家与节点受限路由
9.1 细粒度:把专家切小,把 K 调大
DeepSeekMoE 的核心操作是:把每个专家切成 分之一(中间维度变为 ),同时把激活数量也乘 ,这样总参数量与计算量都不变,变化的是组合空间。组合数用二项式表示,论文给的例子是:
也就是说,从”16 选 2”切细成”64 选 8”之后,可用的专家组合从 120 种变成约 44 亿种。这就是”细粒度专家”的量化收益:在同样的算力预算下,路由器的表达自由度放大了七个数量级。V3 的截面正好落在这条路上:稠密 FFN 宽度 18432,专家宽度 2048(约九分之一),激活数从稠密的”全部”变成 8 个。
9.2 共享专家:把通用知识从路由专家身上摘出去
DeepSeekMoE 的第二个策略是隔离出 个共享专家,对所有 token 恒激活。论文给的动机是:token 被分给不同专家时,它们其实都需要一些公共知识,于是多个路由专家会各自去学同一批通用知识,造成参数冗余;把这些知识压缩进共享专家,路由专家才能专心做”专才”。
论文的消融还给出了一个可操作的配比:在”64 个总专家”这一规模上比较 1、2、4 个共享专家,得到 Pile loss 1.808 / 1.806 / 1.811,共享专家数与激活的路由专家数取 1:3(即 2 共享 + 6 激活)时略优,放大模型时沿用这一比例。
注意这两个数字都是”共享 : 激活路由专家”的口径,别把它们读成”总专家数”:2B 验证模型的截面是 1 个共享专家 + 63 个路由专家、激活其中 7 个,也就是共享:激活路由 = (63 才是总路由专家数);而 是放大时采用的配比(论文里对应 2 共享 + 6 激活)。两者不冲突——一个是 2B 截面上的取值,一个是缩放策略。
9.3 节点受限路由:把跨机通信变成有界预算
这一条是把 MoE 从论文推到万亿参数可训练的关键工程约束。V3 的规则是:每个 token 最多发往 个节点,节点按”该节点上专家的最高 个亲和度分数之和”来排序选择。代入 V3 的取值 、,即每个节点贡献 2 个专家分数参与节点级排序。
配套的部署事实(都来自报告正文):路由专家被均匀部署在 8 个节点、共 64 张 GPU 上;训练用 16 路流水并行 + 64 路专家并行 + ZeRO-1 数据并行,集群规模 2048 张 H800。
flowchart TB
subgraph N0["节点 0 (8 GPU, EP 分片 0-31)"]
x0["专家 0..31"]
end
subgraph N1["节点 1 (8 GPU, EP 分片 32-63)"]
x1["专家 32..63"]
end
subgraph N7["节点 7 (8 GPU, EP 分片 224-255)"]
x7["专家 224..255"]
end
r["路由器: 先在节点级取 top(K_r/M) 之和最高的 M 个节点"] --> N0
r --> N1
r --> N7
x0 --> ib["跨节点 IB all-to-all"]
x1 --> ib
x7 --> ib
ib --> agg["Combine 回到发起 token 所在 GPU"]这张图说明了什么:节点限制的作用是在 all-to-all 之前先做一层”粗筛”。它把” 个专家可能落在多少台机器上”这件事从”最多 台”压到”最多 台”,从而把跨机通信量变成一个有上界的预算——代价是路由器在节点这一级先被削掉了自由度(这也是 V4 后来取消该约束的直接动因,见第十二节)。
报告里还有一个常被引用的量化结论:在这套通信策略下,每个 token 平均可以在每个节点上选 3.2 个专家而不额外付出 NVLink 开销;这意味着虽然 V3 实际只选 8 个路由专家,但在同样的通信代价下最多可以扩到 13 个(4 节点 × 3.2)。同时报告提到,只需 20 个 SM 就能吃满 IB 与 NVLink 的带宽。这个结论的价值在于它给出了” 还能不能继续加”的通信上限,而不只是”当前是多少”。
十、通信量估算:MoE 的瓶颈常常不在显存
这一节把通信量算一遍。DeepSeek-V4 技术报告给了一个可以直接用的口径:每个 token-expert 对需要 6hd FLOPs(SwiGLU 的 gate、up、down 三个投影),但只需要 3h 字节的通信量(FP8 Dispatch + BF16 Combine)。由此得到”通信能否被计算完全隐藏”的判据:
报告对此的解释是:只要计算通信比达到这个门槛,带宽就不再是瓶颈,“每 GBps 互联带宽足以隐藏 6.1 TFLOP/s 的计算量”,继续堆带宽的收益递减。这里 对应的 ,正是 V4-Pro 的专家中间维度。
用同一套口径给 V3 估一遍。下表的运算是我按公开配置做的量级估算,先对齐符号:V4 报告公式里的 是它自己的记号,对应本文符号表的 (模型隐藏维度),V3 取 7168;别按本文的 代入——本文的 是专家中间维度 2048,代错就会算出 。物理含义是每个 token 的激活值(隐藏维度那一条向量)在 dispatch 与 combine 中各被完整搬运一次:
| 项目 | 算式 | 结果 |
|---|---|---|
| 每个 token-expert 对的通信量 | 7168 × (1 字节 FP8 + 2 字节 BF16) | 约 21 KB |
| 每个 token 每层(8 个路由专家) | 8 × 21 KB | 约 168 KB |
| 每个 token 全部 58 个 MoE 层 | 58 × 168 KB | 约 9.5 MB |
| 每个 token 每层的专家计算量(8 个路由专家,不含共享专家) | 6 × 7168 × 2048 × 8 | 约 0.70 GFLOPs(58 层合计约 40.9 GFLOPs) |
| 每 token 前向总算力(按 2 × 激活参数估) | 2 × 37 × 10⁹ | 约 74 GFLOPs |
这张表想说三件事:
- 通信量随 线性增长,而专家内部计算量也随 线性增长——所以”多选几个专家”不会天然改善通信比,改善通信比要靠降低每次搬运的字节数(量化到 FP8/FP4)或提高搬运的并发度(overlap)。
- 每 token 约 10 MB 的 all-to-all 总量不是小数。这里要标清口径:9.5 MB 是专家并行 all-to-all 的总量(dispatch + combine,只算 8 个路由专家,未计共享专家的搬运),其中既包含跨机段也包含与 token 同节点专家之间的机内段。按 V3 的节点受限路由 ,一个 token 的 8 个专家最多落在 4 个节点上;极端情形下 8 个专家全在远端节点,此时全部走 IB,跨机流量就等于这个总量——所以 9.5 MB 同时可以当作跨机流量的上界看,实际比例取决于专家落点与部署。报告里那句”跨节点专家并行让计算通信比恶化到约 1:1”,说的就是这件事在训练侧的后果。
- 这也解释了 V3 为什么要为通信单独设计一套机制:DualPipe 把每个 chunk 拆成 attention、all-to-all dispatch、MLP、all-to-all combine 四段做重叠;报告还提到通过 warp specialization 用 10 个通信通道、20 个 SM 就能吃满带宽。
V4 之后又往前走了一步:把专家按 wave 切分调度,一个 wave 内的专家通信完成就可以立刻开始计算,不必等所有专家;实测相对强 baseline 在通用推理上拿到 1.50~1.73× 加速、在 RL rollout 这类延迟敏感场景最高 1.96×,并以 MegaMoE 的名字开源进了 DeepGEMM。报告同时提到一个反直觉的结论:完全重叠的瓶颈是”计算通信比”而不是”带宽本身”——达到门槛之后,把硅面积继续投给带宽是递减收益。
顺着这张表还可以看出三个可调杠杆,以及各自的边界:
- 降低每次搬运的字节数。 V3 训练用 FP8 混合精度;V4 的 MoE 专家权重进一步用到 FP4 + FP8 混合(官方模型卡口径:MoE 专家参数用 FP4,其余多数参数用 FP8),并在后训练阶段引入 FP4 量化感知训练。这一杠杆的收益是线性的,代价是数值稳定性——ST-MoE 早就发现稀疏模型对舍入误差特别敏感(因为路由器里有大量指数运算),这也是它引入 z-loss 的原因。
- 提高 的边际收益有限。 因为专家内部计算与通信同比例增长,单纯调大 不改善计算通信比; 的实际上限来自第九节那个”每节点 3.2 个专家”的结构性结论,而不是来自算力预算。
- 把通信藏到计算下面(overlap)。 这是唯一一条”不额外花预算”的路,也是最难的:它需要框架级改造(DualPipe 把 chunk 切四段、V4 把专家切成 wave),并且 overlap 的上限由计算通信比决定——到不了门槛就藏不住。
十一、方案对照:五种均衡路线摆在一起
把前面几张牌摊开对照,差异一眼可见:
| 方案 | 均衡施加在哪里 | 关键式子 / 参数 | 主要代价 | 代表来源 |
|---|---|---|---|---|
| Switch 辅助损失 | 损失函数,batch 粒度 | , | 均衡目标污染梯度; 不可导,只有 拿得到梯度 | Switch Transformer |
| DeepSeekMoE 两级损失 | 损失函数,专家级 + 设备级 | 小、 大,分组 | 超参变多;专家级约束过严会掉点 | DeepSeekMoE |
| ST-MoE router z-loss | 损失函数,但目标不是均衡 | 不为负载均衡服务,需与均衡手段并用 | ST-MoE | |
| V3/V4 无辅助损失偏置 | 路由排序键,batch 粒度 | 选人, 定权, | 看不见序列内失衡,需极轻量序列级损失兜底 | DeepSeek-V3、DeepSeek-V4 |
| V4 Hash 路由 | 前 3 层完全不用学习式路由 | 按 token ID 的预设哈希函数定专家 | 放弃前几层的自适应性,换取确定性与稳定 | DeepSeek-V4 |
架构侧的对照同样重要——同一个”DeepSeekMoE 血统”里,三代配置的方向并不一致:
| 维度 | DeepSeek-V3 | DeepSeek-V4-Flash | DeepSeek-V4-Pro | Mixtral 8x7B |
|---|---|---|---|---|
| 总参数 / 激活参数 | 671B / 37B | 284B / 13B | 1.6T / 49B | 46.7B / 12.9B |
| 层数 × 隐藏维度 | 61 × 7168 | 43 × 4096 | 61 × 7168 | 32 × 4096(Mistral 官方 HF config.json) |
| 路由专家数 | 256 | 256 | 384 | 8(每层) |
| 共享专家数 | 1 | 1 | 1 | 0(不使用共享专家) |
| 每 token 激活专家数 | 8 | 6 | 6 | 2 |
| 专家中间维度 | 2048 | 2048 | 3072 | 14336(标准 FFN 宽度,未做细粒度切分) |
| 稠密 FFN 层 | 前 3 层 | 无(全部层为 MoE,前 3 个 MoE 层用 Hash 路由) | 同左,前 3 个 MoE 层用 Hash 路由 | 无 |
| 亲和度函数 | Sigmoid | Sqrt(Softplus) | Sqrt(Softplus) | softmax over top-K logits |
| 节点受限路由 | 有, | 已取消 | 已取消 | 未涉及 |
| 均衡手段 | 偏置调整 + 极轻序列级损失 | 偏置调整 + 极轻序列级损失 | 同左 | 未见专门的均衡损失方案 |
从这张表能读出一条很清楚的演化线:“每次激活更少”是共同方向(每 token 激活的路由专家数 8→6);但”专家更多”不是——V4-Flash 仍是 256 个路由专家,与 V3 持平,只有 V4-Pro 扩到 384。新方向是**“减少人为约束”**:节点限制取消、前 3 层改用 Hash 路由、稠密层也全部换成 MoE。约束被削掉的代价由基础设施(wave 调度、MegaMoE 融合核)来承担,而不是由模型质量来承担。
十二、工程含义:选型、部署与成本
(1)比成本要看激活参数,比容量才看总参数。 1.6T/49B 与 671B/37B 的推理算力账分别落在 49B 与 37B 这一档;总额外出来的那部分权重换来的是知识容量。用总参数比较推理成本,会得出完全错误的结论。
(2)自部署 MoE 的第一约束常常是互联,不是显存。 上面那张通信量表给出了量级:每 token 约 10 MB 的专家并行 all-to-all 总量(含机内段;它同时是跨机流量的上界——8 个专家全落远端节点时即全额走 IB)。这解释了两个现象:为什么 MoE 推理服务特别依赖高带宽互联与 overlap,为什么”卡多但互联差”的机器跑 MoE 反而不如跑同激活量的稠密模型。
(3)“不丢 token”是从均衡策略推出来的结论,不是可以单独勾选的配置项。 如果你的路由失衡严重,静态容量下必然丢 token;调大容量系数又会按比例放大 padding 的计算与通信。正确顺序是先把均衡做对,再谈容量。
(4)推理期要单独设计,因为流量分布会漂移。 V3 的线上做法是冗余专家部署:把高负载专家复制,按线上统计(约每 10 分钟调整一次)在节点内重排专家,使各 GPU 处理量接近;prefilling 阶段设 32 个冗余专家,每张 GPU 除原有 8 个专家外再承载 1 个冗余专家。这类手段不属于模型结构,但决定了服务的实际吞吐。
(5)不要让”总参数量”进入用户可见的承诺。 模型卡上写 1.6T 是容量口径;API 的延迟与价格由激活参数量、上下文长度、缓存策略共同决定。把两个数混用,会在容量估算和成本估算上同时出错。
(6)调这套东西时,先分清是”训练问题”还是”部署问题”。 训练侧的超参是 、、、;部署侧的是专家放置、冗余专家、容量系数、EP 度。两者会互相掩盖——训练侧看不出 imbalance 的代价,会在部署侧以 tail latency 的形式暴露出来。
(7)API 价格低是”补贴”还是”结构”?是结构,而这条因果链有两条腿。 一条在算力侧:MoE 让每 token 只计算激活的那部分参数(V4-Pro 49B、V3 37B),而不是 1.6T / 671B;另一条在显存与搬运侧:MLA 把每 token 需要缓存、需要搬运的 KV 状态压到很小——本栏 注意力的显存战争:从 MHA 到 MLA 一文按维度算过这笔账,MLA 的每 token 缓存约为 MHA 口径的 1/57。两者叠加,才是 DeepSeek 系 API 价格能长期站在行业低位的结构性原因,不是单纯的补贴。 这个判断反过来也成立:同样是标称 1M 上下文、激活参数量相近的模型,若注意力仍是 GQA 口径,长上下文下的真实服务成本可能明显更高;而”1.6T 参数所以服务一定贵”的推断,是把容量账当成了成本账。
十三、边界与未解
未解一:专家到底在学什么,比我们以为的更模糊。 Mixtral 论文的第五节点名要做”专家是否按领域分工”的分析,结论是反直觉的:没有观察到明显的按主题分配规律——ArXiv 论文、PubMed 生物学摘要、PhilPapers 哲学文献的专家分配分布非常相似,只有 DM Mathematics 因为语料是合成的而略有差异;更符合观察的说法是”专家的选择与句法的相关性高于与领域的相关性,尤其在首末层”。同时它给了一个对工程有直接影响的数据:相邻 token 被分到同一专家的概率高于随机(高层的局部性更强),这既会让 EP 下的某些专家被过度订阅,也意味着这种局部性可以被缓存利用。
未解二:为什么偏置法是稳的,还没有完整解释。 V4 报告在讨论训练不稳定时给了两条实用手段,并明确承认”对其底层机理的完整理论理解目前仍是开放问题”。同一节里它还说了一个更值得警惕的观察:loss spike 与 MoE 层的 outlier 稳定相关,而且路由机制本身会加剧 outlier。也就是说,让路由更自由(这正是本文一直在讲的收益来源)会同时放大数值不稳定风险。
未解三:取消节点限制的代价还没有定量答案。 V4 报告的原句是 “we remove the constraint on the number of routing target nodes, and carefully redesign the parallelism strategy to maintain training efficiency”(译述:移除了路由目标节点数的约束,并重新设计并行策略以维持训练效率)。这里给英文原句、中文只作译述而不是加引号,是因为引号会被读成官方原话。但官方没有公布取消约束后通信量的变化幅度、对 wave 调度器施加了多少额外压力,也没有给出”什么规模的集群上这样才划算”。对自部署者而言,V3 的 是一个有量化配套(3.2 专家/节点、13 专家上限)的可抄参数,V4 的”取消限制”则缺少同等量化的部署配方。
未解四:Nash 式的平衡点仍靠经验找。 均衡约束放松能提升专家分工(7.3 节的验证损失差 0.005),但专家分工越彻底,推理期 domain shift 造成失衡的风险越大——V3 用冗余专家、V4 用 wave 调度来对付,都属于”用基础设施换算法自由度”。什么时候这个交换不划算(例如专家数少、跨机带宽差、流量高度集中在少数领域),官方材料没有给出判据。
明确说清楚”官方未公布”的部分:Mixtral 那一列的结构字段(32 层 × 4096 隐藏维度、每层 8 个专家、每 token 激活 2 个、FFN 中间维度 14336)取自 Mistral 官方 HF 仓库的 config.json,官方博客只给了 46.7B 总参 / 12.9B 激活这两个口径;V3 报告正文未逐字给出偏置项初值(该方法的出处 Wang et al. 2024a 的 Algorithm 1 写的是 ),偏置与路由器的实际更新时序(先更新偏置还是先反传)在 V3 报告正文中未展开;V4 的 Sqrt(Softplus) 亲和度函数与 Hash 路由均未公布消融数据。本文不做推测性填补,宁可标”未公布”。
什么时候这套东西不适用:如果目标只是单机、小批量、不追求容量上限,MoE 的收益很可能是负的——你要多记住 套权重,却省不下那个 all-to-all;如果请求分布高度集中(例如只服务一个狭窄领域),专家分工的收益也会被削弱,此时均衡约束反而更容易做对。
十四、小结
回到开头的直觉:1.6 万亿参数之所以不等于 1.6 万亿的算力,本质上是因为”选谁”成了一个可学习的稀疏决策。而这个决策一旦可学习,两个问题就必然出现——分布会失衡,以及均衡手段会反过来扭曲路由。
这篇文章把这条链走完:门控的三步(打分、Top-K、归一化)决定了稀疏性怎么落地;容量与溢出决定了失衡的代价是”丢 token”而不只是”变慢”;辅助损失的梯度只作用在 而 不可导,所以”粒度错了才有害”(序列级 2.258 vs batch 级 2.253);偏置调整把均衡从损失里搬到排序键上,用 的外部迭代换掉了对梯度的污染;细粒度与共享专家把组合空间从 120 种推到 44 亿种、同时把通用知识从路由专家手里摘走;节点受限路由把跨机通信压成有界预算,代价是路由器少了一个自由度——而 V4 的答案正是把这个自由度还回去,改用 wave 调度的基础设施去付账。
最后一个可以带走的判断:在 MoE 上,几乎所有算法层面的自由度提升,最后都要以通信或稳定性预算的形式偿还。 论文里那些看似互相矛盾的选择(V3 限制节点、V4 取消限制;Switch 用 的辅助损失、V3 用 0.0001 的”极轻”版本),其实是在同一个预算表上做的不同取舍。
📋 来源与核验记录
本文所有具体数字与公式均来自下列一手来源,逐条已实际打开核对(核验日期:2026-09-29):
- DeepSeek-V3 技术报告(671B/37B、14.8T token、61 层/7168、256 路由专家 + 1 共享专家、专家中间维度 2048、激活 8 个、 节点限制、sigmoid 亲和度、式 (12)–(20)、偏置更新速度 与 0.0、均衡损失 、64 路 EP 跨 8 节点、每节点 3.2 专家与 13 专家上限、20 个 SM、32 个冗余专家、消融验证损失 2.258 / 2.253 / 2.085 / 2.080、1B 与 3B MoE 规模、15.7B/228.7B 基线):https://arxiv.org/abs/2412.19437
- 同上报告的可读 HTML 版本(正文式 (12)–(20) 与 4.5.2 / 4.5.3 消融段落逐字核对):https://arxiv.org/html/2412.19437v2
- DeepSeek-V4 技术报告(V4-Pro 1.6T/49B、V4-Flash 284B/13B、1M 上下文、32T/33T token、61 层/7168 与 43 层/4096、384 与 256 路由专家、专家中间维度 3072 与 2048、激活 6 个、Sqrt(Softplus) 亲和度、取消节点限制、前 3 个 MoE 层 Hash 路由、、均衡损失权重 0.0001、通信量公式 FLOPs 与 字节、判据 、1 GBps 对应 6.1 TFLOP/s、wave 调度 1.50~1.73× 与最高 1.96×、Anticipatory Routing 约 20% 墙钟开销、SwiGLU Clamping、理论理解仍为开放问题):https://arxiv.org/abs/2606.19348
- DeepSeek-V4-Pro 官方模型卡(1.6T/49B、1M 上下文、32T+ token、FP4 + FP8 混合精度说明):https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro
- DeepSeek-V3 官方模型卡(671B/37B、2.788M H800 GPU 小时、2.664M 预训练 GPU 小时、FP8 训练说明):https://huggingface.co/deepseek-ai/DeepSeek-V3
- DeepSeek-V3 官方
config.json(hidden_size 7168、moe_intermediate_size 2048、intermediate_size 18432、n_routed_experts 256、n_shared_experts 1、num_experts_per_tok 8、n_group 8、topk_group 4、first_k_dense_replace 3、num_hidden_layers 61、scoring_func sigmoid、norm_topk_prob true、routed_scaling_factor 2.5、vocab_size 129280;第三节的参数账由此逐项相乘得到):https://huggingface.co/deepseek-ai/DeepSeek-V3/raw/main/config.json - DeepSeek-V3 开源仓库(权重与推理代码入口,模型卡与报告指向此处):https://github.com/deepseek-ai/DeepSeek-V3
- DeepGEMM 中的 MegaMoE 融合核 PR(V4 报告注明的开源位置):https://github.com/deepseek-ai/DeepGEMM/pull/304
- Wang et al. 2024a《Auxiliary-Loss-Free Load Balancing Strategy for Mixture-of-Experts》(V3 无辅助损失偏置法的一手出处:§4.1「we choose sigmoid instead of softmax as the gating function , since we find that the sigmoid baseline performs better than the softmax baseline」;附录 C.1 softmax 门控在相近均衡度下困惑度更高、对负载失衡更敏感;附录 C.2「the normalization property of softmax, which makes the score gap between two experts sensitive to the scores of other experts」;Algorithm 1「Initialize for each expert」;式 (5) 与 Table 4 的加性/乘性偏置对比):https://arxiv.org/abs/2408.15664
- DeepSeekMoE 论文(细粒度切分 专家激活 、组合数 120 对比 4,426,165,368、共享专家隔离、共享与激活路由专家比例 1:3、专家级均衡损失式 (12)–(14) 与设备级均衡损失式 (15)–(17)、专家级系数小 / 设备级系数大的实践口径;2B 截面为 1 共享 + 63 路由、激活 7(Table 1 与附录 Table 7),1:3 配比来自「64 个总专家」规模上的共享专家数消融,原文表述为 the ratio between shared experts and activated routed experts):https://arxiv.org/abs/2401.06066
- Mixtral of Experts 论文(每层 8 专家、每 token 选 2 个、 与 掩码定义、32k 上下文、第五节专家分工分析:无按主题分配的明显规律、选择与句法相关性更高、相邻 token 重复指派高于随机):https://arxiv.org/abs/2401.04088
- Mistral 官方 HF 模型仓库 Mixtral-8x7B-v0.1 的
config.json(num_hidden_layers 32、hidden_size 4096、intermediate_size 14336、num_local_experts 8、num_experts_per_tok 2;§十一 对照表 Mixtral 列的层数/隐藏维度/专家数由此逐项核对):https://huggingface.co/mistralai/Mixtral-8x7B-v0.1/raw/main/config.json - Mistral 官方博客(Mixtral 8x7B:46.7B 总参数、每 token 只用 12.9B、路由器每层为每个 token 选 2 个专家):https://mistral.ai/news/mixtral-of-experts
- Switch Transformer 论文(专家容量式 (3)、辅助损失式 (4)–(6)、 不可导而 可导、全篇 、溢出丢 token 的机制描述、No-Token-Left-Behind 附录、 路由):https://arxiv.org/abs/2101.03961
- ST-MoE 论文(router z-loss 式 (5)、训练容量系数 1.25 与评估容量系数 2.0、z-loss 稳定且不掉质量、update clipping 稳定但显著损质量):https://arxiv.org/abs/2202.08906
数字口径说明:第三节的参数拆解表、第十节的通信量估算表均为本站按上述官方 config.json 与论文公式自行相乘/相加得到的量级估算,不是论文原文表格,误差来源与假设已在该两节正文里写明;凡官方未公布的项(V4 的亲和度函数消融、Hash 路由消融、取消节点限制后的通信量变化)本文均标注”未公布”,不做推测性填补;V3 偏置项初值虽未见于 V3 报告正文,但其方法出处 Wang et al. 2024a 的 Algorithm 1 给出了 ,本文按该一手出处标注。