专家混合:大而便宜的秘密
Fedus, Zoph, Shazeer · Google Brain · 2021 · arXiv:2101.03961 · Switch Transformers
这篇论文造出了一台 1.6 万亿参数的机器——比 GPT-3 大九倍——可它读一个词所花的计算,跟一台普通模型差不多。这不是魔术,是分诊。专家混合、路由器、门控、负载均衡、容量因子……这些名字你一个都不用记。你只需要会一件事:在医院门口挂号。因为你在分诊台做的那个决定,就是这篇论文的全部。
先来当一分钟分诊员
想象你在一家医院的前台。今天来了三位"病人",挂号单已经写好了。你不会让任何一位跑遍全院——看一眼是谁,送去合适的科室,下一位。点一位病人,再点你想送去的科室。凭直觉分就行,没什么大不了的:
全员会诊的账单
Switch 之前的标准做法叫密集模型(dense):没有分诊台。任何一个词进来——哪怕只是一个逗号——全部神经元都要出动算一遍。相当于病人挂个号,全院每一位医生都必须到场会诊,包括那位只是来看标点的。想让医院更能干?只能招更多医生,而每位新医生也要参加每一场会诊。拖动滑块,把模型加宽,看右边那两笔账怎么走:
盯住右边那两根柱子:无论你怎么拖,它们永远一样高。参数(模型的知识储量)每翻一倍,每个词元的计算账单跟着翻一倍——到最右端,一个逗号也要惊动八千多个神经元。密集模型里,参数量和计算量是锁死的一对:想变聪明,必须同步变贵。然而你在分诊台已经亲手证明过另一种可能:来看标点的,何必惊动数字科?
手术:把大脑切成专家,门口摆张分诊台
论文的手术很直接:把 Transformer 每一层里最大的零件——前馈层(FFN,可以理解成负责"消化理解"的那一大坨神经元)——切成 N 份。每一份叫一位专家(Expert),门口摆一张会打分的分诊台。词元进来,分诊台给每位专家打个分,然后送去……几位专家?2017 年最早的专家混合(Mixture of Experts,一栋专科医院)坚持每个词元至少要看两位专家——大家相信不比较就没法学。Switch 这篇论文问了个大胆的问题。先押注:你觉得一个词元应该去几位专家?
想看一次挂号的真实算术?(可跳过,不影响后面)
分诊台就是一个小矩阵。词元「2021」的向量(假设只有 4 维)乘上它,得到四个分数,再过一遍 softmax 变成加起来等于 1 的概率:
| 虚词·标点科 | 数字科 | 专名科 | 实词科 | |
|---|---|---|---|---|
| 原始分数 | 0.4 | 2.6 | 0.7 | 0.5 |
| softmax 之后 | 0.06 | 0.81 | 0.08 | 0.05 |
取最大:去数字科,并且专家的输出 × 0.81。这个乘法是 top-1 能学起来的关键——如果只是硬邦邦地送过去,梯度就断了,分诊台永远学不会反省"我分得对不对"。分诊台本身小得可怜(一个 d×N 的矩阵),所以"打分"这道工序在账单里几乎看不见。
口说无凭——省下的账单到底有多大?我们让两台机器同题竞赛。
同一句话,两张账单
上面一台是 §2 那种密集机,下面一台是 Switch——两台机器的参数总量完全相同,只是下面那台把大前馈层切成了四份。同一句话喂进去,点「同时放行」,看两条账单各自涨多快:
红条走了 44 个单位,绿条只走了 11 个。上面那台每个词都点亮整块大脑,下面那台每个词只点亮一位专家——参数一样多,稀疏只付 1/N 的计算账单。而且这个 N 不必是 4。它可以是 64、是 128、是 2048——绿条依然纹丝不动。这就危险了(好的那种危险)。
白拿的参数:两条曲线分家
既然多一位专家不多花一分计算,那就使劲加。拖动滑块,往医院里加科室,看两条曲线怎么分家:
两条线在最左端(N=1)重合——一位专家就是没有分科,那正是密集模型。往右每走一步,参数线翻着倍往上爬,计算线躺平不动。拖到头:2048 位专家、约 1.6 万亿参数——这就是论文里的 Switch-C,当时世界上参数最多的模型,而它读每个词的计算量仍然只是"一位专家"的量。中间那片绿色阴影,全是你白拿的知识储量。专家数翻倍,参数翻倍,账单不动——"大"第一次和"贵"解了绑。然而这条免费曲线有一个致命前提:分诊台得分得均匀。要是它偷懒呢?
旱的旱死,涝的涝死
分诊台不是天生会分诊的,它是训练出来的。而训练里藏着一个天然的恶性循环:哪位专家一开始碰巧好那么一点点,分诊台就多送它一些词元;它练得多、变得更好,分诊台就更爱送它;其他专家没客人,永远练不出来。下图是训练的缩影(60 个词元流进四个科室)——现在均衡损失是关着的,点「▶ 重新训练一遍」亲眼看这场挤兑,再打开均衡损失对比:
关着均衡时:几乎所有词元挤进同一个科室,超出床位(论文管这个上限叫容量因子,capacity factor)的直接被丢弃,其余三位专家从头到尾没接到一个客人。一台号称"万亿参数"的机器,实际退化成一位明星医生带着两千多个领工资的闲人。论文的解法朴素得可爱:在损失函数里加一小笔"排队管理费"——负载均衡辅助损失,谁的队伍太长,路由器就要罚分。打开它再训练一遍,四条队伍立刻长齐。稀疏的"大"只有在分流均匀时才是真的大;均衡损失就是那位排队管理员。
排队管理费的公式(一行)
对每一批词元,记 fi = 实际去了专家 i 的词元比例,Pi = 路由器分给专家 i 的平均概率。辅助损失 = α · N · Σ fi·Pi(α 取 0.01)。当分配完全均匀时这个乘积和最小;越偏科越受罚。它温柔地把路由器往"人人有份"推,又不至于强到抹平"术业有专攻"。
零件齐了:会打分的分诊台、只去一位的词元、被管住的队伍。现在当着你的面装成整机。
组装时刻:整栋医院开张
点「▶ 开诊」,看整句话流过完整的 Switch 层;跑完之后,点任何一位专家,看看它这一句里都接住了谁:
右上角那两个数字值得多看一眼:仓库里躺着 100% 的参数——显存必须装下它们全部,这一点请记住,结尾要翻旧账——但此刻在燃烧电费的只有 25%。再看专家们接住的词:虚词标点归一家,数字年份归一家,专名归一家。这种分工没有任何人设计,是均衡损失管住队伍之后,专家们在训练里自己"卷"出来的;后续研究在真实模型里确实观察到了标点专家、数字专家这样的角色。参数是仓库,计算是账单——Switch 把两者拆开,各记各的账。
整台机器交给你:能让它丢词吗
最后这台沙盒机随便拧。给你三个挑战:① 把专家数拧回 1,看看你得到了什么老朋友;② 关掉均衡损失,亲手复刻一位明星专家;③ 换上第二句话——一句全是年份的句子——你能让分诊台丢词吗?能亲手造出丢词,才说明你真的懂了这台机器:
第三个挑战戳中的是 Switch 真实的软肋:均衡损失管的是几百万个词元的长期平均,救不了眼前这一句。一句全是数字的话涌向数字科,床位一满,多出来的词元被直接丢掉——在真实模型里它们走残差直通道原样穿过这一层,等于这一层没读它们。工程师用容量因子这个旋钮在"多留床位(费显存)"和"敢丢词(损精度)"之间讨价还价。你刚造出的丢词,不是沙盒的 bug,是这篇论文自己坦白的代价。
大而便宜,从此成了默认答案
回看你这一路亲手做的事:你在分诊台点下第一下,就已经做对了 top-1 路由;你拖着密集模型变宽,看两根柱子锁死着一起涨;你押了"几位专家"的注,看一句话各回各科;你看着红绿两条账单拉开 4:1;你把专家数拖到 2048,看参数线和计算线分家;你关掉均衡损失,亲手养出一位明星医生,又亲手把队伍管齐;最后你还找到了让它丢词的办法。这就是整篇论文——2021 年,它用这套"简单而高效的稀疏"造出了第一台万亿参数模型。
此后"大而便宜"成了行业的默认答案。Mixtral 把 8 位专家装进开源模型(总参数约 470 亿,每个词元只激活约 130 亿);DeepSeek-V3 走得更远——总参数 6710 亿,每个词元只叫醒 370 亿。你日常用的大模型 API 为什么能又聪明又便宜?定价表背后,就是你在第 4 节看到的那两根柱子的差。论文自己报告:同样的算力预算,预训练到同等质量最快提速 7 倍——省下的不是零头,是数量级的开端。
杠精清单:五个你可能正想抬的杠(我们直说)
"没被叫醒的参数不是浪费吗?"——不浪费:不同词元点亮不同科室,一整句下来全楼都在轮班。但它们确实都要住在显存里——"大而便宜"便宜的是计算,不是内存,你在整机图右上角见过这两个数字的分裂。
"训练稳吗?"——不太稳。稀疏模型容易训练发散,论文用"关键部位保留高精度"(selective precision)等手段压住了它。
"微调呢?"——容易过拟合。参数多、下游数据少,论文自己承认这一点,后来的工作用专家 dropout 等办法缓解。
"丢词真的没事?"——有事,只是可控。容量因子调大能少丢词但费显存;你在沙盒里已经拧过这场交易的一头。
"top-1 只有一条路,路由器凭什么学得会?"——凭那个乘上去的门控值(梯度回路)加上均衡损失(探索压力)。第 3 节的折叠算术里演过。
这台机器和注意力共享同一个深层思想:智能不在于把所有东西都算一遍,而在于选择——注意力选择"看谁",专家混合选择"叫醒谁"。如果你读过馆里《注意力,就是你所需要的一切》或者《注意力残差》,会认出这是同一条线索的第三次出现:稀疏,是智能的经济学。下一次再听说某个模型"又大了十倍",你可以问出那个真正内行的问题:这次点亮的是多少?