Transformers documentation
Выбор из нескольких вариантов
Выбор из нескольких вариантов
Задача с множественным выбором похожа на задачу по ответам на вопросы, за исключением того, что вместе с контекстом предоставляется несколько вариантов ответа, а модель обучается выбирать правильный.
В этом руководстве показано, как:
- Настройте BERT на конфигурации
regularнабора данных SWAG, чтобы выбирать лучший ответ из нескольких вариантов с учётом контекста. - Используйте вашу дообученную модель для инференса.
Прежде чем начать, убедитесь, что у вас установлены все необходимые библиотеки:
pip install transformers datasets evaluate
Мы рекомендуем вам войти в свой аккаунт Hugging Face, чтобы вы могли загрузить свою модель и поделиться ею с сообществом. При появлении запроса введите токен для входа:
>>> from huggingface_hub import notebook_login
>>> notebook_login()Загрузка набора данных SWAG
Начните с загрузки конфигурации regular набора данных SWAG из библиотеки 🤗 Datasets:
>>> from datasets import load_dataset
>>> swag = load_dataset("allenai/swag", "regular")Теперь рассмотрим пример:
>>> swag["train"][0]
{'ending0': 'passes by walking down the street playing their instruments.',
'ending1': 'has heard approaching them.',
'ending2': "arrives and they're outside dancing and asleep.",
'ending3': 'turns the lead singer watches the performance.',
'fold-ind': '3416',
'gold-source': 'gold',
'label': 0,
'sent1': 'Members of the procession walk down the street holding small horn brass instruments.',
'sent2': 'A drum line',
'startphrase': 'Members of the procession walk down the street holding small horn brass instruments. A drum line',
'video-id': 'anetv_jkn6uvmqwh4'}Хотя здесь много полей, на самом деле всё довольно просто:
sent1иsent2: эти поля показывают, как начинается предложение, а если объединить их, получится полеstartphrase.ending: предлагает возможный вариант окончания предложения, но только один из них является правильным.label: определяет правильный конец предложения.
Предобработка
Следующий шаг — загрузить токенизатор BERT для обработки начала предложения и четырёх возможных концов:
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased")Функция предобработки, которую вы хотите создать, должна:
- Создайте четыре копии поля
sent1и объедините каждую из них сsent2, чтобы воссоздать начало предложения. - Соедините
sent2с каждым из четырёх возможных окончаний предложения. - Выровняйте эти два списка, чтобы токенизировать их, а затем верните исходную структуру, чтобы у каждого примера были соответствующие поля
input_ids,attention_maskиlabels.
>>> ending_names = ["ending0", "ending1", "ending2", "ending3"]
>>> def preprocess_function(examples):
... first_sentences = [[context] * 4 for context in examples["sent1"]]
... question_headers = examples["sent2"]
... second_sentences = [
... [f"{header} {examples[end][i]}" for end in ending_names] for i, header in enumerate(question_headers)
... ]
... first_sentences = sum(first_sentences, [])
... second_sentences = sum(second_sentences, [])
... tokenized_examples = tokenizer(first_sentences, second_sentences, truncation=True)
... return {k: [v[i : i + 4] for i in range(0, len(v), 4)] for k, v in tokenized_examples.items()}Чтобы применить функцию предобработки ко всему набору данных, используйте метод map библиотеки 🤗 Datasets. Вы можете ускорить работу функции map, установив batched=True, чтобы обрабатывать несколько элементов набора данных одновременно:
>>> tokenized_swag = swag.map(preprocess_function, batched=True)Чтобы создать батч примеров, эффективнее динамически дополнять предложения до максимальной длины в батче на этапе collation, чем дополнять весь датасет до максимальной длины. DataCollatorForMultipleChoice разворачивает все входные данные модели, применяет padding, а затем сворачивает результаты обратно.
>>> from transformers import DataCollatorForMultipleChoice
>>> collator = DataCollatorForMultipleChoice(tokenizer=tokenizer)Оценка
Добавление метрики в процесс обучения часто помогает оценить качество модели. Вы можете быстро загрузить метод оценки с помощью библиотеки 🤗 Evaluate. Для этой задачи загрузите метрику accuracy (ознакомьтесь с быстрым обзором 🤗 Evaluate, чтобы узнать, как загружать и вычислять метрики):
>>> import evaluate
>>> accuracy = evaluate.load("accuracy")Затем создайте функцию, которая передаёт ваши предсказания и метки в compute для вычисления точности:
>>> import numpy as np
>>> def compute_metrics(eval_pred):
... predictions, labels = eval_pred
... predictions = np.argmax(predictions, axis=1)
... return accuracy.compute(predictions=predictions, references=labels)Ваша функция compute_metrics готова, и вы вернётесь к ней при настройке обучения.
Обучение
Если вы не знакомы с дообучением модели с помощью Trainer, загляните в базовое руководство здесь!
Теперь вы готовы приступить к обучению модели! Загрузите BERT с помощью AutoModelForMultipleChoice:
>>> from transformers import AutoModelForMultipleChoice, TrainingArguments, Trainer
>>> model = AutoModelForMultipleChoice.from_pretrained("google-bert/bert-base-uncased")На этом этапе осталось выполнить только три шага:
- Определите гиперпараметры обучения в TrainingArguments. Единственный обязательный параметр —
output_dir, который указывает, куда сохранять модель. Чтобы загрузить модель на Hub, установитеpush_to_hub=True(для загрузки модели необходимо войти в аккаунт Hugging Face). В конце каждой эпохи Trainer оценивает точность и сохраняет контрольную точку обучения. - Передайте аргументы обучения в Trainer вместе с моделью, набором данных, токенизатором, data collator и функцией
compute_metrics. - Вызовите train(), чтобы дообучить модель.
>>> training_args = TrainingArguments(
... output_dir="my_awesome_swag_model",
... eval_strategy="epoch",
... save_strategy="epoch",
... load_best_model_at_end=True,
... learning_rate=5e-5,
... per_device_train_batch_size=16,
... per_device_eval_batch_size=16,
... num_train_epochs=3,
... weight_decay=0.01,
... push_to_hub=True,
... )
>>> trainer = Trainer(
... model=model,
... args=training_args,
... train_dataset=tokenized_swag["train"],
... eval_dataset=tokenized_swag["validation"],
... processing_class=tokenizer,
... data_collator=collator,
... compute_metrics=compute_metrics,
... )
>>> trainer.train()После завершения обучения используйте метод push_to_hub(), чтобы опубликовать модель на Hub и дать всем возможность её использовать:
>>> trainer.push_to_hub()Более подробный пример того, как дообучить модель для задачи с множественным выбором, можно найти в соответствующем ноутбуке PyTorch.
Вывод
Отлично, теперь, когда вы дообучили модель, вы можете использовать её для инференса!
Придумайте какой-либо текст и два варианта ответа:
>>> prompt = "France has a bread law, Le Décret Pain, with strict rules on what is allowed in a traditional baguette."
>>> candidate1 = "The law does not apply to croissants and brioche."
>>> candidate2 = "The law applies to baguettes."Токенизируйте каждую пару «запрос — ответ» и верните тензоры PyTorch. Также необходимо создать некоторые labels:
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_swag_model")
>>> inputs = tokenizer([[prompt, candidate1], [prompt, candidate2]], return_tensors="pt", padding=True)
>>> labels = torch.tensor(0).unsqueeze(0)Передайте входные данные и метки в модель и верните logits:
>>> from transformers import AutoModelForMultipleChoice
>>> model = AutoModelForMultipleChoice.from_pretrained("username/my_awesome_swag_model")
>>> outputs = model(**{k: v.unsqueeze(0) for k, v in inputs.items()}, labels=labels)
>>> logits = outputs.logitsПолучите класс с наибольшей вероятностью:
>>> predicted_class = logits.argmax().item()
>>> predicted_class
0