随着预训练模型的参数越来越大,尤其是175B参数大小的GPT3发布以来,让很多中小公司和个人研究员对于大模型的全量微调望而却步,近年来研究者们提出了各种各样的参数高效迁移学习方法(Parameter-efficient Transfer Learning),即固定住Pretrain Language model(PLM)的大部分参数,仅调整模型的一小部分参数来达到与全部参数的微调接近的效果(调整的可以是模型自有的参数,也可以是额外加入的一些参数)。本文将介绍一些常见的参数高效微调技术,比如:BitFit、Prefix Tuning、Prompt Tuning、P-Tuning、P-Tuning v2、Adapter Tuning及其变体、LoRA、AdaLoRA、QLoRA、MAM Adapter、UniPELT等。
推荐阅读列表:
大模型PEFT技术原理(一):BitFit、Prefix Tuning、Prompt Tuning
大模型PEFT技术原理(二):P-Tuning、P-Tuning v2
6、Adapter Tuning
论文地址:https://arxiv.org/pdf/2106.09685.pdf
代码地址:https://github.com/google-research/adapter-bert
Finetune是NLP中一种有效的迁移机制,然而,该方法需要为每个任务适配一个全新的模型,参数效率比较低。在ChatGPT大模型时代,模型的微调更加不太现实。之前提到的Prefix Tuning、P-Tuning等方法是在Transformer每一层中增加参数量,可以看做是对Transformer的横向扩展,本文提出的Adapter Tuning是对Transformer的纵向扩展,最早是在2019年提出的。
Adapter模块产生一个紧凑且可扩展的模型,只为每个任务添加几个可训练参数,并且可以添加新任务而无需重新访问以前的任务,原始网络的参数保持固定。为了证明Adapter的有效性,论文将最近提出的 BERT Transformer 模型转移到 26 个不同的文本分类任务,包括 GLUE 基准测试。适配器获得了接近最先进的性能,同时每个任务只添加了几个参数。在 GLUE 上获得了完全微调性能的 0.4% 以内损失的结果(那看来还是没有finetine来的猛。),每个任务仅添加 3.6% 的参数。相比之下,finetune为每个任务训练 100% 的参数。
图1显示了 GLUE 基准测试中九个任务的第 20、50 和 80 个性能百分位数。Adapterbased tuning 获得了与 full fine-tuning 相似的性能,训练参数少了两个数量级。
如图2所示,Adapter Tuning针对每一个Transformer层,增加了两个Adapter结构(分别是多头注意力的投影之后和第二个feed-forward层之后),在训练时,固定住原来预训练模型的参数不变,只对新增的 Adapter 结构和 Layer Norm 层进行微调,从而保证了训练的高效性。每个 Adapter 模块主要由两个前馈(Feedforward)子层组成,第一个前馈子层(down-project)将Transformer块的输出作为输入,将原始输入维度d(高维特征)投影到m(低维特征),通过控制m的大小来限制Adapter模块的参数量,通常情况下,m<<d。然后,中间通过一个非线形层。在输出阶段,通过第二个前馈子层(up-project)还原输入维度,将m(低维特征)重新映射回d(原来的高维特征),作为Adapter模块的输出。同时,通过一个skip connection来将Adapter的输入重新加到最终的输出中去,这样可以保证,即便 Adapter 一开始的参数初始化接近0,Adapter也由于skip connection的设置而接近于一个恒等映射,从而确保训练的有效性。
7、AdapterFusion
论文地址:https://arxiv.org/pdf/2005.00247v3.pdf
代码地址:https://github.com/Adapter-Hub/adapter-transformers/blob/master/notebooks/03_Adapter_Fusion.ipynb
Adapter Tuning已经在单任务中微调少量参数可以匹敌全量微调参数的效果,那么有可能应用到多任务中吗?作者提出了AdapterFusion,这是一种新的两阶段学习算法,可以利用来自多个任务的知识,具体如下:
- 知识提取阶段:在不同任务下引入各自的Adapter模块,用于学习特定任务的信息。
- 知识组合阶段:将预训练模型参数与特定于任务的Adapter参数固定,引入新参数(AdapterFusion)来学习组合多个Adapter中的知识,以提高模型在目标任务中的表现。
对于第一阶段,有两种训练方式,分别如下:
- Single-Task Adapters(ST-A):对于多任务,模型分别独立优化各个任务,他们之间互不干扰,互不影响。
- Multi-Task Adapters(MT-A):采用多任务学习的方式进行联合优化。
对于第二阶段,为了避免通过引入特定任务参数而带来的灾难性遗忘问题,AdapterFusion提出了一个共享多任务信息的结构。针对特定任务m,AdapterFusion联合了第一阶段训练得到的N个Adapter信息。固定语言模型的参数跟N个Adapter的参数,新引入AdapterFusion的参数,目标函数也是学习针对特定任务m的AdapterFusion的参数。
AdapterFusion在Transformer中的位置如图1所示,AdapterFusion具体结构如图2所示,本质就是一个Attention,参数包括query,key, value的矩阵参数,应用在transformer的每一层,query是transformer每个子模块的输出结果,key和value来自则是N个任务的adapter的输出。模型为不同的任务对应的adapter分配不同的权重,聚合N个任务的信息,从而为特定任务输出更合适的结果。
实验结果,从表1可以看到第一阶段采用ST-A+第二阶段adapter fusion是最有效的方法,在多个数据集上的平均效果达到了最佳。关于MT-A+adapter fusion没有取得最佳的效果,在于第一阶段其实已经联合了多个任务的信息了,所以adapter fusion的作用没有那么明显,同时MT-A这种多任务联合训练的方式需要投入较多的成本,并不算一种高效的参数更新方式。另外,ST-A的方法在多个任务上都有提升,但是MT-A的方法则不然,这也表明了MT-A虽然可以学习到一个通用的表征,但是由于不同任务的差异性,很难保证在所有任务上都取得最优的效果。
AdapterFusion是一种高效的参数更新方式,能在引入少量参数,只训练少量参数的情况下达到媲美finetune全模型参数的效果,只训练少量参数也意味着对训练数据量更低的要求以及更快的训练速度,是一种将大规模预训练语言模型能力迁移到下游任务的高效方案,跟目前火热的prompt learning有异曲同工之妙。而AdapterFusion则跟MOE很像,可以联合多个任务的信息,从而提升特定任务的性能。但相比于其他的parameter-efficient的方法,AdapterFusion是在原语言模型上加入了新的模块,在推理时会进一步增加延迟。
8、AdapterDrop
论文地址:https://arxiv.org/pdf/2010.11918v1.pdf
代码地址:https://github.com/Adapter-Hub/adapter-transformers
之前介绍的Adapter和AdapterFusion实验效果可以匹敌FineTune的效果,虽然比FineTune的训练快,但是会增加推理延时。本论文在两种不同的GPU上测量了上述两种模型结构,发现Adapter的训练比整个模型微调快60%左右,推理会比原始模型慢4-6%。
AdapterDrop
为了加快推理速度,在推理时可以对某几层的 adapter 进行剪枝。作者提出推理时可以剪掉最靠近输入的前 n 层。为了尽可能地减小掉点,作者设计了两种训练方案:(1)specialized AdapterDrop:训练时固定 n,训练后的模型推理时也固定剪掉前 n 层;(2)robust AdapterDrop:训练时每个 batch 都随机选取 n 的大小,训练后的模型可以适应多个 n。由于原有模型其他参数是不训练的,在训练时梯度就可以只回传到保留 adapter 的最早一层即可,如下图1所示:
对 AdapterFusion 进行剪枝
作者首先测量了 AdapterFusion(AF) 的训练和推理时间,发现和原模型整体微调和推理相比,每层 8 个adapter 的 AF 的训练速度大约慢 47%,推理速度大约慢 62%,主要是因为 adapter 需要逐个推理。作者用 8 个 GLUE 的任务(去除 WNLI)训练了一个 AF 模型,在上面实验了两种加速 AdapterFusion 的思路:
-
去除掉前几个 AF 层,对性能的影响不同的任务有所不同。例如对 RTE 的影响不大,但是 CoLA 十分敏感。这说明直接去除 AF 层并不是一个通用的好方法。
-
剪掉每层中对输出贡献较小的 adapter。作者用训练集测量了每个 adapter 的平均激活水平(应该是加权之后的输出),每层只保留两个贡献最高的 adapter,模型的性能和原来基本持平,推理速度可以提高 68%。