Posted in

从 ACL 2024 录用论文看混合专家模型(MoE)最新研究进展_AI阅读总结 — 包阅AI

包阅导读总结

1. 混合专家模型、ACL 2024、研究进展、方法、动机

2. 本文介绍了 ACL 2024 中混合专家模型(MoE)的最新研究进展,包括相关论文的动机、方法和有趣发现,涵盖增加专家数量、动态路由、共享专家等方法,以及为提高效率和性能所做的各种探索。

3.

– 总体介绍

– ACL 2024 中关于混合专家模型的论文梳理

– 具体论文

– DeepSeekMoE

– 动机:专家不够分化和有冗余

– 方法:增加专家数量、拆分专家

– 现象:特定参数下性能出色,比其他模型激活更少参数有更好性能

– Harder Tasks Need More Experts

– 动机:简单任务和复杂任务所需专家数量不同

– 方法:基于阈值的动态路由

– 发现:推理时平均每个token激活专家数量不超2,下游任务效果好

– XMoE

– 动机:FFN存在计算浪费和冗余知识

– 分析:缩小专家效果、稠密训练和稀疏计算

– HyperMoE

– 动机:让专家互帮互助且不增加计算负担

– 方法:利用未选专家生成矩阵辅助计算

– Not All Experts are Equal

– 动机:节省空间和提高推理速度

– 方法:expert pruning 和 dynamic expert skipping

– 其他

– 多模态多任务学习存在任务干扰

– 专家分化可针对不同任务微调不同专家

思维导图:

文章地址:https://mp.weixin.qq.com/s/SXsG7B42q2hruNo7myzL2Q

文章来源:mp.weixin.qq.com

作者:大模型智能

发布时间:2024/8/14 15:16

语言:中文

总字数:5225字

预计阅读时间:21分钟

评分:88分

标签:混合专家模型(MoE),专家分化,动态路由,参数效率,大语言模型


以下为原文内容

本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com

最近 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

https://arxiv.org/abs/2401.06066
https://github.com/deepseek-ai/DeepSeek-MoE
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 比,拆分专家可以使得模型激活更少的参数取得更好的性能。

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 之后的碎片 —— 需要的专家更多,还挺有趣,但不知道意味着什么。
https://arxiv.org/abs/2403.18926
https://github.com/ysngki/XMoE
这篇文章,竟然,是上面两篇文章方法的并集。缘,妙不可言。但动机不同,分析也挺有趣。

3.1 动机

  • 以前的工作发现,当 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 的切换。

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!
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 模型过来,再使用这些方法来优化。
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 效果

https://arxiv.org/abs/2402.15896
多模态多任务学习会有任务干扰(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,虽然记不太清了,隐约感觉挺像的。

https://arxiv.org/abs/2407.01906
https://github.com/deepseek-ai/ESFT

7.1 动机

  1. 参数高效的微调 (PEFT)在 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 的基于阈值的路由的话,本身路由模块已经进行了专家的相关度的筛选。是不是可以考虑结合一下呢?

扫描二维码添加小助手微信