Проблема формата входных данных суммирования текста HuggingFace

avatar
asymmetryFan
8 августа 2021 в 18:23
188
1
1

Я пытаюсь настроить модель для суммирования текста. Я использую AutoModelForSeq2SeqLM.from_pretrained(), поэтому следующее применимо к нескольким моделям (например, T5, ProphetNet, BART).

Я создал класс с именем CustomDataset, который является подклассом torch.utils.Dataset. Этот класс содержит одно поле: samples — список словарей с ключами encodings и labels. Каждое из значений в каждом из этих словарей представляет собой torch.Tensor. Вот как выглядит запись в samples:

{'encoding': tensor([[21603, 10, 188, 563, 1]]), 'label': tensor([[ 1919, 22003, 22, 7, 1]])}

Вот как я пытаюсь настроить модель с помощью Trainer:

model = AutoModelForSeq2SeqLM.from_pretrained(model_name)

training_args = TrainingArguments("test_trainer")
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=data,
)
trainer.train()

Ошибка, которую я получаю, возникает в строке 63 в transformers\data\data_collator.py. Вот эта строка кода:

label = first["label"].item() if isinstance(first["label"], torch.Tensor) else first["label"]

Вот сообщение об ошибке: ValueError: only one element tensors can be converted to Python scalars

Я понимаю, почему конкретно выдается сообщение об ошибке - тензор first["label"] не является одноэлементным тензором, и, следовательно, item() не может быть вызван для него. Однако я задаю этот вопрос не поэтому.

Я предполагаю, что неправильно передаю данные, но мне кажется, что Trainer должен сам позаботиться о input_ids и decoder_input_ids. Я попытался установить их вручную (передав encodings как input_ids и labels как decoder_input_ids), и модель может успешно выполнять вывод, но мне не удалось ее настроить. Где я делаю ошибку и как ее исправить?

Источник

Ответы (1)

avatar
asymmetryFan
8 августа 2021 в 19:49
1

Использование имени label_ids вместо label устраняет конкретную проблему. label следует использовать, если метка является int, float или одноэлементной torch.Tensor. Для тензоров с несколькими элементами используйте label_ids. Подробнее см. data_collator.py, строки 62-71:

if "label" in first and first["label"] is not None:
    label = first["label"].item() if isinstance(first["label"], torch.Tensor) else first["label"]
    dtype = torch.long if isinstance(label, int) else torch.float
    batch["labels"] = torch.tensor([f["label"] for f in features], dtype=dtype)
elif "label_ids" in first and first["label_ids"] is not None:
    if isinstance(first["label_ids"], torch.Tensor):
        batch["labels"] = torch.stack([f["label_ids"] for f in features])
    else:
        dtype = torch.long if type(first["label_ids"][0]) is int else torch.float
        batch["labels"] = torch.tensor([f["label_ids"] for f in features], dtype=dtype)

Кроме того, следует использовать имя input_ids вместо encoding. В противном случае возникает ошибка unknown kwarg.