使用 Pipelines 进行推理教程

pipeline() 提供了在任何语言、计算机视觉、音频和多模态任务上使用 Hub 中的任何模型进行推理的简单方法。即使您对某个具体模态没有经验或者不熟悉模型背后的代码,您仍然可以使用 pipeline() 进行推理!本教程将教您:

  • 使用 pipeline() 进行推理。
  • 使用特定的 tokenizer 或模型。
  • pipeline() 用于音频,视觉和多模态任务。

查看 pipeline() 的文档,了解支持的任务和可用参数的完整列表。

使用 Pipeline

每个任务都有一个相关联的 pipeline(),但使用通用的 pipeline() 抽象更简单,它包含了所有特定任务的 pipelines。pipeline() 会自动加载一个默认模型和一个能够对您的任务进行推理的预处理类。

  1. 首先创建一个 pipeline() 并指定一个推理任务:
>>> from transformers import pipeline

>>> generator = pipeline(task="automatic-speech-recognition")
  1. 将输入文本传递给 pipeline()
>>> generator("https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/mlk.flac")
{'text': 'I HAVE A DREAM BUT ONE DAY THIS NATION WILL RISE UP LIVE UP THE TRUE MEANING OF ITS TREES'}

不是您想要的结果?在 Hub 上查看一些 下载量最多的自动语音识别模型 ,看看是否可以获得更好的转录结果。让我们尝试一下 openai/whisper-large

>>> generator = pipeline(model="openai/whisper-large")
>>> generator("https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/mlk.flac")
{'text': ' I have a dream that one day this nation will rise up and live out the true meaning of its creed.'}

现在这个结果看起来更准确了!我们真的鼓励您在 Hub 上查找不同语言的模型,专门针对您领域的模型等。您可以直接从浏览器在 Hub 上查看和比较模型结果,看看它是否适合或是否比其他模型更好地处理了边缘情况。如果您找不到适用于您的用例的模型,您总可以自己 训练 模型!

如果您有多个输入,可以将输入作为列表传递给它:

generator(
    [
        "https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/mlk.flac",
        "https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/1.flac",
    ]
)

如果您想对整个数据集进行迭代,或者想在 Web 服务器中使用它进行推理,请查看专用部分

在数据集上使用 pipelines

在 Web 服务器上使用 pipelines

参数

pipeline() 支持许多参数;有些是针对特定任务的,有些是通用的。通常您可以在任何地方指定参数:

generator = pipeline(model="openai/whisper-large", my_parameter=1)
out = generator(...)  # This will use `my_parameter=1`.
out = generator(..., my_parameter=2)  # This will override and use `my_parameter=2`.
out = generator(...)  # This will go back to using `my_parameter=1`.

让我们看看其中三个重要的参数:

设备

如果您使用 device=npipeline() 会自动将模型放在指定的设备上。无论您使用的是 PyTorch 还是 TensorFlow,这都可以正常工作。

generator = pipeline(model="openai/whisper-large", device=0)

如果模型对于单个 GPU 来说太大,您可以设置 device_map="auto",让 🤗 Accelerate 自动确定如何加载和存储模型权重。

#!pip install accelerate
generator = pipeline(model="openai/whisper-large", device_map="auto")

注意,如果传递了 device_map="auto",那么在实例化 pipeline 时,不需要添加 device=device 参数,否则可能会遇到一些意外的行为!

批处理大小

默认情况下,pipelines 不会对推理进行批处理,原因在 这里 有详细解释。原因是批处理未必更快,实际上在某些情况下可能更慢。

但如果在您的用例中起作用,您可以使用:

generator = pipeline(model="openai/whisper-large", device=0, batch_size=2)
audio_filenames = [f"audio_{i}.flac" for i in range(10)]
texts = generator(audio_filenames)

这将在 10 个提供的音频文件上运行 pipeline,但它将将它们分批传递给模型(模型是在 GPU 上,批处理更有可能有助于)而无需您的任何其他代码。输出应该始终与您没有进行批处理时收到的相同。这只是一种帮助您从 pipeline 中获得更快速度的方法。

pipelines 还可以缓解批处理的某些复杂性,因为对于部分 pipelines 来说,单个项(比如一个长音频文件)需要被分成多个部分,以便由模型处理。pipeline 会为您执行这个 chunk batching

任务特定参数

所有任务都提供任务特定参数,它们允许额外的灵活性和选项,以帮助您完成工作。例如,transformers.AutomaticSpeechRecognitionPipeline.__call__() 方法具有一个 return_timestamps 参数,对于为视频制作字幕来说很有帮助:

>>> # 这里没用使用 whisper 模型,因为 whisper 不支持 timestamps.
>>> generator = pipeline(model="facebook/wav2vec2-large-960h-lv60-self", return_timestamps="word")
>>> generator("https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/mlk.flac")
{'text': 'I HAVE A DREAM BUT ONE DAY THIS NATION WILL RISE UP AND LIVE OUT THE TRUE MEANING OF ITS CREED', 'chunks': [{'text': 'I', 'timestamp': (1.22, 1.24)}, {'text': 'HAVE', 'timestamp': (1.42, 1.58)}, {'text': 'A', 'timestamp': (1.66, 1.68)}, {'text': 'DREAM', 'timestamp': (1.76, 2.14)}, {'text': 'BUT', 'timestamp': (3.68, 3.8)}, {'text': 'ONE', 'timestamp': (3.94, 4.06)}, {'text': 'DAY', 'timestamp': (4.16, 4.3)}, {'text': 'THIS', 'timestamp': (6.36, 6.54)}, {'text': 'NATION', 'timestamp': (6.68, 7.1)}, {'text': 'WILL', 'timestamp': (7.32, 7.56)}, {'text': 'RISE', 'timestamp': (7.8, 8.26)}, {'text': 'UP', 'timestamp': (8.38, 8.48)}, {'text': 'AND', 'timestamp': (10.08, 10.18)}, {'text': 'LIVE', 'timestamp': (10.26, 10.48)}, {'text': 'OUT', 'timestamp': (10.58, 10.7)}, {'text': 'THE', 'timestamp': (10.82, 10.9)}, {'text': 'TRUE', 'timestamp': (10.98, 11.18)}, {'text': 'MEANING', 'timestamp': (11.26, 11.58)}, {'text': 'OF', 'timestamp': (11.66, 11.7)}, {'text': 'ITS', 'timestamp': (11.76, 11.88)}, {'text': 'CREED', 'timestamp': (12.0, 12.38)}]}

正如您所见,模型推理出了文本,并输出了句子中各个单词的发音时间。

每个任务都有许多可用参数,请查看每个任务的 API 参考,了解您可以自己玩弄的内容!例如,~ transformers.AutomaticSpeechRecognitionPipeline 有一个 chunk_length_s 参数,对于处理非常长的音频文件(例如为整个电影或长达一小时的视频制作字幕)非常有帮助,这是模型通常无法独自处理的。

如果找不到真正能帮助您的参数,请随时 提出请求

在数据集上使用 pipelines

pipeline 也可以在大型数据集上运行推理。我们建议使用迭代器来完成这个任务。

def data():
    for i in range(1000):
        yield f"My example {i}"


pipe = pipeline(model="gpt2", device=0)
generated_characters = 0
for out in pipe(data()):
    generated_characters += len(out[0]["generated_text"])

data() 迭代器会生成每个结果,并且 pipeline 会自动识别输入是可迭代的,并在继续处理 GPU 上的数据时开始获取数据(在内部使用 DataLoader )。这很重要,因为您不需要为整个数据集分配内存,而且可以尽可能快地将数据提供给 GPU。

由于批处理可能会加快速度,所以在这里尝试调整 batch_size 参数可能会很有用。

迭代数据集的最简单方法是从 🤗 Datasets 加载一个:

# 使用 KeyDataset 来输出我们需要的数据项
from transformers.pipelines.pt_utils import KeyDataset
from datasets import load_dataset

pipe = pipeline(model="hf-internal-testing/tiny-random-wav2vec2", device=0)
dataset = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation[:10]")

for out in pipe(KeyDataset(dataset, "audio")):
    print(out)

使用 pipelines 构建 Web 服务器

创建一个推理引擎是一个复杂的主题,值得有专门的页面来介绍。

链接

视觉任务的 pipeline

对于视觉任务,使用 pipeline() 几乎是相同的。

指定您的任务并将图像传递给分类器。图像可以是链接或图像的本地路径。例如,下面显示的是哪个品种的猫?

pipeline-cat-chonk

>>> from transformers import pipeline

>>> vision_classifier = pipeline(model="google/vit-base-patch16-224")
>>> preds = vision_classifier(
...     images="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg"
... )
>>> preds = [{"score": round(pred["score"], 4), "label": pred["label"]} for pred in preds]
>>> preds
[{'score': 0.4335, 'label': 'lynx, catamount'}, {'score': 0.0348, 'label': 'cougar, puma, catamount, mountain lion, painter, panther, Felis concolor'}, {'score': 0.0324, 'label': 'snow leopard, ounce, Panthera uncia'}, {'score': 0.0239, 'label': 'Egyptian cat'}, {'score': 0.0229, 'label': 'tiger cat'}]

文本任务的 pipeline

对于自然语言处理(NLP)任务,使用 pipeline() 几乎是相同的。

>>> from transformers import pipeline

>>> # 该模型是一个 `zero-shot-classification (零样本分类)` 模型。
>>> # 它会对文本进行分类,您可以传入你能想到的任何标签
>>> classifier = pipeline(model="facebook/bart-large-mnli")
>>> classifier(
...     "I have a problem with my iphone that needs to be resolved asap!!",
...     candidate_labels=["urgent", "not urgent", "phone", "tablet", "computer"],
... )
{'sequence': 'I have a problem with my iphone that needs to be resolved asap!!', 'labels': ['urgent', 'phone', 'computer', 'not urgent', 'tablet'], 'scores': [0.504, 0.479, 0.013, 0.003, 0.002]}

多模态任务的 pipeline

pipeline() 支持多个模态。例如,视觉问答(VQA)任务将文本和图像结合起来。可以使用任何您喜欢的图像链接和要询问的问题。图像可以是 URL 或图像的本地路径。

例如,如果您使用这个 发票图像

>>> from transformers import pipeline

>>> vqa = pipeline(model="impira/layoutlm-document-qa")
>>> vqa(
...     image="https://huggingface.co/spaces/impira/docquery/resolve/2359223c1837a7587402bda0f2643382a6eefeab/invoice.png",
...     question="What is the invoice number?",
... )
[{'score': 0.42515, 'answer': 'us-001', 'start': 16, 'end': 16}]

要运行上面的示例,您还需要安装 pytesseract ,并且额外安装 🤗 Transformers:

sudo apt install -y tesseract-ocr
pip install pytesseract

结合 🤗 accelerate 在大型参数模型上使用 pipeline

您可以轻松地使用 🤗 accelerate 在大型模型上运行 pipeline!请确保您已经使用 pip install accelerate 安装了 accelerate

首先,使用 device_map="auto" 加载模型!我们将在示例中使用 facebook/opt-1.3b

# pip install accelerate
import torch
from transformers import pipeline

pipe = pipeline(model="facebook/opt-1.3b", torch_dtype=torch.bfloat16, device_map="auto")
output = pipe("This is a cool example!", do_sample=True, top_p=0.95)

如果安装了 bitsandbytes 并添加了参数 load_in_8bit=True,还可以传递 8 位加载的模型。

# pip install accelerate bitsandbytes
import torch
from transformers import pipeline

pipe = pipeline(model="facebook/opt-1.3b", device_map="auto", model_kwargs={"load_in_8bit": True})
output = pipe("This is a cool example!", do_sample=True, top_p=0.95)

注意,您可以将检查点(代码中的 model 参数) 替换为任何支持大模型加载的 Hugging Face 模型,例如 BLOOM!