使用T5时Seq2SeqTrainer评估阶段多次调用compute_metrics的问题
问题
按照Hugging Face摘要任务教程适配自有数据集时,发现评估阶段Seq2SeqTrainer会调用3次compute_metrics:
- 第一次传入完整的6400条验证集数据
- 第二次传入规模为127的predictions和labels
- 第三次传入标量值
疑惑为何不是仅调用一次并传入完整的验证集预测与标签?
相关代码如下:
training_args = Seq2SeqTrainingArguments( output_dir="t5_checkpoints", learning_rate=2e-5, per_device_train_batch_size=640, per_device_eval_batch_size=640, num_train_epochs=10, weight_decay=0.01, evaluation_strategy="epoch", save_strategy="epoch", save_total_limit=3, predict_with_generate=True, generation_max_length=128, generation_num_beams=4, load_best_model_at_end=True, logging_steps=1, )
trainer = Seq2SeqTrainer( model=model, args=training_args, train_dataset=tokenized_data["train"], eval_dataset=tokenized_data["valid"], tokenizer=tokenizer, data_collator=data_collator, compute_metrics=compute_metrics, )

解答
这三次调用是Seq2SeqTrainer不同逻辑阶段的正常行为,原因如下:
- 第一次全量数据调用:对应你设置的
evaluation_strategy="epoch",是训练到指定阶段后对完整验证集的正式评估,用来计算并输出整个验证集的最终指标,属于核心评估流程。 - 第二次127条数据调用:因为你开启了
load_best_model_at_end=True,Trainer需要在训练过程中跟踪最优模型,为平衡性能开销,会抽取一小部分验证数据(这里的127是验证集按batch划分后的余数,或是内部用于校准的子集)做中间指标监控,以此判断当前模型是否为最优,避免每次评估都全量计算。 - 第三次标量值调用:这是Trainer内部的兼容性校验逻辑,传入单样本级别的数据,用来验证你的
compute_metrics函数是否能正确处理非批量输入,防止后续流程因函数兼容性问题报错。
若要验证上述逻辑,可尝试:
- 将
load_best_model_at_end设为False,第二次调用会消失 - 确保
compute_metrics函数兼容批量、小批量和单样本输入,就不会影响最终评估结果
内容的提问来源于stack exchange,提问作者Kirk Walla
相关产品推荐
相关产品推荐

