問題生成是自動從文本段落中生成問題的任務。這樣做的最直接方法是回答意識到的問題產生。在回答問題中,該模型帶有答案和段落,並要求通過考慮段落上下文來為該答案產生一個問題。雖然有許多QG任務的論文,但它仍然不像QA那樣主流。原因之一是大多數較早的論文都使用複雜的模型/處理管道,並且沒有可用的預培訓模型。最近,很少有unilm和prophetnet具有SOTA預先培訓的權重,但使用情況似乎很複雜。
該項目的目的是使用直接前向的端到端方法進行的,沒有太多複雜的管道,針對預訓練的變壓器(特別是SEQ-2-SEQ模型)進行了問題的開源研究。目的是提供簡化的數據處理和培訓腳本,並易於使用管道進行推理。
如下所述,使用Squeadv1數據集和T5模型進行了初始實驗。
對於回答意識模型,可以通過兩種方式處理輸入文本。
1。預端格式:
在這裡,答案簡單地添加到上下文之前,並被sep令牌分開。例如
42 [SEP] 42 is the answer to life, the universe and everything.
對於T5模型,輸入是這樣處理的
answer: 42 context: 42 is the answer to life, the universe and everything.
2。高光格式
在這裡,答案跨度在文本中突出顯示,並帶有特殊的高光令牌。
<hl> 42 <hl> is the answer to life, the universe and everything.
這個想法是在“問題生成的基於BERT的經常性模型”中提出的。請參閱第4.3節
由於答案意識模型需要答案來生成問題,因此我們需要一些可以從文本中提取跨度的答案。這可以使用NER,名詞 - 詞組縮放等各種方法來完成,但是在這裡,訓練了一個模型來提取跨度的答案,以查看其將如何工作。使用T5,使用文本對形式進行答案散文。
由於高光格式需要知道提取答案的位置跨度跨度跨度,因此提取的輸入如下。
<hl>令牌突出顯示句子。<sep>令牌加入該句子中的答案。例如,本文
Python is a programming language. Created by Guido van Rossum and first released in 1991.
將創建以下示例
輸入文本: <hl> Python is a programming language. <hl> Created by Guido van Rossum and first released in 1991.
目標文本: Python <sep>
和
輸入文本: Python is a programming language. <hl> Created by Guido van Rossum and first released in 1991 <hl>.
目標文本: Guido van Rossum <sep> 1991 <sep>
在推理時,文本被分為句子,每個句子都會突出顯示。
對於答案的問題生成,我們通常需要3個模型,首先將提取跨越跨度的答案,第二個模型將在該答案上產生問題,第三個模型將是一個質量檢查模型,它將採用問題並產生答案,然後我們可以比較兩個答案,以查看生成的問題是否正確。
擁有3種單個任務模型是很複雜的,因此目標是創建一個可以完成所有這3個任務的多任務模型
如本文所述,使用任務前綴以多任務方式對T5模型進行微調。
在端到端問題生成中,該模型可以生成問題而無需提供答案。本文更詳細地討論了這些想法。在這裡,T5模型經過培訓,可以通過提供上下文來同時產生多個問題。這些問題被<sep>令牌分開。這是處理示例的方式
輸入文本: Python is a programming language. Created by Guido van Rossum and first released in 1991.
目標文本: Who created Python ? <sep> When was python released ? <sep>
所有培訓細節都可以在此WandB項目中找到
使用上述方法在Squad1.0 Dev設置上的結果。為了解碼,使用num_beams 4的光束搜索,最大解碼長度設置為32。
對於多任務QA-QG模型,EM和F1分數被私有為QA-EM和QA-F1。
NLG-Eval軟件包用於計算指標。
| 姓名 | bleu-4 | 流星 | 胭脂-l | Qa-em | QA-F1 | QG形式 |
|---|---|---|---|---|---|---|
| T5-base-QG-HL | 21.3226 | 27.0854 | 43.5962 | - | - | 強調 |
| T5-base-QA-QG-HL | 21.0141 | 26.9113 | 43.2484 | 82.46 | 90.272 | 強調 |
| T5-SMALL-QA-QG-HL | 18.9872 | 25.2217 | 40.7893 | 76.121 | 84.904 | 強調 |
| T5-SMALL-QG-HL | 18.5921 | 24.9915 | 40.1886 | - | - | 強調 |
| t5-small-qg prepend | 18.2791 | 24.6722 | 39.958 | - | - | 預登 |
transformers==3.0.0
nltk
nlp==0.2.0 # only if you want to fine-tune.
安裝nltk後
python -m nltk.downloader punkt使用模擬器管道?變形金剛管道簡單推斷。
管道分為3個任務
question-generation :用於單個任務問題生成模型。multitask-qa-qg :用於多任務QA,QG型號。e2e-qg :用於端到端問題生成。 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?' }]預端格式
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?'
]默認情況下,這兩個管道都將使用T5-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-S-MALL*模型通過model參數傳遞路徑。
默認情況下, question-generation管道將以highlight光格式下載valhalla/t5-small-qg-hl型號。如果要使用預端格式,請提供預端模型的路徑,並將qg_format設置為"prepend" 。為了像跨度一樣提取答案,它使用valhalla/t5-small-qa-qg-hl模型,您可以通過ans_model參數提供不同的模型。
multitask-qa-qg模型適用於可以提取跨度,do QG和QA的答案的多任務模型,因此它不需要單獨的ans_model 。默認情況下,Valhalla/T5-Small-QA-QG-HL模型用於highlight格式。如果要使用預端格式,請提供預端模型的路徑,並將qg_format設置為"prepend"
e2e-qg管道用於端到端問題生成。這些模型可以在沒有答案監督的情況下同時產生多個問題。默認情況下,它使用valhalla/t5-small-e2e-qg
為了支持不同的數據格式,培訓師期望預處理的緩存數據集,因此您可以按照所需的方式處理數據。緩存__getitem__數據集應使用torch.save保存,並應返回source_ids , target_ids , attention_mask鍵的dict 。
source_ids :編碼的源文本target_ids :編碼目標文本attention_mask :源掩碼source_ids T2TDataCollator負責準備正確的input_ids和labels 。它還動態修剪批次以去除過多的填充令牌,以加快訓練的速度。
data/squad_multitask包含修改後的小隊數據集,以進行答案問題生成(同時使用預處和突出顯示格式),問題答案(文本到文本),答案提取和端到端問題生成。可以使用Awesome加載此數據集? nlp庫,這使得處理非常容易。
要處理和緩存數據集使用prepare_data.py腳本。它將根據model_type參數加載正確的令牌。它將兩個新的令牌<sep>和<hl>添加到令牌中,並將其保存在{model_type}_qg_tokenizer路徑上。您應該將此令牌傳遞給微調腳本。
數據集將保存在data/目錄中。您應該使用train_file_name和valid_file_name參數提供文件名。
單個任務問題生成的處理數據,亮點_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 多任務QA-QG的過程數據使用righlight_qg_format
valid_for_qg_only參數用於確定驗證集是否應僅包含QG任務的數據。對於我的多任務實驗,我僅使用QG任務使用驗證數據,以便可以將評估損失曲線與其他單個任務模型進行比較
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 端到端問題生成的過程數據集
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 使用run_qg.py腳本開始培訓。它使用變形金剛Trainer課程訓練模型。
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 100或者,如果您想從腳本或筆記本上訓練它,則
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 )使用eval.py腳本評估模型。
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.txt這將使輸出將輸出保存在{output_path}文件中。
計算指標安裝NLG-eval軟件包並運行
nlg-eval --hypothesis=hypothesis_t5-base-qg-hl.txt --references=data/references.txt --no-skipthoughts --no-glove