Transformers documentation

回调

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

回调

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)],
)

后续步骤

Update on GitHub