正交微调 (OFT 和 BOFT)
本概念指南简要概述了 OFT 和 BOFT,这是一种参数高效的微调技术,它利用正交矩阵来乘法变换预训练的权重矩阵。
为了实现高效的微调,OFT 使用正交变换来表示权重更新。正交变换由一个正交矩阵参数化,该矩阵乘以预训练的权重矩阵。这些新矩阵可以训练以适应新数据,同时保持整体变化数量较低。原始权重矩阵保持冻结状态,不再进行任何进一步的调整。为了生成最终结果,原始权重和适应权重相乘。
正交蝶形 (BOFT) 使用蝶形分解对 OFT 进行泛化,并进一步提高了其参数效率和微调灵活性。简而言之,OFT 可以视为 BOFT 的特例。与使用加性低秩权重更新的 LoRA 不同,BOFT 使用乘法正交权重更新。下面的表格展示了比较。
与 LoRA 相比,BOFT 有一些优势
- BOFT 提出了一种简单而通用的方法,用于将预训练模型微调到下游任务,从而更好地保留预训练知识并提高参数效率。
- 通过正交性,BOFT 引入了一个结构约束,即在微调过程中保持 超球面能量 不变。这可以有效减少对预训练知识的遗忘。
- BOFT 使用蝴蝶分解 (butterfly factorization) 来高效地参数化正交矩阵,从而产生一个紧凑且表达能力强的学习空间(即假设类)。
- BOFT 中的稀疏矩阵分解引入了额外的归纳偏差,这有利于泛化。
原则上,BOFT 可以应用于神经网络中任何权重矩阵的子集,以减少可训练参数的数量。给定注入 BOFT 参数的目标层,可训练参数的数量可以根据权重矩阵的大小确定。
将 OFT/BOFT 权重合并到基础模型中
与 LoRA 类似,OFT/BOFT 学习到的权重可以使用 `merge_and_unload()` 函数集成到预训练的权重矩阵中。此函数将适配器权重与基础模型合并,使您可以有效地将新合并的模型用作独立模型。
这是因为在训练期间,正交权重矩阵(上图中的 R)和预训练的权重矩阵是分开的。但是,一旦训练完成,这些权重实际上就可以合并(相乘)成一个新的等效权重矩阵。
OFT / BOFT 的实用程序
PEFT 中常见的 OFT / BOFT 参数
与 PEFT 支持的其他方法一样,要使用 OFT 或 BOFT 微调模型,您需要
- 实例化一个基础模型。
- 创建一个配置(`OFTConfig` 或 `BOFTConfig`),在其中定义 OFT/BOFT 特定的参数。
- 使用 `get_peft_model()` 包装基础模型以获得可训练的 `PeftModel`。
- 像往常一样训练 `PeftModel`,就像训练基础模型一样。
BOFT 特定参数
BOFTConfig
允许您通过以下参数控制如何将 OFT/BOFT 应用于基础模型
boft_block_size
:不同层之间的 BOFT 矩阵块大小,以 `int` 表示。较小的块大小会导致更新矩阵更稀疏,可训练参数更少。**注意**,请选择 `boft_block_size` 使其能够被大多数层的输入维度(`in_features`)整除,例如 4、8、16。此外,请仅指定 `boft_block_size` 或 `boft_block_num`,而不是同时指定两者或将两者都留为 0,因为 `boft_block_size` x `boft_block_num` 必须等于层的输入维度。boft_block_num
:不同层之间的 BOFT 矩阵块的数量,以 `int` 表示。较少的块会导致更新矩阵更稀疏,可训练参数更少。**注意**,请选择 `boft_block_num` 使其能够被大多数层的输入维度(`in_features`)整除,例如 4、8、16。此外,请仅指定 `boft_block_size` 或 `boft_block_num`,而不是同时指定两者或将两者都留为 0,因为 `boft_block_size` x `boft_block_num` 必须等于层的输入维度。boft_n_butterfly_factor
:蝴蝶因子的数量。**注意**,对于 `boft_n_butterfly_factor=1`,BOFT 与普通 OFT 相同;对于 `boft_n_butterfly_factor=2`,OFT 的有效块大小变为原来的两倍,块的数量减半。bias
:指定是否应训练 `bias` 参数。可以是 `"none"`、`"all"` 或 `"boft_only"`。boft_dropout
:指定乘法 dropout 的概率。target_modules
:要注入 OFT/BOFT 矩阵的模块(例如,注意力块)。modules_to_save
:除了 OFT/BOFT 矩阵之外,要设置为可训练并在最终检查点中保存的模块列表。这些通常包括为微调任务随机初始化的模型自定义头部。
BOFT 使用示例
有关 BOFT 方法应用于各种下游任务的示例,请参阅以下指南
查看以下有关如何使用 BOFT 微调模型的分步指南
对于图像分类任务,可以为 DinoV2 模型初始化 BOFT 配置,如下所示
import transformers
from transformers import AutoModelForSeq2SeqLM, BOFTConfig
from peft import BOFTConfig, get_peft_model
config = BOFTConfig(
boft_block_size=4,
boft_n_butterfly_factor=2,
target_modules=["query", "value", "key", "output.dense", "mlp.fc1", "mlp.fc2"],
boft_dropout=0.1,
bias="boft_only",
modules_to_save=["classifier"],
)
model = transformers.Dinov2ForImageClassification.from_pretrained(
"facebook/dinov2-large",
num_labels=100,
)
boft_model = get_peft_model(model, config)