You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取transformers.Trainer训练阶段的epoch级指标?

获取transformers.Trainer训练阶段各epoch指标的解决方案

目前使用transformers.Trainer时,评估阶段的指标可以通过内置方法轻松获取,但训练过程中每个epoch的loss、准确率、召回率、精确率、F1值这类核心指标却没有直接的获取途径,零散的讨论也未给出完整可落地的方案。以下是一套可行的实现方法:

实现思路

通过自定义TrainerCallback拦截训练的epoch_end事件,在每个epoch结束后,遍历训练集计算并记录各项指标。该方法无需修改Trainer核心逻辑,仅通过回调机制扩展功能。

具体代码实现

from transformers import TrainerCallback, TrainingArguments, Trainer
from sklearn.metrics import accuracy_score, precision_recall_fscore_support
import torch

class TrainMetricsCallback(TrainerCallback):
    def __init__(self, train_dataset):
        self.train_dataset = train_dataset
        self.train_metrics = []  # 存储所有epoch的训练指标

    def on_epoch_end(self, args, state, control, model, **kwargs):
        # 切换模型到评估模式,关闭梯度计算
        model.eval()
        total_loss = 0.0
        all_predictions = []
        all_labels = []

        # 获取训练集的数据加载器
        train_dataloader = Trainer.get_eval_dataloader(args, self.train_dataset)
        
        with torch.no_grad():
            for batch in train_dataloader:
                # 把数据移到模型所在设备
                inputs = {k: v.to(args.device) for k, v in batch.items() if k != "labels"}
                labels = batch["labels"].to(args.device)
                
                # 前向传播计算loss和预测结果
                outputs = model(**inputs)
                total_loss += outputs.loss.item() * labels.size(0)
                
                predictions = torch.argmax(outputs.logits, dim=-1)
                all_predictions.extend(predictions.cpu().numpy())
                all_labels.extend(labels.cpu().numpy())

        # 计算各项指标
        avg_loss = total_loss / len(self.train_dataset)
        accuracy = accuracy_score(all_labels, all_predictions)
        precision, recall, f1, _ = precision_recall_fscore_support(
            all_labels, all_predictions, average="weighted"
        )

        # 整理当前epoch的指标
        epoch_metrics = {
            "epoch": round(state.epoch, 2),
            "train_loss": round(avg_loss, 4),
            "train_accuracy": round(accuracy, 4),
            "train_precision": round(precision, 4),
            "train_recall": round(recall, 4),
            "train_f1": round(f1, 4)
        }
        self.train_metrics.append(epoch_metrics)
        
        # 打印当前epoch的训练指标
        print(f"\nEpoch {epoch_metrics['epoch']} Training Metrics:")
        for metric_name, value in epoch_metrics.items():
            print(f"{metric_name}: {value}")
        
        # 切换回训练模式
        model.train()

# 使用示例
def run_training():
    # 假设已完成model、train_dataset、eval_dataset的初始化
    training_args = TrainingArguments(
        output_dir="./training_results",
        per_device_train_batch_size=8,
        num_train_epochs=5,
        logging_dir="./logs",
        logging_steps=100,
        fp16=True  # 按需开启混合精度训练
    )

    # 初始化自定义回调
    train_metric_callback = TrainMetricsCallback(train_dataset)

    # 初始化Trainer并传入回调
    trainer = Trainer(
        model=model,
        args=training_args,
        train_dataset=train_dataset,
        eval_dataset=eval_dataset,
        callbacks=[train_metric_callback]
    )

    # 启动训练
    trainer.train()

    # 训练结束后可查看所有epoch的指标
    print("\nAll Training Epoch Metrics:")
    for metrics in train_metric_callback.train_metrics:
        print(metrics)

if __name__ == "__main__":
    run_training()

关键说明与优化建议

  • 指标计算逻辑:代码中使用加权平均的精确率、召回率、F1值,若需二分类场景,可将average参数改为binary;多分类场景可改为macro或micro。
  • 性能优化:若训练集规模极大,全量计算指标会增加训练耗时,可抽取训练集的固定比例子集(如10%)来计算近似指标。
  • 分布式训练适配:如果使用多GPU分布式训练,需通过torch.distributed.all_gather聚合各进程的预测结果与loss,避免指标计算偏差。
  • 日志持久化:可将epoch_metrics写入JSON文件或使用可视化工具记录,方便后续分析。

内容的提问来源于stack exchange,提问作者Wassim Jaoui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:42:41