Transformers 库 Trainer 使用与自定义优化器
近期想使用 Hugging Face 的 Trainer 测试一些微调和预训练任务,因此学习一下如何使用 Trainer 以及如何在其中自定义优化器。
Hugging Face Trainer 原理
Trainer 的目的:虽然不用 Trainer,Pytorch 的训练流程看起来也不麻烦,但是如果我们需要加入分布式训练、混合精度训练、梯度累积、日志记录、评估与断点续训时,代码量和复杂度会快速上升。而 Trainer 的目的就是让用户从这些复杂的细节中解放出来。
Trainer 的创建:Trainer 的创建 API 主要如下
=
Trainer 的主要方法:
train(resume_from_checkpoint: str = None):启动训练,允许从某个checkpoint 路径恢复训练。evaluate(eval_dataset: Dataset = None):在给定的数据集上执行一次评估。predict(test_dataset: Dataset):对一个没有标签的测试集进行预测,返回原始输出。save_model(output_dir: str=None):将模型、配置、分词器(如果提供了)保存到指定目录push_to_hub():将训练好的模型、分词器等推送到 Hugging Face Hub。
Trainer 的训练过程:对于一般用户只需要调用 trainer.train(),其内部会执行一套高度优化、功能完备的训练循环。关键部分如下:
- 环境与设置初始化:读取传入的
TrainingArguments 的配置,利用Accelerate 库探测硬件环境; - 数据加载器的准备:读取传入的
Dataset 对象,创建DataLoader,使用DistributedSampler 确保每个 GPU 进程拿到数据的不重复子集; - 核心训练循环
training_step:每个训练步骤中取出一个 Batch 的数据传递给training_step。其中负责将数据移动到device,调用model(**input) 执行前向传播,并取出loss; - 优化过程:使用
GradScaler 防止梯度下溢,控制loss.backward()、optimizer.step()、optimizer.zero_grad() 累计梯度。 - 生命周期钩子 Lifecycle Hooks:
Trainer 提供了一系列回调函数,允许在特定节点(如on_train_begin、on_step_end、on_epoch_end、on_save 等)注入自定义逻辑,例如提前停止、打印自定义日志等。
Hugging Face Trainer 自定义优化器
使用 Trainer 支持的优化器:Trainer 默认支持 AdamW、Adafactor 等优化器,可以通过 --optim 参数选择。
使用 Trainer 不支持的优化器:最方便的方式是继承 Trainer 并重写 create_optimizer 方法。具体而言,Trainer 在初始化过程中会调用 self.create_optimizer_and_scheduler(),其内部再调用 self.create_optimizer()。
- 创建自定义的
TrainingArguments
"""
自定义训练参数,增加了优化器选项及其相关超参数。
"""
: =
: =
: =
: =
# 在 main 的 HfArgumentParser 中修改为自定义的 TrainingArguments
=
- 创建自定义
Trainer 并重写create_optimizer
"""
Create customed optimizers
"""
=
=
=
=
return # 调用父类
return
return
- 在训练脚本中使用
CustomTrainer
# ... 在你的主训练脚本中 ...
# model, data_args, training_args 等都已准备好
# 不再使用:trainer = Trainer(...)
# 而是使用:
=
# 后续调用完全不变