Pipeline Function

概述

Pipeline 是 Hugging Face Transformers 库最实用的推理接口,它将复杂的模型调用代码抽象成简单的 API,让用户无需关注内部细节就能完成各种 AI 任务。

Pipeline 本质上是一个封装器,包含三个核心组件:

Pipeline
  ├── Preprocessing (tokenizer / image_processor / feature_extractor)
  ├── Model (PreTrainedModel)
  └── Postprocessing

基本用法

最简示例

from transformers import pipeline

# 情感分析(模型自动选择)
pipe = pipeline("sentiment-analysis")
pipe("This restaurant is awesome")
# [{'label': 'POSITIVE', 'score': 0.9998743534088135}]

指定模型

# 指定具体模型
pipe = pipeline(model="FacebookAI/roberta-large-mnli")
pipe("This restaurant is awesome")
# [{'label': 'NEUTRAL', 'score': 0.7313136458396912}]

# 也可以指定分词器
pipe = pipeline(
    "question-answering",
    model="distilbert/distilbert-base-cased-distilled-squad",
    tokenizer="google-bert/bert-base-cased"
)

批量处理

# 列表输入
pipe = pipeline("text-classification")
pipe(["This restaurant is awesome", "This restaurant is awful"])
# [{'label': 'POSITIVE', 'score': 0.9998743534088135},
#  {'label': 'NEGATIVE', 'score': 0.9996669292449951}]

# Dataset 输入(推荐用于大数据集)
import datasets
from transformers import pipeline
from transformers.pipelines.pt_utils import KeyDataset

pipe = pipeline("automatic-speech-recognition", model="facebook/wav2vec2-base-960h", device=0)
dataset = datasets.load_dataset("superb", name="asr", split="test")

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

# Generator 输入
pipe = pipeline("text-classification")

def data():
    while True:
        yield "This is a test"

for out in pipe(data()):
    print(out)

核心参数详解

参数说明
task任务名称,如 "text-classification", "sentiment-analysis", "ner"
model模型 ID(字符串)或 PreTrainedModel 实例
tokenizer分词器(可选,默认自动加载)
image_processor图像处理器(可选,用于视觉模型)
feature_extractor特征提取器(可选,用于语音模型)
device设备:"cpu", "cuda:0", "mps",或 device ordinal(如 0)
device_map"auto" 时自动计算最优设备映射(需安装 accelerate)
dtype精度:torch.float16, torch.bfloat16, "auto"
revision模型版本,可以是分支名、tag 或 commit id
use_fast是否使用 Fast tokenizer(默认 True)
tokenHuggingFace token,用于私有模型
trust_remote_code是否执行 Hub 上的自定义代码(默认 False,谨慎使用)

注意:device 和 device_map 不能同时使用,会产生冲突。

支持的任务类型

文本类

任务名别名说明
text-classificationsentiment-analysis文本分类/情感分析
text-generation-文本生成
fill-mask-掩码填充
token-classificationner命名实体识别
question-answering-问答
table-question-answering-表格式问答
zero-shot-classification-零样本分类

语音类

任务名别名说明
audio-classification-音频分类
automatic-speech-recognition-语音识别(ASR)
text-to-audiotext-to-speech文本转语音
zero-shot-audio-classification-零样本音频分类

图像类

任务名说明
image-classification图像分类
image-segmentation图像分割
depth-estimation深度估计
object-detection目标检测
zero-shot-object-detection零样本目标检测
video-classification视频分类

多模态

任务名说明
document-question-answering文档问答
zero-shot-image-classification零样本图像分类
image-text-to-text图文生成
feature-extraction特征提取

Batching 性能优化

性能实测

batching 在 GPU 环境下可带来显著加速:

# GTX 970 实测结果
Streaming no batching:     187.52 it/s
Streaming batch_size=8:    1205.95 it/s  (6.4x)
Streaming batch_size=64:   2478.24 it/s  (13x)
Streaming batch_size=256:  2554.43 it/s  (13.6x)

使用原则

何时使用 batching:

  • GPU 环境处理静态数据(离线批处理)
  • 序列长度整齐的数据
  • 吞吐量敏感场景

何时禁用 batching:

  • 延迟敏感场景(实时产品)
  • CPU 推理
  • 序列长度差异大的数据
# GPU batching 示例
from transformers import pipeline
from transformers.pipelines.pt_utils import KeyDataset
import datasets

dataset = datasets.load_dataset("imdb", name="plain_text", split="unsupervised")
pipe = pipeline("text-classification", device=0)

for out in pipe(KeyDataset(dataset, "text"), batch_size=8, truncation="only_first"):
    print(out)

潜在问题

当数据中序列长度差异很大时,batching 可能适得其反:

# 问题示例:偶尔出现超长句子
class MyDataset(Dataset):
    def __getitem__(self, i):
        if i % 64 == 0:
            n = 100  # 长句子
        else:
            n = 1    # 短句子
        return "This is a test" * n

此时整个 batch 会被 padding 到最大长度,导致内存占用激增甚至 OOM。

经验法则:

  • 用自己的硬件和数据测量实际性能
  • 启用 batching 时添加 OOM 恢复机制
  • 序列长度规则时可大胆增加 batch_size

Chunk Batching

对于 zero-shot-classification 和 question-answering 等单输入多 forward 的任务,Pipeline 使用 ChunkPipeline 机制自动处理:

# 原本的流程
preprocessed = pipe.preprocess(inputs)
model_outputs = pipe.forward(preprocessed)
outputs = pipe.postprocess(model_outputs)

# ChunkPipeline 的流程(对用户透明)
all_model_outputs = []
for preprocessed in pipe.preprocess(inputs):
    model_outputs = pipe.forward(preprocessed)
    all_model_outputs.append(model_outputs)
outputs = pipe.postprocess(all_model_outputs)

用户无需关心内部实现,调用方式完全一样。

FP16 推理

GPU 上使用 FP16 可以加速推理并节省显存:

pipe = pipeline("text-generation", device=0, dtype=torch.float16)

大多数模型使用 FP16 不会有明显性能损失,模型越大影响越小。

自定义 Pipeline

通过继承和 pipeline_class 参数扩展 Pipeline:

from transformers import pipeline, TextClassificationPipeline

class MyPipeline(TextClassificationPipeline):
    def postprocess(self, model_outputs):
        # 自定义后处理:分数乘以 100
        scores = model_outputs.scores * 100
        return [{"score": s} for s in scores]

# 方式一:直接实例化
my_pipe = MyPipeline(model="xxx", tokenizer=tokenizer)

# 方式二:通过 pipeline 函数
my_pipe = pipeline(model="xxx", pipeline_class=MyPipeline)

Pipeline 对象组成

Pipeline 本质上由三部分组成:

1. 预处理(Preprocessing)

  • 文本任务:Tokenizer(分词、padding、truncation)
  • 图像任务:ImageProcessor(resize、normalize)
  • 语音任务:FeatureExtractor(梅尔频谱等)

2. 模型推理(Model)

  • 加载 PreTrainedModel
  • 执行前向传播

3. 后处理(Postprocessing)

  • 将模型输出转换为可读结果(如 softmax、阈值过滤)

如果不手动指定 tokenizer/feature_extractor/image_processor,pipeline 会根据任务和模型自动加载。

实用代码模板

情感分析

from transformers import pipeline

pipe = pipeline("sentiment-analysis")
result = pipe("I love this product!")
# [{'label': 'POSITIVE', 'score': 0.9998}]

命名实体识别

from transformers import pipeline

pipe = pipeline("ner", model="dbmdz/bert-large-cased-finetuned-conll03-english")
result = pipe("Hugging Face is based in New York City")
# [{'entity': 'B-ORG', 'score': 0.99, 'word': 'Hugging', 'index': 1}, ...]

语音识别

from transformers import pipeline

pipe = pipeline("automatic-speech-recognition", model="openai/whisper-base")
result = pipe("audio.mp3")
# {'text': 'The recognized text...'}

图像分割

from transformers import pipeline

pipe = pipeline("image-segmentation", model="facebook/detr-resnet-50-panoptic")
result = pipe("image.jpg")
# [{'label': 'bird', 'mask': <PIL.Image>}, ...]

参考

HuggingFace Tasks

概述:什么是多模态?

多模态指融合多种感知输入(视觉、听觉、触觉等),模拟人类对世界的多感官认知。相比传统单模态 AI,多模态模型能实现更全面、更细致的理解。

典型的图文多模态模型架构:

图像-文本对输入
     ↓
文本编码器 ────→ 文本特征
     ↓
图像编码器 ────→ 图像特征
     ↓
多模态融合模块 ──→ 跨模态表示
     ↓
解码器 ────→ 最终输出

任务类型总览

任务输入输出典型模型
VQA / Visual Reasoning图像 + 问题文本答案BLIP-VQA, DePlot, VLIT
DocVQA文档图像 + 问题文本答案LayoutLM, Donut, Nougat
Image Captioning图像文本描述ViT-GPT2, BLIP, GIT
Image-Text Retrieval图像或文本文本或图像CLIP
Visual Grounding图像 + 文本描述边界框OWL-ViT, Grounding DINO
Text-to-Image文本描述图像Stable Diffusion XL

Visual Question Answering (VQA)

视觉问答让机器能"看懂"图像并回答相关问题。

任务定义:

  • 输入:图像 + 关于图像的问题
  • 输出:多选题(预定义选项)或开放题(自由格式自然语言答案)
  • 本质:大多数 VQA 模型将任务当作预定义答案的分类问题

Visual Reasoning 进一步要求模型理解物体关系、比较对象、理解场景上下文。

代表模型

BLIP-VQA(Salesforce):通过"Bootstrapping Language-Image Pre-training",利用噪声网络数据和标题生成达到 SOTA。

from PIL import Image
from transformers import pipeline

vqa_pipeline = pipeline(
    "visual-question-answering", model="Salesforce/blip-vqa-capfilt-large"
)

image = Image.open("elephant.jpeg")
question = "Is there an elephant?"

vqa_pipeline(image, question, top_k=1)

DePlot(Google):单样本视觉语言推理,将图表翻译成文本摘要,与 LLM 集成回答复杂数据问题。

from transformers import Pix2StructProcessor, Pix2StructForConditionalGeneration
import requests
from PIL import Image

processor = Pix2StructProcessor.from_pretrained("google/deplot")
model = Pix2StructForConditionalGeneration.from_pretrained("google/deplot")

url = "https://raw.githubusercontent.com/vis-nlp/ChartQA/main/ChartQA%20Dataset/val/png/5090.png"
image = Image.open(requests.get(url, stream=True).raw)

inputs = processor(
    images=image,
    text="Generate underlying data table of the figure below:",
    return_tensors="pt",
)
predictions = model.generate(**inputs, max_new_tokens=512)
print(processor.decode(predictions[0], skip_special_tokens=True))

VLIT(ViLT):无卷积、无区域监督的视觉-语言 Transformer,在 VQAv2 上微调后表现竞争力。

from transformers import ViltProcessor, ViltForQuestionAnswering
import requests
from PIL import Image

url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(url, stream=True).raw)
text = "How many cats are there?"

processor = ViltProcessor.from_pretrained("dandelin/vilt-b32-finetuned-vqa")
model = ViltForQuestionAnswering.from_pretrained("dandelin/vilt-b32-finetuned-vqa")

encoding = processor(image, text, return_tensors="pt")
outputs = model(**encoding)
logits = outputs.logits
idx = logits.argmax(-1).item()
print("Predicted answer:", model.config.id2label[idx])

Document Visual Question Answering (DocVQA)

文档视觉问答让机器能像人类一样"读"文档,结合计算机视觉和 NLP 处理文本和布局信息。

任务定义:

  • 输入:文档图像(扫描或数字格式)+ 自然语言问题
  • 输出:直接回答问题的文本
  • 能力:分析视觉元素和文本的布局关系,推理并生成准确答案

代表模型

LayoutLM(Microsoft):联合分析文档文本和布局(字体大小、位置、邻近关系),适合表单理解、收据分析、文档分类。

from transformers import pipeline
from PIL import Image

pipe = pipeline("document-question-answering", model="impira/layoutlm-document-qa")

question = "What is the purchase amount?"
image = Image.open("your-document.png")

pipe(image=image, question=question)
# [{'answer': '20,000$'}]

Donut(Naver):OCR-free 文档理解 Transformer,使用 Swin Transformer 编码器 + BART 解码器,端到端处理文档图像,避免 OCR 错误累积。

from transformers import pipeline
from PIL import Image

pipe = pipeline(
    "document-question-answering", model="naver-clova-ix/donut-base-finetuned-docvqa"
)

question = "What is the purchase amount?"
image = Image.open("your-document.png")

pipe(image=image, question=question)
# [{'answer': '20,000$'}]

Nougat(Meta):学术论文专用,在数百万学术论文上训练,可将扫描 PDF 转换为结构化标记语言,支持数学公式和表格。

from huggingface_hub import hf_hub_download
from PIL import Image
from transformers import NougatProcessor, VisionEncoderDecoderModel
import torch

processor = NougatProcessor.from_pretrained("facebook/nougat-base")
model = VisionEncoderDecoderModel.from_pretrained("facebook/nougat-base")

device = "cuda" if torch.cuda.is_available() else "cpu"
model.to(device)

filepath = hf_hub_download(
    repo_id="hf-internal-testing/fixtures_docvqa",
    filename="nougat_paper.png",
    repo_type="dataset",
)
image = Image.open(filepath)
pixel_values = processor(image, return_tensors="pt").pixel_values

outputs = model.generate(
    pixel_values.to(device),
    min_length=1,
    max_new_tokens=30,
    bad_words_ids=[[processor.tokenizer.unk_token_id]],
)

sequence = processor.batch_decode(outputs, skip_special_tokens=True)[0]
sequence = processor.post_process_generation(sequence, fix_markdown=False)
print(repr(sequence))

Image Captioning

图像描述生成,融合视觉和语言,将图像内容转化为自然语言描述。

任务定义:

  • 输入:图像(JPEG、PNG 等格式)
  • 输出:准确描述图像内容的单句或段落,包含物体、动作、关系和整体上下文
  • 流程:理解视觉内容 → 编码为有意义表示 → 解码为连贯语法正确的句子

代表模型

ViT-GPT2:Vision Transformer + GPT-2 组合,在 COCO 数据集上训练。

from transformers import pipeline

image_to_text = pipeline("image-to-text", model="nlpconnect/vit-gpt2-image-captioning")

image_to_text("https://ankur3107.github.io/assets/images/image-captioning-example.png")
# [{'generated_text': 'a soccer game with a player jumping to catch the ball '}]

BLIP Image Captioning:基于 BLIP 框架,通过自举过滤噪声标题,提高生成质量。

import requests
from PIL import Image
from transformers import BlipProcessor, BlipForConditionalGeneration

processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-large")
model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-large")

img_url = "https://storage.googleapis.com/sfr-vision-language-research/BLIP/demo.jpg"
raw_image = Image.open(requests.get(img_url, stream=True).raw).convert("RGB")

# 条件生成(有提示词)
text = "a photography of"
inputs = processor(raw_image, text, return_tensors="pt")
out = model.generate(**inputs)
print(processor.decode(out[0], skip_special_tokens=True))

# 无条件生成
inputs = processor(raw_image, return_tensors="pt")
out = model.generate(**inputs)
print(processor.decode(out[0], skip_special_tokens=True))

GIT(Microsoft):GenerativeImage2Text,Transformer 解码器同时接受图像和文本 token,预测下一个文本 token。

from transformers import AutoProcessor, AutoModelForCausalLM
import requests
from PIL import Image

processor = AutoProcessor.from_pretrained("microsoft/git-base-coco")
model = AutoModelForCausalLM.from_pretrained("microsoft/git-base-coco")

url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(url, stream=True).raw)

pixel_values = processor(images=image, return_tensors="pt").pixel_values
generated_ids = model.generate(pixel_values=pixel_values, max_length=50)
generated_caption = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(generated_caption)

Image-Text Retrieval

图文检索,像媒人一样匹配图像和描述,支持双向查询。

任务定义:

  • Image-to-text retrieval:给定图像,检索描述其内容的文本
  • Text-to-image retrieval:给定文本查询,检索视觉匹配的图像

代表模型

CLIP(OpenAI):通过对比学习将图像和文本映射到共享嵌入空间,支持零样本分类和跨模态检索。

from PIL import Image
import requests
from transformers import CLIPProcessor, CLIPModel

model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(url, stream=True).raw)

inputs = processor(
    text=["a photo of a cat", "a photo of a dog"],
    images=image,
    return_tensors="pt",
    padding=True,
)

outputs = model(**inputs)
logits_per_image = outputs.logits_per_image  # 图文相似度分数
probs = logits_per_image.softmax(dim=1)  # 转换为概率

Visual Grounding

视觉定位,理解语言如何引用图像中的特定区域,将文本描述对应到图像边界框。

任务定义:

  • 输入:图像 + 自然语言查询
  • 输出:查询对应对象的边界框或分割掩码

代表模型

OWL-ViT(Google):开放词汇目标检测,支持零样本和单样本检测,可识别训练时未见过的物体。

import requests
from PIL import Image
import torch
from transformers import OwlViTProcessor, OwlViTForObjectDetection

processor = OwlViTProcessor.from_pretrained("google/owlvit-base-patch32")
model = OwlViTForObjectDetection.from_pretrained("google/owlvit-base-patch32")

url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(url, stream=True).raw)
texts = [["a photo of a cat", "a photo of a dog"]]

inputs = processor(text=texts, images=image, return_tensors="pt")
outputs = model(**inputs)

target_sizes = torch.Tensor([image.size[::-1]])
results = processor.post_process_object_detection(
    outputs=outputs, threshold=0.1, target_sizes=target_sizes
)

i = 0
text = texts[i]
boxes, scores, labels = results[i]["boxes"], results[i]["scores"], results[i]["labels"]

for box, score, label in zip(boxes, scores, labels):
    box = [round(i, 2) for i in box.tolist()]
    print(f"Detected {text[label]} with confidence {round(score.item(), 3)} at location {box}")

Grounding DINO:结合 DINO Transformer 检测器和文本引导预训练,实现零样本目标检测,能识别完全新类别的物体。

Text-to-Image Generation

文本生成图像,用文字描述"画"出对应图像。

两条技术路线:

自回归模型

将图像当作"图像 token"序列,用类似语言模型的方式生成。图像 tokenizer(如 VQ-VAE)将图像切分为基本特征 token,编码器提取文本信息,解码器逐步预测图像 token。

  • 优势:控制性强,细节丰富
  • 劣势:处理长复杂提示词较慢

扩散模型(主流)

Stable Diffusion 采用"潜扩散"技术,通过逐步去噪生成图像,配合 CLIP 文本编码器引导生成方向。

  • 优势:生成速度快,图像质量高
  • 劣势:对复杂空间关系的控制较弱
# 安装 diffusers
# pip install diffusers transformers accelerate safetensors

from diffusers import DiffusionPipeline
import torch

pipe = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    torch_dtype=torch.float16,
    use_safetensors=True,
    variant="fp16",
)
pipe.to("cuda")

prompt = "An astronaut riding a unicorn"
images = pipe(prompt=prompt).images[0]

参考

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐