PEFT高效调参学习是针对大规模模型的微调技术,旨在通过引入少量微调参数,显著提升模型在特定任务上的表现,同时大幅降低计算和存储资源需求。本文介绍PEFT的全量微调、BitFit、Prompt Tuning和Prefix Tuning方法,通过实例演示如何快速入门并高效微调预训练模型。PEFT方法优势包括减少计算资源需求、节省存储空间以及提高模型多样性。其中,全量微调、BitFit、Prompt Tuning与Prefix Tuning提供了不同的微调策略,旨在在保持高性能的同时,降低资源消耗,适应低资源环境和大规模模型训练的挑战。随着技术的不断进步,PEFT有望在更多应用场景中发挥关键作用。
参数高效微调PEFT(一)快速入门BitFit、Prompt Tuning、Prefix Tuning - peft指南
引言
随着预训练语言模型的普及,如何在减少资源消耗的同时有效提升模型在特定任务上的表现成为了当前研究的焦点。参数高效微调技术(PEFT)应运而生,尤其是针对大规模模型的微调。本文将详细介绍PEFT的几种方法:全量微调、BitFit、Prompt Tuning和Prefix Tuning,并通过实例演示如何高效地微调预训练模型。
参数高效微调PEFT基础
在深入PEFT方法之前,首先理解预训练模型是如何在大规模数据集上进行广泛学习的,以及下游任务微调如何通过调整模型参数来提升特定任务的性能。PEFT旨在通过引入少量微调参数,显著提升模型在特定任务上的表现,同时大大降低内存和计算资源的需求。
预训练语言模型与下游任务微调
预训练模型通常是在大量无标注文本上进行训练,学习到通用的语言表示。下游任务微调则是通过调整模型参数,使其在特定任务上达到最优性能。PEFT通过改变模型参数的更新方式,使得少量的微调参数就能带来性能提升。
PEFT方法的优势
PEFT方法的优势在于:
- 减少计算资源需求:与全量微调相比,PEFT方法通过减少需要更新的参数量,降低了训练和部署的计算资源需求。
- 节省存储空间:微调的参数数量较少,因此节省了存储模型所需的磁盘空间。
- 提高模型多样性:PEFT方法减少了模型遗忘特定任务信息的风险,有助于保持模型的适应性和多样性。
全量微调Bloom模型
以Bloom模型为例进行全量微调的实例演示。
数据集加载与预处理
from datasets import Dataset
from transformers import AutoTokenizer, AutoModelForCausalLM, DataCollatorForSeq2Seq, TrainingArguments, Trainer
# 数据集加载
ds = Dataset.load_from_disk("./alpaca_data_zh/")
# 数据集预处理
def process_func(example):
MAX_LENGTH = 256
input_ids, attention_mask, labels = [], [], []
instruction = tokenizer("\n".join(["Human: " + example["instruction"], example["input"]]).strip() + "\n\nAssistant: ")
response = tokenizer(example["output"] + tokenizer.eos_token)
input_ids = instruction["input_ids"] + response["input_ids"]
attention_mask = instruction["attention_mask"] + response["attention_mask"]
labels = [-100] * len(instruction["input_ids"]) + response["input_ids"]
if len(input_ids) > MAX_LENGTH:
input_ids = input_ids[:MAX_LENGTH]
attention_mask = attention_mask[:MAX_LENGTH]
labels = labels[:MAX_LENGTH]
return {
"input_ids": input_ids,
"attention_mask": attention_mask,
"labels": labels
}
tokenized_ds = ds.map(process_func, remove_columns=ds.column_names)
模型训练与推理
# 模型加载
model = AutoModelForCausalLM.from_pretrained("path/to/pretrained/model")
# 创建训练器
args = TrainingArguments(
output_dir="./chatbot",
per_device_train_batch_size=1,
logging_steps=100,
num_train_epochs=1
)
trainer = Trainer(
model=model,
args=args,
train_dataset=tokenized_ds,
data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer, padding=True)
)
# 模型训练
trainer.train()
# 模型推理
from transformers import pipeline
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, device=0)
ipt = "Human: {}\n".format("考试有哪些技巧?").strip() + "\n\nAssistant: "
pipe(ipt, max_length=256, do_sample=True)
BitFit微调实践
BitFit是一种通过更新或选择性更新特定参数(如偏置项)来微调模型的方法。它显著减少了微调所需的参数数量,从而降低了资源消耗。
# 加载预训练模型
model = AutoModelForCausalLM.from_pretrained("path/to/pretrained/model", low_cpu_mem_usage=True)
# 计算模型的参数数量
num_param = sum(param.numel() for param in model.parameters())
# 只更新偏置参数
for name, param in model.named_parameters():
if "bias" not in name:
param.requires_grad = False
else:
num_param -= param.numel()
# 训练与推理
Prompt Tuning与Prefix Tuning
Prompt Tuning与Prefix Tuning均属于通过引入任务特定的提示或前缀来微调模型的方法,旨在减少资源消耗的同时保持模型性能。
Prompt Tuning
Prompt Tuning使用连续的虚拟令牌作为提示,这些令牌在训练过程被微调,从而引导模型生成期望的输出。
Prefix Tuning
Prefix Tuning通过在模型的输入端添加可训练的前缀,以引导模型生成特定任务的输出。此方法通过微调前缀来调整模型的上下文理解,从而在不同任务上表现良好。
# Prompt Tuning示例
from peft import PromptTuningTarget
# 定义提示目标
target = PromptTuningTarget("前缀")
# 使用PEFT进行微调
from peft import (
get_peft_model,
prepare_model_for_int8_training,
LoraConfig,
TaskType,
PeftType,
)
config = LoraConfig(task_type=TaskType.CAUSAL_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1)
peft_model = get_peft_model(model, config)
peft_model = prepare_model_for_int8_training(peft_model)
# 进行微调
trainer.train()
# 进行推理
结论与展望
PEFT方法为大规模模型的高效微调提供了可行路径,通过减少参数更新量实现了性能提升、资源节约和模型多样性的平衡。未来的研究可能关注于进一步优化PEFT方法的效率,探索更高效、更灵活的参数更新策略,以及在更多应用场景中的拓展与应用。随着硬件和算法的不断进步,PEFT技术有望在低资源环境和大规模模型训练中发挥更大作用。
共同学习,写下你的评论
评论加载中...
作者其他优质文章