transformers 示例教程

作者|huggingface
编译|VK
来源|Github

在本节中,将结合一些示例。所有这些示例都适用于多种模型,并利用
了不同模型之间非常相似的API。

重要 :要运行示例的最新版本,你必须从源代码安装并为示例安装一些特定要求。在新的虚拟环境中执行以下步骤:

git clone https://github.com/huggingface/transformers
cd transformers
pip install .
pip install -r ./examples/requirements.txt
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(在标记化之前没有替换任何标记)。这里的损失是因果语言建模的损失。

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

单个K80 GPU训练大约需要一个半小时,然后大约一分钟的时间评估运行。它微调的结果在数据集上困惑度大约20。

RoBERTa / BERT和掩码语言建模

以下示例对WikiText-2上的RoBERTa进行了微调。在这里,我们也使用原始的WikiText-2。这里损失不一样,因为BERT/RoBERTa具有双向机制。我们所使用的损失与训练前的损失相同,都为掩码语言建模。

根据RoBERTa的论文,我们使用动态掩码而不是静态掩码。因此,模型收敛的
速度可能会稍微慢一些(过拟合会花费更多的时间)。

我们使用--mlm标志,以便脚本可以更改其损失功能。

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

语言生成

基于该脚本run_generation.py。

使用库的自动回归模型生成条件文本:GPT,GPT-2,Transformer-XL,XLNet,CTRL。我们的官方演示(https://transformer.huggingface.co)使用了类似的脚本,你可以在其中试用库中提供的各种模型。

用法示例:

python run_generation.py \ 
    --model_type = gpt2 \ 
    --model_name_or_path = gpt2

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目录中。

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/

其中任务名称可以是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中。

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/ 

我们的测试基于原始实现的超参数(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),然后运行以下示例:

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
分布式训练

下面是一个在8个V100 GPU上使用分布式训练的例子。使用的模型是BERT whole-word-masking模式,在MRPC上达到F1> 92。

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/

这些超参数训练给了我们结果如下

acc = 0.8823529411764706
acc_and_f1 = 0.901702786377709
eval_loss = 0.3418912578906332
f1 = 0.9210526315789473
global_step = 174
loss = 0.07231863956341798
MNLI

下面的示例使用了BERT-large, uncased, whole-word-masking模型并在MNLI任务上对其进行微调。

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 \

结果如下:

***** 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

多项选择题

基于该脚本run_multiple_choice.py

在SWAG上进行微调

下载swag(https://github.com/rowanz/swagaf/tree/master/data)数据

#在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

与所定义的超参数训练产生了以下结果

***** Eval results *****
eval_acc = 0.8338998300509847
eval_loss = 0.44457291918821606

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/)
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/ 

与先前定义的超参数训练产生以下结果

F1 = 88.52 
EXACT_MATCH = 81.22 
分布式训练

下面是使用8个V100 GPU分布式训练的示例和BERT Whole Word Masking uncased 模型在SQuAD1.1达到F1>93

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   \

使用先前定义的超参数进行训练得到以下结果

F1 = 93.15 
EXACT_MATCH = 86.91 

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

在SQuAD上微调XLNet

此示例代码在SQuAD1.0和SQuAD2.0数据集上微调XLNet。参见上文,下载SQuAD的数据。

SQuAD1.0的命令:
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
SQuAD2.0的命令:
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

较大的批处理大小可以提高性能,同时消耗更多的内存。

具有先前定义的超参数的SQuAD1.0的结果:
{
"exact": 85.45884578997162,
"f1": 92.5974600601065,
"total": 10570,
"HasAns_exact": 85.45884578997162,
"HasAns_f1": 92.59746006010651,
"HasAns_total": 10570
}
具有先前定义的超参数的SQuAD2.0的结果:
{
"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
}

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)
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

与先前定义的超参数训练产生以下结果

ACC = 0.7093812375249501 

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

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

模型性能对抗性评估

这是一个使用自然语言推理的对抗性评估和NLI系统启发式分析(HANS)数据集评估模型的示例。该示例由Nafise Sadat Moosavi(https://github.com/ns-moosavi)提供。

可以从此位置(https://github.com/tommccoy1/hans)下载HANS数据集。

这是使用test_hans.py的示例:

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 \

这将在MODEL_PATH中创建hans_predictions.txt文件,然后可以使用HANS数据集中的hans/evaluate_heur_output.py对其进行评估。

使用batch大小8和HANS数据集上的随机种子42在MNLI上训练的基于BERT的模型的结果如下:

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

原文链接:https://huggingface.co/transformers/examples.html

原创文章,作者:pytorch,如若转载,请注明出处:http://pytorchchina.com/2020/03/04/transformers-%e7%a4%ba%e4%be%8b%e6%95%99%e7%a8%8b/

QR code