PEFT 文档
AdaLoRA
并获得增强的文档体验
开始使用
AdaLoRA
AdaLoRA 是一种优化方法,用于确定分配给权重矩阵和层的可训练参数数量。与 LoRA 在所有模块间均匀分配参数不同,AdaLoRA 为重要的权重矩阵和层分配更多参数,而次要的则分配较少。
论文摘要如下:
在下游任务上微调大型预训练语言模型已成为自然语言处理(NLP)领域的重要范式。然而,当存在大量下游任务时,微调预训练模型的所有参数的做法变得不切实际。因此,人们提出了许多微调方法,以参数高效的方式学习预训练权重的增量更新,例如低秩增量。这些方法通常将增量更新的预算均匀地分配给所有预训练的权重矩阵,而忽略了不同权重参数的重要性差异。结果导致微调性能不佳。为了解决这个问题,我们提出了 AdaLoRA,它根据权重矩阵的重要性得分,自适应地分配参数预算。具体来说,AdaLoRA 以奇异值分解(SVD)的形式对增量更新进行参数化。这种新颖的方法使我们能够有效地修剪不重要更新的奇异值,这本质上是减少了它们的参数预算,但避免了高昂的精确 SVD 计算。我们通过在自然语言处理、问答和自然语言生成任务上对多个预训练模型进行广泛实验,验证了 AdaLoRA 的有效性。结果表明,AdaLoRA 相较于基线方法有显著提升,尤其是在低预算设置下。我们的代码已在 https://github.com/QingruZhang/AdaLoRA 公开。.
AdaLoraConfig
class peft.AdaLoraConfig
< 源代码 >( 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 = 8 target_modules: Optional[Union[list[str], str]] = None exclude_modules: Optional[Union[list[str], str]] = None lora_alpha: int = 8 lora_dropout: float = 0.0 fan_in_fan_out: bool = False bias: Literal['none', 'all', 'lora_only'] = 'none' use_rslora: bool = False modules_to_save: Optional[list[str]] = None init_lora_weights: bool | Literal['gaussian', 'eva', 'olora', 'pissa', 'pissa_niter_[number of iters]', 'corda', 'loftq', 'orthogonal'] = True layers_to_transform: Optional[Union[list[int], int]] = None layers_pattern: Optional[Union[list[str], str]] = None rank_pattern: typing.Optional[dict] = None alpha_pattern: Optional[dict] = <factory> megatron_config: Optional[dict] = None megatron_core: Optional[str] = 'megatron.core' trainable_token_indices: Optional[Union[list[int], dict[str, list[int]]]] = None loftq_config: Union[LoftQConfig, dict] = <factory> eva_config: Optional[EvaConfig] = None corda_config: Optional[CordaConfig] = None use_dora: bool = False use_qalora: bool = False qalora_group_size: int = 16 layer_replication: Optional[list[tuple[int, int]]] = None runtime_config: LoraRuntimeConfig = <factory> lora_bias: bool = False target_parameters: Optional[list[str]] = None target_r: int = 8 init_r: int = 12 tinit: int = 0 tfinal: int = 0 deltaT: int = 1 beta1: float = 0.85 beta2: float = 0.85 orth_reg_weight: float = 0.5 total_step: typing.Optional[int] = None )
参数
- target_r (
int
) — 增量矩阵的目标平均秩。 - init_r (
int
) — 每个增量矩阵的初始秩。 - tinit (
int
) — 初始微调预热的步数。 - tfinal (
int
) — 最终微调的步数。 - deltaT (
int
) — 两次预算分配之间的时间间隔。 - beta1 (
float
) — 用于敏感度平滑的 EMA 超参数。 - beta2 (
float
) — 用于不确定性量化的 EMA 超参数。 - orth_reg_weight (
float
) — 正交正则化的系数。 - total_step (
int
) — 应在训练前指定的总训练步数。 - rank_pattern (
list
) — 由 RankAllocator 分配给每个权重矩阵的秩。
这是用于存储 ~peft.AdaLora
配置的配置类。
AdaLoRA 有三个由 tinit
、tfinal
和 total_step
定义的阶段。
初始阶段可以理解为对适配器进行预训练的步骤,这样当降低它们的秩时,已经有一些信息被编码,可以被缩减,而不是随机矩阵。这个阶段通过提供 tinit
来定义。
在初始阶段结束后(经过 tinit
步)且最终阶段尚未开始时,AdaLoRA 会在每一步中减少分配给每一层的秩预算。这是秩缩减发生的地方。这个过程会持续到达到 total_step - tfinal
步。
最后一个阶段,从达到 total_step - tfinal
步开始,不再改变层的秩,而是对前一阶段产生的降秩层进行微调。
一个实际例子:tinit
是 10,tfinal
是 20,total_step
是 100。我们将花费 10 步进行不进行秩缩减的预训练,因为我们的预算是恒定的(初始阶段);然后,我们将在缩减阶段花费 80(100-20)步,期间我们的预算逐步减少;最后,在不进行缩减的最终微调阶段花费 20 步。
AdaLoraModel
class peft.AdaLoraModel
< 源代码 >( model config adapter_name **kwargs ) → torch.nn.Module
从预训练的 transformers 模型创建 AdaLoRA(自适应 LoRA)模型。论文:https://openreview.net/forum?id=lq62uWRJjiY
示例
>>> from transformers import AutoModelForSeq2SeqLM >>> from peft import LoraConfig, AdaLoraModel, AdaLoraConfig
>>> config = AdaLoraConfig(
peft_type="ADALORA", task_type="SEQ_2_SEQ_LM", init_r=12, lora_alpha=32, target_modules=["q", "v"],
lora_dropout=0.01,
)
>>> model = AutoModelForSeq2SeqLM.from_pretrained("t5-base") >>> model = AdaLoraModel(model, config, "default")
属性:
- model ([transformers.PreTrainedModel]) — 待适配的模型。
- peft_config ([AdaLoraConfig]): AdaLora 模型的配置。
AdaLoRA 不支持此方法,请改用 LoRA。
此方法更新 Adalora 预算和掩码。
应在每个训练步中,在 loss.backward()
之后和 zero_grad()
之前调用此方法。
tinit
、tfinal
和 deltaT
都在该方法内部处理。