PEFT 文档

稀疏高秩适配器

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

稀疏高秩适配器

稀疏高秩适配器(Sparse High Rank Adapters)或 SHiRA 是一种替代类型的适配器,已被发现比低秩适配器具有显著优势。具体来说,SHiRA 在各种视觉和语言任务上实现了比 LoRA 更好的准确性。它还通过显著减少概念损失(低秩适配器面临的常见问题)来提供更简单、更高质量的多适配器融合。SHiRA 直接微调基础模型的一小部分参数,以在任何适应任务上微调模型。

SHiRA 目前有以下约束

  • 仅支持 `nn.Linear` 层。

论文摘要如下:

低秩适配(LoRA)在近期的生成式人工智能研究中获得了巨大关注。LoRA 的主要优势之一是它能够与预训练模型融合,在推理过程中不增加额外开销。然而,从移动部署的角度来看,我们要么在融合模式下避免推理开销但失去快速切换适配器的能力,要么在非融合模式下承受显著(高达30%)的推理延迟以实现快速切换。当多个适配器同时使用时,LoRA 还会表现出概念损失。在本文中,我们提出了稀疏高秩适配器(SHiRA),这是一种新的范式,它不产生推理开销,能够快速切换,并显著减少概念损失。具体而言,SHiRA 可以通过直接调整基础模型中仅1-2%的权重进行训练,而其他权重保持不变。这产生了一个高度稀疏的适配器,可以在融合模式下直接切换。我们进一步提供了理论和实证见解,说明 SHiRA 的高稀疏性如何通过减少概念损失来辅助多适配器融合。我们在大型视觉语言模型(LVMs)和大型语言模型(LLMs)上的广泛实验表明,仅微调基础模型中一小部分参数的表现显著优于 LoRA,同时实现了快速切换和多适配器融合。最后,我们提供了一个基于参数高效微调(PEFT)库的延迟和内存高效的 SHiRA 实现,其训练速度与 LoRA 几乎相同,而峰值 GPU 内存消耗降低了高达16%,从而使 SHiRA 易于在实际用例中采用。为了展示推理过程中的快速切换优势,我们表明在 CPU 上将 SHiRA 加载到基础模型上比 LoRA 融合快5倍至16倍。

ShiraConfig

class peft.ShiraConfig

< >

( 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 = 32 mask_type: Literal['random'] = 'random' random_seed: Optional[int] = None target_modules: Optional[Union[list[str], str]] = None fan_in_fan_out: bool = False init_weights: bool = True modules_to_save: Optional[list[str]] = None )

参数

  • r (int, 可选, 默认为 32) — 对于给定的目标模块,SHiRA 参数的数量计算为 r(m+n),其中原始张量维度为 m x n。这意味着 SHiRA 参数的数量与 LoRA 适配器相同。SHiRA 是一个高秩适配器。设置此 r 参数不会将秩限制在此值。
  • mask_type (str, 默认为 random) — 掩码函数的类型。默认为随机稀疏掩码。也可以通过实例化 `config = ShiraConfig(...)` 然后设置 `config.mask_fn = <your custom mask function>` 来提供可选的用户自定义 `mask_fn` 来计算掩码值。对于形状为 m x n 的预训练权重,自定义掩码函数必须只返回一个掩码(形状:m x n),该掩码必须是二元的 0 或 1,对于线性层,`num_shira_parameters = r(m + n)`。掩码的设备和数据类型必须与基础层权重的设备和数据类型相同。请参阅 mask_functions.py 以获取更多详细信息并查看默认的随机稀疏掩码实现。
  • random_seed (int, 可选, 默认为 None) — 用于 `random_mask` 的 torch 生成器的随机种子。
  • target_modules (Union[List[str], str]) — 要替换为 SHiRA 的模块名称列表或模块名称的正则表达式。例如,['q', 'v'] 或 `'.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$'`。仅支持线性层。
  • fan_in_fan_out (bool) — 如果要替换的层存储权重的方式是(fan_in, fan_out),则设置为 True。例如,gpt-2 使用 `Conv1D`,它以(fan_in, fan_out)的方式存储权重,因此此项应设置为 `True`。
  • init_weights (bool, 默认为 True) — 将 SHiRA 权重初始化为零值。如果设置为 False,SHiRA 权重将被初始化为 randn 值而不是零,这仅用于测试。
  • modules_to_save (List[str]) — 除了 SHiRA 层之外,需要设置为可训练并在最终检查点中保存的模块列表。

这是用于存储 ShiraModel 配置的配置类。

ShiraModel

class peft.ShiraModel

< >

( model peft_config: Union[PeftConfig, dict[str, PeftConfig]] adapter_name: str low_cpu_mem_usage: bool = False state_dict: Optional[dict[str, torch.Tensor]] = None ) torch.nn.Module

参数

  • model (PreTrainedModel) — 要适配的模型。
  • config (ShiraConfig) — SHiRA 模型的配置。
  • adapter_name (str) — 适配器的名称,默认为 `"default"`。

返回

torch.nn.Module

SHiRA 模型。

从预训练模型创建一个稀疏高秩适配器(SHiRA)模型。

示例

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

>>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
>>> config = ShiraConfig(r=32)
>>> model = get_peft_model(base_model, config)

属性:

  • model (PreTrainedModel) — 需要被适配的模型。
  • peft_config (ShiraConfig): SHiRA 模型的配置。

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

此方法将 Shira 层合并到基础模型中。如果有人想将基础模型用作独立模型,则需要此方法。

示例

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

>>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
>>> config = ShiraConfig(r=32)
>>> model = get_peft_model(base_model, config)
>>> ## [Train the adapter] ##
>>> merged_model = model.merge_and_unload()

unload

< >

( )

通过移除所有 Shira 模块而不进行合并,恢复基础模型。这将返回原始的基础模型。

< > 在 GitHub 上更新