【Hugging Face】PEFT 库中的 get_peft_model() 函数:将基础模型转换为支持参数高效微调(PEFT)的模型

在 Hugging Face 的 PEFT(Parameter-Efficient Fine-Tuning)库中,get_peft_model() 函数是用于将基础模型(通常是 Hugging Face Transformers 模型)转换为支持参数高效微调(PEFT)的模型的关键函数。它通过应用指定的 PEFT 配置(如 LoraConfigPromptTuningConfig 等)为模型添加适配器(adapters),从而实现高效微调。以下是对 get_peft_model() 函数的详细讲解,包括其功能、参数、用法、代码示例和注意事项。


1. get_peft_model() 功能概述

get_peft_model() 函数的主要作用是将一个预训练模型(base model)与 PEFT 配置结合,生成一个新的 PeftModel 实例。这个实例包含了基础模型和附加的 PEFT 适配器(如 LoRA 矩阵、Prompt Tuning 提示、IA3 缩放向量等)。适配器只包含少量可训练参数,而基础模型的权重通常保持冻结,从而实现高效微调。

核心功能

  • 根据指定的 PEFT 配置(如 LoraConfigVeraConfig 等)为模型添加适配器。
  • 自动冻结基础模型的权重,仅允许适配器参数可训练(除非配置中指定了 modules_to_save)。
  • 支持多任务适配器(通过 adapter_name 参数)。
  • 返回一个 PeftModel 实例,兼容 Hugging Face 的 Trainer 和推理流程。

2. get_peft_model() 函数签名

以下是 get_peft_model() 函数的签名(基于 PEFT 最新版本):

def get_peft_model(
    model: torch.nn.Module,
    peft_config: PeftConfig,
    adapter_name: str = "default",
    mixed: bool = False
) -> PeftModel
参数说明
  • modeltorch.nn.Module,必填)

    • 基础模型,通常是 Hugging Face Transformers 模型(如 AutoModelForCausalLMAutoModelForSequenceClassification 等)。
    • 示例:model = AutoModelForCausalLM.from_pretrained("gpt2")
  • peft_configPeftConfig,必填)

    • PEFT 配置对象,指定使用的微调方法及其参数。
    • 支持的配置类包括:
      • LoraConfig(低秩适配)
      • PromptTuningConfig(提示微调)
      • PrefixTuningConfig(前缀微调)
      • P-tuningConfig(P-Tuning)
      • IA3Config(缩放向量微调)
      • LoftQConfig(量化低秩适配)
      • VeraConfig(向量基随机矩阵适配)
      • AdaLoraConfig(自适应低秩适配)
    • 示例:peft_config = LoraConfig(task_type="CAUSAL_LM", r=8, target_modules=["c_attn"])
  • adapter_name(字符串,默认:"default"

    • 指定适配器的名称,用于支持多任务或多适配器场景。
    • 示例:adapter_name="task1"
    • 如果需要添加多个适配器,可以后续通过 peft_model.add_adapter() 使用不同的 adapter_name
  • mixed(布尔值,默认:False

    • 是否启用混合精度(mixed precision)支持。
    • 如果为 True,适配器将支持混合精度训练(需要 PyTorch 和适当的硬件支持)。
    • 通常保持默认值 False,除非需要优化内存或性能。
返回值
  • PeftModel
    • 一个 PeftModel 实例,包含基础模型和 PEFT 适配器。
    • 该实例支持 Hugging Face 的 Trainergenerate()(生成任务)以及标准 PyTorch 训练流程。
    • 提供方法如 print_trainable_parameters() 查看可训练参数。

3. 使用 get_peft_model() 的基本流程

以下是一个使用 get_peft_model() 微调 GPT-2 模型(用于因果语言建模任务)的完整示例,展示如何结合 LoraConfig

步骤 1:安装和导入库
pip install peft transformers torch datasets
from transformers import AutoModelForCausalLM, AutoTokenizer, Trainer, TrainingArguments
from peft import LoraConfig, get_peft_model
from datasets import load_dataset
步骤 2:加载模型和数据集
# 加载预训练模型和分词器
model_name = "gpt2"
model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token  # 为 GPT-2 设置 pad token

# 加载数据集(以 wikitext 为例)
dataset = load_dataset("wikitext", "wikitext-2-raw-v1")

# 数据预处理
def tokenize_function(examples):
    return tokenizer(examples["text"], truncation=True, padding="max_length", max_length=128)

tokenized_dataset = dataset.map(tokenize_function, batched=True)
步骤 3:配置 PEFT(以 LoraConfig 为例)
# 配置 LoRA
lora_config = LoraConfig(
    task_type="CAUSAL_LM",           # 因果语言模型任务
    r=8,                             # 低秩矩阵的秩
    lora_alpha=16,                   # 缩放因子
    lora_dropout=0.1,                # Dropout 概率
    target_modules=["c_attn"],       # 应用 LoRA 的模块(GPT-2 的注意力层)
    modules_to_save=["lm_head"]      # 全量微调语言模型头
)

# 使用 get_peft_model() 创建 PEFT 模型
peft_model = get_peft_model(model, lora_config, adapter_name="default")

# 查看可训练参数
peft_model.print_trainable_parameters()

输出示例:

trainable params: 294,912 || all params: 124,747,008 || trainable%: 0.236

这表明只有约 0.24% 的参数需要训练(LoRA 权重 + 语言模型头参数)。

步骤 4:训练模型
# 配置训练参数
training_args = TrainingArguments(
    output_dir="./results",
    evaluation_strategy="epoch",
    learning_rate=2e-5,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    weight_decay=0.01,
)

# 初始化 Trainer
trainer = Trainer(
    model=peft_model,
    args=training_args,
    train_dataset=tokenized_dataset["train"].select(range(1000)),  # 选取子集以加速示例
    eval_dataset=tokenized_dataset["validation"].select(range(200)),
)

# 开始训练
trainer.train()
步骤 5:保存和加载 PEFT 模型
# 保存 PEFT 适配器
peft_model.save_pretrained("./lora_model")

# 加载 PEFT 模型
from peft import PeftModel
base_model = AutoModelForCausalLM.from_pretrained(model_name)
loaded_model = PeftModel.from_pretrained(base_model, "./lora_model")
步骤 6:推理
# 准备输入
inputs = tokenizer("Once upon a time", return_tensors="pt").to("cuda")

# 推理
loaded_model.eval()
outputs = loaded_model.generate(**inputs, max_length=50)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))

4. 支持的 PEFT 配置

get_peft_model() 支持以下 PEFT 配置类,每种配置对应一种微调方法:

  • LoraConfig:低秩适配(LoRA),通过低秩矩阵更新权重。
  • AdaLoraConfig:自适应 LoRA,动态调整秩。
  • PromptTuningConfig:提示微调,添加可训练的虚拟 token。
  • PrefixTuningConfig:前缀微调,为每层添加前缀向量。
  • P-tuningConfig:P-Tuning,使用 LSTM 或 MLP 建模提示。
  • IA3Config:(IA)^3,通过缩放向量调整激活。
  • LoftQConfig:量化 LoRA,结合量化初始化。
  • VeraConfig:VeRA,使用共享低秩矩阵和缩放向量。

选择配置的建议

  • 生成任务LoraConfig, VeraConfig, PrefixTuningConfig, P-tuningConfigIA3Config 更适合(如 GPT、LLaMA)。
  • 分类任务LoraConfigPromptTuningConfig 更通用(如 BERT)。
  • 量化场景LoftQConfigLoraConfig 结合 4-bit 量化。
  • 存储受限VeraConfig(可不保存共享矩阵)或 IA3Config(参数量极少)。

5. 进阶用法

以下是一些 get_peft_model() 的高级用法,展示其灵活性:

多任务适配器

支持为不同任务创建多个适配器,并动态切换:

# 配置两个 LoRA 适配器
lora_config_task1 = LoraConfig(
    task_type="CAUSAL_LM",
    r=8,
    target_modules=["c_attn"],
    lora_alpha=16
)
lora_config_task2 = LoraConfig(
    task_type="CAUSAL_LM",
    r=16,
    target_modules=["c_attn"],
    lora_alpha=32
)

# 创建第一个适配器
peft_model = get_peft_model(model, lora_config_task1, adapter_name="task1")

# 添加第二个适配器
peft_model.add_adapter("task2", lora_config_task2)

# 切换适配器
peft_model.set_adapter("task1")  # 使用 task1 适配器
peft_model.set_adapter("task2")  # 切换到 task2 适配器
结合量化

结合 bitsandbytes 进行 4-bit 量化以节省内存:

from transformers import BitsAndBytesConfig

# 加载量化模型
quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model = AutoModelForCausalLM.from_pretrained(model_name, quantization_config=quantization_config)

# 配置 LoRA
lora_config = LoraConfig(
    task_type="CAUSAL_LM",
    r=8,
    target_modules=["c_attn"],
    lora_alpha=16
)

# 创建 PEFT 模型
peft_model = get_peft_model(model, lora_config)
检查可训练参数

使用 print_trainable_parameters() 查看参数分布:

peft_model.print_trainable_parameters()

输出示例:

trainable params: 294,912 || all params: 124,747,008 || trainable%: 0.236
合并适配器权重

将适配器权重合并到基础模型以消除推理延迟:

merged_model = peft_model.merge_and_unload()
merged_model.save_pretrained("./merged_model")
保存到 Hugging Face Hub

将适配器上传到 Hugging Face Hub:

peft_model.push_to_hub("your-username/peft-model")

6. 常见问题与解答

  • Q1:如何选择合适的 peft_config

    • 根据任务和资源选择:
      • 生成任务LoraConfig, VeraConfig, PrefixTuningConfig
      • 分类任务LoraConfig, PromptTuningConfig
      • 量化微调LoftQConfigLoraConfig 结合 4-bit 量化。
      • 存储受限VeraConfig(最小检查点)或 IA3Config(最少参数)。
    • 参考 PEFT 文档中的基准测试或实验不同配置。
  • Q2:为什么 get_peft_model() 报错?

    • 原因 1:target_modules 配置错误
      • 检查 target_modules 是否与模型结构匹配(使用 model.named_modules() 查看)。
      • 示例:LLaMA 使用 ["q_proj", "v_proj"],GPT-2 使用 ["c_attn"]
    • 原因 2:模型不兼容
      • 确保 model 是 Hugging Face Transformers 模型,且支持 PEFT。
    • 原因 3:内存不足
      • 启用量化(4-bit 或 8-bit)或减少 r(LoRA 秩)。
  • Q3:如何添加多个适配器?

    • 使用 get_peft_model() 创建第一个适配器,然后通过 peft_model.add_adapter(adapter_name, peft_config) 添加更多适配器。
    • 示例见“多任务适配器”部分。
  • Q4:mixed=True 有什么作用?

    • 启用混合精度训练(FP16/BF16),减少内存占用并加速训练。
    • 需要 GPU 支持和 PyTorch 的 torch.cuda.amp
  • Q5:如何调试性能不佳?

    • 检查 peft_config 参数(例如,增加 r 或扩展 target_modules)。
    • 调整学习率(LoRA 推荐 2e-5,Prompt Tuning 推荐 1e-3)。
    • 确保数据集质量和预处理正确。
    • 尝试其他 PEFT 方法(例如,从 PromptTuningConfig 切换到 LoraConfig)。

7. 注意事项

  • 模型兼容性

    • get_peft_model() 要求输入模型是 torch.nn.Module 的子类,且通常是 Hugging Face Transformers 模型。
    • 非 Transformer 模型可能需要自定义适配器配置。
  • 冻结权重

    • 默认情况下,基础模型的权重被冻结,仅适配器参数可训练。
    • 如果需要微调特定模块(如分类头),在 peft_config 中设置 modules_to_save
  • 内存管理

    • 对于大型模型,建议结合 bitsandbytes 的 4-bit 或 8-bit 量化。
    • 使用梯度检查点(model.gradient_checkpointing_enable())以进一步节省内存。
  • 适配器切换

    • 多任务场景下,确保通过 set_adapter() 切换到正确的 adapter_name
    • 每次推理或训练前检查当前激活的适配器(peft_model.active_adapter)。

8. 进一步资源

<think>好的,我现在要解释如何使用PyTorch和Hugging FacePEFT进行QLoRA微调,并结合Transformers的Trainer来实现高效训练。首先,我需要回忆一下QLoRA的基本概念,可能和LoRA有关,对吧?LoRA是低秩适应,用于高效微调模型。那QLoRA可能是量化版的LoRA,结合了量化技术来减少内存使用。 然后,PEFTHugging Face的一个参数高效微调支持多种方法,包括LoRA。那QLoRA应该也是PEFT支持的一种方法。需要确认一下PEFT是否支持QLoRA,可能需要查看文档。不过用户已经提到要结合PEFT,所以应该支持。 接下来是Transformers Trainer,这个类提供了训练模型的便捷方式,不需要自己写训练循环。结合Trainer和PEFT的QLoRA,应该是在创建模型的时候应用PEFT的配置,然后传递给Trainer进行训练。 接下来需要分步骤解释整个过程。首先,安装必要的,如torch、transformerspeft。然后,加载预训练模型,并应用QLoRA配置,可能通过get_peft_model函数。然后设置训练参数,使用Trainer类,传入模型、数据集、训练参数等。 需要提到QLoRA的优势,比如通过量化降低显存占用,同时保持低秩适配,这样可以在较小的GPU上微调模型。可能还需要说明量化是如何应用的,比如4-bit量化,以及LoRA的秩和alpha参数的选择。 可能还需要提到数据集的处理,使用datasets加载数据,并进行预处理,比如tokenization。然后使用Trainer的train方法进行训练。 需要注意的细节包括:模型加载时可能需要使用BitsAndBytes进行4-bit量化,因为Hugging Facetransformers已经集成了这个功能。所以在加载模型时,要指定load_in_4bit=True,并结合bnb的配置参数。 然后,PEFT的配置参数,比如LoRA的r、lora_alpha、target_modules等。需要确定哪些模块需要添加LoRA适配器,通常是注意力层的q、v矩阵。 训练参数方面,使用TrainingArguments设置输出目录、学习率、批次大小等,然后传递给Trainer。 最后,训练完成后保存适配器权重,而不是整个模型,这样可以节省空间。加载的时候,需要先加载原模型,再加载适配器。 可能需要考虑常见问题,比如显存不足,这时候QLoRA的优势就体现出来了。或者训练过程中的稳定性,比如梯度裁剪、优化器选择等。 总结步骤应该是:安装,加载并量化模型,应用PEFT配置,准备数据,设置训练参数,训练,保存。每个步骤需要简要说明,并强调QLoRA如何提高效率,减少资源消耗。 还要确保使用正确的中文术语,比如“量化”、“低秩适配器”、“参数高效微调”等。需要检查是否有遗漏的关键点,比如模型保存和加载的方式,或者评估方法,但用户主要关注训练实现,可能不需要深入评估部分。 可能还需要给出一个简单的代码示例框架,帮助用户理解结构,比如如何用代码实现各个步骤。但用户的问题主要是解释,所以代码可以简略,用文字描述步骤。 最后,要确保回答结构清晰,分点或分步骤,让用户容易理解。同时保证技术细节正确,比如QLoRA确实结合了4-bit量化和LoRA,PEFT支持情况等。</think>以下是对使用 **PyTorch + Hugging Face PEFT (QLoRA) + Transformers Trainer** 进行高效模型微调的技术解析,分步说明其核心原理与实现流程: --- ### 一、核心概念 1. **QLoRA (Quantized Low-Rank Adaptation)** - **量化 (Quantization)**:模型权重从 FP32/FP16 压缩为 4-bit 精度,大幅降低显存占用。 - **低秩适配 (LoRA)**: 冻结原模型参数,仅训练低秩分解的适配器(Adapter),减少可训练参数量(通常 <1%)。 - **结合优势**: QLoRA 通过 4-bit 量化 + LoRA 微调,实现在单卡(如 24GB GPU)上微调超大规模模型(如 70B 参数)。 2. **关键技术组件** - **PyTorch**: 基础深度学习框架。 - **Hugging Face Transformers**: 提供预训练模型与 `Trainer` 类(简化训练流程)。 - **PEFT (Parameter-Efficient Fine-Tuning)**: 实现参数高效微调方法(如 LoRA、QLoRA)。 --- ### 二、实现步骤 #### 1. 环境准备 安装关键: ```bash pip install torch transformers peft accelerate bitsandbytes datasets ``` #### 2. 加载模型与量化配置 使用 `BitsAndBytes` 进行 4-bit 量化: ```python from transformers import AutoModelForCausalLM, BitsAndBytesConfig bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.bfloat16, bnb_4bit_use_double_quant=True ) model = AutoModelForCausalLM.from_pretrained( "meta-llama/Llama-2-7b-hf", quantization_config=bnb_config, device_map="auto" ) ``` #### 3. 应用 QLoRA 适配器 通过 PEFT 添加低秩适配层: ```python from peft import LoraConfig, get_peft_model lora_config = LoraConfig( r=8, # 低秩矩阵的秩 lora_alpha=32, # 缩放因子 target_modules=["q_proj", "v_proj"], # 目标模块(注意力层的 Q/V 矩阵) lora_dropout=0.05, task_type="CAUSAL_LM" ) model = get_peft_model(model, lora_config) model.print_trainable_parameters() # 输出可训练参数量(通常 <1%) ``` #### 4. 配置训练参数 使用 `TrainingArguments` 定义训练超参数: ```python from transformers import TrainingArguments training_args = TrainingArguments( output_dir="./results", per_device_train_batch_size=4, gradient_accumulation_steps=4, learning_rate=2e-5, num_train_epochs=3, fp16=True, # 混合精度训练 logging_steps=10, save_steps=100, optim="paged_adamw_8bit" # 优化器适配量化 ) ``` #### 5. 准备数据集 使用 `datasets` 加载数据并预处理: ```python from datasets import load_dataset dataset = load_dataset("json", data_files="data.jsonl") tokenized_data = dataset.map( lambda x: tokenizer(x["text"], truncation=True, max_length=512), batched=True ) ``` #### 6. 启动训练 通过 `Trainer` 封装训练流程: ```python from transformers import Trainer trainer = Trainer( model=model, args=training_args, train_dataset=tokenized_data["train"], data_collator=lambda data: {"input_ids": torch.stack([d["input_ids"] for d in data])} ) trainer.train() ``` #### 7. 保存与加载适配器 仅保存轻量级适配器权重: ```python model.save_pretrained("adapter_weights") # 保存适配器 # 加载时先加载原模型,再加载适配器 model = AutoModelForCausalLM.from_pretrained(...) model = PeftModel.from_pretrained(model, "adapter_weights") ``` --- ### 三、关键优势 1. **显存高效** - 4-bit 量化减少约 70% 显存占用。 - 梯度检查点(Gradient Checkpointing)进一步优化显存。 2. **参数高效** - 仅训练适配器参数(如 7B 模型仅需 0.03B 可训练参数)。 3. **无缝集成** - 与 Hugging Face 生态(如 `Trainer`、`datasets`)深度兼容。 --- ### 四、典型应用场景 - 在有限算力下微调大语言模型(如 LLaMA、Falcon)。 - 快速迭代多任务适配(每个任务保存独立适配器)。 通过 QLoRA + Transformers Trainer,开发者能以极低资源成本实现大模型定制化,平衡效率与性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彬彬侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值