使用Hugging Face训练GPT-2遇IndexError索引越界问题求助
解决GPT-2训练时的IndexError: Invalid key: X is out of bounds for size 0错误
问题分析
错误IndexError: Invalid key: 409862 is out of bounds for size 0本质是训练时尝试访问空数据集索引,核心原因有两点:
- 自定义的
data_collator函数不符合Hugging Face Trainer的要求,无法正确处理批数据 - 未对原始数据集做预处理,直接传入Trainer导致数据格式不匹配
修正后的完整代码
!pip install 'transformers[torch]' datasets from datasets import load_dataset import torch from transformers import ( GPT2Tokenizer, GPT2LMHeadModel, Trainer, TrainingArguments, DataCollatorForLanguageModeling ) # 加载数据集 dataset = load_dataset("Nan-Do/instructional_code-search-net-python") # 初始化tokenizer,GPT2系列默认无pad_token,需手动指定 tokenizer = GPT2Tokenizer.from_pretrained('sberbank-ai/rugpt3large_based_on_gpt2') tokenizer.pad_token = tokenizer.eos_token # 用eos_token替代pad_token model = GPT2LMHeadModel.from_pretrained('sberbank-ai/rugpt3large_based_on_gpt2') model.config.pad_token_id = tokenizer.pad_token_id # 同步模型配置的pad_token_id # 单样本预处理函数,将文本编码为模型可接收的格式 def preprocess_function(examples): return tokenizer( examples["text"], truncation=True, max_length=512, padding="max_length" ) # 批量预处理整个数据集,移除冗余字段 tokenized_dataset = dataset.map( preprocess_function, batched=True, remove_columns=dataset["train"].column_names ) # 使用官方语言建模专用数据收集器,替代错误的自定义实现 data_collator = DataCollatorForLanguageModeling( tokenizer=tokenizer, mlm=False # GPT是自回归模型,无需掩码语言建模 ) training_args = TrainingArguments( output_dir='./results', num_train_epochs=3, # 原8000轮不合理,改为常规训练轮数 per_device_train_batch_size=2, save_steps=2000, save_total_limit=2, prediction_loss_only=True, logging_steps=100, # 添加日志监控训练状态 fp16=True # 启用混合精度训练,适配Colab环境 ) trainer = Trainer( model=model, args=training_args, train_dataset=tokenized_dataset["train"], data_collator=data_collator, ) trainer.train() # 同时保存模型和tokenizer,保证后续加载一致性 model.save_pretrained('/content/drive/MyDrive/MyGPT') tokenizer.save_pretrained('/content/drive/MyDrive/MyGPT')
关键修正点
- 替换data_collator:放弃自定义的
prepare_data,使用官方提供的DataCollatorForLanguageModeling,它专门针对语言建模任务处理批数据,避免手动编码的错误。 - 数据集预处理:通过
dataset.map()批量转换原始文本为模型所需的input_ids和attention_mask,并移除冗余字段,确保数据集格式符合Trainer要求。 - 设置pad_token:GPT-2系列无默认pad_token,手动指定eos_token作为替代,并同步模型配置的
pad_token_id,避免训练时格式不兼容。 - 调整训练参数:将
num_train_epochs从8000改为3(可按需调整),避免无意义的超长时间训练。 - 同步保存tokenizer:训练完成后同时保存tokenizer,确保后续加载模型时使用一致的编码规则。
额外检查项
- 验证数据集有效性:运行
print(len(dataset["train"]))确认训练集样本数不为0,若为空可尝试手动指定split参数:load_dataset("Nan-Do/instructional_code-search-net-python", split="train")。 - 显存适配:若使用
rugpt3large出现显存不足,可将per_device_train_batch_size改为1,保持fp16=True启用混合精度训练。
内容的提问来源于stack exchange,提问作者Vovancho
相关产品推荐
相关产品推荐

