PEFT 文档
VB-LoRA:使用向量库的极限参数高效微调
并获取增强的文档体验
开始使用
VB-LoRA:使用向量库的极限参数高效微调
概述
VB-LoRA 是一种参数高效的微调技术,它通过在子向量级别学习细粒度的参数共享方案来扩展 LoRA,从而实现显著更高的参数效率。这使得 VB-LoRA 在存储和传输成本至关重要的场景中尤其有用。它的工作原理是将低秩矩阵(来自不同层和模块,如 K、Q、V 和 FFN)分解为子向量,然后通过向量库全局共享这些子向量。
论文摘要如下:
随着大型语言模型的采用率不断提高,以及对每个用户或每个任务的模型定制需求不断增长,参数高效微调 (PEFT) 方法(如低秩自适应 (LoRA) 及其变体)会产生大量的存储和传输成本。为了进一步减少存储参数,我们引入了一种“分而治之”的范式,通过向量库全局共享参数,打破了跨矩阵维度、模块和层的低秩分解壁垒。作为该范式在 LoRA 上的实例化,我们提出的 VB-LoRA 通过可微分的 top-k 混合模块,从共享向量库中组合了 LoRA 的所有低秩矩阵。VB-LoRA 实现了极致的参数效率,同时保持了与最先进的 PEFT 方法相当甚至更好的性能。广泛的实验证明了 VB-LoRA 在自然语言理解、自然语言生成和指令调优任务上的有效性。在微调 Llama2-13B 模型时,VB-LoRA 仅使用了 LoRA 存储参数的 0.4%,但取得了更优越的结果。
使用技巧
VB-LoRA 利用稀疏 top-k 模块来学习共享机制。在保存适配器参数时,您可以设置
VBLoRAConfig
中的save_only_topk_weights = True
来仅保存 top-k 权重及其索引,或者将其设置为False
来保存所有可训练的 logits。启用save_only_topk_weights = True
可以显著减少存储空间;例如,在 Llama2-7B 中,存储文件大小从 308MB 减少到 2.5MB。请注意,使用save_only_topk_weights = True
保存的模型仅用于合并或推理,不能用于恢复训练。VB-LoRA 有两组训练参数:向量库参数和 logit 参数。在实践中,我们发现 logit 参数需要更高的学习率,而向量库参数需要更低的学习率。当使用 AdamW 优化器时,logits 的典型学习率为 0.01,向量库参数的典型学习率为 0.001。
VBLoRAConfig
class peft.VBLoRAConfig
< source >( task_type: typing.Union[str, peft.utils.peft_types.TaskType, NoneType] = None peft_type: typing.Union[str, peft.utils.peft_types.PeftType, NoneType] = None auto_mapping: typing.Optional[dict] = None base_model_name_or_path: typing.Optional[str] = None revision: typing.Optional[str] = None inference_mode: bool = False r: int = 4 num_vectors: int = 256 vector_length: int = 256 topk: int = 2 target_modules: Optional[Union[list[str], str]] = None exclude_modules: Optional[Union[list[str], str]] = 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[list[str]] = None init_vector_bank_bound: float = 0.02 init_logits_std: float = 0.1 layers_to_transform: Optional[Union[list[int], int]] = None layers_pattern: Optional[Union[list[str], str]] = None )
参数
- r (
int
) — 增量矩阵的秩。 - num_vectors (
int
) — 向量库中向量的数量。当模型尺寸增加时,使用更高的值。 - vector_length (
int
) — 向量库中向量的长度。向量的长度应能被模型的隐藏维度整除。 - topk (
int
) — Top-K 选择的 K 值。K 值越大,保存的模型尺寸越大。在实践中,设置 K=2 通常可提供最佳性能和参数效率。有关更多详细信息,请参阅论文中的讨论。 - target_modules (
Union[List[str], str]
) — 要应用适配器的模块名称。如果指定此项,则仅替换具有指定名称的模块。当传递字符串时,将执行正则表达式匹配。当传递字符串列表时,将执行精确匹配,或者检查模块的名称是否以任何传递的字符串结尾。如果将其指定为“all-linear”,则将选择所有 linear/Conv1D 模块,但不包括输出层。如果未指定此项,则将根据模型架构选择模块。如果架构未知,则会引发错误 — 在这种情况下,您应手动指定目标模块。 - exclude_modules (
Optional[Union[List[str], str]]
) — 不应用适配器的模块名称。当传递字符串时,将执行正则表达式匹配。当传递字符串列表时,将执行精确匹配,或者检查模块的名称是否以任何传递的字符串结尾。 - save_only_topk_weights (
bool
) — 是否仅保存 topk 权重。设置save_only_topk_weights = True
可以显著减少存储空间。但是,在此模式下保存的模型仅可用于合并或推理,而不能用于恢复训练。 - vblora_dropout (
float
) — VBLoRA 层的 dropout 概率。 - fan_in_fan_out (
bool
) — 如果要替换的层存储的权重类似于 (fan_in, fan_out),则设置为 True。例如,gpt-2 使用Conv1D
,它存储的权重类似于 (fan_in, fan_out),因此应将其设置为True
。 - 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.02 这样的小值是有效的。使用较大的值初始化可能会导致训练不稳定。 - init_logits_std (
float
) — logits 使用标准差为 init_logits_std 的正态分布进行初始化。默认为 0.1。 - layers_to_transform (
Union[List[int],int]
) — 要转换的层索引。如果传递整数列表,它将适配器应用于此列表中指定的层索引。如果传递单个整数,它将在此索引处的层上应用转换。 - layers_pattern (
Optional[Union[List[str], str]]
) — 层模式名称,仅当layers_to_transform
与None
不同时使用。这应针对模型的nn.ModuleList
,通常称为'layers'
或'h'
。
这是用于存储 VBLoRAConfig 配置的配置类。
VBLoRAModel
class peft.VBLoRAModel
< source >( model config adapter_name low_cpu_mem_usage: bool = False ) → torch.nn.Module
参数
- model (PreTrainedModel) — 要适配的模型。
- config (VBLoRAConfig) — VBLoRA 模型的配置。
- adapter_name (
str
) — 适配器的名称,默认为"default"
。 - low_cpu_mem_usage (
bool
,optional
, defaults toFalse
) — 在 meta 设备上创建空适配器权重。有助于加速加载过程。
返回
torch.nn.Module
VBLoRA 模型。
从预训练的 transformers 模型创建 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)
属性:
- model (PreTrainedModel) — 要适配的模型。
- peft_config (VBLoRAConfig): VBLoRAConfig 模型的配置。
删除现有适配器。
返回可保存的 VB-LoRA 参数和其他可保存参数的数量。
merge_and_unload
< source >( progressbar: bool = False safe_merge: bool = False adapter_names: Optional[list[str]] = 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()
打印可保存的 VB-LoRA 参数的数量和总可保存参数。
set_adapter
< source >( adapter_name: str | list[str] )
设置活动的适配器。
此外,此函数会将指定的适配器设置为可训练(即,requires_grad=True)。如果不需要这样做,请使用以下代码。
通过删除所有 VBLoRA 模块但不合并,返回基础模型。这将返回原始基础模型。