Hugging Face:用十行 TensorFlow 2.0 代码实现最先进的自然语言处理
2019 年 11 月 04 日
Hugging Face 团队 撰写

Hugging Face 是领先的 NLP 初创公司,超过一千家公司在生产中使用他们的库,包括必应、苹果和 Monzo。

本教程中使用的所有示例都可以在 Colab 上获取。相应的链接可在相应部分找到。.

The HuggingFace Logo

引言

Hugging Face 是一家专注于 NLP 的初创公司,拥有庞大的开源社区,特别是在 Transformers 库方面。🤗/Transformers 是一个基于 Python 的库,它提供了一个 API 来使用许多知名的 Transformer 架构,例如 **BERT**、**RoBERTa**、**GPT-2** 或 **DistilBERT**,这些架构在各种 NLP 任务(如文本分类、信息提取、问答和文本生成)上获得了最先进的结果。这些架构预先训练了多组权重。使用 Transformers 入门只需要安装 pip 包


pip install transformers

该库在 PyTorch 中发展迅速,最近已移植到 TensorFlow 2.0,提供了一个 API,现在可以使用 Keras 的 fit API、TensorFlow Extended 和 TPU 👏。这篇博文重点介绍了使用 TensorFlow 的 Transformers 库:使用 Keras API 以及 TensorFlow TPUStrategy 微调最先进的 Transformer 模型。

库与理念

Transformers 基于预训练的 Transformer 模型的概念。这些 Transformer 模型具有不同的形状、大小和架构,并具有自己的接受输入数据的方式:通过分词。

该库建立在三个主要类之上:配置类、分词器类和模型类。
  • 配置类:配置类包含与我们将使用的模型相关的信息,例如层数和注意力头的数量。以下是一个 BERT 配置文件的示例,用于预训练的权重 bert-base-cased。配置类使用各种 I/O 方法和标准化名称属性来保存这些属性。

{
  "attention_probs_dropout_prob": 0.1,
  "hidden_act": "gelu",
  "hidden_dropout_prob": 0.1,
  "hidden_size": 768,
  "initializer_range": 0.02,
  "intermediate_size": 3072,
  "max_position_embeddings": 512,
  "num_attention_heads": 12,
  "num_hidden_layers": 12,
  "type_vocab_size": 2,
  "vocab_size": 28996
}

  • 分词器类:分词器类负责将 Python 字符串转换为整数数组或张量,这些整数是模型词表中的索引。它具有许多围绕将字符串分词为标记的便捷功能。这种分词根据模型而有所不同,因此每个模型都有自己的分词器。
  • 模型类:模型类本身包含神经网络建模逻辑。在使用 TensorFlow 模型时,它继承自 tf.keras.layers.Layer,这意味着它可以通过 Keras 的 fit API 很简单地使用,或者使用自定义训练循环和 GradientTape 进行训练。

简洁之乐

使用 **Transformers** 的优势在于它直观的、与模型无关的 API。加载预训练模型及其分词器只需几行代码。以下是如何加载 BERT 和 GPT-2 TensorFlow 模型以及它们的分词器的示例

from transformers import (TFBertModel, BertTokenizer,
                         TFGPT2Model, GPT2Tokenizer)

bert_model = TFBertModel.from_pretrained("bert-base-cased")  # Automatically loads the config
bert_tokenizer = BertTokenizer.from_pretrained("bert-base-cased")

gpt2_model = TFGPT2Model.from_pretrained("gpt2")  # Automatically loads the config
gpt2_tokenizer = GPT2Tokenizer.from_pretrained("gpt2")

权重从 HuggingFace 的 S3 存储桶下载并在你的机器上本地缓存。这些模型已准备好用于推理或微调。让我们看看它的实际操作。

微调 Transformer 模型

Transformer 库中提供的一些方法可以轻松地微调模型。接下来的部分按以下方式构建
  • 加载文本数据并对其进行预处理
  • 定义超参数
  • 训练(使用 Keras 在 CPU/GPU 上以及使用 TPUStrategy)

构建输入管道

我们制作了一个配套的 colab 笔记本,让你快速上手所有代码。我们将利用 tensorflow_datasets 包来加载数据。Tensorflow-dataset 为我们提供了一个 tf.data.Dataset,可以将其输入到我们的 glue_convert_examples_to_features 方法中。

此方法将使用分词器对输入进行分词,并在序列的开头和结尾添加特殊标记(例如 [SEP]、[CLS]、</s> 或 <s>,例如),如果模型需要这些额外的标记。此方法返回一个包含特征化输入的 tf.data.Dataset

然后,我们可以使用标准的 tf.data.Dataset 方法对该数据集进行混洗并将其批处理为 32 个单位的批次。

import tensorflow_datasets
from transformers import glue_convert_examples_to_features

data = tensorflow_datasets.load("glue/mrpc")

train_dataset = data["train"]
validation_dataset = data["validation"]

train_dataset = glue_convert_examples_to_features(train_dataset, bert_tokenizer, 128, 'mrpc')
validation_dataset = glue_convert_examples_to_features(validation_dataset, bert_tokenizer, 128, 'mrpc')
train_dataset = train_dataset.shuffle(100).batch(32).repeat(2)
validation_dataset = validation_dataset.batch(64)

使用 Keras 的 fit 方法进行训练

使用 Keras 的 fit 方法训练模型从未如此简单。现在我们已经设置了输入管道,我们可以定义超参数,并使用我们的数据集调用 Keras 的 fit 方法。

optimizer = tf.keras.optimizers.Adam(learning_rate=3e-5, epsilon=1e-08, clipnorm=1.0)
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
metric = tf.keras.metrics.SparseCategoricalAccuracy('accuracy')
bert_model.compile(optimizer=optimizer, loss=loss, metrics=[metric])

bert_history = bert_model.fit(
 bert_train_dataset, 
 epochs=2, 
 steps_per_epoch=115, 
 validation_data=bert_validation_dataset, 
 validation_steps=7
)

使用 Strategy 进行训练

使用策略进行训练可以更好地控制训练过程。通过在策略之间切换,用户可以选择训练模型的分布式方式:从多 GPU 到 TPU。

在撰写本文时,TPUStrategy 是使用 TensorFlow 2 在 TPU 上训练模型的唯一可靠方法。在这种情况下,使用策略构建自定义循环更有意义,因为策略可以轻松地切换,并且在多 GPU 上进行训练几乎不需要代码更改。

构建自定义循环需要一些工作来设置,因此建议读者打开以下 colab 笔记本以更好地理解手头的主题。它不会详细介绍分词,因为第一个 colab 已经介绍了,但它展示了如何构建 TPUStrategy 将使用的输入管道

这将使用 Google Cloud Platform 存储桶来托管数据,因为在使用本地文件系统时,TPU 很复杂。colab 笔记本在此处提供

Transformers 现在可以使用 TensorFlow API - 那又怎样呢?

Transformers 库的主要卖点是其与模型无关且简单的 API。充当获得 NLP 最先进结果模型的前端,根据手头的任务在模型之间切换非常容易。

例如,以下是在语言分类任务(MRPC)上微调 BERT 的完整脚本

model = TFBertForSequenceClassification.from_pretrained("bert-base-cased")
tokenizer = BertTokenizer.from_pretrained("bert-base-cased")

data = tensorflow_datasets.load("glue/mrpc")
train_dataset = data["train"]
train_dataset = glue_convert_examples_to_features(train_dataset, tokenizer, 128, 'mrpc')

optimizer = tf.keras.optimizers.Adam(learning_rate=3e-5, epsilon=1e-08, clipnorm=1.0)
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
metric = tf.keras.metrics.SparseCategoricalAccuracy('accuracy')

model.compile(optimizer=optimizer, loss=loss, metrics=[metric])
model.fit(train_dataset, epochs=3)

但是,在生产环境中,内存十分宝贵。你可能希望使用更小的模型;例如,切换到 DistilBERT。只需将前两行更改为以下两行即可

model = TFDistilBertForSequenceClassification.from_pretrained("distilbert-base-uncased")
tokenizer = DistilbertTokenizer.from_pretrained("distilbert-base-uncased")

作为托管 10 多个 Transformer 架构的平台,🤗/Transformers 使得使用、微调和比较改变了 NLP 深度学习领域的模型变得非常容易。它充当许多利用 Transformer 模型的下游应用程序的后端,并被许多不同的公司在生产中使用。我们将在我们的 GitHub 存储库 上欢迎你提出任何问题或疑问。
下一篇文章
Hugging Face: State-of-the-Art Natural Language Processing in ten lines of TensorFlow 2.0

Hugging Face 团队 撰写

Hugging Face 是领先的 NLP 初创公司,超过一千家公司在生产中使用他们的库,包括必应、苹果和 Monzo。

本教程中使用的所有示例都可以在 Colab 上获取。相应的链接可在相应部分找到

引言Hugging Face 是一家专注于 NLP 的初创公司,拥有庞大的开源社区,特别是在 Transformers 库方面。🤗/Transformers 是一个基于 Python 的库,它提供了一个 API 来使用许多知名的 Transformer 架构,例如 **BERT**、**RoBERTa**、**GPT-2** 或 **DistilBERT**,这些架构在各种 NLP 任务(如文本分类、信息提取、问答和文本生成)上获得了最先进的结果。这些架构预先训练了多组权重。使用 Transformers 入门只需要安装 pip 包