概述与配置
近年来,基于Transformer架构的大型预训练语言模型(LMs)已成为自然语言处理(NLP)的基础。虽然最流行的迁移学习方法是对所有模型参数进行昂贵的全量微调,但最近出现了一系列高效且轻量级的替代方案。这些方法通常不更新预训练语言模型的所有参数来适应下游目标任务,而是引入少量新参数,仅更新这些新参数,同时保持预训练模型权重不变。
为何使用高效微调?
相比对语言模型进行完全微调,高效的微调方法具有多重优势:
它们是参数高效的,即仅更新模型参数的极小部分(通常低于1%)。
它们通常是模块化的,即更新后的参数可以独立于基础模型参数被提取和共享。
由于它们的文件体积小,例如每个任务仅需约3MB而非共享完整模型所需的约440MB,因此易于分享和部署。
它们加速训练,即高效微调通常比完全微调语言模型需要更少的训练时间。
它们是可组合的,例如,在不同任务上训练得到的多个适配器可以堆叠、融合或混合使用,以利用它们的综合知识。
它们通常提供与完全微调相当的性能。
更具体地说,假设语言模型的参数由一组预训练参数\(\Theta\)(冻结)和一组(新引入的)参数\(\Phi\)组成。 那么,高效微调方法仅根据数据集\(D\)上的损失函数\(L\)来优化\(\Phi\):
高效微调可能会在基于Transformer的语言模型的不同位置插入参数\(\Phi\)。早期且成功的方法之一(瓶颈适配器)在Transformer模型的每一层引入了瓶颈前馈层。虽然这些适配器为adapters库奠定了基础,但此后已引入并集成了多种替代方法。
重要
在文献中,不同术语被用来指代高效微调方法。"适配器"一词通常仅应用于瓶颈适配器模块。然而,大多数高效微调方法都遵循相同的基本思路:插入一小部分新参数,从而"调整"预训练语言模型以适应新任务。在adapters中,若无特别说明,"适配器"一词可以泛指任何高效微调方法。
在接下来的章节中,我们将介绍如何在adapters中配置适配器方法。随后的两页将详细介绍当前支持的所有适配器方法的技术细节。
适配器方法列表
下表概述了adapters支持的所有适配器方法。
标识符和配置类的详细说明请参阅下一节。
| 标识符 | 配置类 | 更多信息 |
|---|---|---|
seq_bn |
SeqBnConfig() |
Bottleneck Adapters |
double_seq_bn |
DoubleSeqBnConfig() |
Bottleneck Adapters |
par_bn |
ParBnConfig() |
Bottleneck Adapters |
scaled_par_bn |
ParBnConfig(scaling="learned") |
Bottleneck Adapters |
seq_bn_inv |
SeqBnInvConfig() |
Invertible Adapters |
double_seq_bn_inv |
DoubleSeqBnInvConfig() |
Invertible Adapters |
compacter |
CompacterConfig() |
Compacter |
compacter++ |
CompacterPlusPlusConfig() |
Compacter |
prefix_tuning |
PrefixTuningConfig() |
Prefix Tuning |
prefix_tuning_flat |
PrefixTuningConfig(flat=True) |
Prefix Tuning |
lora |
LoRAConfig() |
LoRA |
vera |
VeraConfig() |
Vera |
ia3 |
IA3Config() |
IA³ |
mam |
MAMConfig() |
Mix-and-Match Adapters |
unipelt |
UniPELTConfig() |
UniPELT |
prompt_tuning |
PromptTuningConfig() |
Prompt Tuning |
loreft |
LoReftConfig() |
ReFT |
noreft |
NoReftConfig() |
ReFT |
direft |
DiReftConfig() |
ReFT |
配置
所有支持的适配器方法都可以使用同一组模型类函数进行添加、训练、保存和共享(参见类文档)。
每种方法都通过特定的配置类进行指定和配置,这些配置类都派生自通用的AdapterConfig类。
例如,将支持的适配器方法之一添加到现有模型实例遵循以下方案:
model.add_adapter("name", config=<ADAPTER_CONFIG>)
这里, 可以是以下两种之一:
配置字符串,如下所述
配置类的一个实例,如上表所列
指向包含配置字典的JSON文件的路径
配置字符串
配置字符串是一种定义特定适配器方法配置的简洁方式。当适配器配置来自外部来源(如命令行)且无法使用配置类时,它们特别有用。
通常,单个方法的配置字符串格式为。
其中,指代上表中列出的某个标识符,例如par_bn。
在标识符后的方括号内,您可以设置对应配置类中的特定属性,例如par_bn[reduction_factor=2]。
如果所有属性都保持默认值,则可以省略这部分内容。
最后,也可以通过使用|连接多个配置字符串,将方法组合指定为配置字符串,例如:
config = "prefix_tuning[bottleneck_size=800]|parallel"
等同于以下 ConfigUnion:
config = ConfigUnion(
PrefixTuningConfig(bottleneck_size=800),
ParBnConfig(),
)