这个快速指南将帮助入门,并展示如何使用pipeline()进行推理,使用AutoClass加载预训练模型和预处理器,并使用PyTorch或TensorFlow快速训练模型。
首先安装必要的库,例如transformers、datasets等,还需要安装深度学习框架,PyTorch或者TensorFlow。
Pipeline
pipeline()是使用预训练模型进行推理的最简单方法。可以将pipeline()开箱即用地用于不同模式的许多任务。下面是一些支持的任务:
任务 | 描述 | Pipeline标识符 |
文本分类 | 为给定的文本序列分配一个标签 | pipeline(task=”sentiment-analysis”) |
文本生成 | 根据给定的提示生成文本 | pipeline(task=”text-generation”) |
命名实体识别 | 为序列中的每个token分配一个标签(人员、组织、位置等) | pipeline(task=”ner”) |
问答 | 给定上下文和一个问题,从文本中提取答案 | pipeline(task=“question-answering”) |
填充掩码(Fill-mask) | 预测序列中正确的掩码标记 | pipeline(task=“fill-mask”) |
摘要 | 生成一系列文本或文档的摘要 | pipeline(task=“summarization”) |
翻译 | 将文本从一种语言翻译成另一种语言 | pipeline(task=“translation”) |
首先创建一个pipeline()实例,并指定要使用它执行的任务。可以在前面提到的任何任务中使用pipeline(),要了解它支持的任务的完整列表,请查看pipeline API参考(pipeline API reference)。在本指南中,将使用pipeline()进行情感分析作为示例:
from transformers import pipeline
classifier = pipeline("sentiment-analysis")
pipeline()下载并缓存用于情感分析的默认预训练模型和分词器。现在可以在目标文本上使用分类器了:
classifier("We are very happy to show you the Transformers library.")
输出:[{'label': 'POSITIVE', 'score': 0.9998}]
如果有多个输入,将输入作为列表传递给pipeline(),返回一个字典列表:
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
pipeline()也可以遍历整个数据集,执行任何喜欢的任务。对于这个例子,选择自动语音识别任务:
import torch
from transformers import pipeline
speech_recognizer = pipeline("automatic-speech-recognition", model="facebook/wav2vec2-base-960h")
加载想要迭代的音频数据集(更多细节请参阅Datasets Quick Start)。例如,加载MInDS-14数据集:
from datasets import load_dataset, Audio
dataset = load_dataset("PolyAI/minds14", name="en-US", split="train")
需要确保数据集的采样率与facebook/wav2vec2-base-960h训练的采样率相匹配:
dataset = dataset.cast_column("audio", Audio(sampling_rate=speech_recognizer.feature_extractor.sampling_rate))
调用“audio”列时,音频文件会自动加载并重新采样。从前4个样本中提取原始波形数组,并将其作为一个列表传递给pipeline:
result = speech_recognizer(dataset[:4]["audio"])
print([d["text"] for d in result])
输出:['I WOULD LIKE TO SET UP A JOINT ACCOUNT WITH MY PARTNER HOW DO I PROCEED WITH DOING THAT', "FODING HOW I'D SET UP A JOIN TO HET WITH MY WIFE AND WHERE THE AP MIGHT BE", "I I'D LIKE TOY SET UP A JOINT ACCOUNT WITH MY PARTNER I'M NOT SEEING THE OPTION TO DO IT ON THE AP SO I CALLED IN TO GET SOME HELP CAN I JUST DO IT OVER THE PHONE WITH YOU AND GIVE YOU THE INFORMATION OR SHOULD I DO IT IN THE AP AND I'M MISSING SOMETHING UQUETTE HAD PREFERRED TO JUST DO IT OVER THE PHONE OF POSSIBLE THINGS", 'HOW DO I THURN A JOIN A COUNT']
对于输入较大的大型数据集(如语音或视觉),将需要传递一个生成器而不是列表,以将所有输入加载到内存中。查看pipeline API reference以获取更多信息。
在pipeline中使用其他模型和分词器
pipeline()可以容纳来自Hub的任何模型,因此很容易为其他用例调整pipeline()。例如,如果希望模型能够处理法语文本,则使用Hub上的tags来筛选适当的模型。上面的过滤结果返回一个针对情感分析进行微调的多语言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)
classifier = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)
classifier("Nous sommes très heureux de vous présenter la bibliothèque Transformers.")
输出:[{'label': '5 stars', 'score': 0.7273}]
如果找不到适合用例的模型,需要在相关的数据上微调一个预训练的模型。可参考微调(finetuning)教程来学习如何操作。最后,在对预训练模型进行微调后,可以考虑将模型分享(sharing )在Hub上的社区。
AutoClass
在底层,AutoModelForSequenceClassification和AutoTokenizer类一起工作,为上面使用的pipeline()提供动力。AutoClass是一种快捷方式,可以从名称或路径自动检索预训练模型的体系结构。只需要为任务选择适当的AutoClass及其相关的预处理类。回到上一节的例子,使用AutoClass来复制pipeline()的结果。
AutoTokenizer
分词器(tokenizer)负责将文本预处理为数字数组,作为模型的输入。有多种规则管理分词过程,包括如何切分单词以及应该在什么级别切分单词(在tokenizer summary中了解有关分词的更多信息)。要记住的最重要的事情是,需要实例化一个具有相同模型名称的分词器,以确保使用的是与预训练模型相同的分词规则。使用AutoTokenizer加载一个分词器:
from transformers import AutoTokenizer
model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
tokenizer = AutoTokenizer.from_pretrained(model_name)
encoding = tokenizer("We are very happy to show you the Transformers library.")
print(encoding)
输出:
{'input_ids': [101, 11312, 10320, 12495, 19308, 10114, 11391, 10855, 10103, 100, 58263, 13299, 119, 102],
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
分词器返回一个字典,其中包含:input_ids是tokens的数字表示;Attention_mask表示应该处理哪些tokens。分词器还可以接受输入列表,并对文本进行填充和截断,以返回一个长度相同的批处理:
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",
)
查看预处理(preprocess)教程了解有关tokenization的更多详细信息,以及如何使用AutoImageProcessor、 AutoFeatureExtractor和AutoProcessor预处理图像、音频和多模态输入。
AutoModel
Transformers提供了一种简单统一的方法来加载预训练实例。可以像加载AutoTokenizer一样加载AutoModel。唯一的区别是为任务选择正确的AutoModel。有关AutoModel类支持的任务,请参阅task summary。对于文本(或序列)分类,应该加载AutoModelForSequenceClassification:
from transformers import AutoModelForSequenceClassification
model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
pt_model = AutoModelForSequenceClassification.from_pretrained(model_name)
现在将预处理的批量输入直接传递给模型。只需要通过添加**来解压字典:
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)
输出:
tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725],
[0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=<SoftmaxBackward0>)
所有Transformers模型(PyTorch或TensorFlow)在最终激活函数(如softmax)之前输出张量,因为最终激活函数通常与损失融合。模型输出是特殊的数据类,因此它们的属性在IDE中自动补全。模型的输出类似于元组或字典(可以用整数、切片或字符串进行索引),在这种情况下,None属性将被忽略。
保存模型
一旦模型进行了微调,可以使用PreTrainedModel.save_pretrained()将其与分词器一起保存:
pt_save_directory = "./pt_save_pretrained"
tokenizer.save_pretrained(pt_save_directory)
pt_model.save_pretrained(pt_save_directory)
当准备再次使用模型时,使用PreTrainedModel.from_pretrained()重新加载:
pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained")
一个特别酷的Transformers功能是能够保存模型并将其重新加载为PyTorch或TensorFlow模型。from_pt或from_tf参数可以将模型从一个框架转换为另一个框架:
from transformers import AutoModel
tokenizer = AutoTokenizer.from_pretrained(tf_save_directory)
pt_model = AutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True)
自定义模型构建
可以修改模型的配置类以更改模型的构建方式。配置指定模型的属性,如隐藏层或注意力头的数量。当从自定义配置类初始化模型时,将从头开始。模型属性是随机初始化的,在使用模型得到有意义的结果之前,需要对模型进行训练。首先导入AutoConfig,然后加载要修改的预训练模型。在AutoConfig.from_pretrained()中,可以指定要更改的属性,例如注意力头的数量:
from transformers import AutoConfig, AutoModel
my_config = AutoConfig.from_pretrained("distilbert-base-uncased", n_heads=12)
my_model = AutoModel.from_config(my_config)
Trainer——PyTorch优化的训练循环
所有模型都是标准的torch.nn.Module
,因此可以在任何典型的训练循环中使用它们。虽然你可以编写自己的训练循环,但Transformers为PyTorch提供了Trainer类,其中包含基本的训练循环,并添加了额外的功能,如分布式训练、混合精度等。根据任务的不同,通常会将以下参数传递给Trainer:
1、A PreTrainedModel or a torch.nn.Module
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased")
2、TrainingArguments包含可以更改的模型超参数,如学习率、批大小和要训练的epoch数量。如果不指定任何训练参数,则使用默认值:
from transformers import TrainingArguments
training_args = TrainingArguments(
output_dir="path/to/save/folder/",
learning_rate=2e-5,
per_device_train_batch_size=8,
per_device_eval_batch_size=8,
num_train_epochs=2,
)
3、预处理类,如分词器、图像处理器、特征提取器或处理器:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
4、加载数据
from datasets import load_dataset
dataset = load_dataset("rotten_tomatoes") # doctest: +IGNORE_RESULT
5、创建一个函数对数据集进行分词,并使用map将其应用到整个数据集上:
def tokenize_dataset(dataset):
return tokenizer(dataset["text"])
dataset = dataset.map(tokenize_dataset, batched=True)
6、使用DataCollatorWithPadding从数据集中创建一批示例:
from transformers import DataCollatorWithPadding
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
在Trainer中使用所有这些类:
from transformers import Trainer
trainer = Trainer(
model=model,
args=training_args,
train_dataset=dataset["train"],
eval_dataset=dataset["test"],
tokenizer=tokenizer,
data_collator=data_collator,
) # doctest: +SKIP
调用train()开始训练:
trainer.train()
对于使用序列到序列模型的任务(如翻译或摘要),请使用Seq2SeqTrainer和Seq2SeqTrainingArguments类。
可以通过继承Trainer中的方法来自定义训练循环。允许自定义特性,如损失函数、优化器和调度器(scheduler)。请查看 Trainer参考文档,了解哪些方法可以被子类化。
另一种定制训练循环的方法是使用回调(Callbacks)。您可以使用回调与其他库集成,并检查训练循环以报告进度或提前停止训练。回调不会修改训练循环本身的任何内容。如要自定义类似损失函数,需要继承Trainer。