从ACL 2024录用论文看混合专家模型(MoE)最新研究进展

10adb1a44518875167d38f6bf2575ce1.gif

©PaperWeekly 原创 · 作者 | 杨远航

单位 | 哈尔滨工业大学(深圳)

研究方向 | 自然语言处理


最近 ACL 2024 论文放榜,扫了下,SMoE(稀疏混合专家)的论文不算多,这里就仔细梳理一下,包括动机、方法、有趣的发现,方便大家不看论文也能了解的七七八八,剩下只需要感兴趣再看就好。

下面是列表,顺序大抵是个人兴趣程度排序。

1. DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models

2. Harder Tasks Need More Experts: Dynamic Routing in MoE Models 

3. XMoE: Sparse Models with Fine-grained and Adaptive Expert Selection

4. HyperMoE: Towards Better Mixture of Experts via Transferring Among Experts

5. Not All Experts are Equal: Efficient Expert Pruning and Skipping for Mixture-of-Experts Large Language Models 

6. Multimodal Instruction Tuning with Conditional Mixture of LoRA

未完待续,大概还遗漏了一二三四篇,后续再加上 2024 年的一些 MoE 论文:

1. Let the Expert Stick to His Last: Expert-Specialized Fine-Tuning for Sparse Architectural Large Language Models

c6ffc5f9fa82f4c550238a4ff83fe919.png

DeepSeekMoE

1cb50690083fb532a99d599f4e656098.png

论文地址:

https://arxiv.org/abs/2401.06066

代码地址: 

https://github.com/deepseek-ai/DeepSeek-MoE

首先是众所周知的 DeepSeekMoE。

1.1 动机

本文的动机偏直觉:

1)专家不够分化:以往的 MoE 模型专家数量很少,假如模型的知识很繁杂,也就是说涉及的领域很多的话, 即使每个专家处理相同数量的领域,平均分配下来,一个专家仍然要包含很多领域的知识,也就是专家不够“专”——所以增加专家数量,然后寄希望于模型分化吧。

2)专家有冗余:假设每个 token 只能选一个专家,又假设每个 token 都需要常识知识,那么结果就是不论选哪个专家,这个专家的参数里都有常识知识,因此有冗余了——最好的情况是有个专家专门负责提供常识知识,所有 token 都会用一下这个专家。

2.2 方法

看完了动机,想必大家也知道方法怎么做了:

1)增加专家数量。具体来说,是通过拆分专家——比如把一个拆成两个——来增加专家数量。

更具体点,主流的专家实际上就是个 FFN,FFN 实际上就是两个矩阵。假设这两个矩阵的大小分别是: 和 。如果要把这个专家拆分成两个专家,实际上就是把矩阵拆成两个 和 。相应的,假如原本一个 token 选择 top-1 专家来处理,拆成两个后,就变成选择 top-2 专家来出来。这样拆前和拆后,计算量和参数量是没有变化的。

碎碎念:实际上,计算量还是有变化的。 路由模块 原本从 N 个专家里面选择 1 个,现在要从 2N 里选择 2 个。如何快速计算专家的分数,如何快速排序,如何快速分发数据,还是有点讲究的。

好处是什么呢?不妨假设每个专家实际上是一个图书馆。原本只有 4 个图书馆,每个图书馆的藏书都不同。我们想要解决自己的问题,必须且只能选择一个图书馆,说不定我们要的某本书并不在我们要选的图书馆里。拆分后呢,就有了 16 个图书馆,这时候我们可以选择 4 个图书馆来查阅,那么图书的排列组合多样性更多了,我们的选择也更灵活了。

2)增设共享专家。也就是说,有的专家是必选的,除此以外,每个 token 按照自己的喜好,再来选择 top-k。比如有 64 个专家,那么第一个专家是所有 token 都要选的,除此以外,每个 token 还从剩下的 63 个里选择自己的 top-1 专家。实际上就是 top-2 啦。

碎碎念:实际上,正如文章所指出的,deepspeedmoe 在 22 年提出了这个设计。

有趣的现象:

  • 在参数是 1.89B 时,DeepseekMoE 只用 0.24B 的参数,它的性能和 用上全部参数的 dense 模型不分伯仲。

  • 和同样是 MoE 结构的 GShard 比,拆分专家可以使得模型激活更少的参数取得更好的性能。

eca433a647f0de0fc692c818f982c442.png

Dynamic MoE

e4b6f14c569d8c65a11a2e0da6aa91e5.png

论文地址:

https://arxiv.org/abs/2403.07652

代码地址: 

https://github.com/ZhenweiAn/Dynamic_MoE


2.1 动机

top-k 路由在 MoE 模型中被广泛使用。作者认为,简单的任务需要少专家,复杂的任务需要多专家,如果一视同仁,那么效率会低。因此,作者提出了基于阈值 threshold 的路由方法,让每个 token 可以动态选择 1 到 多个专家。

2.2 方法

众所周知,在 MoE 层,对于每个 token,它会对所有的专家打分(算是喜爱程度吧),而且分数经过 softmax 后,总和为 1。

方法很简单,一句话:先人工设置一个超参数阈值,t,为 0.4 。对于每个 token, 把所有专家按分数从大到小排列,然后选择排名前几的专家,使这些专家分数总和大于 t,也就是 0.4,剩下的专家就不选了。于是这就实现了动态路由。

举个例子,假如有场考试,我们的目标是拿到分数超过 60 分及格就好,那么为了速通考试,我们只需要挑选分值最大的题目做,做到总分超过 60,就可以尽快离场了。如果有个题目分值超过 60 分,那么只做一道题就行,这就是 top-1 了。

这有个隐患,考虑极端情况,专家的分数是均匀分布的。如果 t 设置为 0.5,这意味着就需要选择一半的专家来计算。为了避免这种情况,文章增加了一个损失函数,优化目标是让专家概率尽可能大——变得极端。

2.3 发现

  • 在推理时,平均每个 token 激活的专家数量不超过 2 —— 应该损失函数的功劳吧。

  • 在下游任务上,效果居然还比 top-2 好 —— 我猜测或许是训练初期每个 token 选了很多专家(>2,来自 Figure 3),间接让每个专家多训练了。

  • 底层用到的专家更多,甚至会用 4 个,高层反而 1 个就够。

  • subtoken —— 那些 tokenize 之后的碎片 —— 需要的专家更多,还挺有趣,但不知道意味着什么。

62dc409d180b70bbdc8f9ad533fdfd85.png

XMoE

bfe6b0c0e60a9c57b6482031bc3e626d.png

论文地址:

https://arxiv.org/abs/2403.18926

代码地址: 

https://github.com/ysngki/XMoE

这篇文章,竟然,是上面两篇文章方法的并集。缘,妙不可言。但动机不同,分析也挺有趣。

3.1 动机

众所周知,FFN 可以写成 ,其中 是激活函数。

  • 以前的工作发现,当 relu 是激活函数时,输出的向量有 80% 的元素是 0,这意味着第二个矩阵乘法有严重的计算浪费。

  • 这个现象在 MoE 模型也存在,而且随着专家数量增大,浪费增加 —— 是不是有点像 deepseekmoe 的第一个动机。本文提出,参考以往工作,FFN 可以看成 memory network。浪费意味着有冗余的知识。类似于去图书馆,有很多没用的书。

  • 所以方法就是 缩小专家,通过拆分 。

  • 然而, 缩小专家之后,每个 token 选几个专家呢?多了浪费,少了性能下降。

  • 没错,方法就是上面的 基于阈值的路由。

3.2 分析

  • 缩的越小,效果越好,但是后面几乎没有增长。举个例子,缩小 8 倍时,只用先前一半的计算量,效果还更好。

  • 其实,dense 模型,也可以当做混合专家来训练。具体来说,可以把 dense 模型看成仅有一个 FFN 的 MoE 特例,然后拆成好几个小专家,训练时把阈值设置为 1—— 也就是选择所有专家才能满足——从而稠密训练。测试时可以调低阈值,实现稀疏计算。结果发现,又快又好。有趣,建议推广。

  • 拆的越小,relu,甚至 gelu 之后大于 0 的比例越大 —— 参数被更有效的利用了,符合动机。

  • 一味的缩小不可取。这是因为专家数量越多,路由上花的时间显著增加,路由模块的加速或许也必要。

碎碎念:如果专家继续缩小下去,就变成一个专家只有一个向量了,这很像 Large Memory Layers with Product Keys, 19 NIPS,需要特殊方法来加速路由过程。

碎碎念:顺带一提,Adaptive Gating in Mixture-of-Experts based Language Models, 23 EMNLP 也是做动态路由的,但是只支持 top-1 和 top-2 的切换。

1de2347666181f0b9fe9cec48dfd4a20.png

HyperMoE

458ed5b13b2de5057fae980595213400.png

论文地址:

https://arxiv.org/abs/2402.12656

代码地址: 

https://github.com/Bumble666/Hyper_MoE

4.1 动机

原文的动机是:1)token 选的专家越多越好好,但是为了效率,不能选多 -> 2)那就用没被选的专家,来帮助选了的专家 -> 3)这目的很像 multi-task learning 的 knowledge transfer -> 4)以前工作发现 hypernetworks 可以帮助 multi-task learning 的 knowledge transfer -> 5)所有我们把 moe 和 hypernetworks 结合起来。

碎碎念:咱不了解多任务学习,所以不好评价。就事论事,2)这一点还是挺有吸引力的。

简洁版本的动机是:让专家之间互帮互助,又不增加计算负担,这包括:没被选的专家也能帮助选了的专家,曰 cross-expert information

4.2 方法

首先介绍下 hypernetwork:它是用来生成神经网络参数——实际上就是矩阵——的神经网络——实际上也是矩阵。

本文在下游任务微调 Switch Transformer-base-8,每层有 8 个专家,top-1 路由。

对于每个输入的 token,除了让它选择的 top-1 的专家老老实实计算外,本文还新增了如下操作,具体如下:

防止在细节中迷失,这里给出一句话摘要:根据没用上的剩下 7 个专家,生成出 2 个矩阵,然后把 token 和这两个矩阵相乘,得到一个输出向量。

  1. 每层的每个专家都有一个相对应的 expert embedding,标记为 ,维度是 。因为每层有 8 个专家,所有 8 个 。这个 是随机初始化的。

  2. 对于每个 token,它会选择一个专家,这意味着剩下有 7 个专家没用。这 7 个专家的 相加,为了省事,相加得到的向量还是标记为 。

  3. 用一个双层 MLP,把 处理一下,变成 ,叫做 selection embedding。

  4. 每一层还有一个 layer embedding,标记为 ,维度是 。

  5. 把  和  拼在一起,然后,i)和一个大矩阵相乘,得到 W_1,维度是 ,ii)和另一个大矩阵相乘,得到 W_2,维度是 。

  6. 好的,终于最后一步了,把输入 token,标记为 ,进行 的操作。

好了,上面一长串得到的输出向量 和 top-1 专家的计算结果相加,结束了。第 5 步用到了两个大矩阵,就是 hypernetwork。

4.3 吐槽

作者为了不增加激活专家的数量,引入了好多多余的计算啊,有这工夫,为什么不之间变成 top-2 呢。论文没提供复杂度的分析,也没提供维度具体怎么设置的,这里也不分析了。

在最后一页的 Table 5,讨论了一下时间上的开销,对比的指标是每秒能推理多少个 sample,对比的只有两个模型,原始 top-1 moe,以及本文提出的 HyperMoE。具体来说,数量下降了 10% -- 15%。强烈建议增加对比 top-2!

0dbf514d5d2b7998caec8760cc2b601f.png

Expert SparsityPublic

f3d16aab26b62f904c0c5710bbd94b0d.png

论文地址:

https://arxiv.org/abs/2402.14800

代码地址: 

https://github.com/Lucky-Lance/Expert_Sparsity

5.1 动机

  • MoE 有很多专家,就算不用的话,那还是要占空间的。为了省空间,可以在部署前删掉!

  • MoE 的专家不是同样重要。不重要的在推理时跳过,这样推理速度更快。

5.2 方法

和动机相对应,由两个方法构成:1)expert pruning,2)dynamic expert skipping。注意,这两个方法都是 post-training,也就是说,拿个训练好的 MoE 模型过来,再使用这些方法来优化。

Expert Pruning:做法其实很简单

0)从 C4 这个预训练数据集挑一些数据,这里挑 128 个 sequence,每个长度 2048,

1)让模型把这个数据集全都前向传播一遍,保存中间每一层的所有 hidden states,

2)假设我们的目标是只保留 k 个专家,那么从第一个 moe 层开始,遍历所有 k 个专家的组合,只用这个 k 个专家进行计算,衡量和保存的 hidden states 的 Frobenius norm 距离。

3)选择距离最小的那 k 个专家,然后继续处理下一层。

Dynamic expert skipping:本文使用的模型是 Mixtral 8x7B,每层有 8 个专家,选择 top-2。skipping 的做法是,如果 第二名的专家分

5.3 效果

肯定是会下降的,看个人接受程度吧,散了散了。

99f8879041aec30e3486403cdfeeaaf4.png

MixLoRA

12ef19fb05a9857036d8e87c8c0144c9.png

论文地址:

https://arxiv.org/abs/2402.15896

6.1 动机

多模态多任务学习会有任务干扰(task interference),具体表现是梯度冲突 (gradient direction conflicts),即不同任务的 loss 函数对于同一块参数的 梯度优化方向不一致——最糟糕就是完全相反,那就抵消啦。通过多模态数据上的梯度冲突的分析,证明确实这样。

6.2 方法

用 moe 的方法 + lora。简单理解,就是 moe 的专家从 FFN 变成了 lora。下面是细节:

  • lora 本来是 两个小矩阵 A、B合成 一个大矩阵 W,即 W=BA。

  • 这里变成两个向量,a、b,通过外积合成出一个矩阵 W。

碎碎念:这种 vector 当做 moe 专家的做法,让我联想到了 Pushing Mixture of Experts to the Limit: Extremely Parameter Efficient MoE for Instruction Tuning, iclr 24,虽然记不太清了,隐约感觉挺像的。

0a9758429b7607673666bf13ca7a496b.png

ESFT

56486827dbda070247fe1265b975e802.png

论文地址:

https://arxiv.org/abs/2407.01906

代码地址: 

https://github.com/deepseek-ai/ESFT

又是一篇 DeepSeek 的工作。

7.1 动机

  1. 参数高效的微调 (PEFT)在 MoE 模型上还没有充分研究。

  2. 文章提出一种更适合 MoE 的微调方法。

7.2 方法

方法是基于如下的实验发现:

  • 那些使用了小专家的 MoE 模型(deepseek-moe, XMoE)的专家很分化。

  • 分化,即意味着不同任务使用的专家重叠度很低。

  • 因此不同的任务可以 finetune 不同的专家。

那么给定一个具体的任务,到底微调哪些专家呢?

  1. 从这个任务中随机选择若干个 sample,用来拼接出长度 4096 的 32 个新 sample。

  2. 把这 32 个 sample 送到 MoE 模型里前向传播,同时记录些信息,用来给每层的每个专家打分。(打分方式有两种,等会讲。)

  3. 根据打分,还有一个超参数 threshold,选择分数最高的那些专家,使得这些专家的打分之和大于 threshold。(熟悉的感觉)

  4. 只微调这些专家的参数,其他固定不变 —— 个人理解,即便某个专家被激活了,但如果不在微调的专家列表里,就不会被梯度传播。

碎碎念:是不是很直观。有点像上面的剪枝论文。

剩下的细节就是打分的方法了。

1)对于某个专家,token 选择了这个专家的比例,作为分数。举个栗子,有 4096 个 token,每个 token 选 4 个专家,假如有 2048 个 token 选择过专家 1,那么专家 1 的分数就是 2048 /(4096 * 4)。

2)对于某个专家,选择了它的那些 token 给它打的分数的总和,作为分数。举个栗子,有两个 token 选了专家 1,分数分别是 0.1, 0.08,那么这个专家的分数就是 0.1 + 0.08 啦。

总之,每个打分方法,都要保证所有专家的分数总和加起来是 1。(所有方法 2 给的例子不太精确,理解万岁。)

实验结果显示,两种方法在不同数据上各有各的好。

碎碎念:论文给第一种方法设置的阈值是 0.2, 第二种是 0.1。喂,这是不是也太小了啊。但是论文说,“The average number of experts used per task across layers ranges from 2 to 15 out of 66”,所以说,即便阈值只有 0.1,也需要至少 2 个专家才能达到?路由模块的置信度这么低?

7.3 实验

比较对象是 全参数微调 FFT 和 LoRA。本文的方法标记为 ESFT。

训练效率上:LoRA (16.5分钟)> ESFT (19.8分钟)> FFT (28.5 分钟)

性能效率上:FFT > ESFT > LoRA 。(有的场景下 ESFT 还能更好,咱倒也不是不能理解。)

总的来说,如果代码好实现的话,也不是不能用啦。

碎碎念:有一说一,如果用上 论文 2,3 的基于阈值的路由的话,本身路由模块已经进行了专家的相关度的筛选。是不是可以考虑结合一下呢?

更多阅读

ada54d77299392fbda7397910e2cce27.png

bd64e66196271c3139a4aa470db908cb.png

d57743ba15e3e855dcae0ae868537cd4.png

2d3ad744c2109ddf21ea77c8e128595f.gif

#投 稿 通 道#

 让你的文字被更多人看到 

如何才能让更多的优质内容以更短路径到达读者群体,缩短读者寻找优质内容的成本呢?答案就是:你不认识的人。

总有一些你不认识的人,知道你想知道的东西。PaperWeekly 或许可以成为一座桥梁,促使不同背景、不同方向的学者和学术灵感相互碰撞,迸发出更多的可能性。 

PaperWeekly 鼓励高校实验室或个人,在我们的平台上分享各类优质内容,可以是最新论文解读,也可以是学术热点剖析科研心得竞赛经验讲解等。我们的目的只有一个,让知识真正流动起来。

📝 稿件基本要求:

• 文章确系个人原创作品,未曾在公开渠道发表,如为其他平台已发表或待发表的文章,请明确标注 

• 稿件建议以 markdown 格式撰写,文中配图以附件形式发送,要求图片清晰,无版权问题

• PaperWeekly 尊重原作者署名权,并将为每篇被采纳的原创首发稿件,提供业内具有竞争力稿酬,具体依据文章阅读量和文章质量阶梯制结算

📬 投稿通道:

• 投稿邮箱:hr@paperweekly.site 

• 来稿请备注即时联系方式(微信),以便我们在稿件选用的第一时间联系作者

• 您也可以直接添加小编微信(pwbot02)快速投稿,备注:姓名-投稿

253cc0be3a42bd6183c7151d9702e518.png

△长按添加PaperWeekly小编

🔍

现在,在「知乎」也能找到我们了

进入知乎首页搜索「PaperWeekly」

点击「关注」订阅我们的专栏吧

·

·

·

861a98197958ed94963faf5020b3aaf2.jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值