← 返回博客
[从零训练一个200B大语言模型] 5/25:MoE怎样用一部分参数,完成一次计算?

[从零训练一个200B大语言模型] 5/25:MoE怎样用一部分参数,完成一次计算?

上一篇,我们跟着“窗外下着雨,我拿起了……”走过了一个模型。每一层,蓝色A从前文取回信息,金色B继续加工当前状态。许多层接起来,模型就能给后面的文字打分。

接下来,我们想让模型容纳更多学到的东西,一个办法就是增加参数。但在上一篇的稠密模型里,每个token都会经过各层完整的金色B。把这套网络做大,每次经过它也要做更多计算。模型的容量扩大了,训练它、用它回答问题所需的算力也跟着增加。

MoE要解决的,就是怎样让模型拥有更多参数,同时控制每次计算的开销。它把金色B做成多套专家网络,每处理一个token,只选择其中几个工作。蓝色A仍然从前文取信息,选中的专家接着加工,结果再交给下一层。这样,我们就能继续增加专家、扩大模型容量,同时让每个token只经过其中一小部分。MoE的好处,就在于把“模型一共有多大”和“每次要计算多少”分开安排:保持相近的每token计算预算,也可以容纳更多参数。额外容量能带来多少能力提升,要通过训练与评估确认。GPU仍然要存放这些参数;少做计算能否缩短时间,还要看这些工作怎样分到机器上。

这一篇仍然跟着同一句话走。先看看一个token怎样选专家,再把这条路放到GPU上,最后回到我们的200B计划,算清它究竟改变了什么。

总图保留,只打开金色B

在第四篇的稠密模型里,同一层只有一套B。无论送来的是“雨”,还是“拿起”,都交给这套网络。输入不同,输出也不同;计算时使用的是同一套权重。

MoE把这一块展开成多套网络。每套网络有自己的权重,接收一个向量,也输出一个向量。我们把这样一套网络叫作一个专家。这里的“专家”,就是上一篇放大的前馈网络。它的里面仍然是许多数字经过带权重的连接,得到新的数字。

同一层的蓝色A之后,将金色B从一个前馈网络换成路由器与多套专家;分格短条是向量,E方框是一整个网络

图中继续用蓝色A和金色B。第一张图圈出B,下一张图就打开这个位置。分格短条表示一个向量,每格是其中一个数;标着E1、E2的方框则是一整个专家网络,里面可以有很多参数。

叫它“专家”,很容易想到语文老师、数学老师、编程老师。实际训练通常先给它们相似的结构和不同的初始权重,再让数据逐渐形成分工。一个专家可能偏向某些文字特征,也可能承担我们很难用一个学科名字概括的计算。我们先用E1、E2这样的编号,沿着数字的流动看它们怎样工作。

MoE(Mixture of Experts):在模型的一部分设置多个专家网络,每个token只选择其中一部分参与计算的结构。

专家:这里是一段有自己权重的前馈网络,接收和输出向量。

稠密模型:在本文的对比中,每个token都使用各层同一套完整的前馈网络。

谁来决定请哪几个专家?

继续盯住句尾。在英文图里,这个位置是“my”。经过蓝色A后,它的向量已经带着前文的信息。来到B的入口,一小段网络先读取这个向量,为各个专家打分。这一小段网络叫作路由器。

图里先放四个专家,每次选两个。路由器为这个输入算出分数,选择E1和E3,并给它们的结果分配75%和25%的混合比例。E2和E4的权重仍然存在,这个token这一次先不用它们。换一个token,或者到了另一层,选择可以改变。

两个选中的专家收到同一个完整输入向量,各自用自己的权重计算。假如E1输出 [0.8, 0.2, -0.4],E3输出 [0.4, 0.6, 0.8],接下来就把这两份结果按比例合在一起:

0.75 × [0.8, 0.2, -0.4] + 0.25 × [0.4, 0.6, 0.8] = [0.7, 0.3, -0.1]

第一格是 0.75 × 0.8 + 0.25 × 0.4 = 0.7,后面每一格也这样算。得到的仍然是一个向量,宽度与专家的输出相同。这就是B这次交出的加工结果,它再沿着层里的连接往后传。

跟踪一个向量:路由器选E1和E3,两专家各处理完整输入,输出按75%和25%逐分量合并;E2和E4本次未选

看这张图时,把三种东西分开:分格短条是一串数字,专家方框是一段网络,75%则是一个数。这个数乘的是整条向量,也就是里面的每个分量。图里的箭头表示数据去哪里,专家内部的可学习连接没有在这里展开。

这两个比例是为了让算式容易看清而选的例子。具体模型会规定打分、选取和归一化的方法,有些还会再加缩放系数。核心过程始终可以这样追踪:读取当前向量,选出几个专家,各自计算,再合并结果。

这里也能看出MoE和注意力的分工。A的比例决定从哪些文字位置取信息;B里的路由决定请哪些专家网络加工当前位置。它们都可能用到加权相加,但选的对象不同。

路由器(router):读取当前状态,为专家打分并决定选用哪些专家的小网络。

Top-k:从一组候选中选取分数最高的k个。图里k等于2。

路由权重:混合专家输出时使用的比例,由当前输入和路由方法确定。

共享专家,给每个token都走的一条路

接着可以再加一种安排:保留一个每个token都会经过的专家,让它处理普遍需要的部分;旁边再放一排按需选择的专家。前者叫共享专家,后者叫路由专家。

这样,一个token进入B以后,一边经过共享专家,一边去选中的路由专家,最后把两边结果合起来。共享专家与路由专家都接收向量、输出向量。区别在于谁会调用它们,以及结果怎样组合。

这给训练增加了一种分工方式:常用的加工可以留在共享路径,各个路由专家再学习不同的处理方法。具体学到了什么,要看训练后的行为。它们的名字说明的是连接和调用方式。

同一层的专家池会被这一层的所有文字位置共用;到了下一层,则有下一层自己的专家和路由器。选谁,要看这个词当时的状态,以及它走到了哪一层。

训练的目标仍然是把后面的文字预测得更好。预测结果产生的误差,会沿着参与计算的路径,用来调整专家与路由器的可学习权重。很多不同的输入反复经过这里,专家的处理方法和路由器的选择也就一起学习起来。

共享专家:在采用这种设计的MoE层里,每个token都会调用的专家网络。

路由专家:由路由器为当前token选出的专家网络。

200B还在,为什么每次可以少算?

现在可以分清两个数字了。总参数,是模型一共保存多少可学习的数。激活参数,是一个token沿着当前路径会调用其中多少。MoE把这两个数字拉开,让模型保存更多权重,同时控制单个token需要经过的网络规模。

我们用一份圆整的200B账本来算。把共同路径中用于主要矩阵计算的部分取整记为40B,包括注意力投影、共享专家等。其余160B分布在各层的路由专家里。每层有16个同样大小的路由专家,每次选2个。

先按这些主要矩阵做一份圆整的账。输入查表等细项,在确定完整配置时另行核对。所有层都用这个选择比例,路由部分每个token调用的参数就是:

160B × 2 ÷ 16 = 20B

再加共同部分,得到:

40B + 20B = 60B

200B教学账本:40B共同部分加160B路由部分,路由专家每层选2个共16个,每token约调用60B;色块面积表示参数量

这里的160B是所有层的路由专家合计,图中的十六格表示相同的调用比例。实际模型每层各有自己的专家池。图上的方块面积表示参数量,不是向量,也不是GPU数量。

这样,模型仍然保存200B参数,一个token主要经过的参数约为60B。对于这些权重所做的主要乘加,工作量会随调用规模下降。相比把200B都用于每个token,60B对应的这部分计算大约是30%。

省下来的计算,为扩大模型容量留出了空间。但机器还要做注意力计算、选择专家、搬运数据,以及在训练时保存并更新参数。上下文越长,注意力本身的开销也会改变。把这些工作加回来,才能得到一次训练真正需要多少时间。

显存的账也要分开看:没被当前token选中的专家仍然要保存,接下来别的token可能就会用到。一批训练数据里有很多token,它们合起来可能调用许多甚至全部专家,训练信号也随各自经过的路径更新权重。训练还要为这些参数保存相应状态。因此,MoE首先改变的是每个token调用多少计算,并不会把200B模型的存储需求直接缩成60B。

总参数:模型保存的全部可学习参数数量。

激活参数:一个token沿当前计算路径调用的参数数量。比较模型时要核对它是否包含共享部分,以及统计的是哪一种运行路径。

显存:GPU用来存放模型、当前数据和计算中间结果的内存。

四个专家同时算,选两个会更快吗?

先看一个具体例子:只有一个token,四个专家各放在一张GPU上。四张卡都有足够的计算能力,每个专家处理这个token都需要1毫秒。输入已经送到,我们先只看专家计算这一步。

调用方式同时工作的GPU闲置的GPU专家计算完成时间
四个专家全部计算4张0张1毫秒
只选择两个专家2张2张1毫秒

这个例子里,四选二并没有更快。四个专家原本就可以同时完成;不调用其中两个,留下的两个仍然各算1毫秒。减少的是完成的工作总量,单个token等待这一步的时间没有缩短。剩下两张卡确实闲着,仍然要保存专家的权重。

时间会在什么情况下缩短?当同一批硬件原来需要分多轮完成工作时,减少工作才有机会减少轮数。GPU内部的计算单元数量有限,大矩阵通常需要拆成小块、分轮处理;NVIDIA的矩阵乘法指南介绍了这种安排。参数保存在显存里,计算单元会反复读取并处理它们,一个参数并不对应一个专用计算单元。

因此,要分别问两个问题:一个token多久得到结果,以及一整批数据多久处理完。MoE让每个token只经过部分专家,先降低了需要完成的计算量。它能否让当前token更快、让整批数据更早完成,要看原来的工作是否已经能同时做完,以及数据传输和等待占了多少时间。下面把镜头拉到一整批输入,就能看到另一种情况。

计算单元:GPU内部实际执行运算的部件,会反复处理不同的数据和参数。

延迟:一个请求从开始到得到结果所花的时间。上表只计算专家运算这一步的时间。

吞吐:单位时间完成的工作量,例如每秒处理多少token。

专家放到不同GPU,新的等待就出现了

刚才的图里,E1和E3挨得很近。实际模型的专家可能装在不同GPU上。路由器选好以后,系统要把输入向量送到专家所在的卡,让专家计算,再把输出送回来合并。

下面还是同一个B。E1放在GPU 1,E3放在GPU 2。这个token的输入要去两个地方;返回的两份结果都到齐以后,才能完成前面的加权合并。模型的其他文字位置也在做类似的事。

专家分到两张GPU:一个向量发送给选中的E1和E3,专家输出返回原位置合并;箭头是向量传输,卡片是GPU

这里再把镜头从一个token拉远,看看一整批数据。当前token选E1和E3,同一批里的其他token可能选E2和E4。一个专家没有接到这个token,还可能正在处理别的token。一张GPU也可以保存多个专家,由同一套计算单元轮流处理它们的工作。

做一个简单的任务分配例子:4张卡各放1个专家,一批有100个token。假如每个token都经过4个专家,就有400次专家调用,每张卡处理100次。改成每个token选2个,共200次调用;分配均匀时,每张卡处理50次。每张卡的任务量从100次降到50次。如果原来这些工作需要分多轮计算,减少工作就有机会缩短整批完成时间;如果100次本来就能同时做完,变成50次也未必更快。实际还要看每张卡能否用满,以及分发数据要等多久。这里比较的是同一组专家的两种调用量,模型质量还要另外评估。

另一方面,如果大多数token都选中了E1,GPU 1就会排队,其他卡可能有空闲。特别是一批token很少的时候,确实可能只有几张卡在忙,剩下的卡仍然占着显存、等下一轮工作。这种情况下,少算的部分可能主要变成闲置,整批工作的完成时间未必缩短。训练需要让专家获得合适的工作量,同时保留路由对输入的选择能力。

这就是为什么MoE论文会花很多篇幅讨论负载均衡和通信。前面省下的是专家网络里的计算,后面多出来的是任务分配、跨卡传输和等待。一个好用的MoE,需要把这两头一起做好。

NVIDIA的Megatron Bridge性能指南把专家分布、成组计算和通信安排放在一起讨论。工程上会把发往同一张卡的向量成批打包,尽量让传输和计算同时进行,也会根据设备之间的连接安排专家位置。具体怎样把专家放进我们的B200服务器、哪些数据要经过交换机,到了并行训练和网络那两篇再展开。此刻先记住一个直接的判断方法:除了看每秒完成多少token,还要看各专家接到多少工作、GPU花多少时间在等数据。

批次(batch):一起交给模型处理的一组训练数据,里面通常有很多token。

专家并行:把不同专家放到不同设备上,让输入按路由结果送过去计算。

通信:这里指GPU之间传输输入、输出等数据。

负载均衡:让工作合理分布到专家和设备上,减少一边排长队、一边闲置的情况。

把DeepSeek的真实设计放回这张图

看懂这一条路以后,再看最新模型,数字就有位置了。DeepSeek在2026年10月17日发布的V4.1-Flash-1017可以作为一个具体例子。它的公开配置为每个MoE层设置384个路由专家,每个token选6个,另外保留1个共享专家。

对应到上面的B,就是把四个示例专家扩成384个,把“选两个”改成“选六个”,再加上一条每次都走的共享路径。每个专家仍是一段前馈网络;专家变多,基本的数据流仍然可以沿着同一张图读下来。

看这些配置时,要分别读共享部分和路由部分。每次选6个,描述的是384个路由专家中的选择;注意力、共享专家等仍然沿着各自的路径工作。前面的200B例子先把40B共同部分拿出来,正是为了把这些工作一起算进去。

Meta在2026年也同时保留了两条路线。第四篇介绍的Muse Glimmer 30B使用稠密语言主干,面向本地运行;10月15日发布的Muse Spark Open采用MoE,官方列出816B总参数、42B激活参数。一个团队会根据模型容量、运行速度和部署环境,选择不同的结构。它们给我们提供了真实设计,具体哪种更适合这家新公司,还要放回自己的任务里比较。

再看DeepSeek报告里的552B、196B、8B和16B

技术报告把语言主干列为552B参数,另有196B的Engram记忆模块。Engram用另一种方式保存和取用信息,放到后面讲记忆时再展开。

报告中的8B和16B,分别对应读取输入与逐步生成的推理路径。它们说明这套架构怎样控制推理计算;从零训练时,要按训练实际经过的路径重新统计。计算本篇的MoE选择比例时,先找到路由专家那部分,再加共同路径,就能避免把全部主干都乘上6/384。

我们的200B项目,接下来怎样选?

前三篇的2048张B200、约31天主训练,以及第三篇的预算,建立在200B稠密模型、累计处理4T token的基线上。它们保留为一份完整的对照。现在增加MoE候选,就多了一种用这批设备训练模型的方式。

我会先给候选写清三件事:总共保存多少参数,每个token调用多少参数,各层的专家怎样分到设备上。上面的200B、约60B激活账本,可以帮助我们设一个计算规模的起点。真正落地时,还要把层数、向量宽度、每个专家的大小,以及共享部分逐项算到参数清单里。

然后用相同的数据和评估方法做对照实验。我们要看到:同样训练计算投入下,MoE学得是否更好;放到多张卡上以后,省下的计算有多少转化成了更高的训练速度;每个专家是否都得到了足够的训练。再用目标规模实测的吞吐,回算训练周期、卡数与费用。

这一篇可以先作出一个选择:把MoE列为200B项目的正式候选,与稠密基线一起验证。它让我们有机会把“模型能装下多少”与“每个token要算多少”分别设计。决定它是否值得采用的,是这份额外容量带来的能力提升,以及我们的机器能多快地完成整条路径。

新文章,直接发到你的邮箱。

AI、工程与实验,每月 1–2 封。

无垃圾邮件,随时取消。