Transformers 模型示例

在本節中,將結合一些示例。所有這些示例都適用於多種模型,並利用 了不同模型之間非常相似的API。

重要 :要運行示例的最新版本,你必須從源代碼安裝併為示例安裝一些特定要求。在新的虛擬環境中執行以下步驟:

<code>git clone https://github.com/huggingface/transformers
cd transformers
pip install .
pip install -r ./examples/requirements.txt/<code>

Section Description TensorFlow 2.0 GLUE模型 在GLUE任務上運行BERT TensorFlow 2.0模型的示例。 語言模型訓練 對文本數據集上的庫模型進行微調(或從頭開始訓練)。GPT/GPT-2的因果語言建模,BERT/RoBERTa的掩碼語言建模。 語言生成 使用庫的自迴歸模型生成條件文本:GPT、GPT-2、Transformer XL和XLNet。 GLUE 在9個GLUE任務上運行BERT/XLM/XLNet/RoBERTa的示例。示例使用分佈式訓練和半精確性。 SQuAD 使用BERT/RoBERTa/XLNet/XLM回答問題,示例使用分佈式訓練。 多項選擇 在SWAG/RACE/ARC任務上運行BERT/XLNet/RoBERTa的示例。 命名實體識別 在CoNLL 2003數據集上使用BERT進行命名實體識別(NER),示例使用分佈式訓練。 XNLI 在XNLI基準上運行BERT/XLM的示例。 模型性能的對抗性評估 在NLI系統(HANS)的數據集(McCoy等人,2019年)的啟發式分析上測試自然語言推理的對抗性評估模型

GLUE上的TensorFlow 2.0 Bert模型

基於腳本run_tf_glue.py的GLUE上的TensorFlow 2.0 Bert模型。

微調TensorFlow 2.0 Bert模型以對GLUE基準的MRPC任務進行序列分類。

該腳本具有用於在Tensor Core(NVIDIA Volta/Turing GPU)和將來的硬件上運行模型的混合精度(Automatic Mixed Precision / AMP)選項,以及XLA的選項,該選項使用XLA編譯器來減少模型運行時間。在腳本中使用"USE_XLA"或"USE_AMP"變量來切換選項。這些選項和以下基準由@tlkh提供。

腳本快速測試結果(無其他修改):

GPU 模式 時間(第二個epoch) 準確度(3次) Titan V FP32 41s 0.8438 / 0.8281 / 0.8333 Titan V AMP 26s 0.8281 / 0.8568 / 0.8411 V100 FP32 35s 0.8646 / 0.8359 / 0.8464 V100 AMP 22s 0.8646 / 0.8385 / 0.8411 1080 Ti FP32 55s -

對於相同的硬件和超參數(使用相同的批次大小),混合精度(AMP)大大減少了訓練時間。

語言模型訓練

基於腳本run_language_modeling.py。

在GPT,GPT-2,BERT和RoBERTa(即將 添加DistilBERT )的文本數據集上微調(或從頭訓練)用於語言建模的庫模型。GPT和GPT-2使用因果語言建模(CLM)損失 進行微調,而BERT和RoBERTa 使用掩碼語言建模(MLM)損失進行微調。

在運行下面的示例之前,你應該獲取一個包含文本的文件,在該文件上將 訓練或微調語言模型。此類文本的一個很好的例子是WikiText-2數據集(https://blog.einstein.ai/the-wikitext-long-term-dependency-language-modeling-dataset/)。

我們將參考兩個不同的文件:$ TRAIN_FILE,其中包含用於訓練的文本,以及$ TEST_FILE,其中包含將用於評估的文本。

GPT-2/GPT和因果語言建模

以下示例對WikiText-2上的GPT-2進行了微調。我們正在使用原始的WikiText-2(在標記化之前沒有替換任何標記)。這裡的損失是因果語言建模的損失。

<code>export TRAIN_FILE=/path/to/dataset/wiki.train.raw
export TEST_FILE=/path/to/dataset/wiki.test.raw

python run_language_modeling.py \\
--output_dir=output \\
--model_type=gpt2 \\
--model_name_or_path=gpt2 \\
--do_train \\
--train_data_file=$TRAIN_FILE \\
--do_eval \\
--eval_data_file=$TEST_FILE/<code>

單個K80 GPU訓練大約需要一個半小時,然後大約一分鐘的時間評估運行。它微調的結果在數據集上困惑度大約20。

RoBERTa / BERT和掩碼語言建模

以下示例對WikiText-2上的RoBERTa進行了微調。在這裡,我們也使用原始的WikiText-2。這裡損失不一樣,因為BERT/RoBERTa具有雙向機制。我們所使用的損失與訓練前的損失相同,都為掩碼語言建模。

根據RoBERTa的論文,我們使用動態掩碼而不是靜態掩碼。因此,模型收斂的 速度可能會稍微慢一些(過擬合會花費更多的時間)。

我們使用--mlm標誌,以便腳本可以更改其損失功能。

<code>export TRAIN_FILE=/path/to/dataset/wiki.train.raw
export TEST_FILE=/path/to/dataset/wiki.test.raw

python run_language_modeling.py \\
--output_dir=output \\
--model_type=roberta \\
--model_name_or_path=roberta-base \\
--do_train \\
--train_data_file=$TRAIN_FILE \\

--do_eval \\
--eval_data_file=$TEST_FILE \\
--mlm/<code>

語言生成

基於該腳本run_generation.py。

使用庫的自動迴歸模型生成條件文本:GPT,GPT-2,Transformer-XL,XLNet,CTRL。我們的官方演示(https://transformer.huggingface.co)使用了類似的腳本,你可以在其中試用庫中提供的各種模型。

用法示例:

<code>python run_generation.py \\ 
--model_type = gpt2 \\
--model_name_or_path = gpt2/<code>

GLUE

基於該腳本run_glue.py。

在GLUE基準上微調用於序列分類的庫模型。該腳本可以微調以下模型:BERT,XLM,XLNet和RoBERTa。

GLUE由9個不同的任務組成。我們在不帶大小寫的BERT基本模型("bert-base-uncased")的基準開發集上獲得以下結果。所有實驗都運行單個V100 GPU,總訓練批次大小在16至64之間。其中一些任務的數據集較小,訓練可能導致結果差異很大。在不同的運行之間。我們針對每個指標報告取5次運行(隨機數種子不同)的中位數。

任務 度量 結果 CoLA Matthew's 相關係數 49.23 SST-2 準確度 91.97 MRPC F1/準確度 89.47/85.29 STS-B Person/Spearman 相關係數 83.95/83.70 QQP 準確度/F1 88.40/84.31 MNLI 匹配準確度/不匹配準確度 80.61/81.08 QNLI 準確度 87.46 RTE 準確度 61.73 WNLI 準確度 45.07

其中一些結果與網站上GLUE基準測試集上報告的結果有顯著差異。有關QQP和WNLI,請參閱網站上的FAQ12(https://gluebenchmark.com/faq)。

在運行這些GLUE任務中的任何一項之前,你應該通過運行此腳本(https://gist.github.com/W4ngatang/60c2bdb54d156a41194446737ce03e2e)下載GLUE數據(https://gluebenchmark.com/tasks) 並解壓縮將其保存到$ GLUE_DIR目錄中。

<code>export GLUE_DIR=/path/to/glue
export TASK_NAME=MRPC

python run_glue.py \\
--model_type bert \\
--model_name_or_path bert-base-cased \\
--task_name $TASK_NAME \\
--do_train \\
--do_eval \\
--do_lower_case \\
--data_dir $GLUE_DIR/$TASK_NAME \\
--max_seq_length 128 \\
--per_gpu_train_batch_size 32 \\
--learning_rate 2e-5 \\
--num_train_epochs 3.0 \\
--output_dir /tmp/$TASK_NAME//<code>

其中任務名稱可以是CoLA,SST-2,MRPC,STS-B,QQP,MNLI,QNLI,RTE,WNLI之一。

開發集結果將顯示在指定output_dir中的文本文件eval_results.txt中。 對於MNLI,由於有兩個單獨的開發集(匹配和不匹配),所以除了/tmp/MNLI/之外,還有一個單獨的輸出文件夾,稱為/tmp/MNLI-MM/。

除MRPC、MNLI、CoLA、SST-2外,apex在任何GLUE任務中都沒有進行過半精確訓練。以下部分提供瞭如何使用MRPC運行半精確訓練的詳細信息。儘管如此,使用剩餘的GLUE任務運行半精度訓練也不應該有任何問題,因為每個任務的數據處理器都繼承自基類數據處理器。

MRPC

微調示例

以下示例對Microsoft Research Paraphrase Corpus(MRPC)語料庫上的BERT進行微調,並且在單個K-80上運行不到10分鐘,在單個tesla V100 16GB上,僅用27秒鐘安裝了apex。

在運行這些GLUE任務中的任何一項之前,你應該下載運行此腳本(https://gist.github.com/W4ngatang/60c2bdb54d156a41194446737ce03e2e) 來下載GLUE數據(https://gluebenchmark.com/tasks),並將其解壓縮到某個目錄`$ GLUE_DIR`中。

<code>export GLUE_DIR=/path/to/glue

python run_glue.py \\
--model_type bert \\
--model_name_or_path bert-base-cased \\
--task_name MRPC \\
--do_train \\
--do_eval \\
--do_lower_case \\
--data_dir $GLUE_DIR/MRPC/ \\
--max_seq_length 128 \\
--per_gpu_train_batch_size 32 \\
--learning_rate 2e-5 \\
--num_train_epochs 3.0 \\
--output_dir /tmp/mrpc_output/ /<code>

我們的測試基於原始實現的超參數(https://github.com/google-research/bert#sentence-and-sentence-pair-classification-tasks)得出的評估,結果介於84%和88%。

使用Apex和混合精度

使用Apex和16位精度,在MRPC上的微調僅需27秒。首先安裝apex(https://github.com/NVIDIA/apex),然後運行以下示例:

<code>export GLUE_DIR=/path/to/glue

python run_glue.py \\
--model_type bert \\

--model_name_or_path bert-base-cased \\
--task_name MRPC \\
--do_train \\
--do_eval \\
--do_lower_case \\
--data_dir $GLUE_DIR/MRPC/ \\
--max_seq_length 128 \\
--per_gpu_train_batch_size 32 \\
--learning_rate 2e-5 \\
--num_train_epochs 3.0 \\
--output_dir /tmp/mrpc_output/ \\
--fp16/<code>

分佈式訓練

下面是一個在8個V100 GPU上使用分佈式訓練的例子。使用的模型是BERT whole-word-masking模式,在MRPC上達到F1> 92。

<code>export GLUE_DIR=/path/to/glue

python -m torch.distributed.launch \\
--nproc_per_node 8 run_glue.py \\
--model_type bert \\
--model_name_or_path bert-base-cased \\
--task_name MRPC \\
--do_train \\
--do_eval \\
--do_lower_case \\
--data_dir $GLUE_DIR/MRPC/ \\
--max_seq_length 128 \\
--per_gpu_train_batch_size 8 \\
--learning_rate 2e-5 \\
--num_train_epochs 3.0 \\
--output_dir /tmp/mrpc_output//<code>

這些超參數訓練給了我們結果如下

<code>acc = 0.8823529411764706
acc_and_f1 = 0.901702786377709
eval_loss = 0.3418912578906332
f1 = 0.9210526315789473
global_step = 174
loss = 0.07231863956341798/<code>

MNLI

下面的示例使用了BERT-large, uncased, whole-word-masking模型並在MNLI任務上對其進行微調。

<code>export GLUE_DIR=/path/to/glue

python -m torch.distributed.launch \\
--nproc_per_node 8 run_glue.py \\
--model_type bert \\
--model_name_or_path bert-base-cased \\
--task_name mnli \\
--do_train \\
--do_eval \\
--do_lower_case \\
--data_dir $GLUE_DIR/MNLI/ \\
--max_seq_length 128 \\
--per_gpu_train_batch_size 8 \\
--learning_rate 2e-5 \\
--num_train_epochs 3.0 \\
--output_dir output_dir \\/<code>

結果如下:

<code>***** Eval results *****
acc = 0.8679706601466992
eval_loss = 0.4911287787382479
global_step = 18408
loss = 0.04755385363816904

***** Eval results *****
acc = 0.8747965825874695
eval_loss = 0.45516540421714036
global_step = 18408
loss = 0.04755385363816904/<code>

多項選擇題

基於該腳本run_multiple_choice.py。

在SWAG上進行微調

下載swag(https://github.com/rowanz/swagaf/tree/master/data)數據

<code>#在4個tesla V100(16GB)GPU上進行訓練
export SWAG_DIR=/path/to/swag_data_dir
python ./examples/run_multiple_choice.py \\
--model_type roberta \\

--task_name swag \\
--model_name_or_path roberta-base \\
--do_train \\
--do_eval \\
--do_lower_case \\
--data_dir $SWAG_DIR \\
--learning_rate 5e-5 \\
--num_train_epochs 3 \\
--max_seq_length 80 \\
--output_dir models_bert/swag_base \\
--per_gpu_eval_batch_size=16 \\
--per_gpu_train_batch_size=16 \\
--gradient_accumulation_steps 2 \\
--overwrite_output/<code>

與所定義的超參數訓練產生了以下結果

<code>***** Eval results *****
eval_acc = 0.8338998300509847
eval_loss = 0.44457291918821606/<code>

SQuAD

基於該腳本run_squad.py。

在SQuAD1.0上對BERT進行微調

此示例代碼在SQuAD1.0數據集上微調BERT。在單個tesla V100 16GB上,它可以在24分鐘(基於BERT-base上)或68分鐘(對於BERT-large上)上運行。可以通過以下鏈接下載SQuAD的數據,並將其保存在$ SQUAD_DIR目錄中。

  • train-v1.1.json(https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json)
  • dev-v1.1.json(https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json)
  • evaluate-v1.1.py(https://github.com/allenai/bi-att-flow/blob/master/squad/evaluate-v1.1.py)

對於SQuAD2.0,你需要下載:

  • train-v2.0.json(https://rajpurkar.github.io/SQuAD-explorer/dataset/train -v2.0.json)
  • dev-v2.0.json(https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json)
  • evaluate-v2.0.py(https://worksheets.codalab.org/rest/bundles/0x6b567e1cf2e041ec80d7098f031c5c9e/contents/blob/)
<code>export SQUAD_DIR=/path/to/SQUAD

python run_squad.py \\
--model_type bert \\
--model_name_or_path bert-base-cased \\
--do_train \\
--do_eval \\
--do_lower_case \\
--train_file $SQUAD_DIR/train-v1.1.json \\
--predict_file $SQUAD_DIR/dev-v1.1.json \\
--per_gpu_train_batch_size 12 \\
--learning_rate 3e-5 \\
--num_train_epochs 2.0 \\
--max_seq_length 384 \\
--doc_stride 128 \\
--output_dir /tmp/debug_squad/ /<code>

與先前定義的超參數訓練產生以下結果

<code>F1 = 88.52 
EXACT_MATCH = 81.22 /<code>

分佈式訓練

下面是使用8個V100 GPU分佈式訓練的示例和BERT Whole Word Masking uncased 模型在SQuAD1.1達到F1>93

<code>python -m torch.distributed.launch --nproc_per_node=8 ./examples/run_squad.py \\
--model_type bert \\
--model_name_or_path bert-large-uncased-whole-word-masking \\
--do_train \\
--do_eval \\
--do_lower_case \\
--train_file $SQUAD_DIR/train-v1.1.json \\
--predict_file $SQUAD_DIR/dev-v1.1.json \\
--learning_rate 3e-5 \\
--num_train_epochs 2 \\
--max_seq_length 384 \\
--doc_stride 128 \\
--output_dir ./examples/models/wwm_uncased_finetuned_squad/ \\

--per_gpu_eval_batch_size=3 \\
--per_gpu_train_batch_size=3 \\/<code>

使用先前定義的超參數進行訓練得到以下結果

<code>F1 = 93.15 
EXACT_MATCH = 86.91 /<code>

此模型也在模型庫中,按以下字符串可引用 bert-large-uncased-whole-word-masking-finetuned-squad。

在SQuAD上微調XLNet

此示例代碼在SQuAD1.0和SQuAD2.0數據集上微調XLNet。參見上文,下載SQuAD的數據。

SQuAD1.0的命令:

<code>export SQUAD_DIR=/path/to/SQUAD

python run_squad.py \\
--model_type xlnet \\
--model_name_or_path xlnet-large-cased \\
--do_train \\
--do_eval \\
--do_lower_case \\
--train_file $SQUAD_DIR/train-v1.1.json \\
--predict_file $SQUAD_DIR/dev-v1.1.json \\
--learning_rate 3e-5 \\
--num_train_epochs 2 \\
--max_seq_length 384 \\
--doc_stride 128 \\
--output_dir ./wwm_cased_finetuned_squad/ \\
--per_gpu_eval_batch_size=4 \\
--per_gpu_train_batch_size=4 \\
--save_steps 5000/<code>

SQuAD2.0的命令:

<code>export SQUAD_DIR=/path/to/SQUAD

python run_squad.py \\
--model_type xlnet \\
--model_name_or_path xlnet-large-cased \\
--do_train \\

--do_eval \\
--version_2_with_negative \\
--train_file $SQUAD_DIR/train-v2.0.json \\
--predict_file $SQUAD_DIR/dev-v2.0.json \\
--learning_rate 3e-5 \\
--num_train_epochs 4 \\
--max_seq_length 384 \\
--doc_stride 128 \\
--output_dir ./wwm_cased_finetuned_squad/ \\
--per_gpu_eval_batch_size=2 \\
--per_gpu_train_batch_size=2 \\
--save_steps 5000/<code>

較大的批處理大小可以提高性能,同時消耗更多的內存。

具有先前定義的超參數的SQuAD1.0的結果:

<code>{
"exact": 85.45884578997162,
"f1": 92.5974600601065,
"total": 10570,
"HasAns_exact": 85.45884578997162,
"HasAns_f1": 92.59746006010651,
"HasAns_total": 10570
}/<code>

具有先前定義的超參數的SQuAD2.0的結果:

<code>{
"exact": 80.4177545691906,
"f1": 84.07154997729623,
"total": 11873,
"HasAns_exact": 76.73751686909581,
"HasAns_f1": 84.05558584352873,
"HasAns_total": 5928,
"NoAns_exact": 84.0874684608915,
"NoAns_f1": 84.0874684608915,
"NoAns_total": 5945
}/<code>

XNLI

基於腳本run_xnli.py(https://github.com/huggingface/transformers/blob/master/examples/run_xnli.py)。

XNLI(https://www.nyu.edu/projects/bowman/xnli/)是基於MultiNLI(http://www.nyu.edu/projects/bowman/multinli/)的眾包數據集。它是跨語言文本表示形式的評估基準。成對的文本用15種不同語言(包括高資源語言(例如英語)和低資源語言(例如斯瓦希里語)進行文本註釋)。

XNLI上的微調

此示例代碼在XNLI數據集上微調了mBERT(多語言的BERT)。它在單個tesla V100 16GB上需要運行106分鐘。可以通過以下鏈接下載XNLI的數據,並且應將其同時保存(並解壓縮)在$ XNLI_DIR目錄中。

  • XNLI 1.0(https://www.nyu.edu/projects/bowman/xnli/XNLI-1.0.zip)
  • XNLI-MT 1.0(https://www.nyu.edu/projects/bowman/xnli/XNLI-MT-1.0.zip)
<code>export XNLI_DIR=/path/to/XNLI

python run_xnli.py \\
--model_type bert \\
--model_name_or_path bert-base-multilingual-cased \\
--language de \\
--train_language en \\
--do_train \\
--do_eval \\
--data_dir $XNLI_DIR \\
--per_gpu_train_batch_size 32 \\
--learning_rate 5e-5 \\
--num_train_epochs 2.0 \\
--max_seq_length 128 \\
--output_dir /tmp/debug_xnli/ \\
--save_steps -1/<code>

與先前定義的超參數訓練產生以下結果

<code>ACC = 0.7093812375249501 /<code>

MM-IMDB

基於腳本run_mmimdb.py(https://github.com/huggingface/transformers/blob/master/examples/mm-imdb/run_mmimdb.py)。

MM-IMDb(http://lisi1.unal.edu.co/mmimdb/)是一個多模式數據集,包含大約26,000部電影,包括圖像,劇情和其他元數據。

訓練MM-IMDB

<code>python run_mmimdb.py \\
--data_dir /path/to/mmimdb/dataset/ \\
--model_type bert \\
--model_name_or_path bert-base-uncased \\
--output_dir /path/to/save/dir/ \\
--do_train \\
--do_eval \\
--max_seq_len 512 \\
--gradient_accumulation_steps 20 \\
--num_image_embeds 3 \\
--num_train_epochs 100 \\
--patience 5/<code>

模型性能對抗性評估

這是一個使用自然語言推理的對抗性評估和NLI系統啟發式分析(HANS)數據集評估模型的示例。該示例由Nafise Sadat Moosavi(https://github.com/ns-moosavi)提供。

可以從此位置(https://github.com/tommccoy1/hans)下載HANS數據集。

這是使用test_hans.py的示例:

<code>export HANS_DIR=path-to-hans
export MODEL_TYPE=type-of-the-model-e.g.-bert-roberta-xlnet-etc
export MODEL_PATH=path-to-the-model-directory-that-is-trained-on-NLI-e.g.-by-using-run_glue.py

python examples/hans/test_hans.py \\
--task_name hans \\
--model_type $MODEL_TYPE \\
--do_eval \\
--do_lower_case \\
--data_dir $HANS_DIR \\
--model_name_or_path $MODEL_PATH \\
--max_seq_length 128 \\

--output_dir $MODEL_PATH \\/<code>

這將在MODEL_PATH中創建hans_predictions.txt文件,然後可以使用HANS數據集中的hans/evaluate_heur_output.py對其進行評估。

使用batch大小8和HANS數據集上的隨機種子42在MNLI上訓練的基於BERT的模型的結果如下:

<code>Heuristic entailed results:
lexical_overlap: 0.9702
subsequence: 0.9942
constituent: 0.9962

Heuristic non-entailed results:
lexical_overlap: 0.199
subsequence: 0.0396
constituent: 0.118/<code>


分享到:


相關文章: