跳转至

Transformers

最新时间:2024年5月16日20:35:57

之前写的太简单了,这次将其拓展的尽量全面一点,参考:官方文档

概述

Transformers是一个非常大的库,经常和Datasets/Accelerate/ bitsandbytes/evaluate/PEFT/Gradio一起使用。它可以支持非常便捷的模型调用服务,同时还可以支持多卡并行、量化、模型训练、模型微调、模型可视化,可以说基本涵盖我们所需要用到的大部分功能了。所以说,好好学习这个库真的很有必要!!!

之前零零散散的看了和使用了一些Transformers的功能,但是偶然间发掘他们官方文档写的真的很好,所以决定通读一下官方文档,学习一下这个库的整体功能架构。以下是我的学习过程中的一些整理。

查看huggingface支持哪些task? TASK官方文档

Pipeline

更多内容可以去看官方文档,下面是最常用的函数:

# 多卡并行 + 16bit (需要安装 Accelerate)
pipeline = pipeline(task="text-generation", model="gpt2", torch_dtype=torch.bfloat16, device_map="auto")

# 单卡运行 + 8bit (需要安装 bitsandbytes)
pipeline = pipeline(task="text-generation", model="gpt2", device=0, load_in_8bit=True)
# load_in_4bit 允许 4bit 运行

上面附带介绍了一点量化和多卡并行,但实际上,还可以加速!(可以提高多达30%的速度!)

from transformers import AutoModelForImageClassification

model = AutoModelForImageClassification.from_pretrained(MODEL_ID).to("cuda")
+ model = torch.compile(model) # 2.0及以上版本的torch

AutoClass

对于不同类型的任务有不同的AutoClass,比如:

from transformers import AutoTokenizer # 文字
from transformers import AutoImageProcessor # 图片
from transformers import AutoFeatureExtractor # 音频
from transformers import AutoProcessor # 多模态

# Model(1) : AutoModelForXXX (好麻烦,不推荐)
from transformers import AutoModelForSequenceClassification
from transformers import AutoModelForTokenClassification

# Model(2) : AutoModel (很万能,推荐)
from transformers import AutoConfig, AutoModel
config = AutoConfig.from_pretrained("google-bert/bert-base-cased")
model = AutoModel.from_config(config)

Tranier

数据处理(tokenizer/划分) -> 训练准备(数据整理器/模型/参数/评估方法) -> 模型训练(训练器/训练)

官方文档中给了两个事例,详细内容见官方案例,数据处理的部分可以见Datasets库

Trainer会自动利用所有可用的GPU进行分布式训练

训练准备

evaluate可以参考官方文档了解更多:evaluate库

一个非常好的视频详细介绍了evaluate库的用法:B站教程:Evaluate

# (1)参数(以下例子是乱写的,旨在说明一些常用参数)
from transformers import TrainingArguments
training_args = TrainingArguments(
    output_dir="./results", 
    evaluation_strategy="epoch", # 评估策略 "no"、"steps" 或 "epoch"
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    # 等同于:optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay=0.01)
    learning_rate=2e-5,
    weight_decay=0.01, # 权重衰减系数,防止训练过拟合,限制模型权重
    fp16=True,
)

# (2)设置评估函数(如果不需要在训练时评估则不必设置)
import numpy as np
import evaluate
metric = evaluate.load("accuracy")
def compute_metrics(eval_pred):
    logits, labels = eval_pred
    predictions = np.argmax(logits, axis=-1)
    return metric.compute(predictions=predictions, references=labels)

# (3)data_collator 其主要作用是将一批数据样本(batch)进行整理和处理
# 可以有效地处理批次内样本长度不同、填充、掩码生成等问题
from transformers import DataCollatorForSeq2Seq
data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=model)

模型训练

# 训练器初始化
trainer = Trainer(
    # data
    data_collator=data_collator,
    train_dataset=small_train_dataset,
    eval_dataset=small_eval_dataset,
    # model
    model=model,
    tokenizer=tokenizer,
    # args
    args=training_args,
    compute_metrics=compute_metrics
)

# 开始训练
trainer.train()

Accelerate

使用Aceelerate,可以在原生PyTorch训练循环中启用分布式训练。

修改代码

分布式训练代码

from accelerate import Accelerator

# 不需要model.to(device)
accelerator = Accelerator()
train_dataloader, eval_dataloader, model, optimizer = 
    accelerator.prepare(train_dataloader, eval_dataloader, model, optimizer)

for epoch in range(num_epochs):
    for batch in train_dataloader:

        # 不需要data.to(device)
        outputs = model(**batch)
        loss = outputs.loss

        # 不需要loss.backward()
        accelerator.backward(loss)

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()
        progress_bar.update(1)

分布式评估代码

for inputs, targets in validation_dataloader:
    predictions = model(inputs)

    # Gather all predictions and targets
    all_predictions, all_targets = accelerator.gather_for_metrics((predictions, targets))

    # Example of use with a *Datasets.Metric*
    metric.add_batch(all_predictions, all_targets)

启动分布式训练

根据训练环境(torchrun、DeepSpeed 等)和可用硬件,有许多方法可以启动和运行代码。Accelerate 提供了一个统一的界面,用于在不同的分布式设置上启动和训练。

accelerate config # 按照提示信息进行配置即可
accelerate launch train.py --config_file config.yaml

# 或者可以输入如下指令:
accelerate launch --multi_gpu --mixed_precision=fp16 --num_processes=2 {script_name.py} {--arg1} {--arg2} ...

PEFT

加载PEFT adapter

首先确保Hub仓库或本地目录包含一个adapter_config.json文件和adapter权重

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)

训练PEFT adapter

from peft import LoraConfig

peft_config = LoraConfig(
    lora_alpha=16,
    lora_dropout=0.1,
    r=64,
    bias="none",
    task_type="CAUSAL_LM",
)

model.add_adapter(peft_config)

trainer = Trainer(model=model, ...)
trainer.train()

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

Gradio

其教程非常丰富:官方教程

需要用的时候看看官方教程 + 问问GPT就好啦!而且这个比Flask还要方便!