Quick tour 快速上手¶
Pipeline¶
使用 pipeline() 是利用预训练模型进行推理的最简单的方式。你能够将 pipeline() 开箱即用地用于跨不同模态的多种任务。来看看它支持的任务列表:
| 任务 | 描述 | 模态 | Pipeline 标识符 |
|---|---|---|---|
| 文本分类 | 为给定的文本序列指定标签 | 自然语言处理 | pipeline(task="sentiment-analysis") |
| 文本生成 | 在给定提示的情况下生成文本 | 自然语言处理 | pipeline(task="text-generation") |
| 总结 | 生成文本或文档序列的摘要 | 自然语言处理 | pipeline(task="summarization") |
| 图像分类 | 为图像指定标签 | 计算机视觉 | pipeline(task="image-classification") |
| 图像分割 | 为图像的每个像素分配标签(支持语义、全景和实例分割) | 计算机视觉 | pipeline(task="image-segmentation") |
| 对象检测 | 预测图像中对象的边界框和类别 | 计算机视觉 | pipeline(task="object-detection") |
| 音频分类 | 为某些音频数据分配标签 | 音频 | pipeline(task="audio-classification") |
| 自动语音识别 | 将语音转录为文本 | 音频 | pipeline(task="automatic-speech-recognition") |
| 视觉问题回答 | 回答一个关于图像的问题,给出一个图像和一个问题 | Multimodal多式 | pipeline(task="vqa") |
| 文档问答 | 回答一个关于文档的问题,给出一个文档和一个问题 | Multimodal多式 | pipeline(task="document-question-answering") |
| 图像字幕 | 为给定图像生成字幕 | Multimodal多式 | pipeline(task="image-to-text") |
你可以将pipeline()用于任何一种上面提到的任务,如果想知道支持的任务的完整列表,可以查阅pipeline API。
首先,创建一个 pipeline() 实例并且指定你想要将它用于的任务(Task)。在这篇教程中,我们将 pipeline() 用在一个情感分析任务(task="sentiment-analysis")上作为示例:
try:
import tf_keras
except ImportError:
raise ImportError(f"'tf_keras' could not be resolved. Please install it by 'pip install tf-keras'.")
from transformers import pipeline
# pipeline() 会下载并缓存一个用于情感分析的预训练模型和分词器。
classifier = pipeline("sentiment-analysis")
# 在目标文本上使用 classifier
classifier("We are very happy to show you the 🤗 Transformers library.")
也可以把多个输入放入一个列表然后传给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)}")
pipeline() 也可以遍历整个数据集。在下面这个示例中,我们选择自动语音识别作为任务, 加载 MInDS-14 音频数据集:
try:
import soundfile
except ImportError:
raise ImportError(f"'soundfile' could not be resolved. Please install it by 'pip install soundfile'.")
speech_recognizer = pipeline("automatic-speech-recognition", model="facebook/wav2vec2-base-960h")
from datasets import load_dataset, Audio
dataset = load_dataset("PolyAI/minds14", name="en-US", split="train", trust_remote_code=True)
# 你需要确保数据集中音频的采样率与 facebook/wav2vec2-base-960h 训练用到的音频的采样率一致
dataset = dataset.cast_column("audio", Audio(sampling_rate=speech_recognizer.feature_extractor.sampling_rate))
当调用 "audio" 列时, 音频文件将会自动加载并重采样。 从前四个样本中提取原始波形数组,将它作为列表传给 pipeline:
try:
import librosa
except ImportError:
raise ImportError(f"'librosa' could not be resolved. Please install it by 'pip install librosa'.")
result = speech_recognizer(dataset[:4]["audio"])
print([d["text"] for d in result])
需要注意的是,对于输入很大的大型数据集(如语音或视觉),则需要传递一个生成器而不是用一个列表来加载内存中的所有输入。
在 pipeline 中使用另一个模型和分词器¶
在上文中提到,若 pipeline() 在指定任务后未指定模型和分词器,则会下载并缓存一个用于情感分析的预训练模型和分词器。
因为 pipeline() 可以容纳Hub中的任何模型,从而我们可以轻松地让 pipeline() 适用于其他用例。
例如,如果你想要一个能够处理法语文本的模型,可以先使用 Hub 上的 Tags 筛选合适的模型。
在这里,我们选择了一个多语言BERT模型,该模型经过微调,可用于法语文本的情感分析:
# 多语言BERT模型
model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
在 transformers 库中,加载预训练模型主要有两种方式:
使用 pipeline() 加载。
特点
- 高阶封装:pipeline 函数提供了一个高阶封装,使得加载和使用预训练模型变得非常简单。
- 易用性:适合快速实验和原型开发,因为它自动处理了很多细节,如模型加载、分词器配置等。
- 多功能:支持多种任务类型(如文本分类、问答、命名实体识别等),只需指定任务名称即可。
- 默认配置:使用默认的模型和分词器配置,无需手动调整。
适用场景
- 快速验证模型效果。
- 简单的应用程序开发。
- 不需要自定义模型或分词器配置的情况。
直接加载模型和分词器。
特点
- 灵活性:允许更细粒度的控制和自定义,如修改分词器的配置、调整模型的超参数等。
- 可扩展性:适合需要自定义模型或分词器的情况,例如添加新的特殊标记、调整分词策略等。
- 显式控制:加载模型和分词器的过程是显式的,便于调试和理解。
适用场景
- 需要自定义模型或分词器配置。
- 进行更深入的模型研究和调优。
- 开发复杂的应用程序,需要更精细的控制。
这里使用AutoModelForSequenceClassification和AutoTokenizer直接加载预训练模型及其关联的分词器:
# Pytorch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
# TensorFlow
from transformers import AutoTokenizer, TFAutoModelForSequenceClassification
model = TFAutoModelForSequenceClassification.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
在 pipeline() 中指定模型和分词器tokenizer,现在你可以将分类器classifier来处理法语文本:
classifier = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)
# 在后台,`AutoModelForSequenceClassification`和`AutoTokenizer`类一起工作,为上面使用的 pipeline() 提供动力。
classifier("Nous sommes très heureux de vous présenter la bibliothèque 🤗 Transformers.")
如果你没有找到适合你的模型,就需要在你的数据上微调一个预训练模型了。
查看微调教程来学习怎样进行微调。
Auto Class¶
AutoClass是一种快捷方式,可以从预训练模型的名称或路径中自动检索其架构,你只需为任务及其关联的预处理类选择适当的AutoClass。
让我们回到上一节的示例,看看如何使用 AutoClass 复制 pipeline() 的结果。
AutoTokenizer¶
分词器负责预处理文本,将文本转换为用于输入模型的数字数组。有多个用来管理分词过程的规则,包括如何拆分单词和在什么样的级别上拆分单词。
注意:实例化的分词器要与模型的名称相同, 以确保和模型训练时使用相同的分词规则。
from transformers import AutoTokenizer
model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
# 使用AutoTokenizer加载令牌化器,实例化的分词器要与模型的名称相同
tokenizer = AutoTokenizer.from_pretrained(model_name)
将文本传入分词器 tokenizer:
encoding = tokenizer("We are very happy to show you the 🤗 Transformers library.")
print(encoding)
Tokenizer 会返回一个包含三个重要对象的字典:
input_ids:这是一个整数序列,每个整数代表词汇表中的一个特定token。模型使用这个序列作为输入来理解和处理文本数据。token_type_ids:这是一个与 input_ids 相同长度的序列,它表示输入序列中每个 token 的类型。这个字段主要用于区分不同类型的输入序列,尤其是在处理由多个文本序列组成的输入时,例如问答系统中的问题和答案,或者文本分类任务中的文本和标签。attention_mask:这个序列表示输入序列中哪些 token 是实际的文本token,哪些是填充(padding)token。在处理批量数据时,由于不同序列的长度可能不同,通常需要使用填充token来使所有序列长度一致。attention_mask中的1 表示实际的文本token,而0 表示填充token,这样模型就可以忽略填充token。
分词器也可以接受列表作为输入,并填充和截断文本,返回具有统一长度的批次:
# Pytorch
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",
)
# TensorFlow
tf_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="tf"
)
查阅预处理数据教程来获得有关分词的更详细的信息,以及如何使用 AutoFeatureExtractor 和 AutoProcessor 来处理图像,音频,还有多模式输入。
AutoModel¶
🤗 Transformers 提供了一种简单统一的方式来加载预训练的实例. 这表示你可以像加载 AutoTokenizer 一样加载 AutoModel。
需要注意的是,AutoModel 是一个通用的接口,它可以加载各种类型的预训练模型,但可能需要额外的配置才能用于特定任务。
而 AutoModelForSequenceClassification 是专门为文本或序列的分类任务定制的接口,已自动为你配置好了一个适用于序列分类任务的模型。
# Pytorch
from transformers import AutoModelForSequenceClassification
model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
pt_model = AutoModelForSequenceClassification.from_pretrained(model_name)
# TensorFlow
from transformers import TFAutoModelForSequenceClassification
model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
tf_model = TFAutoModelForSequenceClassification.from_pretrained(model_name)
通过 任务摘要 查找 AutoModel 支持的任务.
现在可以把之前预处理好的输入批次直接传递模型。你需要通过 ** 来解包字典:
# Pytorch
pt_outputs = pt_model(**pt_batch)
# TensorFlow
tf_outputs = tf_model(**tf_batch)
logits
- 定义:logits是模型输出的原始分数,通常是通过一个线性层(全连接层)得到的。这些分数在没有经过任何激活函数处理之前,表示模型对每个类别的原始预测值。
- 作用:logits本身并不直接表示概率,而是需要通过激活函数(如softmax)转换为概率。 激活结果
- 定义:激活结果通常是指将logits通过激活函数(如softmax、sigmoid等)处理后的输出。激活函数的作用是将logits转换为某种形式的概率或决策边界。
- 作用:激活函数可以使模型的输出更易于解释和使用。例如,softmax函数可以将logits转换为多类分类任务中的概率分布。
模型在 pt_outputs.logits 输出最终的激活结果. 这里在 logits 上应用 softmax 函数来查询概率:
dim = -1:表示在最后一个维度上进行softmax操作,通常在多类分类任务中,最后一个维度是类别维度。- 在多类分类任务中,softmax 函数将 logits 转换为概率分布,能够帮助我们了解模型对每个类别的预测置信度,从而做出更准确的决策。
# Pytorch
from torch import nn
pt_predictions = nn.functional.softmax(pt_outputs.logits, dim=-1)
print(pt_predictions)
pt_predictions 是一个概率分布,每个元素表示对应类别的概率,每个类别的概率值表示模型对该类别的置信度。
# TensorFlow
import tensorflow as tf
tf_predictions = tf.nn.softmax(tf_outputs.logits, dim=-1)
print(tf_predictions)
所有 🤗 Transformers 模型(PyTorch 或 TensorFlow)在最终的激活函数(比如 softmax)之前输出张量, 因为最终的激活函数常常与损失(loss)融合。
模型的输出是特殊的数据类,所以它们的属性可以在 IDE 中被自动补全。模型的输出就像一个元组或字典(你可以通过整数、切片或字符串来索引它),为 None 的属性会被忽略。
保存模型¶
当你的模型微调完成(预训练完成),可以使用 PreTrainedModel.save_pretrained() 把模型和模型的分词器保存下来:
# Pytorch
pt_save_directory = "./pt_save_pretrained"
tokenizer.save_pretrained(pt_save_directory)
pt_model.save_pretrained(pt_save_directory)
# TensorFlow
tf_save_directory = "./tf_save_pretrained"
tokenizer.save_pretrained(tf_save_directory)
tf_model.save_pretrained(tf_save_directory)
再次使用这个模型时,可以使用 PreTrainedModel.from_pretrained() 加载它:
# Pytorch
pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained")
# TensorFlow
tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained")
🤗 Transformers 有一个特别酷的功能,保存一个模型后,在加载时可以选择地将它加载为 PyTorch 或 TensorFlow 模型。from_pt 或 from_tf 参数可以将模型从一个框架转换为另一个框架:
# TensorFlow To Pytorch
from transformers import AutoModelForSequenceClassification
tokenizer = AutoTokenizer.from_pretrained(tf_save_directory)
pt_model = AutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True) # from_tf 将 TensorFlow 模型加载为 PyTorch 模型
# Pytorch To TensorFlow
from transformers import TFAutoModelForSequenceClassification
tokenizer = AutoTokenizer.from_pretrained(pt_save_directory)
tf_model = TFAutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True)
自定义模型构建¶
你可以修改模型的配置类来改变模型的构建方式。配置模型的属性,比如隐藏层或者注意力头的数量。当你根据自定义的配置类初始化模型时,模型的属性都是随机初始化的,你需要先训练模型才能得到有意义的结果。
自定义模型构建通过导入 AutoConfig 来加载你想修改的预训练模型。在 AutoConfig.from_pretrained() 中,你能够指定想要修改的属性,比如注意力头的数量:
from transformers import AutoConfig
my_config = AutoConfig.from_pretrained("distilbert/distilbert-base-uncased", n_heads=12)
使用 AutoModel.from_config() 根据你的自定义配置创建一个模型:
# Pytorch
from transformers import AutoModel
my_model = AutoModel.from_config(my_config)
# TensorFlow
from transformers import TFAutoModel
my_model = TFAutoModel.from_config(my_config)
Trainer - PyTorch 优化训练循环¶
所有的模型都是标准的 [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module),所以你可以在任何典型的训练模型中使用它们。
当你编写自己的训练循环时,🤗 Transformers 为 PyTorch 提供了一个 Trainer 类,它包含了基础的训练循环并且为诸如分布式训练,混合精度等特性增加了额外的功能。
根据于你的任务, 你可以传递以下的参数给 Trainer:
- 使用
PreTrainedModel或者torch.nn.Module来开始:
# Pytorch
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased")
TrainingArguments含有你可以修改的模型超参数,比如学习率,批次大小和训练时的迭代次数。如果你没有指定训练参数,那么它会使用默认值:
# Pytorch
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,
)
- 加载一个预处理类,比如分词器,特征提取器或者处理器:
# Pytorch
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased")
- 加载一个数据集:
from datasets import load_dataset
dataset = load_dataset("rotten_tomatoes") # doctest: +IGNORE_RESULT
- 创建一个给数据集用于分词的函数,并且使用
map将分词器应用到整个数据集:
def tokenize_dataset(dataset):
return tokenizer(dataset["text"])
dataset = dataset.map(tokenize_dataset, batched=True)
- 创建一个数据集预处理工具
DataCollatorWithPadding
DataCollatorWithPadding是一个高效的数据预处理工具,能够自动处理批次数据的填充和掩码生成,极大地简化了NLP任务中的数据预处理步骤。通过使用这个类,可以确保模型输入的一致性,提高训练效率。
from transformers import DataCollatorWithPadding
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
现在把所有的类传给 Trainer:
# Pytorch
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,
)
# 一切准备就绪后,调用 train() 进行训练
trainer.train()
对于像翻译或摘要这些使用序列到序列模型的任务,用 Seq2SeqTrainer 和 Seq2SeqTrainingArguments 来替代。
自定义训练循环¶
你可以通过子类化 Trainer 并重写其中的方法来自定义训练循环。这样你就可以自定义像损失函数,优化器和调度器等这样的特性。查阅 Trainer 参考手册了解哪些方法能够被子类化。
另一个自定义训练循环的方式是通过回调(Callbacks)。你可以使用回调来与其他库集成,查看训练循环来报告进度或提前结束训练。
注意:回调并不会修改训练循环。如果想自定义损失函数等,就需要子类化 Trainer 了。
使用 Tensorflow 训练¶
所有模型都是标准的 tf.keras.Model,所以你可以通过 Keras API 实现在 Tensorflow 中训练。
🤗 Transformers 提供了 prepare_tf_dataset() 方法来轻松地将数据集加载为 tf.data.Dataset,这样你就可以使用 Keras 的 compile 和 fit 方法马上开始训练。
- 使用
TFPreTrainedModel或者tf.keras.Model来开始:
# TensorFlow
from transformers import TFAutoModelForSequenceClassification
model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased")
- 加载一个数据集
from datasets import load_dataset
dataset = load_dataset("rotten_tomatoes")
- 加载一个预处理类,比如分词器,特征提取器或者处理器:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased")
- 创建一个给数据集用于分词的函数,并且使用
map将分词器应用到整个数据集:
def tokenize_dataset(dataset):
return tokenizer(dataset["text"])
dataset = dataset.map(tokenize_dataset, batched=True)
- 将数据集和分词器传给
prepare_tf_dataset()对数据集进行预处理。如果你需要的话,也可以在这里改变批次大小和是否打乱数据集
# TensorFlow
tf_dataset = model.prepare_tf_dataset(
dataset, batch_size=16, shuffle=True, tokenizer=tokenizer
)
- 一切准备就绪后,调用
compile和fit开始训练:
# TensorFlow
from transformers.keras.optimizers import Adam
model.compile(optimizer=Adam(3e-5))
model.fit(dataset)
接下来做什么¶
现在你已经完成了 🤗 Transformers 的快速上手教程,来看看我们的指南并且学习如何做一些更具体的事情,比如写一个自定义模型,为某个任务微调一个模型以及如何使用脚本来训练模型。
如果你有兴趣了解更多 🤗 Transformers 的核心章节,那就喝杯咖啡然后来看看我们的概念指南吧!