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

使用Hugging Face微调模型预测时触发IndexError: list index out of range

问题:微调BERT后使用Trainer.predict报错IndexError

训练代码

from transformers import AutoModelForSequenceClassification, AutoTokenizer, TrainingArguments, Trainer
from datasets import load_dataset
import numpy as np
import torch

# Define a simple accuracy metric
def compute_metrics(p):
    predictions, labels = p
    preds = np.argmax(predictions, axis=1)
    return {"accuracy": (preds == labels).mean()}

# Load the dataset
dataset = load_dataset("imdb", split='train[:1%]')
small_train_dataset = dataset.train_test_split(test_size=0.1)['train']
small_eval_dataset = dataset.train_test_split(test_size=0.1)['test']

# Load the tokenizer and model
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)

# Tokenize the dataset
def tokenize_function(examples):
    return tokenizer(examples['text'], padding="max_length", truncation=True)

small_train_dataset = small_train_dataset.map(tokenize_function, batched=True)
small_eval_dataset = small_eval_dataset.map(tokenize_function, batched=True)
small_train_dataset = small_train_dataset.rename_column("label", "labels")
small_eval_dataset = small_eval_dataset.rename_column("label", "labels")
small_train_dataset.set_format("torch", columns=["input_ids", "attention_mask", "labels"])
small_eval_dataset.set_format("torch", columns=["input_ids", "attention_mask", "labels"])

# Define training arguments
training_args = TrainingArguments(
    output_dir="test_trainer",
    evaluation_strategy="epoch",
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    weight_decay=0.01
)

# Initialize the Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=small_train_dataset,
    eval_dataset=small_eval_dataset,
    compute_metrics=compute_metrics
)

# Train the model
trainer.train()

# Evaluate the model
validation_results = trainer.evaluate()
print(validation_results)

预测代码

inputs=tokenizer(dataset[0]['text'], padding="max_length", truncation=True,return_tensors="pt")
predictions = trainer.predict(test_dataset=inputs)

错误信息

IndexError Traceback (most recent call last) Cell In[8], line 7 3
inputs=tokenizer(dataset[0]['text'], padding="max_length",
truncation=True,return_tensors="pt") 6 # Make predictions
----> 7 predictions = trainer.predict(test_dataset=inputs)

File C:\Python311\Lib\site-packages\transformers\trainer.py:3305, in
Trainer.predict(self, test_dataset, ignore_keys, metric_key_prefix)
3302 start_time = time.time() 3304 eval_loop = self.prediction_loop if
self.args.use_legacy_prediction_loop else self.evaluation_loop → 3305
output = eval_loop( 3306 test_dataloader, description="Prediction",
ignore_keys=ignore_keys, metric_key_prefix=metric_key_prefix 3307 )
3308 total_batch_size = self.args.eval_batch_size *
self.args.world_size 3309 if
f"{metric_key_prefix}_jit_compilation_time" in output.metrics:

File C:\Python311\Lib\site-packages\transformers\trainer.py:3408, in
Trainer.evaluation_loop(self, dataloader, description,
prediction_loss_only, ignore_keys, metric_key_prefix) 3406
observed_num_examples = 0 3407 # Main evaluation loop → 3408 for step,
inputs in enumerate(dataloader): 3409 # Update the observed num
examples 3410 observed_batch_size = find_batch_size(inputs) 3411 if
observed_batch_size is not None:

File C:\Python311\Lib\site-packages\accelerate\data_loader.py:454, in
DataLoaderShard.iter(self) 452 # We iterate one batch ahead to check
when we are at the end 453 try: → 454 current_batch = 
next(dataloader_iter) 455 except StopIteration: 456 yield

File
C:\Python311\Lib\site-packages\torch\utils\data\dataloader.py:631, in
_BaseDataLoaderIter.next(self) 628 if self._sampler_iter is None: 629 # TODO(Bug in dataloader iterator found by mypy · Issue #76750 · pytorch/pytorch · GitHub) 630 self._reset() # type: ignore[call-arg] →
631 data = self._next_data() 632 self._num_yielded += 1 633 if
self._dataset_kind == _DatasetKind.Iterable and 634
self._IterableDataset_len_called is not None and 635 self._num_yielded

self._IterableDataset_len_called:

File
C:\Python311\Lib\site-packages\torch\utils\data\dataloader.py:675, in
_SingleProcessDataLoaderIter._next_data(self) 673 def _next_data(self): 674 index = self._next_index() # may raise StopIteration → 675 data = self._dataset_fetcher.fetch(index) # may
raise StopIteration 676 if self._pin_memory: 677 data = 
_utils.pin_memory.pin_memory(data, self._pin_memory_device)

File
C:\Python311\Lib\site-packages\torch\utils\data_utils\fetch.py:51, in
_MapDatasetFetcher.fetch(self, possibly_batched_index) 49 data = self.dataset.getitems(possibly_batched_index) 50 else: —> 51 data = 
[self.dataset[idx] for idx in possibly_batched_index] 52 else: 53 data
= self.dataset[possibly_batched_index]

File
C:\Python311\Lib\site-packages\torch\utils\data_utils\fetch.py:51, in
(.0) 49 data = self.dataset.getitems(possibly_batched_index) 50 else:
—> 51 data = [self.dataset[idx] for idx in possibly_batched_index] 52
else: 53 data = self.dataset[possibly_batched_index]

File
C:\Python311\Lib\site-packages\transformers\tokenization_utils_base.py:255,
in BatchEncoding.getitem(self, item) 253 return self.data[item] 254
elif self._encodings is not None: → 255 return self._encodings[item]
256 elif isinstance(item, slice): 257 return {key:
self.data[key][item] for key in self.data.keys()}

IndexError: list index out of range

问题原因与解决方法

原因

Trainer.predict()要求传入标准数据集格式(比如datasets.Dataset或torch.utils.data.Dataset),但你直接传入了tokenizer返回的BatchEncoding对象。Trainer会把这个对象当作数据集尝试按索引访问,而单个样本的BatchEncoding无法支持这种索引操作,因此抛出IndexError。

解决方法

方法1:直接用模型前向推理(适合单/少量样本)

跳过Trainer.predict,直接调用模型做前向传播,更简洁高效:

inputs = tokenizer(dataset[0]['text'], padding="max_length", truncation=True, return_tensors="pt")
# 若模型在GPU上,需将输入移至对应设备
inputs = {k: v.to(model.device) for k, v in inputs.items()}

# 关闭梯度计算提升速度
with torch.no_grad():
    outputs = model(**inputs)

# 解析预测结果
logits = outputs.logits
predicted_class = torch.argmax(logits, dim=1).item()
print(f"预测类别: {predicted_class}")

方法2:将样本转为Dataset格式(适配Trainer.predict)

如果一定要用Trainer.predict,需要把单样本转为标准Dataset格式,和训练时的处理逻辑对齐:

from datasets import Dataset

# 包装单样本为字典,转为Dataset
sample = {"text": dataset[0]['text']}
test_dataset = Dataset.from_dict(sample)

# 用训练时的tokenize函数处理数据集
test_dataset = test_dataset.map(tokenize_function, batched=True)
test_dataset = test_dataset.set_format("torch", columns=["input_ids", "attention_mask"])

# 执行预测
predictions = trainer.predict(test_dataset=test_dataset)
# 解析结果
preds = np.argmax(predictions.predictions, axis=1)
print(f"预测类别: {preds[0]}")

额外提示

如果需要预测多个样本,只需把所有样本的文本放到字典的列表中,再转为Dataset即可,无需逐个处理:

# 示例:预测前3个样本
samples = {"text": [dataset[i]['text'] for i in range(3)]}
test_dataset = Dataset.from_dict(samples)
test_dataset = test_dataset.map(tokenize_function, batched=True)
test_dataset = test_dataset.set_format("torch", columns=["input_ids", "attention_mask"])

predictions = trainer.predict(test_dataset=test_dataset)
preds = np.argmax(predictions.predictions, axis=1)
print(f"预测类别列表: {preds.tolist()}")

内容的提问来源于stack exchange,提问作者Lijin Durairaj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 14:07:03