写点什么

最强 NLP 预训练模型库 PyTorch-Transformers 正式开源:支持 6 个预训练框架,27 个预训练模型

2019 年 7 月 23 日

最强NLP预训练模型库PyTorch-Transformers正式开源:支持6个预训练框架,27个预训练模型

先上开源地址:


https://github.com/huggingface/pytorch-transformers#quick-tour


官网:


https://huggingface.co/pytorch-transformers/index.html


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(《BERT:用于语言理解的深度双向 Transformer 的预训练》)

  2. GPT (来自 OpenAI):作者 Alec Radford、Karthik Narasimhan、Tim Salimans 和 Ilya Sutskever:Improving Language Understanding by Generative Pre-Training (《通过生成式预训练提高语言理解能力》)

  3. GPT-2 (来自 OpenAI):作者

  4. Alec Radford、Jeffrey Wu、Rewon Child、David Luan、Dario Amodei 和 Ilya Sutskever: Language Models are Unsupervised Multitask Learners (《语言模型是无监督的多任务学习器》)

  5. Transformer-XL (来自 Google/CMU):作者 Zihang Dai、Zhilin Yang、Yiming Yang, Jaime Carbonell、Quoc V. Le、Ruslan Salakhutdinov:Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context (《Transformer-XL:超长上下文关系的注意力语言模型》)

  6. XLNet (来自 Google/CMU):作者 Zihang Dai、Zhilin Yang、Yiming Yang、Jaime Carbonell、Quoc V. Le、Ruslan Salakhutdinov:​XLNet: Generalized Autoregressive Pretraining for Language Understanding (《XLNet:用于语言理解的广义自回归预训练》)

  7. XLM (来自 Facebook):作者 Guillaume Lample 和 Alexis Conneau:Cross-lingual Language Model Pretraining (《跨语言的语言模型预训练》)


这些实现已在几个数据集上进行测试(参见示例脚本),应该与原始实现的性能相当(例如,BERT 全词覆盖(Whole-Word-Masking)在 SQUAD 数据集上的 F1 分数为 93,OpenAI GPT 在 RocStories 上的 F1 分数为 88,Transformer-XL 在 WikiText 103 上的 困惑度为 18.3、XLNet 的 STS-B 上的皮尔逊积矩相关系数为 0.916)。用户可以在官方网站的文档示例部分中,找到有关性能的更多详细信息。


安 装

此 repo 在 Python 2.7 和 3.5+(示例代码仅在 Python 3.5+ 上通过测试)以及 PyTorch 0.4.1 到 1.1.0 上进行了测试。


使用 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/
复制代码


快速指南

让我们快速导览一下 PyTorch-Transformer。每个模型架构(Bert、GPT、GPT-2、Transformer-XL、XLNet、XLM)的详细示例均可在完整的文档中找到。


import torchfrom pytorch_transformers import *
# PyTorch-Transformers has a unified API# for 6 transformer architectures and 27 pretrained weights.# Model | Tokenizer | Pretrained weights shortcutMODELS = [(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')]
# 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")]) 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 tasktokenizer = BertTokenizer.from_pretrained(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 layermodel = 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 Torchscriptmodel = model_class.from_pretrained(pretrained_weights, torchscript=True)traced_model = torch.jit.trace(model, (input_ids,))
# Simple serialization for models and tokenizersmodel.save_pretrained('./directory/to/save/') # savemodel = model_class.from_pretrained('./directory/to/save/') # re-loadtokenizer.save_pretrained('./directory/to/save/') # savetokenizer = tokenizer_class.from_pretrained(pretrained_weights)
# SOTA examples for GLUE, SQUAD, text generation...
复制代码


微调 / 用法脚本的快速指南

该库包含几个示例脚本,这些脚本具有用于 NLU 和 NLG 任务的 SOTA 性能:


  • run_glue.py :一个针对九个不同的 GLUE 任务(序列级分类)对 BERT、XLNet 和 XLM 进行微调的示例

  • run_squad.py :一个针对问答数据集 square 2.0(令牌级分类)对 BERT、XLNet 和 XLM 的示例

  • run_generation.py :一个使用 GPT、GPT-2、Transformer-XL 和 XLNet 生成条件语言的示例

  • 其他特定于模型的示例(请参阅文档)


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


run_glue.py :对 GLUE 任务进行微调用于序列分类

通用语言理解评估(General Language Understanding Evaluation benchmark,GLUE)基准是由九条句子或句子对语言理解任务的集合,用于评估和分析自然语言理解系统。


在运行这些 GLUE 任务之前,你应该通过运行此脚本下载 GLUE 数据,并将其解压缩到某个目录 $GLUE_DIR。


你还应该安装示例所需的附加包:


pip install -r ./examples/requirements.txt
复制代码


export GLUE_DIR=/path/to/glueexport 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 中的一个。


开发集的结果将出现在指定 output_dir 的文本文件“eval_results.txt”中。对于 MNLI,由于有两个单独的 dev 集,匹配的和不匹配的,除了“/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 以达到相同的批大小。这些超参数应该导致在开发集上的皮尔逊积矩相关系数(Pearson correlation coefficient )为 +0.917 。


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

此示例代码使用 8 块 V100 GPU 上的分布式训练,对 Microsoft Research 语句改写语料库(Microsoft Research Paraphrase Corpus,MRPC)中的 Bert 全词覆盖模型进行微调,使其达到 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 上的分布式训练和 BERT 全词覆盖模型对 SQuAD 数据集上的 BERT 进行微调,以在 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-bert 迁移到 pytorch-transformers 时应该注意的事项。


模型总是输出 tuples

从 pytorch-pretrained-bert 迁移到 pytorch-transformers 时,主要的突破性变化是模型的正演方法始终根据模型和配置参数输出包含各种元素的 tuple。


每个模型的元组的确切内容,在模型的文档注释和文档中有详细说明。


在几乎所有情况下,你都可以将输出的第一个元素作为之前在 pytorch-pretrained-bert 中使用的输出。


下面是一个 pytorch-pretrained-bert 到 pytorch-transformers 转换的示例,用于 BertForSequenceClassification 分类模型:


# Let's load our modelmodel = 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 weigths 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() 方法实例化时,模型现在默认设置为评估模式。要训练它们,不要忘记将它们设置回训练模式 ( model.train() ),以激活 dropout 模块。


此外,虽然不是突破性更改,但序列化方法已经标准化,如果你以前使用过任何其他序列化方法,你可能应该切换到新方法 save_pretrained(save_directory) 。


下面是一个例子:


### Let's load a model and tokenizermodel = 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 modeltokenizer.add_tokens(['[SPECIAL_TOKEN_1]', '[SPECIAL_TOKEN_2]'])model.resize_token_embeddings(len(tokenizer))# Train our modeltrain(model)
### Now let's save our model and tokenizer to a directorymodel.save_pretrained('./my_saved_model_directory/')tokenizer.save_pretrained('./my_saved_model_directory/')
### Reload the model and the tokenizermodel = BertForSequenceClassification.from_pretrained('./my_saved_model_directory/')tokenizer = BertTokenizer.from_pretrained('./my_saved_model_directory/')
复制代码


优化器:BertAdam 和 OpenAIAdam 现在是 AdamW,定时任务是标准的 PyTorch schedules。

之前包含的两个优化器 BertAdam 和 OpenAIAdam ,现在已被单个 AdamW 优化器取代。新的优化器 AdamW 与 PyTorch AdamW 优化器 API 相匹配。


任务调度现在是标准的 PyTorch learning rate schedulers 程序,而不再是优化器的一部分。


下面是 BertAdam 到 AdamW 的转换示例,前者具有线性预热(linear warmup)和衰减计划,后者有相同的任务调度。


# Parameters:lr = 1e-3num_total_steps = 1000num_warmup_steps = 100warmup_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=Falsescheduler = 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() scheduler.step() optimizer.step()
复制代码


引 文

目前尚无与 PyTorch-Transformers 相关的论文,但我们正在准备一篇。如果你在已发布或开源项目中使用了我们的项目,请提及对该库的说明以及附上当前存储库的链接。


2019 年 7 月 23 日 08:0513313
用户头像

发布了 342 篇内容, 共 108.6 次阅读, 收获喜欢 1153 次。

关注

评论

发布
暂无评论
发现更多内容

第三章总结

孤星

Navicat无法连接MySQL怎么办?

MySQL从删库到跑路

MySQL navicat 3306端口

应用实战——数据库设计时设计标识字段的一些思考【mysql】

老农小江

数据库设计 实战

把打胜仗的决心作为信仰

吴晨曦

创业

week07作业

追风

架构师一期

7.7 第七周课后练习

张荣召

设计模式

小黄鱼

极客大学架构师训练营

架构 2 期 - 第三周作业(1)

浮生一梦

极客大学架构师训练营 第三章作业 2组

[架构师训练营第 1 期] 第七周命题作业

猫切切切切切

极客大学架构师训练营

《一本小小的MyBatis源码分析书》.pdf

田维常

电子书

第三章学习笔记

博博

第三章课后作业

博博

架构师训练营第七周课程笔记及心得

Airs

架构师训练营第三周学习笔记

李日盛

设计模式

多团队如何评估故事点(译) ——来自Mike Cohn的建议

Bruce Talk

敏捷开发 Agile 估算与计划

架构一期第七周作业

Airs

第七周作业总结

Geek_ce484f

极客大学架构师训练营

[架构师训练营第 1 期] 第七周学习总结

猫切切切切切

极客大学架构师训练营

【第七周】课后作业

云龙

JVM真香系列:轻松理解class文件到虚拟机(上)

田维常

JVM

架构师训练营 - 第七周总结

一个节点

极客大学架构师训练营

Week3作业一

幸福小子

单例模式

架构师训练营第 1 期 -第七周作业

睁眼看世界

极客大学架构师训练营

性能优化一第七周作业「架构师训练营第 1 期」

天天向善

架构师训练营—第七周学习总结

Geek_shu1988

极客大学架构师训练营

Week3小结

幸福小子

设计模式

架构师训练营—第七周作业

Geek_shu1988

性能测试中并发量与响应时间和吞吐量的关系

天天向上

极客大学架构师训练营

第七周作业

Geek_ce484f

极客大学架构师训练营

第七周作业

fmouse

极客大学架构师训练营

第七周总结

fmouse

极客大学架构师训练营

最强NLP预训练模型库PyTorch-Transformers正式开源:支持6个预训练框架,27个预训练模型-InfoQ