La génération de questions est la tâche de générer automatiquement des questions à partir d'un paragraphe de texte. La manière la plus simple pour cela est la génération de questions consciente des réponses. En réponse à la génération de questions conscientes, le modèle est présenté avec la réponse et le passage et a demandé de générer une question pour cette réponse en considérant le contexte du passage. Bien qu'il existe de nombreux articles disponibles pour la tâche QG, il n'est toujours pas aussi courant que l'AQ. L'une des raisons est que la plupart des articles précédents utilisent des modèles complexes / pipelines de traitement et n'ont pas de modèles pré-formés disponibles. Peu d'articles récents, en particulier unilm et Prophetnet, ont des poids pré-formés SOTA disponibles pour QG, mais l'utilisation semble assez compliquée.
Ce projet est destiné à une étude open source sur la génération de questions avec des transformateurs pré-formés (en particulier les modèles SEQ-2-SEQ) en utilisant des méthodes de bout en bout simples sans pipelines beaucoup compliqués. L'objectif est de fournir des scripts de traitement des données et de formation simplifiés et des pipelines faciles à utiliser pour l'inférence.
Les expériences initiales sont menées à l'aide de l'ensemble de données SKADV1 et du modèle T5 avec différents formats de traitement d'entrée comme décrit ci-dessous.
Pour les modèles de rendez-vous de réponse, le texte d'entrée peut être traité de deux manières.
1. Format de prépendre:
Ici, la réponse est simplement ajoutée avant le contexte et séparée par SEP Token. Par exemple
42 [SEP] 42 is the answer to life, the universe and everything.
Pour le modèle T5, l'entrée est traitée comme celle-ci
answer: 42 context: 42 is the answer to life, the universe and everything.
2. Format de mise en évidence
Ici, la durée de réponse est mise en évidence dans le texte avec des jetons de surbrillance spéciaux.
<hl> 42 <hl> is the answer to life, the universe and everything.
Cette idée est proposée dans l'article "un modèle récurrent basé sur Bert pour la génération de questions". Voir section 4.3
Comme les modèles de rendez-vous de réponse ont besoin de réponses pour générer une question, nous avons besoin de quelque chose qui peut extraire des réponses comme des portées du texte. Cela peut être fait en utilisant diverses méthodes comme NER, Extarction du nom-phrase, etc., mais ici, un modèle est formé pour extraire des réponses comme des portes, pour voir comment cela fonctionnera. Avec T5, l'extarction de la réponse est effectuée en utilisant le texte à format.
Comme le format de surbrillance devra connaître la position de réponse extraite s'étend, l'entrée pour l'extraction de réponse est traitée comme suit
<hl> .<sep> .Par exemple pour ce texte
Python is a programming language. Created by Guido van Rossum and first released in 1991.
Des exemples suivants seront créés
Texte d'entrée: <hl> Python is a programming language. <hl> Created by Guido van Rossum and first released in 1991.
Texte cible: Python <sep>
et
Texte d'entrée: Python is a programming language. <hl> Created by Guido van Rossum and first released in 1991 <hl>.
Texte cible: Guido van Rossum <sep> 1991 <sep>
Au moment de l'inférence, le texte est divisé en phrases et chaque phrase est mise en évidence.
Pour la génération de questions consciente de la réponse, nous avons généralement besoin de 3 modèles, d'abord qui extraire la réponse comme des portées, le deuxième modèle générera une question sur cette réponse et le troisième sera un modèle QA qui prendra la question et produira une réponse, alors nous pouvons comparer les deux réponses pour voir si la question générée est correcte ou non.
Avoir 3 modèles pour une seule tâche est beaucoup de complexité, donc l'objectif est de créer un modèle multi-tâches qui peut effectuer toutes ces 3 tâches
Le modèle T5 est affiné de manière multi-tâches en utilisant les préfixes de tâches comme décrit dans l'article.
Dans la génération de questions de bout en bout, le modèle devrait générer des questions sans fournir les réponses. Cet article traite de ces idées plus en détail. Ici, le modèle T5 est formé pour générer plusieurs questions simultanément en fournissant simplement le contexte. Les questions sont séparées par le jeton <sep> . Voici comment les exemples sont traités
Texte d'entrée: Python is a programming language. Created by Guido van Rossum and first released in 1991.
Texte cible: Who created Python ? <sep> When was python released ? <sep>
Tous les détails de formation peuvent être trouvés dans ce projet WANDB
Résultats sur l'ensemble de développeurs Squad1.0 en utilisant les approches ci-dessus. Pour le décodage, la recherche de faisceau avec num_beams 4 est utilisée avec une longueur de décodage maximale réglée sur 32.
Pour les modèles QA-QG multitastiques, les scores EM et F1 sont privés comme QA-EM et QA-F1.
Le package NLG-Eval est utilisé pour calculer les mesures.
| Nom | Bleu-4 | MÉTÉORE | Rouge-l | QA-EM | QA-F1 | Qg-format |
|---|---|---|---|---|---|---|
| t5-base-qg-hl | 21.3226 | 27.0854 | 43.5962 | - | - | souligner |
| t5-base-qa-qg-hl | 21.0141 | 26.9113 | 43.2484 | 82.46 | 90.272 | souligner |
| T5-Small-QA-QG-HL | 18.9872 | 25.2217 | 40.7893 | 76.121 | 84.904 | souligner |
| t5-small-qg-hl | 18.5921 | 24.9915 | 40.1886 | - | - | souligner |
| T5-Small-Qg-PrePend | 18.2791 | 24.6722 | 39.958 | - | - | appuyer sur |
transformers==3.0.0
nltk
nlp==0.2.0 # only if you want to fine-tune.
Après avoir installé nltk DO
python -m nltk.downloader punktUtilisez le pipeline WHCH Mimics? Transformers Pipeline pour une inférence facile.
Le pipeline est divisé en 3 tâches
question-generation : pour les modèles de génération de questions à tâches.multitask-qa-qg : pour les modèles QA multi-tâches, QG.e2e-qg : Pour la génération de questions de bout en bout. from pipelines import pipeline
nlp = pipeline ( "question-generation" )
nlp ( "42 is the answer to life, the universe and everything." )
= > [{ 'answer' : '42' , 'question' : 'What is the answer to life, the universe and everything?' }]Format de préparation
nlp = pipeline ( "question-generation" , model = "valhalla/t5-small-qg-prepend" , qg_format = "prepend" )
nlp ( "42 is the answer to life, the universe and everything." )
= > [{ 'answer' : '42 ' , 'question' : 'What is the answer to life, the universe, and everything?' }] nlp = pipeline ( "multitask-qa-qg" )
# to generate questions simply pass the text
nlp ( "42 is the answer to life, the universe and everything." )
= > [{ 'answer' : '42' , 'question' : 'What is the answer to life, the universe and everything?' }]
# for qa pass a dict with "question" and "context"
nlp ({
"question" : "What is 42 ?" ,
"context" : "42 is the answer to life, the universe and everything."
})
= > 'the answer to life, the universe and everything' nlp = pipeline ( "e2e-qg" )
nlp ( "Python is a programming language. Created by Guido van Rossum and first released in 1991." )
= > [
'What is a programming language?' ,
'Who created Python?' ,
'When was Python first released?'
] Par défaut, les deux pipelines utiliseront les modèles T5-Small *, pour utiliser les autres modèles passer le paramètre de modèle à travers model .
Par défaut, le pipeline question-generation téléchargera le modèle Valhalla / T5-Small-QG-HL avec le format QG highlight . Si vous souhaitez utiliser le format Prend, fournissez le chemin du modèle PRENPEND et définissez qg_format sur "prepend" . Pour extraire la réponse comme Spans, il utilise le modèle Valhalla / T5-Small-QA-QG-HL, vous pouvez fournir un modèle différent via le paramètre ans_model .
Le modèle multitask-qa-qg est destiné aux modèles multitastiques qui peuvent extraire des réponses comme des portes, DO QG et QA, donc il n'aura pas besoin d'être séparé ans_model . Par défaut, le modèle Valhalla / T5-Small-QA-QG-HL est utilisé avec le format highlight . Si vous souhaitez utiliser le format Prend, fournissez le chemin du modèle PRENPEND et définissez qg_format sur "prepend"
Le pipeline e2e-qg est destiné à la génération de questions de bout en bout. Ces modèles peuvent générer plusieurs questions simultanément sans supervision de réponse. Par défaut, il utilise Valhalla / T5-Small-E2E-QG
Pour prendre en charge différents formats de données, le formateur s'attend à un ensemble de données mis en cache pré-traité, afin que vous puissiez traiter les données comme vous le souhaitez. L'ensemble de données mis en cache doit être enregistré à l'aide de torch.save et il doit renvoyer un dict avec source_ids , target_ids , attention_mask Keys de __getitem__ .
source_ids : texte source codétarget_ids : texte cible codéattention_mask : Masque d'attention pour le source_ids Le T2TDataCollator s'occupe de la préparation de la droite input_ids et labels . Il coupe également les lots dynamiquement pour éliminer les jetons de rembourrage excessifs, pour accélérer l'entraînement.
Le data/squad_multitask entrera le jeu de données de l'escouade modifié pour la génération de questions conscients de réponse (en utilisant les formats de pré-prédalage et de surbrillance), de réponse aux questions (texte à texte), extraction de réponse et génération de questions de bout en bout. Cet ensemble de données peut être chargé en utilisant le génial? Bibliothèque nlp , cela rend le traitement très facile.
Pour traiter et mettre en cache l'ensemble de données, utilisez le script prepare_data.py . Il chargera le tokenizer correct en fonction de l'argument model_type . Il ajoute deux nouveaux jetons <sep> et <hl> au tokenizer et l'enregistre sur le chemin {model_type}_qg_tokenizer . Vous devez transmettre ce tokenzer au script de réglage fin.
Les ensembles de données seront enregistrés dans data/ répertoires. Vous devez fournir des noms de fichiers à l'aide train_file_name et valid_file_name Arguments.
Traiter les données pour la génération de questions à tâche unique avec highlight_qg_format
python prepare_data.py
--task qg
--model_type t5
--dataset_path data/squad_multitask/
--qg_format highlight_qg_format
--max_source_length 512
--max_target_length 32
--train_file_name train_data_qg_hl_t5.pt
--valid_file_name valid_data_qg_hl_t5.pt Traiter les données pour la QA-QG multi-tâches avec Highlight_QG_Format
L'argument valid_for_qg_only est utilisé pour décider si l'ensemble de validation ne doit contenir que des données pour la tâche QG. Pour mes expériences multi-tâches, j'ai utilisé des données de validation avec une tâche QG unique
python prepare_data.py
--task multi
--valid_for_qg_only
--model_type t5
--dataset_path data/squad_multitask/
--qg_format highlight_qg_format
--max_source_length 512
--max_target_length 32
--train_file_name train_data_qa_qg_hl_t5.pt
--valid_file_name valid_data_qg_hl_t5.pt Ensemble de données de processus pour la génération de questions de bout en bout
python prepare_data.py
--task e2e_qg
--valid_for_qg_only
--model_type t5
--dataset_path data/squad_multitask/
--qg_format highlight_qg_format
--max_source_length 512
--max_target_length 32
--train_file_name train_data_e2e_qg_t5.pt
--valid_file_name valid_data_e2e_qg_t5.pt Utilisez le script run_qg.py pour commencer la formation. Il utilise la classe Trainer Transformers pour former les modèles.
python run_qg.py
--model_name_or_path t5-small
--model_type t5
--tokenizer_name_or_path t5_qg_tokenizer
--output_dir t5-small-qg-hl
--train_file_path data/train_data_qg_hl_t5.pt
--valid_file_path data/valid_data_qg_hl_t5.pt
--per_device_train_batch_size 32
--per_device_eval_batch_size 32
--gradient_accumulation_steps 8
--learning_rate 1e-4
--num_train_epochs 10
--seed 42
--do_train
--do_eval
--evaluate_during_training
--logging_steps 100ou si vous souhaitez le former à partir du script ou du cahier, alors
from run_qg import run_qg
args_dict = {
"model_name_or_path" : "t5-small" ,
"model_type" : "t5" ,
"tokenizer_name_or_path" : "t5_qg_tokenizer" ,
"output_dir" : "t5-small-qg-hl" ,
"train_file_path" : "data/train_data_qg_hl_t5.pt" ,
"valid_file_path" : "data/valid_data_qg_hl_t5.pt" ,
"per_device_train_batch_size" : 32 ,
"per_device_eval_batch_size" : 32 ,
"gradient_accumulation_steps" : 8 ,
"learning_rate" : 1e-4 ,
"num_train_epochs" : 10 ,
"seed" : 42 ,
"do_train" : True ,
"do_eval" : True ,
"evaluate_during_training" : True ,
"logging_steps" : 100
}
# start training
run_qg ( args_dict ) Utilisez le script eval.py pour évaluer le modèle.
python eval.py
--model_name_or_path t5-base-qg-hl
--valid_file_path valid_data_qg_hl_t5.pt
--model_type t5
--num_beams 4
--max_decoding_length 32
--output_path hypothesis_t5-base-qg-hl.txtCela enregistrera la sortie dans le fichier {output_path}.
Pour calculer les mesures, installez le package NLG-Eval et exécutez
nlg-eval --hypothesis=hypothesis_t5-base-qg-hl.txt --references=data/references.txt --no-skipthoughts --no-glove