PEFT documentation
VeRA:基于向量的随机矩阵适配
VeRA:基于向量的随机矩阵适配
VeRA 是一种参数高效微调技术,与 LoRA 类似,但所需的额外参数更少,同时承诺达到相似甚至更优的性能。因此,当参数预算非常有限时(例如扩展到非常大的模型时),它特别有用。通过在所有层之间共享相同的低秩矩阵,并且每层仅训练两个额外向量,即可减少可训练参数的数量。
VeRA 的工作原理
LoRA 通过为每个适配层学习两个小型低秩矩阵来更新冻结的基础模型。秩是这些矩阵的内部维度,它控制着适配器的容量。在 LoRA 中,增加 r 或适配更多层会迅速增加可训练参数的数量,因为每个适配层都会学习自己的一对低秩矩阵。
VeRA 保留了相同的低秩适配思想,但改变了所训练的参数。它不再为每一层学习独立的低秩矩阵,而是使用一对冻结的、随机初始化的低秩矩阵 A 和 B,并在各层之间共享。每个适配层仅学习两个缩放向量 vera_lambda_d 和 vera_lambda_b,用于对共享矩阵进行重新缩放,从而生成特定于该层的更新。由于 vera_lambda_d 的大小为 r,VeRA 的可训练参数数量仍会随着 r 和适配层数的增加而增加。然而,由于较大的 A 和 B 矩阵是共享且冻结的,而非为每一层单独学习,因此其增长速度远慢于 LoRA。
这就是 VeRA 能够使用比 LoRA 更少可训练参数的原因。在论文中简化的参数计数中,LoRA 的参数量与 2 * L_tuned * d_model * r 成正比,其中 L_tuned 是适配层的数量,d_model 是模型维度,r 是秩。VeRA 的参数量与 L_tuned * (d_model + r) 成正比,因为大型低秩矩阵是共享且冻结的,只有较小的逐层向量参与训练。
在保存适配器参数时,可以通过在 VeraConfig 中设置 save_projection=False 来避免存储低秩矩阵。在这种情况下,这些矩阵将根据 projection_prng_key 参数中指定的固定随机种子进行恢复。这可以减小检查点的大小,但我们无法保证在所有设备以及 PyTorch 的所有未来版本上都能实现可复现性。如果您希望确保可复现性,请设置 save_projection=True(这是默认值)。
为了处理不同形状的适配层,VeRA 会为每个维度使用所需的最大尺寸来初始化共享的 A 和 B 矩阵。在前向传播过程中,给定层的子矩阵 A 和 B 会从这些共享矩阵中切片提取出来,并按照论文中的描述使用。例如,适配形状为 (100, 20) 和 (80, 50) 的两个线性层,将分别创建形状为 (rank, 50) 和 (100, rank) 的 A 和 B 矩阵。然后,为了适配形状为 (100, 20) 的层,将提取形状为 (rank, 20) 和 (100, rank) 的子矩阵 A 和 B。
VeRA 目前存在以下限制:
- 仅支持
nn.Linear层。
该论文的摘要如下:
低秩适应(LoRA)是一种在微调大型语言模型时减少可训练参数数量的流行方法,但在扩展到更大的模型或部署大量针对特定用户或特定任务的适配模型时,仍面临严峻的存储挑战。在本工作中,我们提出了基于向量的随机矩阵适应(VeRA),与 LoRA 相比,它显著减少了可训练参数的数量,同时保持了相同的性能。它通过使用在所有层之间共享的一对低秩矩阵,并转而学习小型缩放向量来实现这一点。我们在 GLUE 和 E2E 基准测试、图像分类任务上展示了其有效性,并展示了其在 7B 和 13B 语言模型指令微调中的应用。
何时使用 VeRA
在以下情况下,VeRA 是一个不错的选择:
- 您希望在保持与 LoRA 相当性能的同时,尽可能减少可训练参数的数量。
- 您需要存储或部署许多特定任务的适配器,其中较小的适配器检查点可以降低存储需求。
- 您正在严格的内存或参数预算下微调超大规模语言模型。
何时不使用 VeRA
在以下情况下,VeRA 可能不是最佳选择:
- 您需要为每个适配层提供独立的低秩矩阵,从而在所学到的适配器参数中提供更大的灵活性。
- 您的模型需要适配
nn.Linear以外的模块类型,因为 VeRA 目前仅支持线性层。 - 您的模型包含经过适配的线性层,且这些层的输入和输出维度差异很大。由于 VeRA 在所有适配层之间共享同一对投影矩阵,这些矩阵必须按照最大的形状进行配置。因此,层形状差异较大的模型(例如 Transformer 的上投影层和下投影层)可能需要过度配置共享投影矩阵,从而削弱 VeRA 的部分参数效率优势。
基准测试概览
API
VeRAConfig
类 peft.VeraConfig
< source >( task_type: Optional[Union[str, TaskType]] = Nonepeft_type: Optional[Union[str, PeftType]] = Noneauto_mapping: Optional[dict] = Nonepeft_version: Optional[str] = Nonebase_model_name_or_path: Optional[str] = Nonerevision: Optional[str] = Noneinference_mode: bool = Falser: int = 256target_modules: Optional[Union[list[str], str]] = Noneprojection_prng_key: int = 0save_projection: bool = Truevera_dropout: float = 0.0d_initial: float = 0.1fan_in_fan_out: bool = Falsebias: str = 'none'modules_to_save: Optional[list[str]] = Noneinit_weights: bool = Truelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = None )
参数
- r (
int,可选,默认为256) — VeRA 参数维度(“rank”)。由于 VeRA 使用的参数远少于 LoRA(参见表 1),请在此处选择比 LoRA rank 更高的值。 - target_modules (
Union[List[str], str]) — 要应用 Vera 的模块名称。仅支持线性层。 - projection_prng_key (
int) — Vera PRNG 初始化密钥。用于为新模型初始化 vera_A 和 vera_B,或在加载未包含这些投影的 checkpoint 时使用。默认值为0。 - save_projection (
bool) — 是否将 vera_A / vera_B 投影与每层的 lambda_b / lambda_d 权重一起保存在状态字典中。这会增加检查点的大小,但可保证在所有系统配置上重新加载检查点。默认为True。 - vera_dropout (
float) — Vera 层的 dropout 概率。 - d_initial (
float,可选,默认为0.1) — 用于初始化 VeRA 参数时vera_lambda_d向量的初始值。建议使用较小的值(<=0.1)(参见论文中的表 6c)。 - fan_in_fan_out (
bool) — 如果待替换的层以 (fan_in, fan_out) 的形式存储权重,请将此项设置为 True。例如,gpt-2 使用的Conv1D以 (fan_in, fan_out) 的形式存储权重,因此应将其设置为True。 - bias (
str) — Vera 的偏置类型。可以是 ‘none’、‘all’ 或 ‘vera_only’。如果设置为 ‘all’ 或 ‘vera_only’,相应的偏置将在训练期间被更新。请注意,这意味着即使禁用了适配器,模型的输出也不会与未进行适配的基础模型相同。 - modules_to_save (
List[str]) — 除 Vera 层外,需要设置为可训练并在最终检查点中保存的模块列表。 - init_weights (
bool) — 是否使用默认初始化方式初始化 Vera 层的权重。除非您完全清楚自己在做什么,否则请勿更改此设置。 - layers_to_transform (
Union[List[int],int]) — 要转换的层索引。如果指定了此参数,将在该列表中指定的层索引上应用 Vera 转换。如果传入单个整数,则将在该索引对应的层上应用 Vera 转换。 - layers_pattern (
Optional[Union[List[str], str]]) — 层模式名称,仅在layers_to_transform不同于None时使用。它应指向模型的nn.ModuleList,该列表通常命名为'layers'或'h'。
这是用于存储 VeraModel 配置的类。
VeRAModel
类 peft.VeraModel
< source >( modelpeft_config: Union[PeftConfig, dict[str, PeftConfig]]adapter_name: strlow_cpu_mem_usage: bool = Falsestate_dict: Optional[dict[str, torch.Tensor]] = None ) → torch.nn.Module
参数
- model (PreTrainedModel) — 要适配的模型。
- config (VeraConfig) — Vera 模型的配置。
- adapter_name (
str) — 适配器的名称,默认为"default"。 - low_cpu_mem_usage (
bool,optional, defaults toFalse) — 在 meta 设备上创建空的适配器权重。有助于加快加载过程。
返回值
torch.nn.Module
Vera 模型。
从预训练的 transformers 模型创建基于向量的随机矩阵自适应(Vera)模型。
示例:
>>> from transformers import AutoModelForCausalLM
>>> from peft import VeraConfig, get_peft_model
>>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
>>> config = VeraConfig(r=128)
>>> model = get_peft_model(base_model, config)属性:
- model (PreTrainedModel) — 要适配的模型。
- peft_config (VeraConfig): Vera 模型的配置。