Hugging Face-Transformers快速指南

这个快速指南将帮助入门,并展示如何使用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()支持的NLP任务

首先创建一个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"

使用AutoModelForSequenceClassificationAutoTokenizer来加载预训练模型及其相关的分词器:

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、 AutoFeatureExtractorAutoProcessor预处理图像、音频和多模态输入。

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()

对于使用序列到序列模型的任务(如翻译或摘要),请使用Seq2SeqTrainerSeq2SeqTrainingArguments类。

可以通过继承Trainer中的方法来自定义训练循环。允许自定义特性,如损失函数、优化器和调度器(scheduler)。请查看 Trainer参考文档,了解哪些方法可以被子类化。

另一种定制训练循环的方法是使用回调(Callbacks)。您可以使用回调与其他库集成,并检查训练循环以报告进度或提前停止训练。回调不会修改训练循环本身的任何内容。如要自定义类似损失函数,需要继承Trainer

原文链接

https://huggingface.co/docs/transformers/quicktour