PEFT 文档

VB-LoRA:利用矢量库进行极端参数高效微调

Hugging Face's logo
加入 Hugging Face 社区

并获得扩展文档体验

开始

VB-LoRA:使用向量库的极端参数高效微调

概述

VB-LoRA 是一种参数高效的微调技术,它通过在子向量级别学习精细的参数共享方案来扩展 LoRA,从而实现更高的参数效率。这使得 VB-LoRA 在存储和传输成本至关重要的场景中特别有用。它的工作原理是将来自不同层和模块(如 K、Q、V 和 FFN)的低秩矩阵分解成子向量,然后通过向量库在全局范围内共享这些子向量。

论文摘要如下:

随着大型语言模型的采用不断增加,用户模型或任务模型定制的需求也在不断增长,参数高效微调 (PEFT) 方法(例如低秩自适应 (LoRA) 及其变体)会产生巨大的存储和传输成本。为了进一步减少存储参数,我们引入了一种“分而享之”范例,通过向量库全局共享参数,打破不同矩阵维度、模块及层间的低秩分解障碍。作为面向 LoRA 的范例,我们提出的 VB-LoRA 将 LoRA 的所有低秩矩阵与带有可微分的 top-k 混合模块的共享向量库进行组合。与最先进的 PEFT 方法相比,VB-LoRA 可实现极高的参数效率,同时保持相当或更好的性能表现。详尽的实验表明,VB-LoRA 在自然语言理解、自然语言生成和说明调整任务中具有很高的效率。在微调 Llama2-13B 模型时,VB-LoRA 仅使用了 LoRA 存储参数的 0.4%,却能实现更出色的效果。

使用技巧

  • VB-LoRA 利用稀疏 top-k 模块来学习共享机制。在保存适配器参数时,你既可以通过在 VBLoRAConfig 中将 save_only_topk_weights 设置为 True 来仅保存顶部 k 权重及其索引,也可以通过将其设置为 False 来保存所有可训练的逻辑。启用 save_only_topk_weights = True 可显著减少存储空间;例如,在 Llama2-7B 中,存储文件大小从 308MB 减小到 2.5MB。请注意,使用 save_only_topk_weights = True 保存的模型仅用于合并或推理,不能用于恢复训练。

  • VB-LoRA 具有两组训练参数:词向量参数和逻辑参数。在实践中,我们发现逻辑参数需要更高的学习率,而词向量参数需要更低的学习率。在使用 AdamW 优化器时,逻辑参数的典型学习率为 0.01,词向量参数的学习率为 0.001。

VBLoRAConfig

class peft.VBLoRAConfig

< >

( 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 = 4 num_vectors:int = 256 vector_length:int = 256 topk:int = 2 target_modules:Union = None save_only_topk_weights:bool = False vblora_dropout:float = 0.0 fan_in_fan_out:bool = False bias:str = 'none' modules_to_save:Optional = None init_vector_bank_bound:float = 0.02 init_logits_std:float = 0.1 layers_to_transform:Union = None layers_pattern:Union = None )

参数

  • r (int) — 增量矩阵的秩。
  • num_vectors (int) — 向量库中的向量数量。当模型大小增加时,使用更高的值。
  • topk (int) — K 值,用于进行前 K 选择。K 值越大,保存的模型的尺寸就越大。实际中,将 K=2 设置为通常会带来最佳的性能和参数效率。有关更多详细信息,请参阅文档中的讨论。
  • target_modules (Union[List[str], str]) — 要将适配器应用于的模块的名称。如果指定了此参数,则只会替换具有指定名称的模块。当传递一个字符串时,将执行一个正则表达式匹配。当传递字符串的列表时,将执行确切匹配或检查模块的名称是否以任何传递的字符串结尾。如果将其指定为“all-linear”,则选择所有 linear/Conv1D 模块,排除输出层。如果未指定此参数,则将根据模型架构选择模块。如果不知道架构,则将引发错误 — 在这种情况下,你应手动指定目标模块。
  • save_only_topk_weights (布尔值) — 仅保存 topk 权重。设置 save_only_topk_weights = True 会显著减少存储空间。但是,以这种模式保存的模型只能用于合并或推理,不能用于从头开始训练。
  • vblora_dropout (浮点) — VBLoRA 层的 dropout 概率。
  • bias (str) — VBLoRA 偏置类型。可以是“none”、“all”或“vblora_only”。如果为“all”或“vblora_only”,则将在训练中更新相应的偏差。请注意,这意味着即使禁用适配器,模型也不会产生与未进行适配的基本模型相同的结果。
  • modules_to_save (List[str]) — 要设置为可训练和保存在最终检查点中的 VBLoRA 层之外的模块的列表。
  • init_vector_bank_bound (float) — 矢量库使用介于 -init_vector_bank_bound 和 init_vector_bank_bound 之间的均匀分布进行初始化。避免使用全 0 值初始化矢量库,以防止梯度为 0。通常情况下,0.02 等较小值较为有效。使用较大值进行初始化会导致训练不稳定。
  • init_logits_std (float) — Logit 使用标准差为 init_logits_std 的正态分布进行初始化。默认为 0.1。
  • layers_to_transform (Union[List[int],int]) — 要变换的层索引。如果传入列表格式的整数,它会将适配器应用于此列表中指定的层索引。如果传入单个整数,它会在该索引的层上应用变换。
  • layers_pattern (str) — 层模式名称,仅在 layers_to_transformNone 不同时使用。

此为配置类,用于存储 VBLoRAConfig 的配置。

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

VBLoRAModel

peft.VBLoRAModel

< >

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

参数

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

返回

torch.nn.Module

VBLoRA 模型。

从预训练的 Transformer 模型创建 VBLoRA 模型。

该方法在 https://arxiv.org/abs/2405.15179 中进行了详细描述。

示例

>>> from transformers import AutoModelForCausalLM
>>> from peft import VBLoRAConfig, get_peft_model

>>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
>>> config = VBLoRAConfig(
...     task_type="SEQ_CLS",
...     r=4,
...     target_modules=["fc1", "fc2", "k_proj", "out_proj", "q_proj", "v_proj"],
...     num_vectors=60,
...     vector_length=256,
...     save_only_topk_weights=True,
... )
>>> model = get_peft_model(base_model, config)

属性:

delete_adapter

< >

( adapter_name: str )

参数

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

删除现有适配器。

disable_adapter_layers

< >

( )

禁用所有适配器。

在禁用所有适配器时,模型输出与基本模型的输出相符。

enable_adapter_layers

< >

( )

启用所有调整器。

如果您之前已禁用所有调整器并想要重新启用它们,可以调用此函数。

get_nb_savable_parameters

< >

( adapter = 'default' )

返回可保存的 VB-LoRA 参数和其他可保存参数的数量。

merge_and_unload

< >

( 进度: bool = False 安全合并: bool = False 适配器名称: 可选[str 列表] = 无 )

参数

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

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

示例

>>> 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()

print_savable_parameters

< >

( )

打印可保存 VB-LoRA 参数的数量和可保存参数总数。

set_adapter

< >

( adapter_name: str | list[str] )

参数

  • adapter_name (strlist[str]) — 要激活的适配器的名称。

设置激活的适配器。

此外,此函数将指定适配器设置为可训练(即,requires_grad=True)。如果不需要这样做,请使用以下代码。

>>> for name, param in model_peft.named_parameters():
...     if ...:  # some check on name (ex. if 'lora' in name)
...         param.requires_grad = False

卸载

< >

( )

通过移除所有 VBLoRA 模块(不合并),来获得基础模型。这会返回原始基础模型。

< > 更新到 GitHub