PEFT 文档
适配器
并获得增强的文档体验
开始入门
适配器
基于适配器的方法在冻结的预训练模型的注意力层和全连接层之后添加额外的可训练参数,以减少内存使用并加速训练。该方法根据适配器的不同而有所不同,它可以只是一个额外添加的层,也可以是将权重更新 ∆W 表示为权重矩阵的低秩分解。无论哪种方式,适配器通常都很小,但表现出与完全微调模型相当的性能,并能够使用更少的资源训练更大的模型。
本指南将简要概述 PEFT 支持的适配器方法(如果您有兴趣了解特定方法的更多细节,请查看链接的论文)。
低秩自适应 (LoRA)
LoRA 是最流行的 PEFT 方法之一,如果您刚开始使用 PEFT,这是一个很好的起点。它最初是为大型语言模型开发的,但由于其效率和有效性,它已成为扩散模型非常流行的训练方法。
如前所述,LoRA 是一种加速大型模型微调同时减少内存消耗的技术。
LoRA 通过低秩分解,用两个较小的矩阵(称为更新矩阵)表示权重更新 ∆W。这些新矩阵可以被训练以适应新数据,同时保持参数总数较低。原始权重矩阵保持冻结,不再接收任何进一步的更新。为了产生最终结果,原始权重和额外适配的权重被组合在一起。您也可以将适配器权重与基础模型合并,以消除推理延迟。

这种方法有许多优点
- LoRA 通过大幅减少可训练参数的数量,使微调更加高效。
- 原始的预训练权重保持冻结,这意味着您可以拥有多个轻量级和可移植的 LoRA 模型,用于构建在其之上的各种下游任务。
- LoRA 与其他参数高效的方法正交,可以与许多方法结合使用。
- 使用 LoRA 微调的模型的性能与完全微调模型的性能相当。
原则上,LoRA 可以应用于神经网络中权重矩阵的任何子集,以减少可训练参数的数量。然而,为了简单性和进一步的参数效率,LoRA 通常仅应用于 Transformer 模型中的注意力块。LoRA 模型中可训练参数的最终数量取决于更新矩阵的大小,这主要由秩 r
和原始权重矩阵的形状决定。

LoRA 专家混合 (X-LoRA)
X-LoRA 是一种 LoRA 的专家混合方法,它通过使用密集或稀疏门控来动态激活 LoRA 专家。LoRA 专家和基础模型在训练期间都被冻结,从而产生低参数计数,因为只有门控层必须被训练。特别是,门控层输出的缩放比例(取决于配置)在层和令牌级别上是细粒度的。此外,在推理期间,X-LoRA 动态激活 LoRA 适配器以回忆知识并有效地混合它们
下图演示了每个令牌的不同提示的缩放比例如何变化。这突出了随着生成过程的进行和序列创建新的上下文,不同适配器的激活。
对于每个步骤,X-LoRA 需要基础模型运行两次:首先,获取没有任何 LoRA 适配器的隐藏状态,其次,隐藏状态用于计算应用于 LoRA 适配器的缩放比例,并且模型第二次运行。第二次运行的输出是模型步骤的结果。
最终,由于双重前向传递方案,X-LoRA 允许模型反思其知识,并动态地重新配置架构。
低秩 Hadamard 积 (LoHa)
低秩分解可能会影响性能,因为权重更新被限制在低秩空间中,这可能会限制模型的表达能力。但是,您不一定想使用更大的秩,因为它会增加可训练参数的数量。为了解决这个问题,LoHa(最初为计算机视觉开发的方法)被应用于扩散模型,其中生成多样化图像的能力是一个重要的考虑因素。LoHa 也应该适用于一般的模型类型,但 PEFT 中目前尚未实现嵌入层。
LoHa 使用 Hadamard 积(元素级乘积)而不是矩阵乘积。∆W 由四个较小的矩阵而不是两个矩阵表示 - 就像 LoRA 中一样 - 并且每对低秩矩阵都与 Hadamard 积组合在一起。因此,∆W 可以具有相同数量的可训练参数,但具有更高的秩和表达性。
低秩 Kronecker 积 (LoKr)
LoKr 与 LoRA 和 LoHa 非常相似,它也主要应用于扩散模型,尽管您也可以将其用于其他模型类型。LoKr 用 Kronecker 积代替矩阵乘积。Kronecker 积分解创建了一个块矩阵,该矩阵保留了原始权重矩阵的秩。Kronecker 积的另一个好处是可以通过堆叠矩阵列来对其进行矢量化。这可以加快处理速度,因为您可以避免完全重建 ∆W。
正交微调 (OFT)

OFT 是一种主要关注于在微调模型中保留预训练模型的生成性能的方法。它试图保持一层中所有成对神经元之间相同的余弦相似度(超球面能量),因为这更好地捕获了神经元之间的语义信息。这意味着 OFT 更能保留主题,并且更适合可控生成(类似于 ControlNet)。
OFT 通过学习神经元的正交变换来保持超球面能量,以保持它们之间余弦相似度不变。在实践中,这意味着将正交矩阵与预训练权重矩阵进行矩阵乘积。然而,为了实现参数效率,正交矩阵表示为秩为 r
块的块对角矩阵。LoRA 通过低秩结构减少可训练参数的数量,而 OFT 通过稀疏块对角矩阵结构减少可训练参数的数量。
正交 Butterfly (BOFT)
BOFT 是一种主要关注于在微调模型中保留预训练模型的生成性能的方法。它试图保持一层中所有成对神经元之间相同的余弦相似度(超球面能量),因为这更好地捕获了神经元之间的语义信息。这意味着 OFT 更能保留主题,并且更适合可控生成(类似于 ControlNet)。
OFT 通过学习神经元的正交变换来保持超球面能量,以保持它们之间余弦相似度不变。在实践中,这意味着将正交矩阵与预训练权重矩阵进行矩阵乘积。然而,为了实现参数效率,正交矩阵表示为秩为 r
块的块对角矩阵。LoRA 通过低秩结构减少可训练参数的数量,而 OFT 通过稀疏块对角矩阵结构减少可训练参数的数量。
自适应低秩自适应 (AdaLoRA)
AdaLoRA 通过为更适合任务的重要权重矩阵分配更多参数(换句话说,更高的秩 r
)并修剪不太重要的参数,来管理从 LoRA 引入的参数预算。秩由类似于奇异值分解 (SVD) 的方法控制。∆W 使用两个正交矩阵和一个包含奇异值的对角矩阵进行参数化。这种参数化方法避免了迭代应用计算成本高昂的 SVD。基于此方法,∆W 的秩根据重要性分数进行调整。∆W 分为三元组,每个三元组根据其对模型性能的贡献进行评分。重要性得分低的三元组被修剪,重要性得分高的三元组被保留用于微调。
使用 AdaLoRA 进行训练分为三个阶段:初始化阶段、预算阶段和最终阶段。在初始阶段,不应用预算,因此秩不会被触及。在预算阶段,应用上述过程,并根据预算重新分配秩,旨在为更重要的适配器提供更多秩,为不太重要的层提供更少的秩。当到达最终阶段时,预算已结束,秩已重新分配,但我们可以使用重新分配的秩继续训练一段时间,以进一步提高性能。
Llama-Adapter
Llama-Adapter 是一种将 Llama 改编为指令跟随模型的方法。为了帮助模型适应指令跟随,适配器使用 52K 指令-输出数据集进行训练。
一组可学习的自适应提示被添加到输入指令令牌的前面。这些被插入到模型的上层,因为最好使用预训练模型的更高层次的语义进行学习。添加到输入中的指令-输出令牌引导自适应提示生成上下文响应。

为了避免向令牌添加噪声,适配器使用零初始化的注意力。在此基础上,适配器添加了一个可学习的门控因子(初始化为零),以在训练期间逐步向模型添加信息。这可以防止新学习的指令淹没模型的预训练知识。
Householder 反射自适应 (HRA)
HRA 提供了一个新的视角,将 LoRA 连接到 OFT,这意味着它可以利用这两种策略的优势,减少参数和计算成本,同时惩罚预训练知识的损失。

HRA 构建了一个 r
个可训练 Householder 反射 (HR) 的链。由于 Householder 反射矩阵是正交矩阵,并且正交矩阵的乘积也是正交矩阵,因此 HRA 满足正交微调 (OFT) 的理论保证。同时,通过重写公式,HRA 也可以被视为低秩微调适配器。
r
越高,可训练参数越多,从而导致更大的模型容量和更好的性能。此外,由于链式结构,HR 平面的正交性会影响 HRA 的容量和规则性。为了在模型容量和规则性之间取得平衡,将 HR 平面的正交性正则化项添加到损失函数中。权重可以控制正则化项的强度。
骨骼 (Bone)
Bone 一种新颖的 PEFT 技术,与 LoRA 不同,称为块仿射适配 (Block-Affine Adaptation, Bone)。Bone 通过将原始权重划分为多个子空间,这些子空间共享一个用于权重更新的矩阵,从而简化了流程,它要求可训练矩阵初始化为零,从而消除了像某些 LoRA 变体中那样进行复杂初始化的需求。与 LoRA 相比,Bone 显著减少了内存使用并实现了更快的计算速度。
Bone:大型语言模型的块仿射适配 (Block-Affine Adaptation)直观地看,Bone 中单个可训练矩阵的形状与 lora_B
一致,因此 Bone 中的 r
参数小于 LoRA 中的 r
(in_feature * r
)。
Bat 是一种由 Bone 和“权重引导 (Weight Guide)”组成的新结构。您可以通过设置 init_weights == “bat” 来使用它。Bat 通过使用块分组方法减少了可训练参数的数量,并且权重 W 的块计算有效地促进了原始权重中的信息交换,从而增强了微调期间的数据拟合能力。实验提到通过 b (块大小) 控制可训练参数的大小,类似于 LoRA 中的 r (秩)。为了与 PEFT 保持一致,我们也把 b 命名为 r。注意:Bat 的 r (b) 是特殊的,并且要求权重 W 满足条件 in_features % r == 0
和 out_features % r == 0
。此外,当 in_features == out_features
且 Bone-r 等于 LoRA-r 时,Bone 的可训练参数数量仅为 LoRA 的一半。
Bat 目前存在一些问题:它比 LoRA 慢,并且需要检查点 (checkpointing) 来解决由于中间值导致的过多内存使用问题,这进一步降低了训练速度。我们计划在未来解决这个问题。欢迎贡献。
< > 在 GitHub 上更新