Transformers 文档

使用 🤗 PEFT 加载适配器

Hugging Face's logo
加入 Hugging Face 社区

并获取增强型文档体验

开始使用

使用 🤗 PEFT 加载适配器

参数高效微调 (PEFT) 方法在微调期间冻结预训练模型参数,并在其之上添加少量可训练参数(适配器)。适配器经过训练以学习特定于任务的信息。这种方法已被证明在内存效率方面非常高,计算使用量较低,同时产生的结果与完全微调的模型相当。

使用 PEFT 训练的适配器通常也比完整模型小一个数量级,这使得共享、存储和加载它们变得很方便。

存储在 Hub 上的 OPTForCausalLM 模型的适配器权重仅约为 6MB,而模型权重的完整大小可能约为 700MB。

如果您有兴趣了解更多关于 🤗 PEFT 库的信息,请查看 文档

设置

从安装 🤗 PEFT 开始

pip install peft

如果您想尝试全新的功能,您可能对从源代码安装库感兴趣

pip install git+https://github.com/huggingface/peft.git

支持的 PEFT 模型

🤗 Transformers 本机支持一些 PEFT 方法,这意味着您可以加载本地或在 Hub 上存储的适配器权重,并使用几行代码轻松运行或训练它们。以下方法受支持

如果您想使用其他 PEFT 方法,例如提示学习或提示微调,或了解 🤗 PEFT 库的总体信息,请参阅 文档

加载 PEFT 适配器

要从 🤗 Transformers 加载和使用 PEFT 适配器模型,请确保 Hub 存储库或本地目录包含一个 adapter_config.json 文件和适配器权重,如上面的示例图像所示。然后,您可以使用 AutoModelFor 类加载 PEFT 适配器模型。例如,要加载用于因果语言建模的 PEFT 适配器模型

  1. 指定 PEFT 模型 ID
  2. 将其传递给 AutoModelForCausalLM
from transformers import AutoModelForCausalLM, AutoTokenizer

peft_model_id = "ybelkada/opt-350m-lora"
model = AutoModelForCausalLM.from_pretrained(peft_model_id)

您可以使用 AutoModelFor 类或基本模型类(如 OPTForCausalLMLlamaForCausalLM)加载 PEFT 适配器。

您还可以通过调用 load_adapter 方法加载 PEFT 适配器

from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "facebook/opt-350m"
peft_model_id = "ybelkada/opt-350m-lora"

model = AutoModelForCausalLM.from_pretrained(model_id)
model.load_adapter(peft_model_id)

查看下面的 API 文档 部分以获取更多详细信息。

以 8 位或 4 位加载

bitsandbytes 集成支持 8 位和 4 位精度数据类型,这些类型对于加载大型模型非常有用,因为它可以节省内存(请参阅 bitsandbytes 集成 指南 以了解更多信息)。将 load_in_8bitload_in_4bit 参数添加到 from_pretrained() 并设置 device_map="auto" 以有效地将模型分配到您的硬件

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

peft_model_id = "ybelkada/opt-350m-lora"
model = AutoModelForCausalLM.from_pretrained(peft_model_id, quantization_config=BitsAndBytesConfig(load_in_8bit=True))

添加新适配器

您可以使用 ~peft.PeftModel.add_adapter 向具有现有适配器的模型添加新适配器,只要新适配器与当前适配器类型相同。例如,如果您有一个现有 LoRA 适配器附加到模型

from transformers import AutoModelForCausalLM, OPTForCausalLM, AutoTokenizer
from peft import LoraConfig

model_id = "facebook/opt-350m"
model = AutoModelForCausalLM.from_pretrained(model_id)

lora_config = LoraConfig(
    target_modules=["q_proj", "k_proj"],
    init_lora_weights=False
)

model.add_adapter(lora_config, adapter_name="adapter_1")

要添加新适配器

# attach new adapter with same config
model.add_adapter(lora_config, adapter_name="adapter_2")

现在,您可以使用 ~peft.PeftModel.set_adapter 设置要使用的适配器

# use adapter_1
model.set_adapter("adapter_1")
output_disabled = model.generate(**inputs)
print(tokenizer.decode(output_disabled[0], skip_special_tokens=True))

# use adapter_2
model.set_adapter("adapter_2")
output_enabled = model.generate(**inputs)
print(tokenizer.decode(output_enabled[0], skip_special_tokens=True))

启用和禁用适配器

将适配器添加到模型后,您可以启用或禁用适配器模块。要启用适配器模块

from transformers import AutoModelForCausalLM, OPTForCausalLM, AutoTokenizer
from peft import PeftConfig

model_id = "facebook/opt-350m"
adapter_model_id = "ybelkada/opt-350m-lora"
tokenizer = AutoTokenizer.from_pretrained(model_id)
text = "Hello"
inputs = tokenizer(text, return_tensors="pt")

model = AutoModelForCausalLM.from_pretrained(model_id)
peft_config = PeftConfig.from_pretrained(adapter_model_id)

# to initiate with random weights
peft_config.init_lora_weights = False

model.add_adapter(peft_config)
model.enable_adapters()
output = model.generate(**inputs)

要禁用适配器模块

model.disable_adapters()
output = model.generate(**inputs)

训练 PEFT 适配器

PEFT 适配器由 Trainer 类支持,因此您可以为您的特定用例训练适配器。它只需要添加几行代码。例如,要训练 LoRA 适配器

如果您不熟悉使用 Trainer 微调模型,请查看 微调预训练模型 教程。

  1. 使用任务类型和超参数定义您的适配器配置(有关超参数的作用的更多详细信息,请参阅 ~peft.LoraConfig)。
from peft import LoraConfig

peft_config = LoraConfig(
    lora_alpha=16,
    lora_dropout=0.1,
    r=64,
    bias="none",
    task_type="CAUSAL_LM",
)
  1. 将适配器添加到模型。
model.add_adapter(peft_config)
  1. 现在,您可以将模型传递给 Trainer
trainer = Trainer(model=model, ...)
trainer.train()

要保存您训练的适配器并将其加载回来

model.save_pretrained(save_dir)
model = AutoModelForCausalLM.from_pretrained(save_dir)

向 PEFT 适配器添加其他可训练层

您还可以通过在 PEFT 配置中传递 modules_to_save,在具有附加适配器的模型之上微调其他可训练适配器。例如,如果您还想在具有 LoRA 适配器的模型之上微调 lm_head

from transformers import AutoModelForCausalLM, OPTForCausalLM, AutoTokenizer
from peft import LoraConfig

model_id = "facebook/opt-350m"
model = AutoModelForCausalLM.from_pretrained(model_id)

lora_config = LoraConfig(
    target_modules=["q_proj", "k_proj"],
    modules_to_save=["lm_head"],
)

model.add_adapter(lora_config)

API 文档

class transformers.integrations.PeftAdapterMixin

< >

( )

一个包含所有加载和使用 PEFT 库支持的适配器权重的函数的类。有关适配器及其在基于 Transformer 的模型上的注入的更多详细信息,请查看 PEFT 库的文档:https://huggingface.co/docs/peft/index

目前支持的 PEFT 方法都是非前缀微调方法。以下是任何人都可以使用此混合类加载、训练和运行的支持的 PEFT 方法列表

其他 PEFT 模型,例如提示微调、提示学习,不在此范围内,因为这些适配器无法“注入”到 torch 模块中。要使用这些方法,请参考 PEFT 库的使用指南。

使用此混合类,如果安装了正确的 PEFT 版本,就可以

  • 加载存储在本地路径或远程 Hub 仓库中的适配器,并将其注入到模型中
  • 在模型中附加新的适配器,并使用 Trainer 或您自己的方式对其进行训练。
  • 附加多个适配器,并迭代地激活/停用它们
  • 激活/停用模型中的所有适配器。
  • 获取活动适配器的 state_dict

load_adapter

< >

( peft_model_id: 可选 = None adapter_name: 可选 = None revision: 可选 = None token: 可选 = None device_map: 可选 = 'auto' max_memory: 可选 = None offload_folder: 可选 = None offload_index: 可选 = None peft_config: 字典 = None adapter_state_dict: 可选 = None adapter_kwargs: 可选 = None )

参数

  • peft_model_id (str, 可选) — 要在 Hub 上查找的模型的标识符,或本地保存的适配器配置文件和适配器权重的路径。
  • adapter_name (str, 可选) — 要使用的适配器名称。如果没有设置,将使用默认适配器。
  • revision (str, 可选,默认值为 "main") — 要使用的特定模型版本。它可以是分支名称、标签名称或提交 ID,因为我们使用基于 git 的系统在 huggingface.co 上存储模型和其他工件,因此 revision 可以是 git 允许的任何标识符。

    要测试您在 Hub 上创建的拉取请求,可以传递 revision=“refs/pr/“。

  • token (str, 可选) — 是否使用身份验证令牌来加载远程文件夹。在加载 HuggingFace Hub 上的私有仓库时非常有用。您可能需要调用 huggingface-cli login 并粘贴您的令牌以将其缓存。
  • device_map (strDict[str, Union[int, str, torch.device]]inttorch.device, 可选) — 指定每个子模块应该放置位置的映射。它不需要细化到每个参数/缓冲区名称,只要给定的模块名称在内,它的每个子模块都将被发送到同一个设备。如果我们只传递模型将被分配到的设备(例如,"cpu""cuda:1""mps" 或 GPU 序数排名,如 1),则设备映射将把整个模型映射到此设备。传递 device_map = 0 意味着将整个模型放在 GPU 0 上。

    要让 Accelerate 自动计算最优化的 device_map,请设置 device_map="auto"。有关每个选项的更多信息,请参见 设计设备映射

  • max_memory (Dict, 可选) — 设备标识符到最大内存的字典。如果未设置,将默认为每个 GPU 的可用最大内存和可用的 CPU RAM。
  • offload_folder (stros.PathLike, 可选) — 如果 device_map 包含任何值为 "disk" 的值,则为我们将卸载权重的文件夹。
  • offload_index (int, 可选) — 传递给 accelerate.dispatch_model 方法的 offload_index 参数。
  • peft_config (Dict[str, Any], 可选) — 要添加的适配器的配置,支持的适配器是非前缀调整和自适应提示方法。 如果用户直接传递 PEFT 状态字典,则使用此参数
  • adapter_state_dict (Dict[str, torch.Tensor], 可选) — 要加载的适配器的状态字典。 如果用户直接传递 PEFT 状态字典,则使用此参数
  • adapter_kwargs (Dict[str, Any], 可选) — 传递给适配器配置的 from_pretrained 方法和 find_adapter_config_file 方法的额外关键字参数。

从文件或远程 Hub 文件夹加载适配器权重。 如果您不熟悉适配器和 PEFT 方法,我们邀请您在 PEFT 官方文档中了解更多信息: https://huggingface.co/docs/peft

需要 peft 作为后端来加载适配器权重。

add_adapter

< >

( adapter_config adapter_name: Optional = None )

参数

  • adapter_config (~peft.PeftConfig) — 要添加的适配器的配置,支持的适配器是非前缀调整和自适应提示方法
  • adapter_name (str, 可选, 默认值为 "default") — 要添加的适配器的名称。 如果没有传递名称,则为适配器分配默认名称。

如果您不熟悉适配器和 PEFT 方法,我们邀请您在 PEFT 官方文档中了解更多信息: https://huggingface.co/docs/peft

为当前模型添加一个全新的适配器,用于训练目的。 如果没有传递适配器名称,则为适配器分配默认名称以遵循 PEFT 库的约定(在 PEFT 中,我们使用“default”作为默认适配器名称)。

set_adapter

< >

( adapter_name: Union )

如果您不熟悉适配器和 PEFT 方法,我们邀请您在 PEFT 官方文档中了解更多信息: https://huggingface.co/docs/peft

禁用附加到模型的所有适配器。这会导致仅使用基础模型进行推理。

enable_adapters

< >

( )

如果您不熟悉适配器和 PEFT 方法,我们邀请您在 PEFT 官方文档中了解更多信息: https://huggingface.co/docs/peft

启用附加到模型的适配器。模型将使用 self.active_adapter()

active_adapters

< >

( )

如果您不熟悉适配器和 PEFT 方法,我们邀请您在 PEFT 官方文档中了解更多信息: https://huggingface.co/docs/peft

获取模型当前活动的适配器。在多适配器推理(组合多个适配器进行推理)的情况下,返回所有活动适配器的列表,以便用户可以相应地处理它们。

对于之前的 PEFT 版本(不支持多适配器推理),module.active_adapter 将返回单个字符串。

get_adapter_state_dict

< >

( adapter_name: Optional = None )

参数

  • adapter_name (str, 可选) — 要获取状态字典的适配器名称。如果未传递名称,则使用活动适配器。

如果您不熟悉适配器和 PEFT 方法,我们邀请您在 PEFT 官方文档中了解更多信息: https://huggingface.co/docs/peft

获取适配器状态字典,该字典应仅包含指定 adapter_name 适配器的权重张量。如果未传递 adapter_name,则使用活动适配器。

< > 在 GitHub 上更新