Transformers为自然语言理解(NLU)和自然语言生成(NLG)提供通用架构(BERT、GPT-2、RoBERTa、XLM、DistilBert、XLNet…) 具有 100 多种语言的 32 多种预训练模型以及 Jax、PyTorch 和 TensorFlow 之间的深度互操作性。
所有模型检查点都从 Huggingface.co 模型中心无缝集成,用户和组织直接上传。当前检查点数量22752。
文档分为五个部分:
该库目前包含以下68种模型的 Jax、PyTorch 和 Tensorflow 实现、预训练模型权重、使用脚本和转换实用程序(conversion utilities)。
下表列出每个模型的当前支持:
让我们快速浏览一下 Transformers 库功能。 该库下载用于自然语言理解 (NLU) 任务的预训练模型,例如分析文本的情绪,以及自然语言生成 (NLG),例如用新文本完成提示或翻译成另一种语言。
首先,我们将看到如何轻松利用管道 API 在推理中快速使用这些预训练模型。 然后,我们将进一步挖掘,看看该库如何让您访问这些模型并帮助您预处理数据。
文档中提供的所有代码示例在 Pytorch 与 TensorFlow 的左上角都有一个开关。 如果不是,则该代码预计适用于两个后端,无需任何更改。
Youtube视频
在给定任务上使用预训练模型的最简单方法是使用 pipeline()。
Transformers 提供了以下开箱即用的任务:
让我们看看它如何用于情感分析(其他任务都在task summary中介绍):
from transformers import pipeline
classifier = pipeline('sentiment-analysis')
首次输入此命令时,会下载并缓存预训练模型及其标记器。分词器的工作是预处理文本输入模型,然后模型负责进行预测。 管道将所有这些组合在一起,并对预测进行后处理以使其可读。 例如:
classifier('We are very happy to show you the Transformers library.')
[{'label': 'POSITIVE', 'score': 0.9998}]
你可以输入多个句子,这些句子批处理输入模型,返回一个像这样的字典列表:
results = classifier(["We are very happy to show you the Transformers library.",
"We hope you don't hate it."])
for result in results:
print(f"label: {result['label']}, with score: {round(result['score'], 4)}")
label: POSITIVE, with score: 0.9998
label: NEGATIVE, with score: 0.5309
默认情况下,为此管道下载的模型称为“distilbert-base-uncased-finetuned-sst-2-english”。 我们可以查看它的模型页面以获取有关它的更多信息。 它使用 DistilBERT 架构,并针对情感分析任务在名为 SST-2 的数据集上进行了微调。
假设我们想使用一个用法语预训练的模型。 我们可以搜索 model hub,该中心收集了研究实验室在大量数据上预训练的模型,以及社区模型 community models (通常是特定数据集上那些大模型的微调版本)。 应用标签 “French” 和 “text-classification”会返回一个建议“nlptown/bert-base-multilingual-uncased-sentiment”。 让我们看看如何使用它。
您可以直接将要使用的模型名称“bert-base-multilingual-uncased-sentiment“”传递给 pipeline():
classifier = pipeline('sentiment-analysis', model="nlptown/bert-base-multilingual-uncased-sentiment")
这个分类器现在可以处理英语、法语以及荷兰语、德语、意大利语和西班牙语的文本! model除了接收模型名称,也可以传入保存预训练模型的本地文件夹(见下文)。 您还可以传递model object及其关联的tokenizer。
为此,我们需要两个类:
注意:如果我们在其他任务中使用该库,模型的类会发生变化。 task summary(任务摘要) 总结了哪个类用于哪个任务。
from transformers import AutoTokenizer, AutoModelForSequenceClassification
现在,要下载我们之前找到的模型和标记器,我们只需要使用 from_pretrained() 方法( model_name可以任意替换为其它的transformers模型):
model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
model = AutoModelForSequenceClassification.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
classifier = pipeline('sentiment-analysis', model=model, tokenizer=tokenizer)
如果预训练模型的数据集和您的数据集不够相似,则需要在您的的数据集上进行微调。 我们提供了示例脚本来执行此操作。 完成后,不要忘记在社区分享您的微调模型。
现在让我们看看在使用这些管道时会发生什么。
Youtube视频
正如我们所见,模型和分词器是使用 from_pretrained 方法创建的:
from transformers import AutoTokenizer, AutoModelForSequenceClassification
model_name = "distilbert-base-uncased-finetuned-sst-2-english"
pt_model = AutoModelForSequenceClassification.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
分词器负责对您的文本进行预处理。
使用与模型预训练时相同的分词器来分词:有多个规则可以管理文本分词,使用模型名称来实例化分词器,可以确保我们使用与模型相同的分词规则来预训练。
使用与模型预训练时相同的词汇表,将这些标记转换为数字,以便能够从中构建张量并将它们提供给模型。 from_pretrained 方法实例化tokenizer时就会下载对应的词汇表。
将文本输入分词器就可以执行以上步骤:
inputs = tokenizer("We are very happy to show you the Transformers library.")
这将返回一个字符串到整数列表的字典。 它包含:
print(inputs)
{'input_ids': [101, 2057, 2024, 2200, 3407, 2000, 2265, 2017, 1996, 100, 19081, 3075, 1012, 102],
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
句子列表可以直接传递给分词器。 如果是批处理句子,则
最终返回张量输入模型。可以在tokenizer中设定这些参数:
pt_batch = tokenizer(
["We are very happy to show you the Transformers library.", "We hope you don't hate it."],
padding=True, #填充
truncation=True, #截断
max_length=512,
return_tensors="pt" #将input_ids转为Pytorch张量。Pytorch最终只接受张量作为模型输入
)
填充一般只在句子的一侧填充(如右侧)。attention_mask=True或者0表示padding,计算注意力时需要忽略:
for key, value in pt_batch.items():
print(f"{key}: {value.numpy().tolist()}")
input_ids: [[101, 2057, 2024, 2200, 3407, 2000, 2265, 2017, 1996, 100, 19081, 3075, 1012, 102], [101, 2057, 3246, 2017, 2123, 1005, 1056, 5223, 2009, 1012, 102, 0, 0, 0]]
attention_mask: [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]]
您可以在此处了解有关tokenizers的更多信息。
数据预处理后输入模型。如果您使用的是 TensorFlow 模型,则可以将字典键直接传递给张量,对于 PyTorch 模型,您需要通过添加 ** 来解压字典。
pt_outputs = pt_model(**pt_batch)
在 Transformers 中,所有输出都是包含模型的最终激活以及其他元数据metadata的对象。 此处更详细地描述了这些对象。 现在,让我们自己检查输出:
print(pt_outputs)
SequenceClassifierOutput(loss=None, logits=tensor([[-4.0833, 4.3364],
[ 0.0818, -0.0418]], grad_fn=<AddmmBackward>), hidden_states=None, attentions=None)
所有 Transformers 模型(PyTorch 或 TensorFlow)在最终激活函数(如 SoftMax)之前返回模型的激活值,因为这个最终激活函数通常与损失融合。
让我们用 SoftMax 来获得预测:
from torch import nn
pt_predictions = nn.functional.softmax(pt_outputs.logits, dim=-1)
print(pt_predictions)
tensor([[2.2043e-04, 9.9978e-01],
[5.3086e-01, 4.6914e-01]], grad_fn=<SoftmaxBackward>)
如果除了输入之外还为模型提供标签,模型输出对象还将包含一个 loss 属性:
import torch
pt_outputs = pt_model(**pt_batch, labels = torch.tensor([1, 0]))
print(pt_outputs)
SequenceClassifierOutput(loss=tensor(0.3167, grad_fn=<NllLossBackward>), logits=tensor([[-4.0833, 4.3364],
[ 0.0818, -0.0418]], grad_fn=<AddmmBackward>), hidden_states=None, attentions=None)
models是标准的 torch.nn.Module 或 tf.keras.Model,因此您可以在通常的训练循环中使用它们。 Transformers 还提供了一个 Trainer(或 TFTrainer)类来帮助您进行训练(处理诸如分布式训练、混合精度等)。 有关更多详细信息,请参阅培训教程。
Pytorch 模型输出是特殊的数据类,因此您可以在 IDE 中自动完成其属性。 它们的行为也像元组或字典(例如,您可以使用整数、切片或字符串进行索引),在这种情况下,未设置的属性(具有 None 值)将被忽略。
模型微调后进行保存:
tokenizer.save_pretrained(save_directory)
model.save_pretrained(save_directory)
然后,您可以使用 from_pretrained() 方法通过传递目录名称而不是模型名称来加载此模型。
Transformers 可以轻松地在 PyTorch 和 TensorFlow 之间切换:。 TensorFlow 模型中加载已保存的 PyTorch 模型,请像这样使用 from_pretrained():
from transformers import TFAutoModel
tokenizer = AutoTokenizer.from_pretrained(save_directory)
model = TFAutoModel.from_pretrained(save_directory, from_pt=True)
PyTorch 模型中加载保存的 TensorFlow 模型:
from transformers import AutoModel
tokenizer = AutoTokenizer.from_pretrained(save_directory)
model = AutoModel.from_pretrained(save_directory, from_tf=True)
最后,如果需要,您还可以要求模型返回所有隐藏状态和所有注意力权重:
pt_outputs = pt_model(**pt_batch, output_hidden_states=True, output_attentions=True)
all_hidden_states = pt_outputs.hidden_states
all_attentions = pt_outputs.attentions
AutoModel 和 AutoTokenizer 类只是可以自动与任何预训练模型一起使用的快捷方式,在背后,该库为每个架构加类的组合提供一个model class。
当模型是“distilbert-base-uncased-finetuned-sst-2-english”时,AutoModelForSequenceClassification所自动创建的模型就是 DistilBertForSequenceClassification。所以也有另一种加载模型的方式:
## PYTORCH CODE
from transformers import DistilBertTokenizer, DistilBertForSequenceClassification
model_name = "distilbert-base-uncased-finetuned-sst-2-english"
model = DistilBertForSequenceClassification.from_pretrained(model_name)
tokenizer = DistilBertTokenizer.from_pretrained(model_name)
## TENSORFLOW CODE
from transformers import DistilBertTokenizer, TFDistilBertForSequenceClassification
model_name = "distilbert-base-uncased-finetuned-sst-2-english"
model = TFDistilBertForSequenceClassification.from_pretrained(model_name)
tokenizer = DistilBertTokenizer.from_pretrained(model_name)
如果要更改模型本身的构建方式,可以自定义配置。 每个架构都有自己的相关配置。 例如,DistilBertConfig 允许您指定 DistilBERT 的隐藏维度hidden dimension、 dropout rate等参数。 如果您进行核心修改,例如更改hidden size,您将无法再使用预训练模型,而需要从头开始训练。再将直接从此配置实例化模型。
下面,我们使用 from_pretrained() 方法为分词器加载预定义的词汇表。 然后从头开始初始化模型。 因此,不是使用 from_pretrained() 方法,而是从配置中实例化模型:
## PYTORCH CODE
from transformers import DistilBertConfig, DistilBertTokenizer, DistilBertForSequenceClassification
config = DistilBertConfig(n_heads=8, dim=512, hidden_dim=4*512)
tokenizer = DistilBertTokenizer.from_pretrained('distilbert-base-uncased')
model = DistilBertForSequenceClassification(config)
## TENSORFLOW CODE
from transformers import DistilBertConfig, DistilBertTokenizer, TFDistilBertForSequenceClassification
config = DistilBertConfig(n_heads=8, dim=512, hidden_dim=4*512)
tokenizer = DistilBertTokenizer.from_pretrained('distilbert-base-uncased')
model = TFDistilBertForSequenceClassification(config)
在from_pretrained() 方法中就可以修改model head的参数(例如,标签的数量),而不是创建model 的新配置来改变label数量。 例如,定义一个10个标签的分类器:
from transformers import DistilBertConfig, DistilBertTokenizer, DistilBertForSequenceClassification
model_name = "distilbert-base-uncased"
model = DistilBertForSequenceClassification.from_pretrained(model_name, num_labels=10)
tokenizer = DistilBertTokenizer.from_pretrained(model_name)
transformer的安装见官方文档
transformers库给预训练模型提供了本地下载和缓存的功能。 使用 from_pretrained 等方法时,模型将自动下载到 shell 环境变量 TRANSFORMERS_CACHE 给出的文件夹中。 它的默认值将是 Hugging Face 缓存主页,后跟 /transformers/。 如下(按优先顺序):
所以如果你没有设置任何特定的环境变量,缓存目录将在 ~/.cache/huggingface/transformers/。
此外可以使用cache_dir=… 指定模型存储位置。
可以在有防火墙或无网络的环境中运行 Transformers。
Here is an example of how this can be used on a filesystem that is shared between a normally networked and a firewalled to the external world instances.
下面是一个示例,说明如何在正常联网和防火墙到外部世界实例之间共享的文件系统上使用它。
在具有正常网络的实例上运行您的程序,该程序将下载和缓存模型(如果您使用 数据集,还可以选择数据集)。 例如:
python examples/pytorch/translation/run_translation.py --model_name_or_path t5-small --dataset_name wmt16 --dataset_config ro-en ...
然后使用相同的文件系统filesystem,可以在防火墙实例firewalled instance上运行相同的程序:
HF_DATASETS_OFFLINE=1 TRANSFORMERS_OFFLINE=1 \
python examples/pytorch/translation/run_translation.py --model_name_or_path t5-small --dataset_name wmt16 --dataset_config ro-en ...
并且它应该成功而不会hanging waiting to timeout。
之前的代码都是在线下载(模型、tokenizer),文件缓存以备稍后使用。 但也可以下载到本地使用。
下载文件的两种方式:
下载的内容可以选择为:
详细的下载方法请参考文档。
swift-coreml-transformers 存储库的工具,可将 PyTorch 或 TensorFlow 2.0 训练的 Transformer 模型(目前包含 GPT-2、DistilGPT-2、BERT 和 DistilBERT)转换为在 iOS 设备上运行的 CoreML 模型。未来三者可以无缝连接使用。
Transformers 是一个opinionated库,专为:
该库的设计考虑了两个重要目标:
其他几个目标:
transformers库围绕每个模型的三种类构建:
Model classes ,例如 BertModel,包含30 多个 PyTorch 模型 (torch.nn.Module) 或 Keras 模型 (tf.keras.Model),它们使用库中提供的预训练权重。
Configuration classes 配置类,如 BertConfig存储构建模型所需的所有参数,可自动实例化模型配置(这是模型的一部分)。
Tokenizer 类,例如 BertTokenizer。它存储每个模型的词汇表,并提供用于编码/解码要馈送到模型的token embedding索引列表中的字符串的方法。
所有这些类都可用预训练实例来实例化,本地保存方法有两种:
大多数模型使用相同的输入,此处将与使用示例一起详细说明。
输入 id 通常是作为输入传递给模型的唯一必需参数。 它们是标记索引token indices,标记的数字表示构建将用作模型输入的序列。(numerical representations of tokens building the sequences that will be used as input by the model.)