PEFT 文档

VeRA:基于向量的随机矩阵自适应

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

VeRA:基于向量的随机矩阵自适应

VeRA 是一种参数高效的微调技术,类似于 LoRA,但需要更少的额外参数,同时承诺提供相似甚至更好的性能。因此,当参数预算非常有限时,例如在扩展到非常大的模型时,它特别有用。可训练参数数量的减少是通过跨所有层共享相同的低秩矩阵来实现的,并且每个层仅训练两个额外的向量。

保存适配器参数时,可以通过在 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。

论文摘要如下:

低秩自适应(LoRA)是一种流行的方法,它在微调大型语言模型时减少了可训练参数的数量,但在扩展到更大的模型或部署众多针对每个用户或每个任务的自适应模型时,仍然面临着严峻的存储挑战。在这项工作中,我们提出了基于向量的随机矩阵自适应(VeRA),与LoRA相比,它显著减少了可训练参数的数量,同时保持了相同的性能。它通过使用跨所有层共享的单个低秩矩阵对和学习小的缩放向量来实现这一点。我们在GLUE和E2E基准测试、图像分类任务中证明了其有效性,并展示了其在7B和13B语言模型的指令微调中的应用。

VeRAConfig

class peft.VeraConfig

< >

( peft_type: Union = None auto_mapping: Optional = None base_model_name_or_path: Optional = None revision: Optional = None task_type: Union = None inference_mode: bool = False r: int = 256 target_modules: Union = None projection_prng_key: int = 0 save_projection: bool = True vera_dropout: float = 0.0 d_initial: float = 0.1 fan_in_fan_out: bool = False bias: str = 'none' modules_to_save: Optional = None init_weights: bool = True layers_to_transform: Union = None layers_pattern: Optional = None )

参数

  • r (int, 可选,默认为 256) — VeRA 参数维度(“秩”)。此处选择比LoRA秩更高的值,因为VeRA使用的参数远少于LoRA(参见表1)。
  • target_modules (Union[List[str], str]) — 要应用Vera的模块名称。仅支持线性层。
  • projection_prng_key (int) — Vera PRNG 初始化密钥。用于为新模型初始化vera_A和vera_B,或者在加载不包含这些投影的检查点时使用。默认为 0
  • save_projection (bool) — 是否在状态字典中与每层lambda_b/lambda_d权重一起保存vera_A/vera_B投影。这会增加检查点的大小,但可以保证我们在所有系统配置上重新加载检查点。默认为 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 (str) — 层模式名称,仅在 layers_to_transform 不等于 None 且层模式不在常用层模式中时使用。

这是一个配置类,用于存储 VeraModel 的配置。

论文:https://arxiv.org/abs/2310.11454

VeRAModel

class peft.VeraModel

< >

( model config adapter_name low_cpu_mem_usage: bool = False ) torch.nn.Module

参数

  • model (PreTrainedModel) — 要进行适配的模型。
  • config (VeraConfig) — Vera 模型的配置。
  • low_cpu_mem_usage (bool, 可选, 默认为 False) — 在元设备上创建空的适配器权重。有助于加快加载过程。

返回

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)

属性:

delete_adapter

< >

( adapter_name: str )

参数

  • adapter_name (str) — 要删除的适配器的名称。

删除现有的适配器。

merge_and_unload

< >

( progressbar: bool = False safe_merge: bool = False adapter_names: Optional[list[str]] = None )

参数

  • progressbar (bool) — 是否显示指示卸载和合并过程的进度条
  • safe_merge (bool) — 是否激活安全合并检查以检查适配器权重中是否存在任何潜在的 NaN
  • adapter_names (list[str], 可选) — 应合并的适配器名称列表。如果为 None,则会合并所有活动适配器。默认为 None

此方法将 Vera 层合并到基础模型中。如果有人希望将基础模型用作独立模型,则需要这样做。

示例

>>> from transformers import AutoModelForCausalLM
>>> from peft import PeftModel

>>> base_model = AutoModelForCausalLM.from_pretrained("tiiuae/falcon-40b")
>>> peft_model_id = "smangrul/falcon-40B-int4-peft-lora-sfttrainer-sample"
>>> model = PeftModel.from_pretrained(base_model, peft_model_id)
>>> merged_model = model.merge_and_unload()

unload

< >

( )

通过移除所有 Vera 模块而不进行合并来获取基础模型。这将返回原始基础模型。

< > 在 GitHub 上更新