このリポジトリには、少数のショットのテキスト分類と自然言語の推論のためにClozeの質問を活用するためのコードが含まれており、重要なサイズだけではありません。小さな言語モデルも少ないショット学習者です。この論文では、入力例をClozeスタイルのフレーズとして再定式化する半監視されたトレーニング手順であるパターン抽出トレーニング(PET)が導入されています。リソースの低い設定では、PETとIPETは、99.9%のパラメーターが必要にもかかわらず、定期的な監視されたトレーニング、さまざまな半監視ベースライン、さらにはGPT-3を大幅に上回ります。 PET(IPET)の反復バリアントは、複数の世代のモデルをトレーニングし、トレーニングデータなしで使用することさえできます。
| #examples | トレーニングモード | Yelp(フル) | AGのニュース | Yahooの質問 | 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使用量
?自分のペットを訓練します
引用
PETのすべての要件は、 requirements.txtにあります。txt。必要なすべてのパッケージをpip install -r requirements.txtをインストールできます。txt。
このリポジトリのコマンドラインインターフェイスcli.pyは現在、3つの異なるトレーニングモード(PET、IPET、監視されたトレーニング)、2つの追加の評価方法(監視なしおよびプライミング)、13の異なるタスクをサポートしています。 Yelpのレビューについては、AGのニュース、Yahooの質問、MNLI、X-Stanceについては、詳細については元の論文を参照してください。 8つのスーパーグルータスクについては、この論文を参照してください。
サポートされているタスクの1つについて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使用するPVPSを指定します。たとえば、すべてのパターンを使用する場合は、AgのニュースとYahooの質問またはYelpレビューとMNLIにPATTERN_IDS 0 1 2 3 PATTERN_IDS 0 1 2 3 4を指定します。$DATA_DIR 、トレーニングファイルとテストファイルを含むディレクトリです( tasks.pyをチェックして、これらのファイルの名前とフォーマットを各タスクにどのようにフォーマットするかを確認してください)。$MODEL_TYPE 、 albert 、 bert 、 robertaなどのモデルの名前です。$MODEL_NAME 、事前に処理されたモデル(例、 roberta-largeまたはalbert-xxlarge-v2 )の名前または前処理されたモデルへのパスです。$TASK_NAMEトレーニングおよび評価するタスクの名前です。$OUTPUT_DIR 、訓練されたモデルと評価の結果が保存されるディレクトリの名前です。さらに、個々のPVP(プレフィックス--pet_ )に対応するPETモデルのアンサンブルと最終シーケンス分類モデル(プレフィックス--sc_ )の両方に、さまざまなトレーニングパラメーターを指定できます。たとえば、スーパーグルー評価に使用されるデフォルトのパラメーターは次のとおりです。
--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 )とともに、Finetunedモデルとともにwrapper_config.json :使用されているモデルの構成train_config.json :トレーニングに使用される構成eval_config.json :評価に使用される構成logits.txt :ラベルのないデータに関するモデルの予測eval_logits.txt :評価データに関するモデルの予測results.json :モデルの最終精度などの結果を含むJSONファイルpredictions.jsonl :スーパーグルー形式で設定された評価の予測ファイル各繰り返し$Iの最終(蒸留)モデルは、上記と同じファイルを含む$OUTPUT_DIR/final/p0-i$Iで見つけることができます。
トレーニング中にGPUがメモリがなくなった場合は、 pet_gradient_accumulation_stepsとsc_gradient_accumulation_stepsの両方を増やしながら、 pet_per_gpu_train_batch_sizeとsc_per_gpu_unlabeled_batch_sizeの両方を減少させてみてください。
サポートされているタスクの1つについてIPETモデルをトレーニングおよび評価するには、上記と同じコマンドを実行するだけですが、 --method pet --method ipetに置き換えます。変更できるさまざまな追加のIPETパラメーターがあります。それらはすべて--ipet_が付いています。
各世代の$G 、パターン$P 、および反復$Iについて、これにより、通常のPETのように構造化されたディレクトリ$OUTPUT_DIR/g$G/p$Pi$Iが作成されます。最終(蒸留)モデルは$OUTPUT_DIR/final/p0-i$Iに再び見つけることができます。
ゼロトレーニングの例でIPETを使用する場合、各ラベルの例の数を第1世代に選択する必要がある必要があり、削減戦略を--ipet_n_most_likely 100 --reduction meanするように変更する必要があります。
通常のシーケンス分類器を訓練および評価するには、上記と同じコマンドを実行するだけですが、 --method pet --method sequence_classifierに置き換えます。シーケンス分類器には、変更できるさまざまな追加パラメーターがあります。それらはすべて、 --sc_が付いています。
デフォルトのPETパターンと言語化器を使用して事前に処理された言語モデルを評価するには、微調整せずに、引数を削除して、 --do_train削除して--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を使用するには、2つのことを定義する必要があります。
examples/custom_task_processor.pyを参照してください。例については。examples/custom_task_pvp.py例を参照してください。DataProcessorとPVPを実装した後、上記のようにコマンドラインを使用してPETモデルをトレーニングできます。以下に、PVP、言語化剤、パターンの2つのコンポーネントを定義する方法に関する追加情報をご覧ください。
言語化因子は、タスクラベルを自然言語の単語にマッピングするために使用されます。たとえば、バイナリセンチメント分類タスクでは、ポジティブラベル( +1 )をグッドgoodとbadラベル( -1 )にマッピングすることができます。言語化因子は、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" ]}パターンは、言語モデルに特定のタスクを理解させるために使用されます。彼らは、言葉バラライザーを使用して満たされる1つの<MASK>トークンを含む必要があります。レビューの要約( <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 ]シーケンスのペアを使用したくない場合は、2番目のシーケンスを空にしたままにすることができます。
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の現在の実装は、単一のトークンに対応するすべての例と言葉ババライザーで共有される固定ラベルのセットのみをサポートします。ただし、一部のタスクでは、複数のトークンに対応する言語化剤を使用する必要がある場合があります(ここで説明するように)。そのためには、次の2つの変更が必要です。
タスクの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()メソッドが、口頭化に必要なマスクトークンの最大数を常に挿入することを確認してください。たとえば、Verbalizerが+1に「本当に素晴らしい」、 -1から「ひどい」をマッピングし、それぞれ["really", "awe", "##some"] ["terrible"]トークン化されている場合、それぞれ3マスクトークンを含む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}
}