Transformers documentation
Choix multiples
Choix multiples
Une tâche à choix multiples est similaire à la réponse à des questions, à l’exception près que plusieurs réponses candidates sont fournies avec un contexte et que le modèle est entraîné à sélectionner la bonne réponse.
Ce guide vous montre comment :
- Effectuer l’ajustement fin de BERT sur la configuration
regulardu jeu de données SWAG afin de sélectionner la meilleure réponse parmi plusieurs options et un certain contexte. - Utilisez votre modèle affiné pour l'inférence.
Avant de commencer, assurez-vous d'avoir installé toutes les bibliothèques nécessaires :
pip install transformers datasets evaluate
Nous vous encourage à vous connecter à votre compte Hugging Face afin de pouvoir téléverser et partager votre modèle avec la communauté. Lorsque cela vous est demandé, saisissez votre jeton pour vous connecter :
>>> from huggingface_hub import notebook_login
>>> notebook_login()Charger le jeu de données SWAG
Commencez par charger la configuration regular du jeu de données SWAG à partir de la bibliothèque 🤗 Datasets :
>>> from datasets import load_dataset
>>> swag = load_dataset("allenai/swag", "regular")Puis, jetez un œil à un exemple :
>>> 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'}Bien qu’il semble y avoir beaucoup de champs ici, c’est en réalité assez simple :
sent1etsent2: ces champs indiquent comment une phrase commence, et si vous les combinez, vous obtenez le champstartphrase.ending: suggère une fin possible pour la façon dont une phrase peut se terminer, mais seule l'une d'entre elles est correcte.label: identifie la fin de phrase correcte.
Prétraitement
L'étape suivante consiste à charger un tokenizer BERT pour traiter le début de la phrase et les quatre fins possibles :
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased")La fonction de prétraitement que vous souhaitez créer doit :
- Créez quatre copies du champ
sent1et combinez chacune d'elles avecsent2pour recréer le début d'une phrase. - Combiner
sent2avec chacune des quatre fins de phrase possibles. - Aplatir ces deux listes pour pouvoir les tokeniser, puis les dé-aplatir ensuite afin que chaque exemple possède un champ
input_ids,attention_masketlabelscorrespondant.
>>> 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()}Pour appliquer la fonction de prétraitement à l’ensemble du jeu de données, utilisez la méthode map de 🤗 Datasets. Vous pouvez accélérer la fonction map en définissant batched=True afin de traiter plusieurs éléments du jeu de données à la fois :
>>> tokenized_swag = swag.map(preprocess_function, batched=True)Pour créer un lot d'exemples, il est plus efficace de rembourrer dynamiquement les phrases jusqu'à la longueur maximale du lot lors de la collation, plutôt que de rembourrer l'ensemble du jeu de données jusqu'à la longueur maximale. DataCollatorForMultipleChoice aplatit toutes les entrées du modèle, applique le rembourrage, puis rétablit la structure d'origine des résultats.
>>> from transformers import DataCollatorForMultipleChoice
>>> collator = DataCollatorForMultipleChoice(tokenizer=tokenizer)Évaluer
Inclure une métrique pendant l’entraînement est souvent utile pour évaluer les performances de votre modèle. Vous pouvez charger rapidement une méthode d’évaluation avec la bibliothèque 🤗 Evaluate. Pour cette tâche, chargez la métrique accuracy (consultez le quick tour de 🤗 Evaluate pour en savoir plus sur la façon de charger et de calculer une métrique) :
>>> import evaluate
>>> accuracy = evaluate.load("accuracy")Créez ensuite une fonction qui transmet vos prédictions et vos étiquettes à compute pour calculer la précision :
>>> 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)Votre fonction compute_metrics est prête, et vous y reviendrez lors de la configuration de l’entraînement.
Entraînement
Si vous n’êtes pas familier avec l’ajustement fin d’un modèle à l’aide du Trainer, consultez le tutoriel de base ici !
Vous êtes prêt à commencer l’entraînement de votre modèle ! Chargez BERT avec AutoModelForMultipleChoice :
>>> from transformers import AutoModelForMultipleChoice, TrainingArguments, Trainer
>>> model = AutoModelForMultipleChoice.from_pretrained("google-bert/bert-base-uncased")À ce stade, il ne reste que trois étapes :
- Définissez vos hyperparamètres d’entraînement dans TrainingArguments. Le seul paramètre obligatoire est
output_dir, qui spécifie l’endroit où enregistrer votre modèle. Vous publierez ce modèle sur le Hub en définissantpush_to_hub=True(vous devez être connecté à Hugging Face pour téléverser votre modèle). À la fin de chaque époque, le Trainer évalue la précision et enregistre le point de contrôle d’entraînement. - Transmettez les arguments d’entraînement à Trainer en même temps que le modèle, le jeu de données, le tokenizer, le data collator et la fonction
compute_metrics. - Appel de train() pour l’ajustement fin de votre modèle.
>>> 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()Une fois l’entraînement terminé, partagez votre modèle sur le Hub à l’aide de la méthode push_to_hub() afin que chacun puisse l’utiliser :
>>> trainer.push_to_hub()Pour un exemple plus approfondi sur la façon d’affiner un modèle pour un choix multiple, consultez le notebook PyTorch correspondant.
Inférence
Parfait, maintenant que vous avez affiné un modèle, vous pouvez l'utiliser pour l'inférence !
Proposez un texte et deux réponses candidates :
>>> 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."Tokenisez chaque paire de prompt et de réponse candidate et renvoyez des tenseurs PyTorch. Vous devez également créer des 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)Transmettez vos entrées et étiquettes au modèle et renvoyez les 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.logitsObtenir la classe ayant la probabilité la plus élevée :
>>> predicted_class = logits.argmax().item()
>>> predicted_class
0