在本文中,将深入探讨如何利用Transformers库中的预训练模型和分词器来处理各种自然语言处理任务,例如序列分类和文本生成等。如果对如何快速进行推理任务感兴趣,可以查看之前的博客文章。
为了进行本教程,推荐使用带有GPU的Jupyter笔记本环境。可以通过Google Colaboratory访问,它提供了一个基于云的Jupyter笔记本环境,并附带免费的NVIDIA GPU。
首先,让安装Transformers库。在Jupyter笔记本中,可以使用以下命令安装:
!pip install transformers[sentencepiece]
如果希望在本地环境中安装该库,请按照进行操作。此外,为了充分利用ModelHub中的所有功能,需要有一个HuggingFace账户。
已经看到了Pipeline API,它接受原始文本作为输入,并以文本格式输出模型预测,这使得在任何模型上进行推理和测试变得更加容易。现在,让探索和理解pipeline API的工作原理以及其中涉及的不同组件。
与其他神经网络一样,Transformers也不能直接处理原始输入文本,因此需要将其预处理成模型能够理解的形式。这个过程称为分词,即将文本输入转换为数字。为此,使用分词器执行以下操作:
预处理和分词过程需要与模型训练时的方式相同。由于使用的是预训练模型,需要使用相应的分词器,这可以通过使用AutoTokenizer类的from_pretrained方法实现。
from transformers import AutoTokenizer
checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
在上述代码中,从Transformers库中导入了AutoTokenizer类,并初始化了模型检查点名称。现在,让初始化分词器:
tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name_or_path=checkpoint)
执行上述代码后,名为distilbert-base-uncased-finetuned-sst-2-english的模型的分词器将被下载并缓存以供进一步使用。可以在这个上找到更多信息。
现在可以直接使用这个分词器对原始文本进行处理,以获得可以直接输入到模型的张量字典。Transformers只接受张量作为输入,因此分词器以张量形式返回输入。
raw_inputs = [
"I've been waiting for a HuggingFace course my whole life.",
"I am very excited about training the model !!",
"I hate this weather which makes me feel irritated !"
]
inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt")
输出:
print(inputs)
从上述输出中,可以看到输出是一个包含input_ids和attention_mask键的字典。input_ids包含标记化的输入,而attention_mask包含1和0,这些由transformer中的注意力层使用,定义是否应该关注相应的标记。
可以像下载分词器一样下载预训练模型。
from transformers import AutoModel
checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
使用AutoModel类的from_pretrained方法来加载预训练模型。
model = AutoModel.from_pretrained(checkpoint)
与分词器类似,模型也被下载并缓存以供进一步使用。执行上述代码后,将安装没有头部的基础模型,即对于模型的任何输入,将检索到一个高维向量,表示该输入由Transformer模型理解的上下文。
上述Transformer模型具有编码器-解码器架构,能够从输入文本中提取有用和重要的特征/上下文理解,这可以进一步用于任何任务,如文本分类、语言建模等……
模型的输出是一个高维向量,它有三个维度:
可以通过以下方式检查模型的输出:
outputs = model(**inputs)
print(outputs.last_hidden_state.shape)
输出:
从输出的隐藏状态的形状中,可以看到模型有一个批量大小为3,序列长度为16,隐藏状态大小为768。上述Transformer模型的输出可以发送到模型头部以执行所需的任务。
可以直接使用AutoModel的不同类类型从检查点获取模型,例如:
Transformers库中有多种架构可供选择,每种架构都为特定任务而设计。
现在让导入AutoModel和AutoTokenizer类,并从检查点获取模型和分词器。
from transformers import AutoModelForSequenceClassification, AutoTokenizer
checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
现在让下载模型并获取一些预测:
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)
使用之前使用的from_pretrained方法来获取分类模型。
raw_inputs = [
"I've been waiting for a HuggingFace course my whole life.",
"I am very excited about training the model !!",
"I hate this weather which makes me feel irritated !"
]
inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt")
print(inputs)
现在已经准备好了标记化的输入。现在让获取预测:
outputs = model(**inputs)
print(outputs)
输出:
print(outputs.logits.shape)
可以看到模型返回了一个3 x 2矩阵(因为有3个输入序列,并且有2个类别)。可以对输出应用softmax激活函数以便于理解:
import torch
outputs = torch.nn.functional.softmax(outputs.logits, dim = -1)
print(outputs)
输出:
通过将输出通过softmax激活函数,得到了每个类别对于输入句子的概率。有[0.04, 0.95]作为第一个输入的输出,[0.0002, 0.99]作为第二个输入的输出,最后[0.99, 0.000006]作为第三个输入样本的输出。如果检查模型的标签,通过model.config.id2label,得到输出:
因此可以看到,模型对于第一个输入样本属于POSITIVE类别有95%的信心,对于第二个输入样本属于POSITIVE类别有99%的信心,对于第三个输入样本属于NEGATIVE类别有99%的信心。可以看到模型的输出相当准确。
因此,文本分类的Pipeline API可以写成:
# 导入
import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer
# 定义模型检查点
checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
# 下载并缓存分词器和分类模型
tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name_or_path=checkpoint)
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)
# 定义输入并对其进行标记化
raw_inputs = [
"I've been waiting for a HuggingFace course my whole life.",
"I am very excited about training the model !!",
"I hate this weather which makes me feel irritated !"
]
inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt")
print(inputs)
# 从模型获取输出
outputs = model(**inputs)
print(outputs)
# 找到类别/标签概率
outputs = torch.nn.functional.softmax(outputs.logits, dim = -1)
print(outputs)
# 查找标签到类别的映射以进行验证
print(model.config.id2label)
已经看到,可以下载预训练模型和分词器,并直接在数据集上使用它们。从上述示例中,可以看到预训练模型能够以接近100%的信心对输入序列的标签/情感进行分类。