使用HuggingFace PEFT实现大模型高效微调与推理指南

使用HuggingFace PEFT实现大模型高效微调与推理指南

peft 🤗 PEFT: State-of-the-art Parameter-Efficient Fine-Tuning. peft 项目地址: https://gitcode.com/gh_mirrors/pe/peft

引言

在自然语言处理领域,大型预训练模型如T5、GPT等展现出强大的能力,但这些模型参数量巨大,直接微调需要大量计算资源。PEFT(Parameter-Efficient Fine-Tuning)技术通过仅微调少量参数就能获得接近全参数微调的效果,极大降低了资源需求。本文将详细介绍如何使用PEFT中的LoRA技术对大型序列到序列模型进行高效微调与推理。

环境准备与模型加载

首先需要安装必要的库,包括transformers、peft和datasets等。PEFT提供了PeftModel和PeftConfig等核心类,可以方便地加载和配置基于LoRA的微调模型。

from transformers import AutoModelForSeq2SeqLM
from peft import PeftModel, PeftConfig
import torch
from datasets import load_dataset
from transformers import AutoTokenizer

加载预训练模型与PEFT适配器

对于大型模型,合理分配内存至关重要。我们可以通过max_memory参数控制各设备的内存使用:

peft_model_id = "smangrul/twitter_complaints_bigscience_T0_3B_LORA_SEQ_2_SEQ_LM"
max_memory = {0: "6GIB", 1: "0GIB", 2: "0GIB", 3: "0GIB", 4: "0GIB", "cpu": "30GB"}
config = PeftConfig.from_pretrained(peft_model_id)
model = AutoModelForSeq2SeqLM.from_pretrained(
    config.base_model_name_or_path, 
    device_map="auto", 
    max_memory=max_memory
)
model = PeftModel.from_pretrained(
    model, 
    peft_model_id, 
    device_map="auto", 
    max_memory=max_memory
)

这段代码展示了如何加载一个3B参数的T0模型及其LoRA适配器,并智能地将模型分配到可用设备上。

数据处理与准备

我们使用twitter_complaints数据集,这是一个文本分类任务,需要将推文分类为"complaint"或"no complaint"。

dataset_name = "twitter_complaints"
text_column = "Tweet text"
label_column = "text_label"
batch_size = 8

dataset = load_dataset("ought/raft", dataset_name)
classes = [k.replace("_", " ") for k in dataset["train"].features["Label"].names]
dataset = dataset.map(
    lambda x: {"text_label": [classes[label] for label in x["Label"]]},
    batched=True,
    num_proc=1,
)

文本预处理

序列到序列模型需要将输入文本和标签都转换为模型可理解的token ID序列。我们定义预处理函数:

tokenizer = AutoTokenizer.from_pretrained(config.base_model_name_or_path)
target_max_length = max([len(tokenizer(class_label)["input_ids"]) for class_label in classes])

def preprocess_function(examples):
    inputs = examples[text_column]
    targets = examples[label_column]
    model_inputs = tokenizer(inputs, truncation=True)
    labels = tokenizer(
        targets, max_length=target_max_length, padding="max_length", 
        truncation=True, return_tensors="pt"
    )
    labels = labels["input_ids"]
    labels[labels == tokenizer.pad_token_id] = -100
    model_inputs["labels"] = labels
    return model_inputs

数据加载器创建

使用DataLoader高效加载数据:

processed_datasets = dataset.map(
    preprocess_function,
    batched=True,
    num_proc=1,
    remove_columns=dataset["train"].column_names,
    load_from_cache_file=True,
)

train_dataloader = DataLoader(
    train_dataset, shuffle=True, collate_fn=collate_fn, 
    batch_size=batch_size, pin_memory=True
)

模型推理与评估

加载微调好的模型后,可以进行推理和评估:

model.eval()
i = 15
inputs = tokenizer(f'{text_column} : {dataset["test"][i]["Tweet text"]} Label : ', 
                  return_tensors="pt")

with torch.no_grad():
    outputs = model.generate(input_ids=inputs["input_ids"].to("cuda"), max_new_tokens=10)
    print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))

批量评估与准确率计算

对整个评估集进行预测并计算准确率:

model.eval()
eval_preds = []
for _, batch in enumerate(tqdm(eval_dataloader)):
    batch = {k: v.to("cuda") for k, v in batch.items() if k != "labels"}
    with torch.no_grad():
        outputs = model.generate(**batch, max_new_tokens=10)
    eval_preds.extend(tokenizer.batch_decode(outputs, skip_special_tokens=True))

correct = 0
total = 0
for pred, true in zip(eval_preds, dataset["train"][label_column]):
    if pred.strip() == true.strip():
        correct += 1
    total += 1
accuracy = correct / total * 100
print(f"{accuracy=}")

技术要点解析

  1. 内存优化:通过max_memory参数控制各设备内存使用,实现大模型的分布式加载
  2. 高效微调:LoRA技术仅微调少量参数,大幅降低计算资源需求
  3. 设备映射:device_map="auto"自动将模型分配到可用设备上
  4. 批处理加速:使用DataLoader和pin_memory加速数据加载
  5. 生成控制:max_new_tokens限制生成长度,提高推理效率

实际应用建议

  1. 对于不同的任务,需要调整max_new_tokens参数以适应标签长度
  2. 在资源有限的情况下,可以进一步减小batch_size
  3. 对于生产环境,建议添加异常处理和日志记录
  4. 可以考虑量化技术进一步减小模型内存占用

通过PEFT的LoRA技术,我们能够以极低的计算成本微调大型序列到序列模型,并在保持高性能的同时大幅降低资源消耗。这种方法特别适合资源有限但需要利用大模型能力的应用场景。

peft 🤗 PEFT: State-of-the-art Parameter-Efficient Fine-Tuning. peft 项目地址: https://gitcode.com/gh_mirrors/pe/peft

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

洪赫逊

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

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

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

打赏作者

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

抵扣说明:

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

余额充值