自定义HF数据集调用Trainer.train()报vars()需有__dict__属性错误
问题原因
- 数据集基类引用错误:PyTorch官方数据集基类路径为
torch.utils.data.Dataset,你代码中引用的nn.utils.data.Dataset不存在,导致数据集类行为异常,返回的样本对象不符合你定义的字典结构,触发Hugging Face默认数据整理函数调用vars()解析对象时报错。 - 张量构造方法调用错误:
nn是torch.nn(神经网络层模块)的缩写,不包含张量构造接口,你代码中使用的nn.Tensor、nn.LongTensor属于错误调用,应该使用torch.Tensor、torch.LongTensor构造张量。 - forward方法缩进错误:你将模型的
forward方法定义在了__init__方法内部,属于局部函数,不会被PyTorch识别为模型前向传播入口,后续即使解决数据加载问题也会触发前向逻辑错误。 - 模型输入参数不匹配:你的数据集返回样本的特征key为
embeddings,Hugging Face Trainer会自动将对应key作为参数传入模型forward方法,但你当前forward方法第一个参数命名为inputs,没有接收embeddings的参数,会触发参数不匹配报错。 - 变量名覆盖风险:你实例化训练集时直接用
train_data = CLIPDataset(train_data, y_train)覆盖了原本存储嵌入的train_data变量,属于不规范写法,容易引发后续逻辑异常。
修复代码
模型定义修复
import torch import torch.nn as nn from transformers import CLIPVisionModel, CLIPProcessor, SequenceClassifierOutput class CLIPNN(nn.Module): def __init__(self, num_labels, pretrained_name="openai/clip-vit-base-patch32", dropout=0.1): super().__init__() self.num_labels = num_labels # 调试阶段不需要加载CLIP基座可以注释以下两行 # self.transformer = CLIPVisionModel.from_pretrained(pretrained_name) # self.processor = CLIPProcessor.from_pretrained(pretrained_name) self.classifier = nn.Sequential( nn.Linear(512, 128, bias=True), nn.ReLU(inplace=True), nn.Dropout(p=dropout, inplace=False), nn.Linear(128, self.num_labels, bias=True) ) # forward方法调整为与__init__同级缩进,参数名匹配数据集返回的key def forward(self, embeddings, labels=None, **kwargs): logits = self.classifier(embeddings) loss = None if labels is not None: loss_fct = nn.CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) return SequenceClassifierOutput( loss=loss, logits=logits, )
数据集定义修复
from torch.utils.data import Dataset class CLIPDataset(Dataset): def __init__(self, embeddings, labels): self.embeddings = embeddings self.labels = labels def __getitem__(self, idx): item = {"embeddings": torch.Tensor(self.embeddings[idx])} item['labels'] = torch.LongTensor([self.labels[idx]]) return item def __len__(self): return len(self.labels)
调用逻辑修复
model = CLIPNN(num_labels=2) # 避免覆盖原存储嵌入的变量名 train_dataset = CLIPDataset(train_data, y_train) test_dataset = CLIPDataset(test_data, y_test) trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=test_dataset ) trainer.train()
内容的提问来源于stack exchange,提问作者skidjoe
相关产品推荐
相关产品推荐

