OpenDelta:轻松搞定大模型参数高效微调

作者:丁宁
2022-04-07 00:03:02

近年来预训练语言模型 (PLM) 已成为众多自然语言处理(NLP)任务的基础架构,研究表明更大的模型往往会带来更好的性能。然而,如果微调大模型的所有参数并存储,大规模PLM也会带来计算和存储成本过高的挑战,而且在多任务场景下还需要维护多份大模型版本。因此,相比于全参数微调,参数高效的微调方法(Parameter-Efficient Tuning)在近期受到了广泛的关注,它只调整一小部分参数,并且保持绝大部分参数不动,却能实现与全模型微调相当甚至更好的性能。由于其中被调整的参数只占大模型参数的极小部分,可以类比于一个很小的增量(delta),因此我们将这类方法称为“Delta Tuning”。现有的Delta Tuning方法包括Prefix Tuning, Soft Prompt, Adapter, BitFit, LoRA等等,这些探索为用极少代价驱动大模型打下了坚实的基础。

为了方便学术界和产业界更好地探索和使用Delta Tuning,我们研发了这款即插即用型的Delta Tuning工具包OpenDelta,只需要增加3行代码,就能够将已有全模型微调代码迁移到Delta Tuning框架下,而无需改变原有模型包(例如Huggingface Transformers) 的代码。




OpenDelta和OpenPrompt协同驱动大模型


本工具包是THUNLP实验室继OpenPrompt工具包后,在大模型高效计算应用方面的进一步探索。通过Prompt Learning,研究者可以将各类任务的输入和输出方式改造成预训练中Mask Language Modeling的形式,从而更有效地发挥预训练大模型的能力;而进一步通过Delta Tuning,研究者可以仅用极小的存储成本学习任务相关的增量参数(Delta Object),与大模型协同完成各类下游任务。OpenDelta可以基于现成训练脚本,轻松地完成全参数微调到Delta Tuning的改变,还支持与OpenPrompt联合使用,驱动大模型高效微调和推理。

总之,OpenDelta既可以用在现成训练脚本上,轻松地完成全参数微调到Delta Tuning的改变,又可以和OpenPrompt联合使用,有效地结合以构建驱动大模型的完整pipeline。


设计思路


大模型参数高效微调作为新兴的研究方向,在具体实现上仍然面临一些挑战。以AdapterHub工具包为例,此工具包通过拷贝Huggingface Transformers模型代码并插入相应的接口来实现Adapters方法,在推广高效微调和共享微调模型上做出了先锋贡献。但是随着这个领域的快速发展,这些工具包呈现了一些兼容性、泛用性、灵活性等方面的不足。为了更好地体现Delta Tuning的思想,支持更多参数高效微调方法的探索,OpenDelta秉承了以下设计思路:

便捷:无需编辑现有预训练模型的代码,例如支持直接从Huggingface Transformers框架导入主干预训练模型,无需为了使用OpenDelta更换预训练仓库;

简洁:对于用户的全参数微调训练脚本,仅需增加3行代码即可迁移到Delta Tuning;

可持续:大多数预训练模型库的发展可以被OpenDelta支持,例如在训练中使用半精度训练库后,OpenDelta仍可正常使用;

可扩展:不同的预训练模型可以共享相同的OpenDelta代码,使用者可以轻松将Delta Tuning部署到各类不同模型中;

灵活:可以将Delta Tuning应用到预训练模型内的各个位置,例如可以指定部分层数加Adapter以实现AdapterDrop模型,亦或是同时使用Prefix Tuning和LoRA以提升性能;

明晰提供方便的模型参数可视化功能,可以清楚地观察到使用Delta Tuning后可调参数的位置和数量。


基本使用方法


1、工具包安装

OpenDelta可以通过pip安装,

pip install opendelta


也可以从github进行源码安装。

git clone https://github.com/thunlp/OpenDelta.git


2、载入预训练模型


全参数微调脚本中会载入一个预训练模型。下面用BART举例,载入模型后可视化其网络结构如下。模型的内部结构通过树结构展示,所有的参数信息被标在模块后方。其中红色是因重复而折叠的模块,蓝色高亮的参数全部可调;

from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained("facebook/bart-base")





3、定义Delta Tuning


以下三行代码足以完成从全参数微调到Delta Tuning的转变。

从opendelta中导入AdapterModel


from opendelta import AdapterModel


可以看到bart-base中全连接层的命名为fc1和fc2, 若要在其后加入adapter模块, 只需指定modified_modules = ['fc2']。其他超参数例如adapter的中间维度也可以方便地指定。


delta_model = AdapterModel(backbone_model=model, modified_modules=['fc2'], bottleneck_dim=12)


加完adapter模块后,通过freeze_module来固定绝大部分参数,例如仅仅将adapter和layernorm中的参数设置为可调。

delta_model.freeze_module(exclude=["deltas", "layernorm_embedding"], set_state_dict=True)


4、可视化操作

修改完成后,可以通过可视化修改过程,来确定修改符合预期。

delta_model.log()

从下面的动图中可以看出,BART原模型的结构中被插入了adapter,随后大部分参数被固定。结构图中,灰色(录屏呈现藏青色)的是固定参数,蓝色(录屏呈现灰绿色)的是可调参数,紫色的是Delta Object中的参数(同样可调)。



参考文献

1. Houlsby, Neil, et al. Parameter-efficient transfer learning for NLP. ICML, PMLR, 2019.

2. Hu E J, Shen Y, Wallis P, et al. Lora: Low-rank adaptation of large language models[J]. arXiv preprint arXiv:2106.09685, 2021.

3. Li, Xiang Lisa, and Percy Liang. Prefix-tuning: Optimizing continuous prompts for generation. arXiv preprint arXiv:2101.00190 (2021).

4. Lester, Brian, Rami Al-Rfou, and Noah Constant. "The power of scale for parameter-efficient prompt tuning." EMNLP, 2021.

5. Lester, Brian, Rami Al-Rfou, and Noah Constant. "The power of scale for parameter-efficient prompt tuning." EMNLP, 2021.

6. Mahabadi, Rabeeh Karimi, James Henderson, and Sebastian Ruder. Compacter: Efficient low-rank hypercomplex adapter layers. arXiv preprint arXiv:2106.04647, 2021.

7. Han, Wenjuan, Bo Pang, and Yingnian Wu. Robust transfer learning with pretrained language models through adapters. arXiv preprint arXiv:2108.02340, 2021.

8. Guo, Demi, Alexander M. Rush, and Yoon Kim. Parameter-efficient transfer learning with diff pruning. arXiv preprint arXiv:2012.07463, 2020.

9. Ding, Ning, et al. Openprompt: An open-source framework for prompt-learning. arXiv preprint arXiv:2111.01998, 2021.

10. Rücklé, Andreas, et al. Adapterdrop: On the efficiency of adapters in transformers. arXiv preprint arXiv:2010.11918, 2020.