1.Adapter Tuning
1.背景
2019年谷歌的研究人员首次在论文《Parameter-Efficient Transfer Learning for NLP》提出针对 BERT 的 PEFT微调方式,拉开了 PEFT 研究的序幕。他们指出,在面对特定的下游任务时,如果进行 Full-Fintuning(即预训练模型中的所有参数都进行微调),太过低效;而如果采用固定预训练模型的某些层,只微调接近下游任务的那几层参数,又难以达到较好的效果。
2.技术原理
于是他们设计了如下图所示的 Adapter 结构,将其嵌入 Transformer 的结构里面,在训练时,固定住原来预训练模型的参数不变,只对新增的 Adapter 结构进行微调。同时为了保证训练的高效性(也就是尽可能少的引入更多参数),他们将 Adapter 设计为这样的结构:
在预训练模型每一层(或某些层)中添加 Adapter 模块(如上图左侧结构所示),微调时冻结预训练模型主体,由 Adapter 模块学习特定下游任务的知识。
每个 Adapter 模块由两个前馈(Feedforward)子层组成,第一个前馈(down-project)子层将 Transformer 块的输出作为输入,将原始输入维度 d(高维特征) 投影到 m(低维特征),通过控制 m 的大小来限制 Adapter 模块的参数量,通常情况下 m<<d。中间通过一个非线形层。
在输出阶段,通过第二个前馈(up-project)子层还原输入维度,将 m (低维特征)重新投影到 d(原来的高维特征),作为 Adapter 模块的输出(如上图右侧结构)。同时,通过一个skip connection来将Adapter的输入重新加到最终的输出中去,这样可以保证,即便 Adapter 一开始的参数初始化接近0,Adapter也由于skip connection的设置而接近于一个恒等映射,从而确保训练的有效性。
通过添加 Adapter 模块来产生一个易于扩展的下游模型,每当出现新的下游任务,通过添加 Adapter 模块来避免全模型微调与灾难性遗忘的问题。Adapter 方法不需要微调预训练模型的全部参数,通过引入少量针对特定任务的参数,来存储有关该任务的知识,降低对模型微调的算力要求。
通过实验发现,只训练少量参数的Adapter方法的效果可以媲美全量微调,这也验证了Adapter是一种高效的参数训练方法,可以快速将语言模型的能力迁移到下游任务中去。同时,可以看到,Adapter 最佳的中间层特征维度m视数据集的大小而异,如:MINI数据集为256,最小的RTE数据集为8。如果始终将维度限制在64,将导致平均准确率略微下降。
从实验结果来看,该方法能够在只额外对增加的 3.6% 参数规模(相比原来预训练模型的参数量)的情况下取得和Full-Finetuning 接近的效果(GLUE指标在0.4%以内)。
2. AdapterFusion
1.背景
为了整合来自多个任务的知识,并且避免模型遗忘之前任务学到的知识。想要把来自多个任务的知识结合起来,是否可以考虑把多个任务的Adapter的参数结合起来?基于此,作者提出了 AdapterFusion,这是一种新的两阶段学习算法,可以利用来自多个任务的知识。
2020 年,Pfeiffer J 等人对 Adapter 进行改进,提出了AdapterFusion 算法,用以实现多个 Adapter 模块间的最大化任务迁移《AdapterFusion: Non-Destructive Task Composition for Transfer Learning》https://arxiv.org/abs/2005.00247。
2.技术原理
其模型结构如下图所示:
AdapterFusion 将学习过程分为两个阶段:
1.知识提取阶段:训练 Adapter 模块学习下游任务的特定知识,将知识封装在 Adapter 模块参数中。
2.知识组合阶段:将预训练模型参数与特定于任务的 Adapter 参数固定,引入新参数学习组合多个 Adapter 中的知识,提高模型在目标任务中的表现。
在知识提取阶段有两种训练方式:
1.Single-Task Adapters(ST-A):对于N个任务,模型都分别独立进行优化,各个任务之间互不干扰,互不影响。
2.Multi-Task Adapters(MT-A):N个任务通过多任务学习的方式,进行联合优化。
在知识组合阶段阶段,为了避免通过引入特定任务参数而带来的灾难性遗忘问题,AdapterFusion提出了一个共享多任务信息的结构。对于 N 的不同的下游任务训练 N 个 Adapter 模块,使用 AdapterFusion 组合 N 个适配器中的知识,将预训练参数 Θ 和全部的 Adapter 参数 Φ 固定,引入新的参数 Ψ,使用 N 个下游任务的数据集训练,让 AdapterFusion 学习如何组合 N 个适配器解决特定任务。
AdapterFusion具体结构就是一个Attention,参数 Ψ 在每一层中包含 Key、Value 和 Query。它的query是transformer每个子模块的输出结果,它的key跟value则是N个任务的adapter的输出。通过AdapterFusion,模型可以为不同的任务对应的adapter分配不同的权重,聚合N个任务的信息,从而为特定任务输出更合适的结果。
在给定的上下文中,AdapterFusion 学习经过训练的适配器的参数混合,根据给定的输入识别和激活最有用的适配器。通过将适配器的训练分为知识提取和知识组合两部分,解决了灾难性遗忘、任务间干扰和训练不稳定的问题。Adapter 模块的添加也导致模型整体参数量的增加,降低了模型推理时的性能。
Adapter Fusion 在 Adapter 的基础上进行优化,通过将学习过程分为两阶段来提升下游任务表现。作者对全模型微调(Full)、Adapter、AdapterFusion 三种方法在各个数据集上进行和对比试验。AdapterFusion 在大多数情况下性能优于全模型微调和 Adapter,特别在 MRPC(相似性和释义任务数据集)与 RTE(识别文本蕴含数据集)中性能显著优于另外两种方法。
通过将适配器的训练分为知识提取和知识组合两部分,解决了灾难性遗忘、任务间干扰和训练不稳定的问题。但是,Adapter模块的添加也导致模型整体参数量的增加,降低了模型推理时的性能。
3.AdapterDrop
1.背景
Adapter的计算效率与全量微调相比,Adapter在训练时快60%,但是在推理时慢4%-6%。基于此,作者提出了AdapterDrop方法缓解该问题。
2.技术原理
AdapterDrop(论文:AdapterDrop: On the Efficiency of Adapters in Transformers),在不影响任务性能的情况下,对Adapter动态高效的移除,尽可能的减少模型的参数量,提高模型在反向传播(训练)和正向传播(推理)时的效率。
实验表明,从较低的 Transformer 层中删除Adapter可以显着提高多任务设置中的推理速度。 例如,将前五个Transformer层中的Adapter丢弃,在对 8 个任务进行推理时,速度提高了 39%。并且即使有多个丢弃层,AdapterDrop 也能保持良好的结果。
除此之外,作者还研究了对 AdapterFusion中的Adapter进行剪枝后的效果。
通过实验表明可以移除 AdapterFusion 中的大多数Adapter而不影响任务性能。使用剩余的两个Adapter,实现了与具有八个Adapter的完整 AdapterFusion 模型相当的结果,并将推理速度提高了 68%。 因此,作者建议在实际部署这些模型之前执行 AdaperFusion 剪枝。 这是一种简单而有效的技术,即使在完全保持性能的情况下也能实现效率提升。
总之,AdapterDrop 通过从较低的 Transformer 层删除可变数量的Adaper来提升推理速度。 当对多个任务执行推理时,动态地减少了运行时的计算开销,并在很大程度上保持了任务性能。