第1篇 Transformers各种API的综述
Quick tour
Pipeline
pipeline()是对于给定任务使用预训练模型最简单的方法。
pipeline()支持很多常见任务:
文本:
- 情感分析:对于给定文本的情感极性进行分类
- 文本生成(英语):针对给定输入生成文本
- 命名实体识别:将文本中的每个实体标注对应的标签
- 问答:给定一个文本和一个问题,从文本中抽取问题的答案
- 完形填空:填充给定文本中掩盖的单词
- 摘要:生成长文本的摘要
- 翻译:将给定文本翻译成另外的语言
- 特征提取:创建一个文本的张量表示
图像:
- 图像分类:对图像进行分类
- 图像分割:对图像的每个像素进行分类
- 物体识别:识别出图像中的物体
音频:
- 音频分类:将给定音频段赋予一个标签
- 自动语音识别:将音频数据转换成文本
Pipeline的使用方法
在本文中,以情感分析任务为例,演示pipeline()的使用
首先,引入pipeline()以及指定将要完成的任务:
from transformers import pipeline
classifier = pipeline("sentiment-analysis")
pipeline下载下来,并载入了一个默认的预训练模型以及用于情感分析的分词器。现在就可以将classifier用于文本了。
classifier("We are very happy to show you the 🤗 Transformers library.")
#output: [{"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)}")
'''
output:
label: POSITIVE, with score: 0.9998
label: NEGATIVE, with score: 0.5309
'''
Pipeline
pipeline()是对于给定任务使用预训练模型最简单的方法。
pipeline()支持很多常见任务:
文本:
- 情感分析:对于给定文本的情感极性进行分类
- 文本生成(英语):针对给定输入生成文本
- 命名实体识别:将文本中的每个实体标注对应的标签
- 问答:给定一个文本和一个问题,从文本中抽取问题的答案
- 完形填空:填充给定文本中掩盖的单词
- 摘要:生成长文本的摘要
- 翻译:将给定文本翻译成另外的语言
- 特征提取:创建一个文本的张量表示
图像:
- 图像分类:对图像进行分类
- 图像分割:对图像的每个像素进行分类
- 物体识别:识别出图像中的物体
音频:
- 音频分类:将给定音频段赋予一个标签
- 自动语音识别:将音频数据转换成文本
Pipeline的使用方法
在本文中,以情感分析任务为例,演示pipeline()的使用
首先,引入pipeline()以及指定将要完成的任务:
from transformers import pipeline
classifier = pipeline("sentiment-analysis")
pipeline下载下来,并载入了一个默认的预训练模型以及用于情感分析的分词器。现在就可以将classifier用于文本了。
classifier("We are very happy to show you the 🤗 Transformers library.")
'''
output: [{"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)}")
'''
output:
label: POSITIVE, with score: 0.9998
label: NEGATIVE, with score: 0.5309
'''
除此之外,pipeline()也可以迭代整个数据集。先从安装Datasets库开始吧
!pip install datasets
创建一个带有任务名称和希望使用模型的pipeline,将device设置为0即可将张量加载到cuda设备
from transformers import pipeline
speech_recognizer = pipeline("automatic-speech-recognition", model="facebook/wav2vec2-base-960h", device=0)
接下来,加载一个数据集,这里使用的是superb数据集
import datasets
dataset = datasets.load_dataset("superb", name="asr", split="test")
然后就可以使用pipeline迭代整个数据集了。
from transformers.pipelines.base import KeyDataset
from tqdm.auto import tqdm
for out in tqdm(speech_recognizer(KeyDataset(dataset, "file"))):
print(out)
在pipeline中使用其他模型和分词器
pipeline()可以承载Model Hub中的任何模型,使其更容易得适用于其他场景。例如:如果你希望一个模型可以处理法语文本,可以通过Model Hub中的标签找到恰当的模型。过滤结果返回了一个在情感分析上微调过的多语言bert模型,让我们来使用这个模型吧。
model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
使用AutoModelForSequenceClassification和AutoTokenizer加载预训练模型以及相关联的分词器。
from transformers import AutoTokenizer, AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
然后你可以在pipeline中指定模型和分词器,并将其用于目标文本分类。
classifier = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)
classifier("Nous sommes très heureux de vous présenter la bibliothèque 🤗 Transformers.")
如果不能找到合适的模型,你需要在自己数据集上微调一个预训练模型,后面的文章会详细介绍。
AutoClass
AutoTokenizer
分词器负责将文本预处理成一个模型能够理解的形式。首先,分词器将文本将文本切成一个个的词汇(tokens)。这里有很多管理分词过程的规则,包括如何切词、切成什么层级。最重要的事情是你需要用同一个模型名字去实例化分词器,从而确保与模型预训练所使用的分词规则相同。
要使用一个分词器,首先需要使用AutoTokenizer加载进来
from transformers import AutoTokenizer
model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
tokenizer = AutoTokenizer.from_pretrained(model_name)
接下来,为了构建张量作为模型的输入,分词器将tokens转换成数字。这就相当于模型的“词汇表”。
下面将你的文本输入到分词器中:
encoding = tokenizer("We are very happy to show you the 🤗 Transformers library.")
print(encoding)
'''
output:
{"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]}
'''
(这里可以观察到,分词器自动在文本的首尾分别加了一个token)
分词器返回一个词典,包括:
- input_ids:每一个token的数值表示
- attention_mask:指示哪个token需要被关注
与pipeline一样,分词器也可以接受一系列输入。除此之外,分词器还可以填充很截断文本,返回一批次等长文本。
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",
)
AutoModel
Transformers提供了一个简单、统一的方式加载实例。这意味着你可以像加载AutoTokenizer一样加载AutoModel。唯一的区别就是你需要选择适合当前任务的模型。当你做文本或者序列分类时,加载AutoModelForSequenceClassification。
from transformers import AutoModelForSequenceClassification
model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
pt_model = AutoModelForSequenceClassification.from_pretrained(model_name)
现在你可以将已经预处理好的批次数据直接放进模型了。在Pytorch中,**可以将字典解开。
pt_outputs = pt_model(**pt_batch)
模型在logits属性里面输出了最终的激活值。对logits进行softmax来得到概率值。
from torch import nn
pt_predictions = nn.functional.softmax(pt_outputs.logits, dim=-1)
print(pt_predictions)
'''
output:
tensor([[2.2043e-04, 9.9978e-01],
[5.3086e-01, 4.6914e-01]], grad_fn=<SoftmaxBackward>)
'''
所有的transformers模型在最终的激活函数(如softmax)之前输出张量,因为最终的激活函数经常被融合进损失里面。
模型是一个标准的nn.Module类,所有你可以在你常规的训练循环中使用它们。但是,为了让事情更简洁,transformers为Pytorch提供了一个Trainer类,添加了一些函数用来分布式训练、混合精度等。
Transformers模型的输出是特殊的数据类,因此它们的参数在IDE里面可以自动补全。模型的输出通常表现为元组或字典的形式,值为None的属性自动忽略。
保存模型
保存模型:
pt_save_directory = "./pt_save_pretrained"
tokenizer.save_pretrained(pt_save_directory)
pt_model.save_pretrained(pt_save_directory)
加载模型:
pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained")