通过餐厅类比理解DeepSeekMoE的新视角
作者使用ChatGPT创建的图片。
这是我们DeepSeek-V3系列的第二篇文章,我们将解释DeepSeek[1, 2, 3]模型中另一个关键的架构创新:DeepSeekMoE[4]。
具体来说,我们将解释混合专家(Mixture-of-Experts, MoE)的工作原理,它为什么在大语言模型中如此流行以及面临的挑战。我们还将讨论专家专业化与知识共享之间的权衡,以及DeepSeekMoE如何设计以达到更好的平衡。
最精彩的部分是:为了使这些概念更直观,我们将使用餐厅类比来解释所有内容,通过厨房中厨师的角色来说明MoE中的每个元素。
本系列有3篇文章,请在站内搜索:
-
DeekSeek-V3解析1:多头潜在注意力
-
DeepSeek-V3解析2: DeepSeekMoE
-
DeepSeek-V3解析3: 无辅助损失的负载均衡
本文目录:
-
背景:介绍MoE的工作原理、优势和挑战,并讨论专家专业化与知识共享之间的权衡。
-
DeepSeekMoE架构:解释细粒度专家分割和共享专家隔离。
-
评估:通过几个有趣的实验讨论DeepSeekMoE的性能。
-
总结
背景
大语言模型中的MoE(混合专家)
在大语言模型的背景下,MoE通常指用MoE层替换Transformer模型中的前馈网络(FFN)层,如下图所示:
图1. MoE层示意图。图片来自GShard论文[5]。
具体来说,左侧显示了N个Transformer层的堆叠,每个层包含一个多头注意力(MHA)子层,后跟一个前馈网络(FFN)子层。相比之下,右侧显示了N/2个Transformer层的堆叠,其中下层Transformer的FFN子层被MoE层替换。换句话说,每隔一个Transformer层的FFN子层将被MoE层替换。在实践中,我们可以实现MoE以在指定间隔的Transformer层中替换FFN。
如果我们进一步查看MoE层,我们可以发现它包含一个门控操作,后跟一组FFN,每个FFN的架构与标准FFN子层相同。这些FFN层在MoE中被称为"专家",而门控操作经过训练以选择应该激活哪个专家来处理特定输入。
图2. 带有门控和多个FFN作为专家的MoE层。图片来自[5]。
MoE的一般架构可以更正式地描述如下(等式编号沿用自[4]):
其中:
-
u^l_t 和 h^l_t 分别是第l层Transformer中第t个token的输入和输出隐藏状态。
-
FFN_i 是N个专家中的第i个专家。
-
g_{i, t} 是给定token t和专家i的门控值,通过对softmax输出应用TopK操作获得。
-
等式(5)中的 e^l_i 通常被称为第i个专家的质心,可以通过聚合过去所有被路由到第i个专家的输入token来计算:
作者创建的等式。
现在让我们从(5)到(3)逐步解释上述等式:
-
在等式(5)中,u^l_t 和 e^l_i 的内积衡量了当前输入token与过去被路由到第i个专家的平均输入token的接近程度。直观地说,如果专家i处理过许多与当前token相似的输入token,它应该更擅长处理当前token。然后,对这个内积应用Softmax,将其转换为一个分布。由于我们有N个专家,对于每个token我们也会有N个s_{i, t}值。
-
在等式(4)中,我们对所有s{i, t}值应用TopK,产生稀疏的g{i, t}值。
-
在等式(3)中,稀疏的g_{i, t}值用于选择K个专家来计算输出隐藏状态。
换句话说,对于第t个token,只有N个专家中的K个会被激活,导致g_{i, t}值稀疏,因为K通常很小。通过这种设计,模型中的总可训练参数会因额外的FFN而增加,但在前向传播过程中只有一小部分会被激活。
这就是为什么我们经常看到使用MoE的大语言模型将其模型大小描述为"总参数XX,其中每个token激活YY个参数",其中YY远小于XX,就像DeepSeek-V3的例子:
"它包含236B总参数,其中每个token激活21B参数..."
那么,如果MoE会引入更多参数,它的好处是什么呢?
MoE的优势和挑战
MoE的优点在于它反映了许多具有相似原理的现实场景,因此我们可以使用这些例子来更直观地理解它。
现在想象我们正在为一家提供中餐和意大利菜的餐厅招聘厨师,我们有两个选择:
-
选项1:雇佣一名精通中餐和意大利菜的单一厨师,这样他或她可以独自处理每道菜。这类似于标准的Transformer模型,其中单个FFN子层将处理所有输入token。
-
选项2:雇佣多名厨师,每个专门负责中餐或意大利菜,再加上一名主厨根据他们的专长分配订单给两位厨师。这类似于MoE方法,其中每个厨师充当专家,主厨充当门控机制来选择专家。
通过上述类比,很明显选项2不仅使招聘更容易,而且还能确保两种菜系都能以更高的质量准备。相比之下,找到一位精通多种菜系的单一厨师要困难得多 - 如果不是不可能的话 - 我们可能不得不在菜品质量上做出妥协。
回到我们的大语言模型场景,MoE的动机部分与扩展假说有关,即在大规模数据上扩展大语言模型时可能会出现涌现能力,这就是为什么我们目前看到大语言模型变得越来越大,例如GPT模型已经从117M扩展到175B。
然而,并非每个人都有特权在如此大规模上训练大语言模型,MoE提供了一种折衷方案:它允许我们扩大模型规模以增加模型容量,同时保持训练和推理成本可控,因为每个输入token只激活总参数的一小部分。
如[4]所示,您可以训练一个2B参数的模型,只激活0.3B参数,一个16B参数的模型,只激活2.8B参数,甚至一个145B参数的模型,只激活22.2B参数。在每种情况下,一次只使用总参数的约1/7,显著提高了训练和推理效率。
然而,每种设计都有其自身的局限性,并带来新的挑战。对于MoE来说,其性能在很大程度上依赖于门控机制的有效性,因为无法保证它总能将每个输入token路由到最佳专家,而且有可能少数专家频繁激活处理大多数输入token,而其他专家则闲置,没有接触到足够的训练token。这通常被称为"专家崩溃"问题。
这还会导致其他问题,如负载不平衡(因为大多数输入token被路由到一小部分专家)和不稳定性(当输入token被路由到未充分训练该任务的专家时会产生糟糕的结果)。
这就是为什么在MoE架构中我们经常看到很多关于负载均衡的讨论。
DeepSeekMoE也提出了一些负载均衡策略,但我们将在本文中重点关注关键创新,并在下一篇文章中深入探讨负载均衡策略,那里我们将解释 *无辅助损失的负载均衡* [8]。
知识专业化与知识共享
当我们在上述餐厅示例中做出招聘决策时,我们也在权衡知识专业化与知识共享:选项1优先考虑通才但可能牺牲深度,而选项2优先考虑专业化。这种权衡在现实生活中的许多组织中都存在,如公司、团队等。
它在MoE中也存在,但以更隐含的方式。理论上,每个专家应该专注于特定方面,因为只有一部分输入token被路由到每个专家,而所有专家仍然共享一些共同知识,因为它们共享许多参数。与现实组织的情况不同,很难确定每个专家的专业化程度以及它们共享知识的程度。
权衡专业化和知识共享是MoE架构设计的一个关键考虑因素,因为过度专业化和过度冗余都不理想。
在前一种情况下,过度专业化的专家可能导致训练和推理的不稳定性,任何次优路由都可能导致性能下降。同时,这通常会导致容量利用不足,因为高度专业化的专家只能处理一小部分token。
在后一种情况下,如果专家变得过于相似,MoE引入的额外参数将不会带来成比例的容量增益,这无疑是对有限计算资源的浪费。
在下一节中,我们将看到DeepSeekMoE如何设计以实现两者之间更好的权衡。
DeepSeekMoE架构
DeepSeekMoE利用两个关键创新来平衡MoE中的知识专业化与知识共享,即细粒度专家分割和共享专家隔离。
图3. DeepSeekMoE示意图。图片来自[4]。
细粒度专家分割
DeepSeekMoE提出细粒度专家分割来促进专家专业化,其背后的直觉非常简单:对于一个输入token激活更多专家,处理该token所需的知识更有可能被分解并由不同专家获得。
在我们之前的餐厅示例中,这类似于将每个厨师分为专门的技能,如下图所示。最初,我们有一名厨师准备所有中餐,另一名厨师处理所有意大利菜。应用细粒度专家分割后,每种菜系所需的技能被分为多个专家,因此我们将有一组中餐厨师和另一组意大利菜厨师,每个厨师只需掌握该菜系的特定技能。
图4. 使用餐厅示例说明(a)应用细粒度专家分割前和(b)应用后的情况。作者绘制的图片。
这也在图3中得到说明,其中子图(a)中每个输入token被路由到N个专家中的2个,而在(b)中每个token将被路由到2N个专家中的4个。在更一般的情况下,我们可以将专家数量从N增加到mN,同时将每个专家FFN的中间隐藏维度减少到1/m,并为每个输入token激活m倍多的专家。这样,(a)和(b)的整体计算成本大致保持不变。
虽然作者没有为这种策略的有效性提供任何理论证明,但他们确实设计了实验来验证他们的想法,我们将在评估部分介绍这些实验。
共享专家隔离
DeepSeekMoE提出的另一种技术是隔离一些共享专家以减少冗余,其背后的直觉是,如果我们保留一些共享专家来学习跨各种任务的通用知识,这可能会给其他专家更多自由摆脱这种通用知识,从而减少这些非共享专家之间的冗余。
在我们的餐厅示例中,这类似于将所有厨师进一步分为两组,如下图所示,其中第一组(上部所示)处理通用烹饪技能,如基本刀工、烹饪技巧和调味原则,而第二组的厨师则更专注于自己的特色菜品。
例如,饺子厨师可以只专注于饺子的包法和蒸制,而不需要担心摆盘技巧,而意大利面厨师可以只专注于制作更好的面条,而不需要学习切菜技巧。因此,厨师之间的知识冗余可以减少。
图5. 在图4的餐厅示例基础上添加共享专家隔离。作者绘制的图片。
图3(c)也显示了这种策略在DeepSeekMoE中的实现方式,其中一个专家被选为共享专家(以绿色突出显示),因此所有输入token都会被路由到该专家,而无需通过路由器。同时,激活的专门专家数量从4个减少到3个,使得激活的专家总数与图3(b)中保持相同。
将所有内容整合在一起,DeepSeekMoE架构可以更正式地用下图右侧表示,我们将其与之前的通用MoE进行比较以突出差异:
图6. (左)通用MoE vs. (右)DeepSeekMoE。作者根据[4]中的等式创建的图片。
其中
-
等式(11)与之前的等式(5)相同,
-
等式(10)类似于等式(4),但这里我们应用TopK从(mN - K_s)个专家中选择(mK - K_s)个,其中K_s表示共享专家的数量。
-
等式(9)将等式(3)中的第一项分为两个子项,分别对应共享专家和路由专家。
同样,原始论文中没有提供理论证明来证明所提出策略的有效性,但正如我们将在下一节中看到的,评估结果确实表明添加共享专家可以提高性能并减少知识冗余。
评估
正如我们之前提到的,虽然这两种策略背后的直觉听起来合理,但作者没有提供任何理论证明来证明它们,这使得不清楚它们是否真的可以帮助解决专业化与知识共享之间的矛盾,以及它们可以在多大程度上提供帮助。
基本上,我们想要理解三个核心问题:
-
DeepSeekMoE能否取得更好的结果?
-
细粒度专家分割能否以及在多大程度上有利于专业化?
-
共享专家隔离能否以及在多大程度上减少冗余?
为了理解这些问题,作者精心设计了一系列实验,在此提及这些实验至关重要。
DeepSeekMoE能否取得更好的结果?
首先,作者研究了他们的方法是否能带来更好的整体性能。为了验证这一点,他们训练了一系列具有可比总参数/激活参数的模型,并在不同任务上评估它们。他们的主要结果总结在下表中,最佳指标以粗体突出显示。
图7. 整体性能。作者根据[4]中的表1创建的图片。
几个要点:
-
蓝色突出显示的列比较了标准Transformer(Dense)与两种MoE架构(Hash Layer [6]和Switch Transformer [7]),显示在可比的激活参数下,MoE架构可以实现显著更好的性能。
-
绿色突出显示的列进一步比较了DeepSeekMoE与另一种MoE方法GShard [5],显示在可比的激活参数下,DeepSeekMoE实现了显著更好的性能。
然而,实现更好的性能并不一定意味着在专业化与知识共享之间取得了更好的权衡,因此我们仍然需要其他实验。
DeepSeekMoE是否有利于专业化?
直接衡量专家的专业化程度是困难的,相反,作者设计了一个有趣的实验,从相反的方向入手,通过禁用一些最常路由的专家并观察结果。
直观地说,当专家更专业化时,它们应该更难被替代,因此,禁用最常路由的专家应该对性能产生更大影响。
具体来说,他们通过在DeepSeekMoE和GShard x 1.5中禁用最常路由的专家进行实验,后者作为基线,因为这两种方法在没有禁用专家时具有可比的Pile损失,见下图中对应比率0的最左侧点:
图8. 禁用最常路由专家时DeepSeekMoE和GShard x 1.5的Pile损失。图片来自[4]。
随着禁用路由专家的比例增加,DeepSeekMoE始终产生更高的Pile损失,表明DeepSeekMoE中的路由专家更专业化,因此更难被其他专家替代。
DeepSeekMoE是否减少了知识冗余?
遵循类似的思路,作者还禁用了共享专家并激活了一个额外的路由专家,以观察共享专家是否可以通过添加一个额外的路由专家来替代。
结果,他们观察到"Pile损失显著增加,从1.808上升到2.414",这证实了共享专家获得的知识在某种程度上是独特的,而路由专家没有充分训练以覆盖那部分知识。换句话说,路由专家更专业化,冗余更少。
总结
在本文中,我们通过餐厅类比解释了DeepSeekMoE,这是DeepSeek-V2和DeepSeek-V3等DeepSeek模型中采用的主要架构创新之一。
具体来说,我们介绍了MoE的一般工作原理、其优势和挑战,以及专家专业化与知识共享之间的权衡。随后,我们解释了DeepSeekMoE中的两个关键元素:细粒度专家分割和共享专家隔离。我们还在评估部分讨论了其性能。
作为我们的主要收获,DeepSeekMoE通过促进专家专业化,在与通用MoE架构相当的计算成本下实现了更好的结果,从而提高了计算效率。