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还要方便!