Transformers documentation
回调
回调
TrainerCallback 会介入特定的训练事件(如 epoch 开始、评估、训练结束),以修改训练状态或控制流程。您可以使用回调将指标记录到 Trackio 等实验跟踪器中,自定义保存和评估的时机,或添加其他自定义行为。通过叠加多个回调来组合各项功能。
回调无法修改训练循环本身,例如前向传播。若要更改 Trainer 的计算内容,请改为子类化其方法。
下图展示了回调可以挂钩的所有事件。
on_train_begin
└─ for each epoch:
on_epoch_begin
└─ for each step:
on_step_begin
├─ for each gradient accumulation substep:
│ on_substep_end
on_pre_optimizer_step ← after gradient clipping, before optimizer.step()
on_optimizer_step ← after optimizer.step()
on_step_end
└─ (conditionally):
on_log
on_evaluate
on_save
on_epoch_end
on_train_end
on_predict / on_prediction_step
on_push_begin创建回调
子类化 TrainerCallback 并覆盖上图中一个或多个事件方法。下面的示例演示了三个钩子:
on_epoch_begin会打印 TrainerState 中的当前 epoch(实时值)以及 TrainingArguments 中的学习率(静态值)。on_step_end从 lr_scheduler(通过**kwargs传入)中读取当前的学习率,并在 TrainerControl 上设置should_evaluate(完整的控制对象列表请参见 TrainerControl),以在学习率低于阈值时触发评估。on_train_end会打印最佳指标及其出现的步数。
from transformers import TrainerCallback
class EpochLoggerCallback(TrainerCallback):
def __init__(self, lr_eval_threshold=1e-5):
self.lr_eval_threshold = lr_eval_threshold
def on_epoch_begin(self, args, state, control, **kwargs):
print(f"Starting epoch {int(state.epoch) + 1}/{state.num_train_epochs} "
f"(lr={args.learning_rate})")
def on_step_end(self, args, state, control, **kwargs):
lr_scheduler = kwargs.get("lr_scheduler")
if lr_scheduler is not None:
current_lr = lr_scheduler.get_last_lr()[0]
if current_lr < self.lr_eval_threshold:
control.should_evaluate = True
def on_train_end(self, args, state, control, **kwargs):
print(f"Training complete! Best metric: {state.best_metric} at step {state.best_global_step}")在 callbacks 参数中,将该回调注册到 Trainer。您也可以以列表形式传入多个回调。
trainer = Trainer(
callbacks=[EpochLoggerCallback(lr_eval_threshold=1e-5)],
...,
)内置回调
Transformers 包含多个默认启用的内置回调。额外的集成回调会向日志平台(如Trackio)记录信息。
DefaultFlowCallback
DefaultFlowCallback 根据 TrainingArguments 中的 logging_strategy、eval_strategy 和 save_strategy 值,管理默认的日志记录、评估和检查点保存计划。在合适的步数或轮次时,它会设置相应的 control 标志(should_log、should_evaluate、should_save)。此外,当 global_step 达到 max_steps 时,它还会设置 should_training_stop。
重写此回调是自定义何时执行日志记录、评估或保存的主要方式。
ProgressCallback 和 PrinterCallback
Trainer 会根据 TrainingArguments 中的 disable_tqdm 字段,自动在这两个回调之间进行选择。
- 默认使用 ProgressCallback。它在训练期间显示 tqdm 进度条,在评估或预测期间显示单独的进度条,并在每次
on_log事件时打印最新的指标。在分布式训练期间,它仅在主进程上运行,以避免重复输出。 - PrinterCallback 在
disable_tqdm=True时使用。它会在每次on_log事件时将日志字典打印到标准输出,且不显示进度条。
您也可以使用 remove_callback() 和 add_callback() 手动替换它们。
from transformers import PrinterCallback
trainer = Trainer(...)
trainer.remove_callback(ProgressCallback)
trainer.add_callback(PrinterCallback)EarlyStoppingCallback
EarlyStoppingCallback 会在评估指标停止提升时停止训练。每次评估后,它会检查该指标的提升幅度是否超过 early_stopping_threshold。如果指标在连续 early_stopping_patience 次评估中均未提升,训练将停止。
EarlyStoppingCallback 需要两个 TrainingArguments:
metric_for_best_model,用于监控的评估指标eval_strategy,是否在"steps"或"epoch"上进行评估
from transformers import EarlyStoppingCallback
trainer = Trainer(
...,
callbacks=[EarlyStoppingCallback(early_stopping_patience=3, early_stopping_threshold=0.001)],
)后续步骤
- 查看所有可用于向实验跟踪器记录日志的集成回调。
- 子类化 Trainer 方法指南介绍了在需要更改训练循环计算内容时,如何重写 Trainer 方法。