AI应用开发 - Hugging Face入门
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) |
token | HuggingFace token,用于私有模型 |
trust_remote_code | 是否执行 Hub 上的自定义代码(默认 False,谨慎使用) |
注意:
device和device_map不能同时使用,会产生冲突。
支持的任务类型
文本类
| 任务名 | 别名 | 说明 |
|---|---|---|
text-classification | sentiment-analysis | 文本分类/情感分析 |
text-generation | - | 文本生成 |
fill-mask | - | 掩码填充 |
token-classification | ner | 命名实体识别 |
question-answering | - | 问答 |
table-question-answering | - | 表格式问答 |
zero-shot-classification | - | 零样本分类 |
语音类
| 任务名 | 别名 | 说明 |
|---|---|---|
audio-classification | - | 音频分类 |
automatic-speech-recognition | - | 语音识别(ASR) |
text-to-audio | text-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]
参考
更多推荐

所有评论(0)