第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")
posted @ 2022-02-11 15:23  pbc的成长之路  阅读(1480)  评论(0编辑  收藏  举报