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

使用Trainer与直接调用模型评估HuggingFace Transformer为何结果不同?

问题:Trainer类与直接调用模型预测的准确率差异

我使用预训练Transformer模型进行序列分类任务,通过Trainer类在自有数据集上完成微调。使用Trainer类评估模型时,准确率达到94%,代码如下:

trainer = Trainer(model=model)
preds = trainer.predict(validation_dataset)
predictions = np.argmax(preds.predictions, axis=-1)

metric = evaluate.load("accuracy")
metric.compute(predictions=predictions, references=preds.label_ids)
# prints: {'accuracy': 0.9435554514341591}

但当我直接调用模型获取预测结果时,准确率仅约86%,代码如下:

predictions = []
model.eval()
for row in validation_dataset:
    text_ids = row['input_ids'].unsqueeze(0)
    predicted = torch.argmax(model(text_ids)[0])
    predictions += [predicted.item()]

metric.compute(predictions, labels)
# prints {'accuracy': 0.8639942552151239}

想了解为何两种方式的预测结果存在差异,且Trainer评估的准确率更高?是遗漏了什么环节,还是实现存在问题?


原因分析与解决方法
  • 未传入注意力掩码(attention_mask):Transformer模型需要attention_mask区分真实输入和padding token,Trainer会自动从数据集中读取并传入,但你的手动推理代码只传了input_ids,模型会错误处理padding部分,导致预测偏差。修改后代码:
    for row in validation_dataset:
        text_ids = row['input_ids'].unsqueeze(0)
        mask = row['attention_mask'].unsqueeze(0)
        predicted = torch.argmax(model(text_ids, attention_mask=mask)[0])
        predictions += [predicted.item()]
    
  • 设备不一致问题:如果Trainer用GPU训练/预测,而手动推理时模型或输入张量在CPU上,会导致结果异常。需确保模型和输入在同一设备:
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model.to(device)
    for row in validation_dataset:
        text_ids = row['input_ids'].unsqueeze(0).to(device)
        mask = row['attention_mask'].unsqueeze(0).to(device)
        predicted = torch.argmax(model(text_ids, attention_mask=mask)[0])
        predictions += [predicted.item()]
    
  • 标签匹配错误:手动推理用的labels可能和Trainer使用的preds.label_ids顺序或内容不一致,比如数据集循环时被打乱。建议直接从循环的row中取标签:
    predictions = []
    true_labels = []
    model.eval()
    for row in validation_dataset:
        # 输入处理代码
        predicted = torch.argmax(model(text_ids, attention_mask=mask)[0])
        predictions += [predicted.item()]
        true_labels += [row['label'].item()]
    metric.compute(predictions=predictions, references=true_labels)
    
  • 未关闭自动梯度计算:即使开了model.eval(),手动推理时最好加上torch.no_grad()上下文管理器,避免显存占用和潜在计算误差:
    predictions = []
    true_labels = []
    model.eval()
    with torch.no_grad():
        for row in validation_dataset:
            # 输入处理代码
            predicted = torch.argmax(model(text_ids, attention_mask=mask)[0])
            predictions += [predicted.item()]
            true_labels += [row['label'].item()]
    

内容的提问来源于stack exchange,提问作者Jan Koci

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:17:34