384 个专家里只叫醒 6 个:MoE 与路由入门
从"一家公司有 384 位专家、每来一个问题只准叫 6 个"讲起:MoE 为什么要切开 FFN,路由器这个"前台"到底在做什么,sqrtsoftplus 与 noaux_tc 偏置各自解决什么问题,为什么图像 token 要单独排一队,以及那句最该带走的话——MoE 省的是电费,不是房租。
本篇属于系列 关于deepseek部署你要知道的一切 · 第 2 篇
来源:vLLM Recipes · deepseek-ai/DeepSeek-V4.1-Flash(页面标注 Updated 2026-09-20)
说明 本文是系列《关于deepseek部署你要知道的一切》的第 2 篇,面向只熟悉 vanilla transformer 的读者,把官方页面里的术语逐个拆开解释。文中所有数字、参数与命令均来自上述页面,未作独立核实。
先设想一个场景
你刚入学,某天被拉进一家公司的“超级问答部”实习。
这个部门有 384 位专家,从量子场论到螺蛳粉配方,无所不包。规矩只有一条: 每来一个问题,只准叫 6 个人进会议室。 另外还有一位永远在岗的值班专家,任何问题他都得先过一遍。
而你的岗位是前台。你的活儿是:看一眼问题,从 384 个名字里挑出最合适的 6 位。
你挑得准,公司又快又聪明;你挑得随意,公司就变成一个昂贵的随机数发生器。 DeepSeek-V4.1 里那个叫路由器(router)的东西,干的就是你这个前台的活。
MoE(Mixture of Experts,混合专家)的全部大意,到这里就讲完了。 剩下的内容,都是在回答一个问题:这个前台该怎么干,才不至于把事情搞砸。
为什么要这么麻烦:一个你必须先接受的取舍
先回到你熟悉的那一层。vanilla transformer 的 block 长这样:
x → LayerNorm → 注意力 → 残差 → LayerNorm → FFN → 残差
注意力负责“看哪儿”,FFN 负责“想什么”。而 FFN 有一个性格特点:它对每个 token 一视同仁。 不管这个 token 是“的”还是“黎曼猜想”,都要过同一个巨大的矩阵。
于是你陷入两难:
- 把 FFN 做大 → 模型更聪明,但每算一个 token 都要把整块大矩阵搬一遍,又慢又贵;
- 把 FFN 做小 → 便宜了,但装不下那么多知识。
MoE 的回答非常干脆:那我不做一块胖矩阵,我做 384 块瘦矩阵,每次只搬其中几块。
- 仓库:384 块都躺在显存里,一块不少;
- 单次搬运:只激活 6 块 + 1 块共享。
这就造出了这台模型最反直觉的数字:总参数 552B,而每个 token 只激活 8B(读 prompt 时)或 16B(写答案时)。 差了将近 50 倍。
这不是压缩算法的胜利,而是“根本不需要全用上”的胜利。
一句话记住:MoE 把“仓库有多大”和“每次搬多少”这两件事彻底解耦了。
前台值班日志:一次路由到底发生了什么
每个 token 走进来,你(路由器)要做三件事:
- 打分:给 384 位专家各算一个分数,表示“这位有多适合当前这个 token”;
- 取前 6:挑出分数最高的 6 位(这就是 top-k,这里 k=6);
- 加权汇总:6 位各自给一个结果,按分数加权求和,作为这一层的输出。
第 3 步是很多人第一次会理解错的地方:不是“挑一位专家说了算”,而是“6 位各写一段,按票数拼起来”。
写成公式就是 y = Σ wᵢ · Expertᵢ(x),其中只有 6 个 wᵢ 不是零。
你不用记这个公式,只需要记住画面:6 个人合伙答一道题,谁的分高谁的话更重。
顺手感受一下 top-k(30 秒)
import torch
scores = torch.randn(384) # 路由器给 384 位专家打的原始分
top6 = scores.topk(6).indices # 只叫这 6 位
print(top6.tolist())
真实实现要复杂得多(要算权重、要加权求和、要处理跨卡通信),但这一步的骨架就是这四行: 给所有人打分,然后无情地只留前 6 个。 剩下的 378 位,这一次连话都不用说。
(这也是“专家”这个名字容易骗人的地方:他们不是 384 个不同的人格,就是 384 个结构相同、 各自被训练出不同偏好的前馈网络。)
打分的函数名很吓人,但它只做一件事
页面上的原话是:路由用 sqrtsoftplus 打分,并带一个 noaux_tc 偏置。
先说 sqrtsoftplus。它只是一个把任意实数变成正数的函数(常见做法是 softmax,这里换成了另一套)。
它的职责是把原始分数翻译成“推荐度”,用来决定 6 位专家的权重比例;
而选哪 6 位,靠的是排序——把一个函数做单调变换,不会改变谁的分数最高。
所以这个名字你不用怕:它不改变机制,只改变票数的分配形状。 (至于为什么不用最常见的 softmax,页面没有解释,这属于模型作者的口味,不影响你理解这台机器在干什么。)
本篇最深刻的一点:为什么要有那个“偏置”
请注意,下面这段值得慢一点读。
如果前台严格按“谁最合适”来喊人,会发生什么?
答案是头部效应:训练刚开始时,某几位专家碰巧多被选中几次 → 它们被训练得更充分 → 下一次显得更“合适” → 被选中的概率更高……雪球滚下去,384 位专家里可能只剩十几位真在干活,其余全在吃空饷。
这不是杞人忧天,而是训练 MoE 时最经典的翻车方式。
常规解法是加一个“辅助损失”(auxiliary loss):你分得越不匀,训练时我就额外罚你一下。 有效,但有点粗暴——为了调节“谁被选中”这件小事,去动整个模型的损失函数。
而这个模型的偏置叫 noaux_tc,名字里就把答案写着:no aux——不用辅助损失。
它改成给每个专家加一个可学习的偏置,直接作用在 top-k 的选择上:
最近太红的专家,偏置压低一点;长期坐冷板凳的,抬一抬。
为什么这招更优雅?因为“选中与否”是一个离散决定:你没法对着“谁被选中”这件事本身求梯度—— 能回传的只有权重,不是选择。既然直接调不动,就在旁边加一个小旋钮去干扰它。 动的手术更小,效果却同样能达到均衡。
这里还藏着一个值得玩味的推论:偏置是训练学出来的、会变化的。 所以专家的“人气”不是固定属性,而是被动态调节的结果。 这也解释了 MoE 的一个脾气:同一个词出现在不同上下文里,可能被送给完全不同的专家—— 它的“擅长”永远是相对于当前数据分布说的。
图像 token 走另一套人名册
页面上有一句特别容易被跳过的话:
对落在图像 span 内的 token,使用单独的路由偏置——这样视觉 token 和文本 token 不会去抢同一批专家。
用前台的话说:公司里有“摄影组”的 token 在排队,而且一来就是成千上万个。 如果图片和文字共用一套人名册,图片会瞬间把最受欢迎的专家全部占满,文字 token 只能退而求其次——两边都受害。
所以这里准备了两本人名册:图片走图片的,文字走文字的。 不是“专家不够多”,而是“两类顾客的口味差太远,得分开排队”。
那位永远在岗的共享专家
384 选 6 之外,还有 1 位 shared expert(共享专家),每个 token 都会经过他。
为什么必须存在?因为不是所有知识都“专精”。语法、高频词、“因为…所以…”这类连接关系, 每个 token 都用得上。如果指望 Top-6 去覆盖这些公共常识,会出两件坏事: 6 个宝贵名额被常识占掉,专精知识没地方站;384 位专家还得各自把常识重学一遍。
于是工程上做了分工:1 位公用专家负责“人人都需要的”,6 位路由专家负责“你这个 token 特别的”。
代价同样干脆:这位共享专家永远被激活,所以他的权重永远是贵的。
一个反直觉结论,请务必带走
MoE 省的是电费,不是房租。
- 每次只搬 6+1 位专家 → 算力和显存带宽省下来了,所以更快、更便宜;
- 但 384 位专家的权重一个都不能少,全部得躺在显存里 → 显存是按“总参数”付钱的。
看官方账本里的那一行:路由专家(含投机解码的草稿专家)合计 557.2B 参数、259.5 GiB 显存—— 这是全模型最大的一块,比 Engram 表(183.1 GiB)还大。
你不可能靠“只用 6 个”把显存省成 384 分之 6。 这就是为什么部署这台模型的第一难题永远是“装不装得下”,而不是“算得快不快”。 (这笔账的完整拆解在系列的第 9 篇。)
三个常见误解
① “只用 6 个专家,显存只要 1/64。” 不会。省的是算力与带宽;384 份权重照样全部驻留。容量是付了全款的。
② “专家是随机挑的。” 不是。路由是学出来的、与输入相关的。这既是 MoE 能力的来源,也是它“比稠密模型更难预测”的原因。
③ “专家越多越强。” 不一定。专家越多,路由越难学、越难均衡,跨卡通信也越贵(专家分了,token 就得跑过去)。 384 选 6 不是好看,而是被工程约束反复调出来的平衡点。
自测:三句话确认你真的懂了
- MoE 把一个 FFN 换成了 384 个 FFN + 一个路由器,每次只激活 6 + 1 个。
- 路由的核心矛盾是**“按能力选人”与“别让专家闲死/累死”之间的拉锯**,本模型用可学习偏置而不是辅助损失来缓解。
- 省的是算力,不是显存——性能的账和成本的账,要分开算。
三句能顺下来,你就已经比只会说“MoE 就是混合专家”的人懂得多了。
术语卡片
| 术语 | 中文 | 人话版定义 |
|---|---|---|
| MoE | 混合专家 | 把一个大 FFN 换成很多小 FFN,每次只激活其中几个 |
| routed expert | 路由专家 | 由路由器按 token 决定是否启用的专家(这里 384 选 6) |
| shared expert | 共享专家 | 每个 token 都会经过的那 1 位“值班专家” |
| router | 路由器 | 给 384 位专家打分、选出前 6 位的小网络 |
| top-k | 取前 k | 从所有分数里挑最高的 k 个;本模型 k = 6 |
sqrtsoftplus |
— | 把路由原始分转成正的推荐度的打分函数 |
noaux_tc bias |
路由偏置 | 不用辅助损失,改用可学习偏置来调节“人气”、维持负载均衡 |
| image routing bias | 图像路由偏置 | 图像区间内 token 专用的一套偏置,避免和文字抢专家 |
想看部署细节?在这几篇
本篇讲的是“是什么、为什么”。如果你关心这些设计在部署时怎么落地:
- 专家太多装不下怎么办 → 并行三兄弟(TP / DP / EP / DEP),第 11 篇;
- 专家的权重用什么格式存 → BF16 / FP8 / MXFP4 与显存账本,第 9 篇;
- AMD 上选哪个 MoE 内核(
--moe-backend aiter之类)→ 上手篇,第 13 篇。
小结
- MoE 的本质:用“每次只叫 6 位专家”的办法,把仓库大小和单次搬运量解耦。
- 路由的本质:一个要在“选最合适的”和“别让专家闲死/累死”之间走钢丝的学习问题。
- 最该带走的一句话:MoE 省的是电费,不是房租。
下一篇:《模型也会看图:ViT、aligner、图像 token 与 Encoder parallel》——我们去看这台模型为什么叫“视觉-语言”,以及那 32 层 ViT 是怎么把一张照片塞进文本序列里的。
讨论
这里是静态站点,没有内嵌评论区。如果这篇文章对你有用,欢迎通过 RSS 订阅后续更新。