A geração de perguntas é a tarefa de gerar automaticamente perguntas de um parágrafo de texto. A maneira mais direta para isso é a geração de perguntas conscientes da resposta. Na geração de perguntas conscientes da resposta, o modelo é apresentado com a resposta e a passagem e solicitada a gerar uma pergunta para essa resposta considerando o contexto da passagem. Embora existam muitos trabalhos disponíveis para a tarefa QG, ainda não é tão mainstream quanto o controle de qualidade. Uma das razões é que a maioria dos documentos anteriores usa modelos/dutos de processamento complicados e não possui modelos pré-treinados disponíveis. Poucos artigos recentes, especificamente unilm e profetnet, têm pesos pré-treinados SOTA disponíveis para QG, mas o uso parece bastante complicado.
Este projeto é voltado como um estudo de código aberto sobre geração de perguntas com transformadores pré-treinados (especificamente modelos SEQ-2-seq) usando métodos de ponta a ponta diretos sem pipelines com muito complicados. O objetivo é fornecer scripts simplificados de processamento e treinamento de dados e pipelines fáceis de usar para inferência.
As experiências iniciais são realizadas usando o conjunto de dados Squadv1 e o modelo T5 com diferentes formatos de processamento de entrada, conforme descrito abaixo.
Para modelos de consciência de resposta, o texto de entrada pode ser processado de duas maneiras.
1. Formato de prenda:
Aqui, a resposta é simplesmente adicionada antes do contexto e separada pelo token de setembro. Por exemplo
42 [SEP] 42 is the answer to life, the universe and everything.
Para o modelo T5, a entrada é processada assim
answer: 42 context: 42 is the answer to life, the universe and everything.
2. Formato de destaque
Aqui, o período de resposta é destacado no texto com tokens de destaque especial.
<hl> 42 <hl> is the answer to life, the universe and everything.
Essa idéia é proposta no artigo "Um modelo recorrente baseado em Bert para geração de perguntas". Consulte a Seção 4.3
Como os modelos conscientes da resposta precisam de respostas para gerar perguntas, precisamos de algo que possa extrair respostas como vãos do texto. Isso pode ser feito usando vários métodos, como NER, exparto de frase de substantivo etc. Mas aqui um modelo é treinado para extrair respostas como vãos, para ver como funcionará. Com o T5, a resposta da resposta é feita usando o texto em formato.
Como o formato de destaque precisará saber a posição de resposta extraída em abrangência, a entrada para a extração de respostas é processada da seguinte forma
<hl> .<sep> .Por exemplo para este texto
Python is a programming language. Created by Guido van Rossum and first released in 1991.
A seguir, exemplos serão criados
Texto de entrada: <hl> Python is a programming language. <hl> Created by Guido van Rossum and first released in 1991.
Texto -alvo: Python <sep>
e
Texto de entrada: Python is a programming language. <hl> Created by Guido van Rossum and first released in 1991 <hl>.
Texto -alvo: Guido van Rossum <sep> 1991 <sep>
No momento da inferência, o texto é dividido em frases e cada frase é destacada.
Para a geração de perguntas conscientes da resposta, geralmente precisamos de 3 modelos, primeiro que extrairá respostas como vãos, o segundo modelo gerará perguntas nessa resposta e o terceiro será um modelo de controle de qualidade que levará a pergunta e produzirá uma resposta, então podemos comparar as duas respostas para ver se a pergunta gerada está correta ou não.
Ter 3 modelos para tarefa única é muita complexidade, então o objetivo é criar um modelo de várias tarefas que possa realizar todas essas 3 tarefas
O modelo T5 é ajustado de maneira múltipla usando prefixos de tarefas, conforme descrito no papel.
Em geração de perguntas de ponta a ponta, o modelo é analisado para gerar perguntas sem fornecer as respostas. Este artigo discute essas idéias com mais detalhes. Aqui, o modelo T5 é treinado para gerar várias perguntas simultaneamente, apenas fornecendo o contexto. As perguntas são separadas pelo token <sep> . Veja como os exemplos são processados
Texto de entrada: Python is a programming language. Created by Guido van Rossum and first released in 1991.
Texto -alvo: Who created Python ? <sep> When was python released ? <sep>
Todos os detalhes de treinamento podem ser encontrados neste projeto Wandb
Resultados no conjunto de dev Squad1.0 usando abordagens acima. Para decodificação, a pesquisa de feixe com num_beams 4 é usada com o comprimento máximo de decodificação definido como 32.
Para modelos de QA-QG de várias tarefas, as pontuações EM e F1 estão envolvidas como QA-EM e QA-F1.
O pacote NLG-EVAL é usado para calcular as métricas.
| Nome | Bleu-4 | METEORO | Rouge-l | QA-EM | QA-F1 | QG-formato |
|---|---|---|---|---|---|---|
| T5-BASE-QG-HL | 21.3226 | 27.0854 | 43.5962 | - | - | destaque |
| T5-BASE-QA-QG-HL | 21.0141 | 26.9113 | 43.2484 | 82.46 | 90.272 | destaque |
| T5-Small-QA-QG-HL | 18.9872 | 25.2217 | 40.7893 | 76.121 | 84.904 | destaque |
| T5-Small-QG-HL | 18.5921 | 24.9915 | 40.1886 | - | - | destaque |
| T5-Small-QG-Prepender | 18.2791 | 24.6722 | 39.958 | - | - | Preparar |
transformers==3.0.0
nltk
nlp==0.2.0 # only if you want to fine-tune.
Depois de instalar nltk fazer
python -m nltk.downloader punktUse o pipeline whch imita? Transformers Pipeline para facilitar a inferência.
O oleoduto é dividido em 3 tarefas
question-generation : para modelos de geração de perguntas para tarefas únicas.multitask-qa-qg : para QA de várias tarefas, modelos QG.e2e-qg : Para geração de perguntas de ponta a ponta. 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?' }]Formato de prenda
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?'
] Por padrão, ambos os pipelines usarão os modelos T5-Small*, para usar os outros modelos passarem o caminho através do paramter model .
Por padrão, o pipeline question-generation baixará o modelo Valhalla/T5-Small-QG-HL com o formato QG highlight . Se você deseja usar o formato Prendend, forneça o caminho para o modelo de prenda e defina qg_format como "prepend" . Para extrair respostas, como vãos, ele usa o modelo Valhalla/T5-Small-QA-QG-HL, você pode fornecer um modelo diferente através do parâmetro ans_model .
O modelo multitask-qa-qg é para modelos multitarefa que podem extrair respostas como vãos, fazer QG e QA, para que não precise separar ans_model . Por padrão, o modelo Valhalla/T5-Small-QA-QG-HL é usado com o formato highlight . Se você deseja usar o formato de prenda, forneça o caminho para o modelo de prenda e defina qg_format para "prepend"
O pipeline e2e-qg é para geração de perguntas de ponta a ponta. Esses modelos podem gerar várias perguntas simultaneamente sem a supervisão de resposta. Por padrão, ele usa Valhalla/T5-Small-E2e-QG
Para suportar diferentes formatos de dados, o treinador espera um conjunto de dados em cache pré-processado, para que você possa processar os dados da maneira que deseja. O conjunto de dados em cache deve ser salvo usando torch.save e deve retornar um dict com source_ids , target_ids , attention_mask teclas de __getitem__ .
source_ids : texto de origem codificadotarget_ids : texto de destino codificadoattention_mask : Máscara de atenção para os source_ids O T2TDataCollator CUIDADO DE PREPARAR input_ids E labels . Ele também apara os lotes dinamicamente para remover tokens de preenchimento excessivo, para acelerar o treinamento.
O data/squad_multitask contém o conjunto de dados de esquadrão modificado para a geração de perguntas conscientes da resposta (usando formatos de prenda e destaque), respondendo a perguntas (texto para texto), extração de respostas e geração de perguntas de ponta a ponta. Este conjunto de dados pode ser carregado usando o incrível? Biblioteca nlp , isso facilita muito o processamento.
Para processar e armazenar em cache o conjunto de dados, use o script prepare_data.py . Ele carregará o tokenizer correto, dependendo do argumento model_type . Ele adiciona dois novos tokens <sep> e <hl> ao tokenizer e o salva em {model_type}_qg_tokenizer Path. Você deve passar este tokenizador para o script de ajuste fino.
Os conjuntos de dados serão salvos no data/ Diretório. Você deve fornecer nomes de arquivos usando os argumentos de train_file_name e valid_file_name .
Processar dados para geração de perguntas de tarefa única com destaque_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 Processar dados para QA-QG com várias tarefas com destaque_qg_format
O argumento valid_for_qg_only é usado para decidir se o conjunto de validação deve conter apenas dados para a tarefa QG. Para meus experimentos com várias tarefas, usei dados de validação apenas com tarefa QG para que a curva de perda de avaliação possa ser facilmente comparada com outros modelos de tarefas únicos
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 Processar conjunto de dados para geração de perguntas de ponta a ponta
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 Use o script run_qg.py para iniciar o treinamento. Ele usa a classe Trainer Transformers para treinar os modelos.
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 se você quiser treiná -lo de script ou notebook, então
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 ) Use o script eval.py para avaliar o modelo.
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.txtIsso salvará a saída no arquivo {output_path}.
Para calcular as métricas, instale o pacote NLG-EVAL e execute
nlg-eval --hypothesis=hypothesis_t5-base-qg-hl.txt --references=data/references.txt --no-skipthoughts --no-glove