Transformers Pipelines

This content was generated with the assistance of AI and should be verified against the official documentation of each tool and framework before being relied on in production.

This section’s bibliography lists the reference material consulted while preparing these pages.

This page was written against transformers 5.17.0 and its documentation as checked on 2026-09-30. The pipeline() function is the shortest route from a Hub model ID to a prediction: it downloads the model, picks the right pre-processor and post-processor for the task, runs the model and returns plain Python objects. It is the tool to reach for when you explore a model; when you need control over batching, generation or memory, you drop down to the Auto* classes described further down. Python 3.10 or later and PyTorch are assumed: transformers v5 is PyTorch-only.

How a pipeline works

A pipeline chains three stages: pre-processing (tokenizer, feature extractor or image processor turns raw text, audio or pixels into tensors), the model forward pass (or generate() for generative models) and post-processing (logits become labels, token IDs become text). You choose the stage set with a task identifier; every task has a default model, but you should always pass model= explicitly so the behaviour is reproducible.

The shape of every pipeline call
from transformers import pipeline

classifier = pipeline(task="image-classification", model="google/vit-base-patch16-224")
print(classifier("cat.jpg", top_k=3))   # a path, URL or PIL image

Inputs can be a file path, a URL or an in-memory object; a list of inputs returns a list of results. Task-specific keyword arguments (top_k, threshold, candidate_labels, return_timestamps) go on the call, and arguments for generate() go in generate_kwargs. Everything in this section is downloaded from the Hub on first use, so the repository must be one you trust: pipelines load safetensors when they exist, and only models that ship custom code need trust_remote_code=True, which runs the author’s Python on your machine (see Model Formats).

Speech recognition: automatic-speech-recognition

The automatic-speech-recognition task turns audio into text. Whisper-family models are the usual choice; the pipeline resamples the audio to the model’s rate (ffmpeg must be installed to decode compressed files) and can split long recordings into chunks.

Transcribing a spoken question with Whisper large-v3-turbo (MIT licence)
import torch
from transformers import pipeline

asr = pipeline(
    task="automatic-speech-recognition",
    model="openai/whisper-large-v3-turbo",
    dtype=torch.float16,
)
result = asr(
    "question.wav",
    return_timestamps=True,          # "word" for per-word timestamps
    generate_kwargs={"language": "english"},
)
print(result["text"])

For long files chunk_length_s=30 splits the audio, but the library documents chunking with Whisper as experimental and recommends the model’s own long-form generate() route for best accuracy (see the AutoModelForSpeechSeq2Seq example below); return_timestamps adds a chunks list. A smaller model such as openai/whisper-tiny.en (Apache-2.0) is enough for a first test. Other speech models and the faster runtimes are compared on Speech Models: STT & TTS.

Speech synthesis: text-to-audio

The text-to-audio task (alias text-to-speech) generates a waveform from text. The pipeline returns a dictionary with the samples (audio, a NumPy float array, squeezed to one dimension for mono output) and their sampling_rate; you write or play it yourself.

Generating speech with Bark small (MIT licence) and saving it as WAV
import scipy.io.wavfile as wavfile
from transformers import pipeline

tts = pipeline(task="text-to-speech", model="suno/bark-small")
out = tts("The documentation assistant is now running offline.")

wavfile.write("answer.wav", rate=out["sampling_rate"], data=out["audio"].squeeze())

Not every TTS model is wired into the pipeline: check the model card for a transformers snippet. Kokoro-82M, for example, has its own kokoro package. Licences differ widely (facebook/mms-tts-eng is CC-BY-NC-4.0), so check the card before shipping. Generation options (do_sample, temperature, max_new_tokens) go in generate_kwargs.

Image classification: image-classification

The image-classification task assigns one of the model’s fixed labels to an image and returns the best top_k as label and score pairs. Scores are softmax probabilities by default (function_to_apply changes that).

Classifying an image with a Vision Transformer (Apache-2.0)
from transformers import pipeline

clf = pipeline(task="image-classification", model="google/vit-base-patch16-224")
for item in clf("screenshot.png", top_k=3):
    print(f"{item['label']}: {item['score']:.3f}")

The label set is whatever the checkpoint was trained on; for arbitrary labels use the zero-shot variant.

Open-vocabulary classification: zero-shot-image-classification

The zero-shot-image-classification task compares an image with text labels you supply at call time, using a contrastive model such as CLIP or SigLIP 2. There is no retraining: changing the label list changes the classifier.

Classifying a screenshot into your own categories with SigLIP 2 (Apache-2.0)
from transformers import pipeline

zs = pipeline(
    task="zero-shot-image-classification",
    model="google/siglip2-base-patch16-224",
)
result = zs(
    "screenshot.png",
    candidate_labels=["error dialog", "code editor", "settings page", "chart"],
)
print(result[0])   # best label first

Phrase labels the way the model’s card suggests (for example "a photo of a …​" through hypothesis_template), because prompt wording changes scores.

Detection: object-detection

The object-detection task returns a list of score, label and box (xmin, ymin, xmax, ymax in pixels) entries for each object above threshold. RT-DETR v2 is an Apache-2.0 real-time detector.

Detecting objects with RT-DETR v2 (Apache-2.0)
from transformers import pipeline

detector = pipeline(task="object-detection", model="PekingU/rtdetr_v2_r18vd")
for det in detector("street.jpg", threshold=0.5):
    print(det["label"], round(det["score"], 2), det["box"])

The classic facebook/detr-resnet-50 (Apache-2.0) works the same way. The pipeline also offers zero-shot-object-detection for detection with free-text labels.

Segmentation: image-segmentation

The image-segmentation task returns a list of segments, each with a label, an optional score and a mask (a PIL image the size of the input). Depending on the model the segments are semantic, instance or panoptic; models that support several modes accept subtask=.

Panoptic segmentation with DETR (Apache-2.0)
from transformers import pipeline

segmenter = pipeline(task="image-segmentation", model="facebook/detr-resnet-50-panoptic")
for seg in segmenter("street.jpg"):
    print(seg["label"], seg["score"], seg["mask"].size)
    seg["mask"].save(f"mask-{seg['label']}.png")

Check the licence of each checkpoint: several segmentation models on the Hub (for example some SegFormer and Mask2Former checkpoints) carry a custom licence tag rather than Apache-2.0.

Segment anything: mask-generation

The mask-generation task runs a promptless "segment everything" pass with a SAM-style model: it proposes masks for all objects it finds, without class labels. It is the pipeline behind automatic masks in SAM demos.

Automatic mask generation with SAM (Apache-2.0)
from transformers import pipeline

generator = pipeline(task="mask-generation", model="facebook/sam-vit-base")
outputs = generator("street.jpg", points_per_batch=64)

print(len(outputs["masks"]), "masks")
print(outputs["scores"][:5])

points_per_batch controls how many prompt points are processed at once and therefore peak memory. Prompted segmentation (points or boxes) uses the model class and processor directly; the catalogue of SAM generations is in Vision Models.

Vision-language chat: image-text-to-text

The image-text-to-text task feeds an image and a prompt to a vision-language model and returns generated text. It takes chat-style messages whose content is a list of typed parts; in v5 the image must be embedded in the message content, not passed as a separate argument next to a chat. In v5 this task replaces the removed image-to-text and visual-question-answering pipelines (see the migration section).

Describing a screenshot with SmolVLM-256M-Instruct (Apache-2.0)
from transformers import pipeline

vlm = pipeline(task="image-text-to-text", model="HuggingFaceTB/SmolVLM-256M-Instruct")
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image", "url": "https://example.com/screenshot.png"},
            {"type": "text", "text": "Describe this screenshot in one sentence."},
        ],
    }
]
out = vlm(text=messages, max_new_tokens=64, return_full_text=False)
print(out[0]["generated_text"])

Keyword names for the prompt have changed between minor releases, so confirm the call signature on the pipeline’s API page for your installed version.

Text generation: text-generation

The text-generation task continues a prompt with a causal language model. Given chat messages it applies the model’s chat template automatically, and the result contains the whole conversation, with the assistant’s reply last.

Chatting with Qwen3-0.6B (Apache-2.0)
from transformers import pipeline

gen = pipeline(task="text-generation", model="Qwen/Qwen3-0.6B", device_map="auto")
messages = [{"role": "user", "content": "Give me one sentence about safetensors."}]
out = gen(messages, max_new_tokens=128)
print(out[0]["generated_text"][-1]["content"])

With a plain string prompt, return_full_text=False returns only the new text, and num_return_sequences with do_sample=True produces several samples. Some models, such as Qwen3, emit a reasoning block first; see the model card for how to switch it off. Gemma checkpoints (for example google/gemma-3-1b-it) are gated: accept the licence on the Hub and authenticate with $HF_TOKEN or hf auth login first, as described in Hub Essentials. For serving a model to many users, pipelines are the wrong tool; see vLLM and SGLang.

Tasks no longer available as pipelines

The v5 pipeline reference lists, among others, audio-classification, depth-estimation, feature-extraction, fill-mask, text-classification, token-classification, zero-shot-classification and video-classification. The v5 migration guide states that the question-answering, summarization, translation, image-to-text, visual-question-answering and image-to-image pipelines were removed. For those tasks load the model with the matching Auto* class (or use a chat model through text-generation or image-text-to-text). The pipeline documentation still mentions a few of these names in places, so when a task identifier raises an error, the list on the API page for your installed version is authoritative.

Auto* classes and processors

A pipeline hides three objects that you can also create yourself. The Auto* classes read config.json in the repository and instantiate the right architecture, so your code does not name it. AutoModel returns the bare network (hidden states); AutoModelFor…​ classes add a task head (AutoModelForCausalLM, AutoModelForSequenceClassification, AutoModelForSpeechSeq2Seq, AutoModelForImageClassification, AutoModelForImageTextToText). Pre-processing objects come from AutoTokenizer for text, AutoImageProcessor and AutoFeatureExtractor for pixels and audio, and AutoProcessor, which bundles whichever of them a multimodal model needs behind one object.

Loading a chat model and running generation without a pipeline
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "Qwen/Qwen3-0.6B"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, dtype="auto", device_map="auto")

messages = [{"role": "user", "content": "Name two Hub model formats."}]
inputs = tokenizer.apply_chat_template(
    messages, add_generation_prompt=True, return_tensors="pt", return_dict=True
).to(model.device)

with torch.inference_mode():
    output_ids = model.generate(**inputs, max_new_tokens=96)

reply = tokenizer.decode(output_ids[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
print(reply)

For vision-language and speech models the same pattern uses AutoProcessor, which turns images, audio and text into the model’s inputs and decodes its outputs.

Preparing speech input with AutoProcessor and AutoModelForSpeechSeq2Seq
import torch
from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor

model_id = "openai/whisper-large-v3-turbo"
processor = AutoProcessor.from_pretrained(model_id)
model = AutoModelForSpeechSeq2Seq.from_pretrained(model_id, dtype=torch.float16, device_map="auto")

# `samples` is a 16 kHz mono float array, for example loaded with soundfile or librosa
inputs = processor(samples, sampling_rate=16000, return_tensors="pt").to(model.device, torch.float16)
ids = model.generate(**inputs)
print(processor.batch_decode(ids, skip_special_tokens=True)[0])

Use this route when you need custom decoding, your own batching or to hand the model to another library. Save what you load with save_pretrained() (safetensors) to keep an offline copy.

Device and dtype

Device. When device is unset, a pipeline places the model on the first available accelerator (CUDA, Apple silicon MPS, XPU) and falls back to the CPU; pass device="cpu" to force the CPU, device=0 for the first GPU or device="mps" for Apple silicon. device_map="auto" hands placement to Accelerate, which fills the fastest device first and spills the rest to CPU RAM and disk; it needs accelerate installed and is the option for models larger than one GPU. Do not combine device and device_map.

dtype. The dtype argument sets the PyTorch data type of the weights. By default from_pretrained() uses the value stored in the model’s config.json and otherwise the dtype of the first floating-point weight in the checkpoint, so a checkpoint saved in bfloat16 is no longer silently upcast to float32. Pass dtype=torch.bfloat16 where the hardware supports it (more range) or torch.float16 to halve memory against float32, and dtype="auto" to ask for the stored dtype explicitly. The former name torch_dtype is still accepted as a legacy alias; write dtype in new code.

Choosing device, dtype and quantization when creating a pipeline
import torch
from transformers import BitsAndBytesConfig, pipeline

# Apple silicon
pipe_mps = pipeline("text-generation", model="Qwen/Qwen3-0.6B", device="mps", dtype=torch.float16)

# One or more NVIDIA GPUs, weights spread by Accelerate
pipe_gpu = pipeline("text-generation", model="Qwen/Qwen3-0.6B", device_map="auto", dtype=torch.bfloat16)

# 8-bit weights through bitsandbytes (CUDA)
pipe_q = pipeline(
    "text-generation",
    model="Qwen/Qwen3-0.6B",
    device_map="auto",
    model_kwargs={"quantization_config": BitsAndBytesConfig(load_in_8bit=True)},
)

Batching is off by default; batch_size=N may help on a GPU with regular input lengths and rarely helps on a CPU or when latency matters, so measure. Quantization options are compared in Quantization for Inference, and memory estimates in Hardware Sizing.

transformers serve

transformers serve starts a local HTTP server that speaks the OpenAI API, so existing OpenAI SDK code, curl and tools that accept a custom base URL can talk to a Hub model loaded through transformers. It is meant for evaluation, experiments and moderate load, not for large-scale production; the documentation points to vLLM or SGLang with transformers as the backend for that. Install the extra, then start it; the default address is http://localhost:8000.

Starting the server and calling it with the OpenAI client
pip install "transformers[serving]"

# Pin one model; --dtype and --continuous-batching are optional
transformers serve Qwen/Qwen3-0.6B --dtype bfloat16 --continuous-batching
from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")
resp = client.chat.completions.create(
    model="Qwen/Qwen3-0.6B",
    messages=[{"role": "user", "content": "Say hello in five words."}],
)
print(resp.choices[0].message.content)

The server exposes /v1/chat/completions (text, image, audio and video inputs), /v1/completions, /v1/responses, /v1/audio/transcriptions (multipart upload with a speech model such as Whisper), /v1/models and /load_model, which streams loading progress. Without a model argument, models load on demand and are unloaded after 300 seconds of inactivity (--model-timeout changes it, -1 disables unloading). The local server has no authentication and binds to localhost by default; if you expose it, put it behind a reverse proxy with authentication or an SSH tunnel. Compare it with the other local servers in Ollama and vLLM and SGLang; for Spring applications the endpoint plugs into Spring AI through its OpenAI integration.

Migrating from v4 to v5

Code written for the books and tutorials of the v4 era often needs small edits. The changes that matter most for the code on this page are below; the official guide lists the rest.

v4 habit v5 behaviour

TensorFlow and Flax models, TF* and Flax* classes

Removed: transformers is PyTorch-only

Separate slow and fast tokenizer classes, use_fast

One tokenizer implementation per model; encode_plus() is deprecated in favour of calling the tokenizer, and decode() now accepts batches too; batch_decode() stays available (on tokenizers and processors) for backwards compatibility, which is why model-card examples on these pages still call it

torch_dtype=…​

dtype=…​; weights load in their stored dtype by default

use_auth_token=…​

token=…​

load_in_8bit=True, load_in_4bit=True on from_pretrained()

Removed: pass quantization_config=BitsAndBytesConfig(…​)

apply_chat_template() returning input_ids

Returns a BatchEncoding; pass return_dict=True and unpack it into generate()

pipeline("summarization"), "translation", "question-answering", "image-to-text", "visual-question-answering"

Pipelines removed: use text-generation or image-text-to-text with a chat model, or an Auto* class

AutoModelWithLMHead

Removed: use AutoModelForCausalLM, AutoModelForMaskedLM or AutoModelForSeq2SeqLM

save_pretrained(safe_serialization=False)

Not accepted: safetensors only; default shard size is larger

TRANSFORMERS_CACHE and other legacy cache variables

Removed: use HF_HOME and HF_HUB_CACHE

A v4 snippet and its v5 form
# v4
# model = AutoModelForCausalLM.from_pretrained(
#     model_id, torch_dtype=torch.float16, load_in_8bit=True, use_auth_token=True)

# v5
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

model = AutoModelForCausalLM.from_pretrained(
    model_id,
    dtype="auto",
    device_map="auto",
    quantization_config=BitsAndBytesConfig(load_in_8bit=True),
    token=True,   # use the token saved by `hf auth login` or $HF_TOKEN
)

Pin transformers in requirements.txt (for example transformers>=5,<6) and run your tests after each minor upgrade: pipeline signatures and task lists still change between v5 minors.