HuggingFace Transformers 基础组件之Trainer

Reference:【HuggingFace Transformers-入门篇】基础组件之TrainerTrainer-Huggingface官方说明文档

Trainer内部封装了完整的训练以及评估逻辑,搭配TrainingArguments可以对训练过程中的各项参数进行配置。Trainer的参数非常多,Trainer-Huggingface官方说明文档提供了详细的参数说明。 Trainer对模型的输入输出是有限制的,要求模型返回一定是元组,或者是ModelOutput的一个子类。输入如果包含labels,Trainer要求模型能返回loss的结果,如果是元组,要求loss应该是元组的第一个值。

因此,并非所有的自定义模型都能用Trainer。

创建评估函数

传入的eval_predict涉及到Trainer的源码,以后再做深究。在这里先定义好metric的计算方式。

1
2
3
4
5
6
7
8
9
10
acc_metric = evaluate.load("accuracy")
f1_metric = evaluate.load("f1")

def eval_metric(eval_predict):
predictions, labels = eval_predict
predictions = predictions.argmax(axis=-1)
acc = acc_metric.compute(predictions=predictions, references=labels)
f1 = f1_metric.compute(predictions=predictions, references=labels)
acc.update(f1)
return acc

创建TrainingArguments

1
2
3
4
5
6
7
8
9
10
11
train_args = TrainingArguments(output_dir="./checkpoints",      # 输出文件夹
per_device_train_batch_size=64, # 训练时的batch_size
per_device_eval_batch_size=128, # 验证时的batch_size
logging_steps=10, # log 打印的频率
evaluation_strategy="epoch", # 评估策略
save_strategy="epoch", # 保存策略
save_total_limit=3, # 最大保存数
learning_rate=2e-5, # 学习率
weight_decay=0.01, # weight_decay
metric_for_best_model="f1", # 设定评估指标
load_best_model_at_end=True) # 训练完成后加载最优模型
  • output_dir指定每轮训练模型的保存路径。
  • logstep默认值是500,也可以自行指定。
  • 如果希望每一轮训练做一次评估,可以通过evaluation_strategy指定评估策略,选择epoch或者是step。如果选择step,要制定eval_steps的值,即多少步做一次评估,其默认值为None。
  • save_strategy用于指定保存策略,与evaluation_strategy相似。同时也可以通过save_total_limit设置最大保存的数量。
  • 通过learning_rate自定义学习率。
  • 通过metric_for_best_model指定模型的好坏最终取决于哪个metric。
  • load_best_model_at_end若设为True,会在使用模型时加载整个训练过程中表现最好的模型,而非最后一次训练的模型。

此外,模型训练的日志会保存到tensorboard,在checkpoints的目录下执行命令行tensorboard --logdir runs,可以得到可视化的日志。

Vscode里内置了tensorboard,ctrl+shift+p搜索tensorboard即可在vscode内查看。(我的没加载出来,还把我跑的模型中断了……可能是版本问题,以后有时间再细究)

创建Trainer

通过args将TrainingArguments指定的参数传入Trainer,compute_metrics将前面创建好的评估函数传入Trainer。还要通过data_collator指定dataloader,使用DataCollatorWithPadding进行数据堆叠。

1
2
3
4
5
6
trainer = Trainer(model=model, 
args=train_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["test"],
data_collator=DataCollatorWithPadding(tokenizer=tokenizer),
compute_metrics=eval_metric)
Trainer如果不重新加载,trainer.train()的时候会在之前训练好的基础上继续做训练。

基于Transformers的nlp解决方案

up的ppt上已经总结好了,详见up的github主页

【文本分类代码优化】

与上一章的代码相比,不需要引入dataloader、optimizer,且Trainer里会自动判定能不能用cuda,所以不需要在代码中做额外的判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset
from transformers import DataCollatorWithPadding
import evaluate

# 1. 读取数据 + 简单清洗数据
dataset = load_dataset("csv", data_files="D:\\transformers_test\\01 Getting Started\\07 trainer\ChnSentiCorp_htl_all.csv", split="train")
dataset = dataset.filter(lambda x: x["review"] is not None)

# 2. 划分数据集
datasets = dataset.train_test_split(test_size=0.1)

# 3. 数据集预处理
tokenizer = AutoTokenizer.from_pretrained("hfl/rbt3")

def process_function(examples):
tokenized_examples = tokenizer(examples["review"], max_length=128, truncation=True)
tokenized_examples["labels"] = examples["label"]
return tokenized_examples

tokenized_datasets = datasets.map(process_function, batched=True, remove_columns=datasets["train"].column_names)

# 4. 创建模型
model = AutoModelForSequenceClassification.from_pretrained("hfl/rbt3")

# 5. 创建评估函数
acc_metric = evaluate.load("accuracy")
f1_metric = evaluate.load("f1")

def eval_metric(eval_predict):
predictions, labels = eval_predict
predictions = predictions.argmax(axis=-1)
acc = acc_metric.compute(predictions=predictions, references=labels)
f1 = f1_metric.compute(predictions=predictions, references=labels)
acc.update(f1)
return acc

# 6. 创建TrainingArguments
train_args = TrainingArguments(output_dir="./checkpoints", # 输出文件夹
per_device_train_batch_size=64, # 训练时的batch_size
per_device_eval_batch_size=128, # 验证时的batch_size
logging_steps=10, # log 打印的频率
evaluation_strategy="epoch", # 评估策略
save_strategy="epoch", # 保存策略
save_total_limit=3, # 最大保存数
learning_rate=2e-5, # 学习率
weight_decay=0.01, # weight_decay
metric_for_best_model="f1", # 设定评估指标
load_best_model_at_end=True) # 训练完成后加载最优模型

# 7. 创建Trainer
trainer = Trainer(model=model,
args=train_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["test"],
data_collator=DataCollatorWithPadding(tokenizer=tokenizer),
compute_metrics=eval_metric)

# 8. 模型训练
trainer.train()

# 9. 模型评估
trainer.evaluate(tokenized_datasets["test"])

# 10. 模型对测试集 test 进行预测
trainer.predict(tokenized_datasets["test"])


HuggingFace Transformers 基础组件之Trainer
https://jiangcara.github.io/posts/5c24a1dc/
作者
Jiang Cara
发布于
2024年7月31日
许可协议