跳转到主要内容

预训练NLP Transformer模型仓库:BERT & RoBERTa, GPT & GPT-2, Transformer-XL, XLNet和XLM

项目描述

👾 PyTorch-Transformers

CircleCI

PyTorch-Transformers(之前称为pytorch-pretrained-bert)是一个用于自然语言处理(NLP)的顶级预训练模型的库。

该库目前包含以下模型的PyTorch实现、预训练模型权重、使用脚本和转换工具

  1. BERT(来自Google),与Jacob Devlin、Ming-Wei Chang、Kenton Lee和Kristina Toutanova发表的论文BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding一同发布。
  2. GPT(来自OpenAI),与Alec Radford、Karthik Narasimhan、Tim Salimans和Ilya Sutskever发表的论文Improving Language Understanding by Generative Pre-Training一同发布。
  3. GPT-2(来自OpenAI),与Alec Radford*、Jeffrey Wu*、Rewon Child、David Luan、Dario Amodei**和Ilya Sutskever**发表的论文Language Models are Unsupervised Multitask Learners一同发布。
  4. Transformer-XL(来自谷歌/CMU)随论文《Transformer-XL:超越固定长度上下文的注意力语言模型》发布,作者:Zihang Dai*、Zhilin Yang*、Yiming Yang、Jaime Carbonell、Quoc V. Le、Ruslan Salakhutdinov。
  5. XLNet(来自谷歌/CMU)随论文《XLNet:用于语言理解的泛化自回归预训练》发布,作者:Zhilin Yang*、Zihang Dai*、Yiming Yang、Jaime Carbonell、Ruslan Salakhutdinov、Quoc V. Le。
  6. XLM(来自Facebook)与论文《跨语言语言模型预训练》同时发布,作者:Guillaume Lample 和 Alexis Conneau。
  7. RoBERTa(来自Facebook)与论文《鲁棒优化BERT预训练方法》同时发布,作者:Yinhan Liu、Myle Ott、Naman Goyal、Jingfei Du、Mandar Joshi、Danqi Chen、Omer Levy、Mike Lewis、Luke Zettlemoyer、Veselin Stoyanov。
  8. DistilBERT(来自HuggingFace)与博客文章《更小、更快、更便宜、更轻量:介绍DistilBERT,BERT的蒸馏版本》同时发布,作者:Victor Sanh、Lysandre Debut 和 Thomas Wolf。

这些实现已在多个数据集上进行了测试(请参阅示例脚本),应与原始实现的性能相匹配(例如,BERT Whole-Word-Masking 在 SQuAD 上的 F1 值约为 93,OpenAI GPT 在 RocStories 上的 F1 值约为 88,Transformer-XL 在 WikiText 103 上的困惑度约为 18.3,XLNet 在 STS-B 上的 Peason R 系数约为 0.916)。您可以在文档的示例部分中找到更多关于性能的详细信息。

章节 描述
安装 如何安装该软件包
快速浏览:用法 分词器与模型用法:Bert 和 GPT-2
快速浏览:微调/用法脚本 使用提供的脚本:GLUE、SQuAD 和文本生成
从 pytorch-pretrained-bert 迁移到 pytorch-transformers 将代码从 pytorch-pretrained-bert 迁移到 pytorch-transformers
文档 完整的API文档等

安装

此存储库已在 Python 2.7 和 3.5+ 上进行测试(示例仅在 python 3.5+ 上进行测试)以及 PyTorch 1.0.0+。

使用pip

PyTorch-Transformers 可以通过以下方式通过 pip 安装

pip install pytorch-transformers

从源代码

克隆存储库并运行

pip install [--editable] .

测试

库和示例脚本包含一系列测试。库测试可在tests 文件夹中找到,示例测试在examples 文件夹中。

您可以使用 pytest 运行这些测试(如果需要,请使用 pip install pytest 安装 pytest)。

您可以使用以下命令从克隆的存储库的根目录运行测试

python -m pytest -sv ./pytorch_transformers/tests/
python -m pytest -sv ./examples/

您想在移动设备上运行 Transformer 模型吗?

您应该查看我们的swift-coreml-transformers 存储库。

它包含了一个将 Pytorch 训练的 Transformer 模型(此处为 GPT-2)转换为在 iOS 设备上运行的 CoreML 模型的转换脚本的示例。

在未来的某个时刻,您将能够无缝地从 PyTorch 中的预训练或微调模型迁移到 CoreML 中的产品化,或者从 CoreML 中原型化模型或应用程序,然后在 PyTorch 中研究其超参数或架构。非常令人兴奋!

快速浏览

让我们对 PyTorch-Transformers 做一个非常快速的概述。每个模型架构(Bert、GPT、GPT-2、Transformer-XL、XLNet 和 XLM)的详细示例可以在完整文档中找到。

import torch
from pytorch_transformers import *

# PyTorch-Transformers has a unified API
# for 7 transformer architectures and 30 pretrained weights.
#          Model          | Tokenizer          | Pretrained weights shortcut
MODELS = [(BertModel,       BertTokenizer,      'bert-base-uncased'),
          (OpenAIGPTModel,  OpenAIGPTTokenizer, 'openai-gpt'),
          (GPT2Model,       GPT2Tokenizer,      'gpt2'),
          (TransfoXLModel,  TransfoXLTokenizer, 'transfo-xl-wt103'),
          (XLNetModel,      XLNetTokenizer,     'xlnet-base-cased'),
          (XLMModel,        XLMTokenizer,       'xlm-mlm-enfr-1024'),
          (RobertaModel,    RobertaTokenizer,   'roberta-base')]

# Let's encode some text in a sequence of hidden-states using each model:
for model_class, tokenizer_class, pretrained_weights in MODELS:
    # Load pretrained model/tokenizer
    tokenizer = tokenizer_class.from_pretrained(pretrained_weights)
    model = model_class.from_pretrained(pretrained_weights)

    # Encode text
    input_ids = torch.tensor([tokenizer.encode("Here is some text to encode", add_special_tokens=True)])  # Add special tokens takes care of adding [CLS], [SEP], <s>... tokens in the right way for each model.
    with torch.no_grad():
        last_hidden_states = model(input_ids)[0]  # Models outputs are now tuples

# Each architecture is provided with several class for fine-tuning on down-stream tasks, e.g.
BERT_MODEL_CLASSES = [BertModel, BertForPreTraining, BertForMaskedLM, BertForNextSentencePrediction,
                      BertForSequenceClassification, BertForMultipleChoice, BertForTokenClassification,
                      BertForQuestionAnswering]

# All the classes for an architecture can be initiated from pretrained weights for this architecture
# Note that additional weights added for fine-tuning are only initialized
# and need to be trained on the down-stream task
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
for model_class in BERT_MODEL_CLASSES:
    # Load pretrained model/tokenizer
    model = model_class.from_pretrained('bert-base-uncased')

# Models can return full list of hidden-states & attentions weights at each layer
model = model_class.from_pretrained(pretrained_weights,
                                    output_hidden_states=True,
                                    output_attentions=True)
input_ids = torch.tensor([tokenizer.encode("Let's see all hidden-states and attentions on this text")])
all_hidden_states, all_attentions = model(input_ids)[-2:]

# Models are compatible with Torchscript
model = model_class.from_pretrained(pretrained_weights, torchscript=True)
traced_model = torch.jit.trace(model, (input_ids,))

# Simple serialization for models and tokenizers
model.save_pretrained('./directory/to/save/')  # save
model = model_class.from_pretrained('./directory/to/save/')  # re-load
tokenizer.save_pretrained('./directory/to/save/')  # save
tokenizer = tokenizer_class.from_pretrained('./directory/to/save/')  # re-load

# SOTA examples for GLUE, SQUAD, text generation...

微调/用法脚本的快速浏览

该库包含多个示例脚本,这些脚本在NLU和NLG任务中具有SOTA性能。

  • run_glue.py:一个示例,展示了如何在九个不同的GLUE任务(序列级分类)上微调Bert、XLNet和XLM。
  • run_squad.py:一个示例,展示了如何在SQuAD 2.0问答数据集(标记级分类)上微调Bert、XLNet和XLM。
  • run_generation.py:一个示例,展示了如何使用GPT、GPT-2、Transformer-XL和XLNet进行条件语言生成。
  • 其他特定模型示例(请参阅文档)。

以下是这些脚本的三个快速使用示例。

run_glue.py:在GLUE任务上进行序列分类的微调

通用语言理解评估(GLUE)基准是一组九个用于评估和分析自然语言理解系统的句子或句子对语言理解任务。

在运行任何GLUE任务之前,您应该通过运行此脚本并解压缩到某个目录$GLUE_DIR来下载GLUE数据

您还应安装示例所需的其他包

pip install -r ./examples/requirements.txt
export GLUE_DIR=/path/to/glue
export TASK_NAME=MRPC

python ./examples/run_glue.py \
    --model_type bert \
    --model_name_or_path bert-base-uncased \
    --task_name $TASK_NAME \
    --do_train \
    --do_eval \
    --do_lower_case \
    --data_dir $GLUE_DIR/$TASK_NAME \
    --max_seq_length 128 \
    --per_gpu_eval_batch_size=8   \
    --per_gpu_train_batch_size=8   \
    --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之一。

开发集结果将显示在指定输出目录中的文本文件'eval_results.txt'中。对于MNLI,由于有两个单独的开发集,匹配和未匹配,除了'/tmp/MNLI/'外,还将有一个单独的输出文件夹'/tmp/MNLI-MM/'。

在STS-B回归任务上微调XLNet模型

此示例代码使用服务器上4个V100 GPU的并行训练在STS-B语料库上微调XLNet。并行训练是使用多个GPU的一种简单方法(但比分布式训练慢且灵活性差,见下文)。

export GLUE_DIR=/path/to/glue

python ./examples/run_glue.py \
    --model_type xlnet \
    --model_name_or_path xlnet-large-cased \
    --do_train  \
    --do_eval   \
    --task_name=sts-b     \
    --data_dir=${GLUE_DIR}/STS-B  \
    --output_dir=./proc_data/sts-b-110   \
    --max_seq_length=128   \
    --per_gpu_eval_batch_size=8   \
    --per_gpu_train_batch_size=8   \
    --gradient_accumulation_steps=1 \
    --max_steps=1200  \
    --model_name=xlnet-large-cased   \
    --overwrite_output_dir   \
    --overwrite_cache \
    --warmup_steps=120

在此机器上,我们因此批次大小为32,如果您有更小的机器,请增加gradient_accumulation_steps以达到相同的批次大小。这些超参数应在开发集上产生+0.917的皮尔逊相关系数。

在MRPC分类任务上微调Bert模型

此示例代码使用8个V100 GPU的分布式训练在Microsoft Research Paraphrase Corpus (MRPC)语料库上微调Bert Whole Word Masking模型,以实现F1 > 92。

python -m torch.distributed.launch --nproc_per_node 8 ./examples/run_glue.py   \
    --model_type bert \
    --model_name_or_path bert-large-uncased-whole-word-masking \
    --task_name MRPC \
    --do_train   \
    --do_eval   \
    --do_lower_case   \
    --data_dir $GLUE_DIR/MRPC/   \
    --max_seq_length 128   \
    --per_gpu_eval_batch_size=8   \
    --per_gpu_train_batch_size=8   \
    --learning_rate 2e-5   \
    --num_train_epochs 3.0  \
    --output_dir /tmp/mrpc_output/ \
    --overwrite_output_dir   \
    --overwrite_cache \

使用这些超参数训练的结果如下

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

run_squad.py:在SQuAD上进行问答的微调

此示例代码使用8个V100 GPU的分布式训练在SQuAD数据集上微调BERT,并使用Bert Whole Word Masking uncased模型,以在SQuAD上实现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 ../models/wwm_uncased_finetuned_squad/ \
    --per_gpu_eval_batch_size=3   \
    --per_gpu_train_batch_size=3   \

使用这些超参数训练的结果如下

python $SQUAD_DIR/evaluate-v1.1.py $SQUAD_DIR/dev-v1.1.json ../models/wwm_uncased_finetuned_squad/predictions.json
{"exact_match": 86.91579943235573, "f1": 93.1532499015869}

这是作为bert-large-uncased-whole-word-masking-finetuned-squad提供的模型。

run_generation.py:使用GPT、GPT-2、Transformer-XL和XLNet进行文本生成

还包括一个条件生成脚本,可以从提示中生成文本。生成脚本包括Aman Rusia提出的技巧,用于使用像Transformer-XL和XLNet这样的内存模型获得高质量的生成(包括预定义文本以使短输入更长)。

以下是使用OpenAI GPT-2模型的小版本运行脚本的示例

python ./examples/run_generation.py \
    --model_type=gpt2 \
    --length=20 \
    --model_name_or_path=gpt2 \

从 pytorch-pretrained-bert 迁移到 pytorch-transformers

以下是迁移从pytorch-pretrained-bertpytorch-transformers时需要注意的快速总结

模型始终输出tuples

pytorch-pretrained-bert迁移到pytorch-transformers时的主要重大更改是模型的前向方法始终输出一个包含各种元素的tuple,这些元素取决于模型和配置参数。

每个模型的tuple的确切内容详细说明在模型的docstrings和文档中。

在绝大多数情况下,您只需将输出中的第一个元素作为之前在 pytorch-pretrained-bert 中使用的输出即可。

以下是一个从 pytorch-pretrained-bertpytorch-transformers 的转换示例,用于 BertForSequenceClassification 分类模型

# Let's load our model
model = BertForSequenceClassification.from_pretrained('bert-base-uncased')

# If you used to have this line in pytorch-pretrained-bert:
loss = model(input_ids, labels=labels)

# Now just use this line in pytorch-transformers to extract the loss from the output tuple:
outputs = model(input_ids, labels=labels)
loss = outputs[0]

# In pytorch-transformers you can also have access to the logits:
loss, logits = outputs[:2]

# And even the attention weights if you configure the model to output them (and other outputs too, see the docstrings and documentation)
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', output_attentions=True)
outputs = model(input_ids, labels=labels)
loss, logits, attentions = outputs

序列化

from_pretrained() 方法中的重大变更

  1. 现在在实例化时,模型默认处于评估模式。要训练它们,别忘了将它们设置回训练模式(model.train()),以激活dropout模块。

  2. 之前提供给 from_pretrained() 方法的额外 *input**kwargs 参数曾直接传递给底层模型的类 __init__() 方法。现在它们用于更新模型配置属性,这可能会破坏基于先前 BertForSequenceClassification 示例构建的派生模型类。我们正在努力通过将模型 __init__() 方法(i)提供的位置参数和(ii)不匹配任何配置类属性的键控参数传递给 #866 来缓解这种破坏性变更。

此外,虽然这不是一个破坏性变更,但序列化方法已经标准化,如果您之前使用了任何其他序列化方法,那么您可能应该切换到新的方法 save_pretrained(save_directory)

以下是一个示例

### Let's load a model and tokenizer
model = BertForSequenceClassification.from_pretrained('bert-base-uncased')
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

### Do some stuff to our model and tokenizer
# Ex: add new tokens to the vocabulary and embeddings of our model
tokenizer.add_tokens(['[SPECIAL_TOKEN_1]', '[SPECIAL_TOKEN_2]'])
model.resize_token_embeddings(len(tokenizer))
# Train our model
train(model)

### Now let's save our model and tokenizer to a directory
model.save_pretrained('./my_saved_model_directory/')
tokenizer.save_pretrained('./my_saved_model_directory/')

### Reload the model and the tokenizer
model = BertForSequenceClassification.from_pretrained('./my_saved_model_directory/')
tokenizer = BertTokenizer.from_pretrained('./my_saved_model_directory/')

优化器:BertAdam 和 OpenAIAdam 现在是 AdamW,调度程序是标准的 PyTorch 调度程序

之前包含的两个优化器 BertAdamOpenAIAdam 已被单个 AdamW 优化器替换,它有一些差异

  • 它仅实现权重衰减校正,
  • 调度程序现在是外部的(见下文),
  • 梯度裁剪现在也是外部的(见下文)。

新的优化器 AdamW 与 PyTorch Adam 优化器 API 匹配,并允许您使用标准的 PyTorch 或 apex 方法进行调度和裁剪。

现在,调度程序是标准的 PyTorch 学习率调度程序,不再属于优化器的一部分。

以下是从具有线性预热和衰减计划的 BertAdam 转换到具有相同计划的 AdamW 的示例

# Parameters:
lr = 1e-3
max_grad_norm = 1.0
num_total_steps = 1000
num_warmup_steps = 100
warmup_proportion = float(num_warmup_steps) / float(num_total_steps)  # 0.1

### Previously BertAdam optimizer was instantiated like this:
optimizer = BertAdam(model.parameters(), lr=lr, schedule='warmup_linear', warmup=warmup_proportion, t_total=num_total_steps)
### and used like this:
for batch in train_data:
    loss = model(batch)
    loss.backward()
    optimizer.step()

### In PyTorch-Transformers, optimizer and schedules are splitted and instantiated like this:
optimizer = AdamW(model.parameters(), lr=lr, correct_bias=False)  # To reproduce BertAdam specific behavior set correct_bias=False
scheduler = WarmupLinearSchedule(optimizer, warmup_steps=num_warmup_steps, t_total=num_total_steps)  # PyTorch scheduler
### and used like this:
for batch in train_data:
    loss = model(batch)
    loss.backward()
    torch.nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm)  # Gradient clipping is not in AdamW anymore (so you can use amp without issue)
    optimizer.step()
    scheduler.step()
    optimizer.zero_grad()

引用

目前,PyTorch-Transformers 没有相关论文,但我们正在准备一份。在此期间,如果您在已发布的或开源项目中使用此工作,请包括对库的提及和链接到当前存储库。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪一个,请了解有关 安装包 的更多信息。

源分布

pytorch_transformers-1.2.0.tar.gz (152.3 kB 查看散列)

上传时间

构建分布

pytorch_transformers-1.2.0-py3-none-any.whl (176.4 kB 查看散列)

上传时间 Python 3

pytorch_transformers-1.2.0-py2-none-any.whl (176.4 kB 查看哈希值)

上传时间 Python 2

由...