【AICon】 如何构建高效的 RAG 系统?RAG 技术在实际应用中遇到的挑战及应对策略?>>> 了解详情
写点什么

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

  • 2019-07-23
  • 本文字数:7107 字

    阅读完需:约 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-07-23 08:0514821
用户头像

发布了 518 篇内容, 共 233.4 次阅读, 收获喜欢 1542 次。

关注

评论

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

选择TiDB的10个理由

TiDB 社区干货传送门

数据库架构选型

使用 Coze 搭建 TiDB 助手

TiDB 社区干货传送门

实践案例

程序只占用服务器里一个核心使用,是什么问题

德迅云安全杨德俊

OpenCloudOS 迁移工具征集中,18 万奖金等你来拿!|开放原子开源大赛

OpenCloudOS

Linux 迁移

Higress × OpenKruiseGame 游戏网关最佳实践

阿里巴巴云原生

阿里云 云原生 游戏 OpenKruiseGama Higress

从零到一:我的软件测试开发工程师之路

测试人

软件测试

ECMAScript 悄悄更新了两个对象分组 API,你注意到了么?

OpenTiny社区

开源 前端 低代码 组件库 OpenTiny

大模型“四小龙”,能否跨越深渊?

脑极体

AI

让错误码规范起来吧

京东科技开发者

搜索推荐DeepFM算法详解:算法原理、代码实现、比赛实战

汀丶人工智能

自然语言处理 排序算法 搜索推荐 召回算法 DeepFM

未来时尚:数字化管理引领服装企业商品计划的创新浪潮

第七在线

官宣“2024西部(成都)国际人工智能展会”招展工作全面启动

AIOTE智博会

人工智能展会 人工智能展

京东广告算法架构体系-高性能计算最佳实践

京东零售技术

算法 性能优化 技术架构 GPU算力

ETL能实现什么流程控制方式?

RestCloud

ETL 数据集成 数据集成工具

分享7个常用的 JavaScript 库

伤感汤姆布利柏

测试 TIDB in k8s 一次问题记录(pd failed to respond)

TiDB 社区干货传送门

7.x 实践

墨水屏电子纸标签/电子纸价签领域如何选择无线通信方案?

Geek_ab1536

精选案例|首创证券 NoETL 敏捷数据分析创新实践

Aloudata

数仓 ETL

Flink 2.0 状态管理存算分离架构演进

Apache Flink

Premiere Pro 2022下载 (PR2022中文破解) v22.2.0 语音转字幕专用版

Rose

Premiere Pro 2022 pr2022怎么添加字幕

数字人的定义与分类!

青否数字人

​让游戏云原生化别再「左右为难」

阿里巴巴云原生

阿里云 阿里云云原生 OpenKruiseGama

PolarDB-X最佳实践系列(四):如何设计一张订单表

阿里云数据库开源

数据库 阿里云 最佳实践 polarDB PolarDB-X

TiDB 快速入门:从零到一 部署初探

TiDB 社区干货传送门

安装 & 部署

“分布式透明化”在杭州银行核心系统上线之思考

TiDB 社区干货传送门

实践案例

分布式数据库国产替代,杭州银行在挑战什么

TiDB 社区干货传送门

实践案例

最强NLP预训练模型库PyTorch-Transformers正式开源:支持6个预训练框架,27个预训练模型_AI&大模型_Hugging Face_InfoQ精选文章