加载HuggingFace微调模型后trainer.evaluate()出现异常高损失问题问询
问题根因
这不是HuggingFace框架的Bug,本质是数据处理流程和Trainer配置与训练时不一致导致的,核心触发点如下:
- 训练时用的
DataCollatorForTokenClassification默认会把padding位置的标签替换为-100(PyTorch交叉熵损失默认忽略的标签值),计算损失时会自动跳过这些无效位置;但你新进程加载数据时用的DataCollator没有做这个处理,padding位置的标签被设为0或其他有效值,大量无效padding位置的损失被计入总损失,直接导致损失值翻数十倍。 - 你自定义的F1计算逻辑里主动过滤了padding、特殊符号位置的标签,因此F1指标不受影响,符合预期。
- 损失的随机性来源于动态padding的长度波动:每次运行时不同批次的padding长度不同,无效损失的占比有差异,最终总损失就会出现随机波动。
- 次要原因是你初始化
Trainer时没有传入训练时的TrainingArguments配置,默认的损失规约规则(比如是按有效token平均还是所有token平均)和训练时不一致,进一步放大了损失偏差。
修复步骤
- 对齐数据整理器配置:
显式初始化和训练时完全一致的DataCollatorForTokenClassification,指定padding标签为-100,初始化Trainer时传入:
from transformers import DataCollatorForTokenClassification data_collator = DataCollatorForTokenClassification( tokenizer=tokenizer, label_pad_token_id=-100, padding=True ) trainer: Trainer = Trainer( model=model, args=training_args, # 必须传入和训练时完全一致的训练参数 eval_dataset=dataset.valid_dataset, data_collator=data_collator, )
- 验证损失一致性:
可以手动用评估输出的logits和标签计算损失,确认逻辑对齐:
import torch import torch.nn.functional as F # 过滤掉标签为-100的无效位置 active_mask = labels.view(-1) != -100 active_logits = logits.view(-1, dataset.label_number)[active_mask] active_labels = labels.view(-1)[active_mask] manual_loss = F.cross_entropy(active_logits, active_labels) print(manual_loss) # 正常结果应和训练时的0.3接近
内容的提问来源于stack exchange,提问作者Blake
相关产品推荐
相关产品推荐

