如何使用Huggingface Trainer微调GPT2并修复运行报错
你的代码存在多个逻辑错误,按以下步骤修改即可解决所有报错:
1. 修复自定义数据集的返回格式错误
你自定义torchDataset的__getitem__方法错误使用了集合推导式,集合没有键名,Trainer无法从中获取input_ids、attention_mask等模型必需的字段,这是空batch报错的核心原因之一。另外因果语言模型微调需要传入标签计算自回归损失,直接将输入id复制为标签即可。
将__getitem__方法替换为如下实现:
def __getitem__(self, index): item = {key: val[index] for key, val in self.encodings.items()} item["labels"] = item["input_ids"].clone() return item
注意:你调用tokenizer时已经传入了
return_tensors='pt',返回值本身就是torch张量,不需要再手动调用torch.tensor()做转换。
2. 修复自定义数据集的长度计算错误
你在__init__中写的self.len = len(encodings),计算的是BatchEncoding对象的键数量(固定为2,即input_ids和attention_mask),不是实际样本总数,会导致数据集长度完全错误。
将__init__方法修改为:
def __init__(self, encodings): self.encodings = encodings self.len = len(encodings["input_ids"])
3. 预处理阶段过滤空样本
WikiText数据集包含大量无内容的空行,tokenizer后会生成空序列,直接送入训练会触发空batch报错。加载数据集后增加过滤逻辑:
dataset = load_dataset('wikitext', 'wikitext-2-v1') # 过滤空文本 dataset = dataset.filter(lambda x: len(x["text"].strip()) > 0)
4. 修正训练参数配置
你当前的训练参数存在3个问题:
- 没有指定训练/验证batch size,会使用默认值8,和你定义的
BATCH_SIZE=2不符 - 学习率
1e-3过大,GPT2微调的常规学习率在5e-5~2e-4区间,过大会导致训练发散 - 输出目录写为系统根目录
/model_dump/,大概率会触发权限错误
将TrainingArguments替换为如下配置:
training_args = TrainingArguments( output_dir='./model_dump/', num_train_epochs=EPOCHS, per_device_train_batch_size=BATCH_SIZE, per_device_eval_batch_size=BATCH_SIZE, warmup_steps=WARMUP_STEPS, learning_rate=5e-5, weight_decay=DECAY, logging_steps=100, evaluation_strategy="epoch" )
5. 修正Trainer的入参
不要直接将tokenizer返回的BatchEncoding对象传入Trainer,要传入你实例化好的自定义数据集对象:
trainer = Trainer( model=model, args=training_args, train_dataset=torch_dataset_train, eval_dataset=torch_dataset_eval )
之前触发的TypeError: vars() argument must have __dict__ attribute报错,就是因为传入的数据集格式不符合Trainer要求,修正上述所有问题后该报错会自动消失。
内容的提问来源于stack exchange,提问作者Neskelogth

