該存儲庫包含用於利用披肩問題的代碼,以進行幾種文本分類和自然語言推斷,而不僅僅是大小很重要:小語言模型也很少。這些論文介紹了模式開發培訓(PET),這是一種半監督的培訓程序,將輸入示例重新定義為固定的短語。在低資源環境中,儘管需要少99.9%的參數,但PET和IPET的表現明顯勝過定期監督培訓,各種半監督基線甚至GPT-3。 PET(IPET)的迭代變體訓練多代模型,甚至可以在沒有任何培訓數據的情況下使用。
| #examples | 訓練模式 | Yelp(完整) | AG的新聞 | 雅虎問題 | mnli |
|---|---|---|---|---|---|
| 0 | 無監督 | 33.8 | 69.5 | 44.0 | 39.1 |
| IPET | 56.7 | 87.5 | 70.7 | 53.6 | |
| 100 | 監督 | 53.0 | 86.0 | 62.9 | 47.9 |
| 寵物 | 61.9 | 88.3 | 69.2 | 74.7 | |
| IPET | 62.9 | 89.6 | 71.2 | 78.4 |
注意:要準確地重現上述結果,請確保使用v1.1.0( --branch v1.1.0 )。
?設定
CLI用法
API使用
?訓練自己的寵物
引用
寵物的所有要求都可以在requirements.txt中找到。您可以使用pip install -r requirements.txt安裝所有必需的軟件包。
該存儲庫中的命令行界面cli.py當前支持三種不同的培訓模式(PET,IPET,監督培訓),兩種其他評估方法(無監督和啟動)以及13個不同的任務。有關Yelp評論,AG的新聞,Yahoo問題,MNLI和X-Stance,請參閱原始論文以獲取更多詳細信息。有關8個超級工作任務,請參見本文。
要訓練和評估其中一項任務的PET模型,只需運行以下命令:
python3 cli.py
--method pet
--pattern_ids $PATTERN_IDS
--data_dir $DATA_DIR
--model_type $MODEL_TYPE
--model_name_or_path $MODEL_NAME_OR_PATH
--task_name $TASK
--output_dir $OUTPUT_DIR
--do_train
--do_eval
在哪裡
$PATTERN_IDS指定要使用的PVP。例如,如果您想使用所有模式,請指定PATTERN_IDS 0 1 2 3 4以獲取AG的新聞和Yahoo問題或PATTERN_IDS 0 1 2 3用於Yelp評論和MNLI。$DATA_DIR是包含火車和測試文件的目錄(檢查tasks.py 。$MODEL_TYPE是所使用的模型的名稱,例如albert , bert或roberta 。$MODEL_NAME是驗證模型的名稱(例如, roberta-large或albert-xxlarge-v2 )或預算模型的路徑。$TASK_NAME是要訓練和評估的任務的名稱。$OUTPUT_DIR是訓練有素的模型和評估結果的目錄名稱。您還可以為對應於單個PVP(前綴--pet_ )的PET模型的集合和最終序列分類模型(前綴--sc_ )指定各種訓練參數。例如,用於我們的SuperGlue評估的默認參數是:
--pet_per_gpu_eval_batch_size 8
--pet_per_gpu_train_batch_size 2
--pet_gradient_accumulation_steps 8
--pet_max_steps 250
--pet_max_seq_length 256
--pet_repetitions 3
--sc_per_gpu_train_batch_size 2
--sc_per_gpu_unlabeled_batch_size 2
--sc_gradient_accumulation_steps 8
--sc_max_steps 5000
--sc_max_seq_length 256
--sc_repetitions 1
對於每個模式$P和重複$I ,運行以上命令創建一個目錄$OUTPUT_DIR/p$Pi$I ,其中包含以下文件:
pytorch_model.bin :填充模型,可能與某些模型特定文件一起(例如, spiece.model , special_tokens_map.json )wrapper_config.json :使用的模型的配置train_config.json :用於培訓的配置eval_config.json :用於評估的配置logits.txt :模型對未標記數據的預測eval_logits.txt :模型對評估數據的預測results.json :json:一個包含結果的JSON文件,例如模型的最終精度predictions.jsonl :以超級插曲格式設置的評估預測文件每個重複$I的最終(蒸餾)模型可以在$OUTPUT_DIR/final/p0-i$I中找到,其中包含與上述相同的文件。
如果您的GPU在訓練過程中用完了內存,則可以嘗試減少pet_per_gpu_train_batch_size和sc_per_gpu_unlabeled_batch_size ,同時增加pet_gradient_accumulation_steps和sc_gradient_accumulation_steps 。
要訓練和評估一個受支持的任務之一的IPET模型,只需運行與上述相同的命令,而是用--method ipet替換--method pet 。您可以修改各種其他IPET參數;所有這些都帶有--ipet_ 。
對於每一代$G ,模式$P和迭代$I ,這將創建一個目錄$OUTPUT_DIR/g$G/p$Pi$I該目錄與常規寵物結構結構。最終(蒸餾)模型可以再次在$OUTPUT_DIR/final/p0-i$I中找到。
如果您使用零培訓示例的IPET,則需要在第一代中選擇每個標籤的示例數量,並且需要將--ipet_n_most_likely 100 --reduction mean 。
要以有監督的方式訓練和評估常規序列分類器,只需運行與上述相同的命令,但用--method sequence_classifier替換--method pet 。序列分類器有各種其他參數,您可以修改。所有這些都帶有--sc_ 。
為了評估使用默認的PET模式和語言器的驗證語言模型,但是如果不進行微調,請刪除參數--do_train and add --no_distillation ,以免執行最終的蒸餾。
如果要使用啟動,請刪除參數--do_train並添加參數--priming --no_distillation ,以便將所有訓練示例用於啟動,並且不執行最終的蒸餾。
請記住,您可能需要將最大序列長度增加到更大的值,例如--pet_max_seq_length 5000 。這僅適用於支持如此長序列的語言模型,例如xlnet。對於使用XLNET,您可以指定--model_type xlnet --model_name_or_path xlnet-large-cased --wrapper_type plm 。
您還可以直接使用命令行接口,而是可以直接使用PET API,其中大多數是在pet.modeling中定義的。通過包括import pet ,您可以訪問諸如train_pet , train_ipet和train_classifier之類的方法。查看他們的文檔以獲取更多信息。
要使用PET進行自定義任務,您需要定義兩件事:
examples/custom_task_processor.py 。examples/custom_task_pvp.py 。實現了數據po儀和PVP後,您可以使用上述命令行訓練PET模型。在下面,您可以找到有關如何定義PVP的兩個組成部分,語言和模式的其他信息。
語言器用於將任務標籤映射到自然語言的單詞。例如,在二進制情感分類任務中,您可以將正面標籤( +1 )映射到good一詞,而負標籤( -1 )則將其映射到bad一詞。通過PVP的verbalize()方法來實現語言器。定義語言器的最簡單方法是使用詞典:
VERBALIZER = { "+1" : [ "good" ], "-1" : [ "bad" ]}
def verbalize ( self , label ) -> List [ str ]:
return self . VERBALIZER [ label ] 重要的是,在PET的當前版本中,默認情況下,語言器僅限於基礎LMS詞彙中的單個令牌(用於使用多個令牌,請參見下文)。給定語言模型的令牌,您可以通過驗證len(tokenizer.tokenize(word)) == 1輕鬆檢查一個單詞是否與單個令牌相對應。
您還可以為單個標籤定義多個語言。例如,如果您不確定哪些單詞最能代表二進制情感分類任務中的標籤,則可以按以下方式定義您的口語:
VERBALIZER = { "+1" : [ "great" , "good" , "wonderful" , "perfect" ], "-1" : [ "bad" , "terrible" , "horrible" ]}模式用於使語言模型理解給定的任務;它們必須完全包含一個<MASK>令牌,該令牌必須使用Verbalizer填充。對於基於評論的摘要( <A> )和身體( <B> )的二進制情感分類,可以是<A>. <B>. Overall, it was <MASK>.模式通過PVP的get_parts()方法實現,該方法返回一對文本序列(每個序列都由字符串列表表示):
def get_parts ( self , example : InputExample ):
return [ example . text_a , '.' , example . text_b , '.' ], [ 'Overall, it was ' , self . mask ]如果您不想使用一對序列,則可以簡單地將第二個序列留空:
def get_parts ( self , example : InputExample ):
return [ example . text_a , '.' , example . text_b , '. Overall, it was ' , self . mask ], []如果要定義幾種模式,只需使用PVP S pattern_id屬性:
def get_parts ( self , example : InputExample ):
if self . pattern_id == 1 :
return [ example . text_a , '.' , example . text_b , '.' ], [ 'Overall, it was ' , self . mask ]
elif self . pattern_id == 2 :
return [ 'It was just ' , self . mask , '!' , example . text_a , '.' , example . text_b , '.' ], []使用命令行訓練模型時,請指定要使用的所有模式(例如--pattern_ids 1 2 )。
重要的是,如果序列長於基礎LM的指定最大序列長度,則PET必須知道輸入的哪些部分可以縮短,哪些部分不能(例如,蒙版令牌必須始終存在)。因此, PVP提供了一種shortenable()方法,以表明可以縮短一段文本:
def get_parts ( self , example : InputExample ):
text_a = self . shortenable ( example . text_a )
text_b = self . shortenable ( example . text_b )
return [ text_a , '.' , text_b , '. Overall, it was ' , self . mask ], []默認情況下,當前的PET和IPET實現僅支持一組固定的標籤,這些標籤在與單個令牌相對應的所有示例和語言器中共享。但是,對於某些任務,可能有必要使用與多個令牌相對應的語言器(如下所述)。為此,您只需要以下兩個修改:
在任務的dataprocessor中添加以下行(請參閱examples/custom_task_processor.py ):
from pet . tasks import TASK_HELPERS
from pet . task_helpers import MultiMaskTaskHelper
TASK_HELPERS [ 'my_task' ] = MultiMaskTaskHelper 'my_task'是您任務的名稱。
在您的PVP中,請確保get_parts()方法始終插入任何口頭化所需的掩碼令牌數量。例如,如果您的語言映射+1將“真的很棒”和-1 to“可怕”,如果將這些映射為["really", "awe", "##some"]和["terrible"] ,則您的get_parts()方法應該始終返回一個包含3個掩碼標記的序列。
通過此修改,您現在可以使用由多個令牌組成的語言器:
VERBALIZER = { "+1" : [ "really good" ], "-1" : [ "just bad" ]}但是,需要考慮幾個限制:
MultiMaskTaskHelper時,評估的最大批量大小為1。MultiMaskTaskHelper類是未經徹底測試的實驗功能。特別是,此功能僅對PET進行了測試,而不是針對IPET進行了測試。如果您觀察到奇怪的東西,請提出一個問題。為了獲得更大的靈活性,您還可以編寫自定義TaskHelper 。作為起點,您可以在pet/task_helpers.py中查看CopaTaskHelper , WscTaskHelper和RecordTaskHelper類。
如果您在此存儲庫中使用代碼,請引用以下論文:
@article{schick2020exploiting,
title={Exploiting Cloze Questions for Few-Shot Text Classification and Natural Language Inference},
author={Timo Schick and Hinrich Schütze},
journal={Computing Research Repository},
volume={arXiv:2001.07676},
url={http://arxiv.org/abs/2001.07676},
year={2020}
}
@article{schick2020small,
title={It's Not Just Size That Matters: Small Language Models Are Also Few-Shot Learners},
author={Timo Schick and Hinrich Schütze},
journal={Computing Research Repository},
volume={arXiv:2009.07118},
url={http://arxiv.org/abs/2009.07118},
year={2020}
}