CoreMesh

Hugging Face Pipeline Tasks With Examples You Can Run

Hugging Face pipeline tasks with working code: text generation, sentiment analysis, speech recognition, image captioning, GPU or CPU selection, and batching.

Hugging Face Pipeline Tasks With Examples You Can Run

A Hugging Face pipeline is the one-call inference API in the Transformers library. You pick a task identifier such as text-generation or automatic-speech-recognition, name a model from the Hub, and call the returned object with your input. Tokenizing, running the model and decoding the result all happen inside that call.

As of October 18, 2026, the Transformers pipeline tutorial covers tasks across text, audio, image and multimodal inputs, plus parameters for picking a device, loading half-precision or quantized weights, and batching. The sections below list the task identifiers with working code for the common ones, then go through hardware selection and batching, which is where most people get surprised.

Hugging Face pipeline tasks and their identifiers#

Transformers ships a generic Pipeline class and many task-specific pipelines such as TextGenerationPipeline. You never instantiate those directly. You call the pipeline() factory with a task string, and it loads the right class together with a default model and preprocessor for that task, or whatever model you pass instead. Each task identifier lives in the API docs of its pipeline class, collected on the pipelines reference page.

These are the tasks with complete examples in the official docs right now:

Task identifier What it does Models used in the official examples
text-generation Continues a text prompt google/gemma-2-2b, openai-community/gpt2
text-classification (alias sentiment-analysis) Labels text with a score distilbert/distilbert-base-uncased-finetuned-sst-2-english
automatic-speech-recognition Transcribes audio, optionally with timestamps openai/whisper-large-v3
image-text-to-text Captions an image or chats about it Salesforce/blip-image-captioning-base, llava-hf/llava-interleave-qwen-0.5b-hf
any-to-any Generates text from any mix of modalities google/gemma-3n-E4B-it

The tutorial also names image classification, visual question answering, zero-shot classification and question answering as supported tasks, and the reference page documents each pipeline with its own identifier and parameters. Model choice is open: any Hub model fine-tuned for the task works, and the Hub model list can be filtered by task. Pipelines are built for inference with a decoded result; if what you actually need is vectors for search, running EmbeddingGemma 2 with Ollama is a different route.

The smallest example: text generation#

Every pipeline follows the same three steps. Import the factory, build the pipeline once, then call it as often as you like.

python
from transformers import pipeline

pipe = pipeline(task="text-generation", model="google/gemma-2-2b")
pipe("the secret to baking a really good cake is ")
# [{'generated_text': 'the secret to baking a really good cake is 1. the right ingredients 2. the'}]

Pass a list to run several prompts in one call. The output shape changes with the input: a single string returns a list of dicts, while a list of strings returns a list of lists, one inner list per prompt.

python
pipe(["the secret to baking a really good cake is ", "a baguette is "])
# [[{'generated_text': '...'}], [{'generated_text': '...'}]]

Each task has a default model, so pipeline(task="text-generation") works on its own. I'd still pass model every time. Defaults can change between Transformers releases, and a named model keeps your results reproducible.

Sentiment analysis with the text classification pipeline#

The classic "is this review positive" case uses TextClassificationPipeline, which loads under either sentiment-analysis or text-classification. Both names resolve to the same class. If you pass only a model, the factory infers the task from the model's configuration, which is how the official example is written:

python
from transformers import pipeline

classifier = pipeline(model="distilbert/distilbert-base-uncased-finetuned-sst-2-english")
classifier("This movie is disgustingly good !")
# [{'label': 'POSITIVE', 'score': 1.0}]

classifier("Director tried too much.")
# [{'label': 'NEGATIVE', 'score': 0.996}]

The score comes from the model's raw outputs through a function selected by function_to_apply. The default applies softmax when the model has several labels, sigmoid when it has one, and nothing at all for regression models. You can force "sigmoid", "softmax" or "none" if you want raw logits or a different normalization.

Speech recognition with word timestamps#

The automatic speech recognition pipeline accepts a URL or a local file and returns a dict with a text key:

python
from transformers import pipeline

asr = pipeline(task="automatic-speech-recognition", model="openai/whisper-large-v3")
asr("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.'}

For meeting notes, subtitles, or a voice agent that needs to know when something was said, pass return_timestamps="word". The result gains a chunks list, where each entry holds one word and a (start, end) tuple in seconds:

python
asr(
    audio="https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/mlk.flac",
    return_timestamps="word",
)
# {'text': ' I have a dream ...',
#  'chunks': [{'text': ' I', 'timestamp': (0.0, 1.1)},
#             {'text': ' have', 'timestamp': (1.1, 1.44)}, ...]}

That structure is plain Python, so post-processing needs no extra libraries. The snippet below takes the first words from the official example output and groups them into subtitle cues of at most three seconds each:

python
chunks = [
    {"text": " I", "timestamp": (0.0, 1.1)},
    {"text": " have", "timestamp": (1.1, 1.44)},
    {"text": " a", "timestamp": (1.44, 1.62)},
    {"text": " dream", "timestamp": (1.62, 1.92)},
    {"text": " that", "timestamp": (1.92, 3.7)},
    {"text": " one", "timestamp": (3.7, 3.88)},
    {"text": " day", "timestamp": (3.88, 4.24)},
    {"text": " this", "timestamp": (4.24, 5.82)},
    {"text": " nation", "timestamp": (5.82, 6.78)},
    {"text": " will", "timestamp": (6.78, 7.36)},
    {"text": " rise", "timestamp": (7.36, 7.88)},
    {"text": " up", "timestamp": (7.88, 8.46)},
]

def to_cues(chunks, max_seconds=3.0):
    cues, current = [], []
    for chunk in chunks:
        if current and chunk["timestamp"][1] - current[0]["timestamp"][0] > max_seconds:
            cues.append(current)
            current = []
        current.append(chunk)
    if current:
        cues.append(current)
    return cues

for cue in to_cues(chunks):
    start = cue[0]["timestamp"][0]
    end = cue[-1]["timestamp"][1]
    text = "".join(c["text"] for c in cue).strip()
    print(f"{start:5.2f}s - {end:5.2f}s  {text}")

Long audio is handled by the chunked pipeline variant, which splits one input into several forward passes on its own. You don't configure that per input; it's part of how the task is implemented.

Image captioning and multimodal chat#

The image-text-to-text task takes an image plus a text prompt. The image can be an HTTP(S) URL, a local path, or an already-loaded PIL image.

python
from transformers import pipeline

pipe = pipeline(task="image-text-to-text", model="Salesforce/blip-image-captioning-base")
pipe("https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png", text="A photo of")
# [{'generated_text': 'a photo of two birds'}]

With a conversational model, the same pipeline accepts a chat: a list of messages, each with a role and a content list whose items are typed image or text. Roles can be user, system or assistant. Passing return_full_text=False returns only the newly generated text, and ending the chat with an assistant message prefills the reply, because continue_final_message defaults to true in that case.

python
from transformers import pipeline

pipe = pipeline("image-text-to-text", model="llava-hf/llava-interleave-qwen-0.5b-hf")
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image", "url": "https://huggingface.co/datasets/hf-internal-testing/transformers-synthetic-assets/resolve/main/images/qwen_vl_demo.jpeg"},
            {"type": "text", "text": "Describe this image."},
        ],
    },
    {"role": "assistant", "content": [{"type": "text", "text": "There is a dog and"}]},
]
pipe(text=messages, max_new_tokens=20, return_full_text=False)

Unless the model's generation_config.json says otherwise, this pipeline generates up to 256 new tokens. Set max_new_tokens explicitly when you care about latency. The any-to-any task uses the identical call pattern and message format; the official example loads google/gemma-3n-E4B-it.

Choosing a GPU, CPU or Apple Silicon#

When you leave device unset, the pipeline places the model on the first available accelerator (CUDA, Apple Silicon MPS, XPU) and only falls back to CPU when none exists. So on a laptop with a working GPU you get the GPU without doing anything. To be explicit:

python
from transformers import pipeline

# first CUDA GPU
pipe = pipeline(task="text-generation", model="google/gemma-2-2b", device=0)

# force CPU; device=-1 does the same
pipe = pipeline(task="text-generation", model="google/gemma-2-2b", device="cpu")

# a specific accelerator by name
pipe = pipeline(task="text-generation", model="google/gemma-2-2b", device="cuda:1")

The tutorial's own examples read the device from Accelerate, which picks the right one for the machine the code is running on:

python
from transformers import pipeline
from accelerate import Accelerator

device = Accelerator().device
pipe = pipeline(task="text-generation", model="google/gemma-2-2b", device=device)

For models that don't fit on one device, install Accelerate and pass device_map="auto" instead of device. Accelerate puts weights on the fastest device first, then spills to CPU and disk as needed. The two arguments are mutually exclusive: a model loaded with a device map cannot also receive device.

bash
pip install -U accelerate
python
from transformers import pipeline

pipe = pipeline(task="text-generation", model="google/gemma-2-2b", device_map="auto")

Two more knobs cut memory. dtype defaults to "auto", which loads the precision the checkpoint was saved in; pass torch.float16 or torch.bfloat16 to override it. Half precision only works with the PyTorch backend, and inputs are converted internally. For a further reduction, install bitsandbytes and pass a quantization config through model_kwargs, as the tutorial does for a 7B model:

python
import torch
from transformers import pipeline, BitsAndBytesConfig

pipe = pipeline(
    model="google/gemma-7b",
    dtype=torch.bfloat16,
    device_map="auto",
    model_kwargs={"quantization_config": BitsAndBytesConfig(load_in_8bit=True)},
)

If you'd rather call a model over HTTP than load weights into your Python process, the Ollama API examples show that route.

Batching inputs and large datasets#

Batching is off by default: batch_size is 1. Setting it higher makes the pipeline send that many inputs to the model per forward pass. With four inputs and batch_size=2, the model runs twice.

python
from transformers import pipeline
from accelerate import Accelerator

device = Accelerator().device
pipe = pipeline(task="text-generation", model="google/gemma-2-2b", device=device, batch_size=2)
pipe(["the secret to baking a really good cake is", "a baguette is", "paris is the", "hotdogs are"])

The tutorial is blunt that batching may speed things up on a GPU but isn't guaranteed to. Its rules of thumb:

  • Measure on your own model, data and hardware; that's the only way to know.
  • Don't batch when latency matters, as in a live product.
  • Don't batch on a CPU.
  • Don't batch when you don't know your sequence lengths. Grow the length gradually and handle out-of-memory errors.
  • Do batch when sequence lengths are regular, and push the batch size until you hit an OOM error. Bigger GPUs benefit more.

For a whole dataset, iterate over it instead of loading everything into a list. KeyDataset pulls one field out of each record, and the pipeline yields results as it goes:

python
from datasets import load_dataset
from transformers import pipeline
from transformers.pipelines.pt_utils import KeyDataset
from accelerate import Accelerator

device = Accelerator().device
dataset = load_dataset("stanfordnlp/imdb", name="plain_text", split="unsupervised")
pipe = pipeline(
    task="text-classification",
    model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
    device=device,
)
for out in pipe(KeyDataset(dataset, "text"), batch_size=8, truncation="only_first"):
    print(out)

A plain generator works too, which is handy for data arriving from a queue or a file you're reading line by line:

python
from transformers import pipeline

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

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

You never write the batching loop yourself, but it helps to see what batch_size does with a stream, including the short final batch. This stand-alone snippet groups a generator the way the pipeline groups inputs:

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

def batches(iterable, batch_size):
    batch = []
    for item in iterable:
        batch.append(item)
        if len(batch) == batch_size:
            yield batch
            batch = []
    if batch:
        yield batch

for n, batch in enumerate(batches(data(), 4), start=1):
    print(f"batch {n}: {batch}")

Some tasks need several forward passes for one input, such as zero-shot classification, question answering, or long audio. Those run on ChunkPipeline, which batches across the internal chunks for you, so batch_size there refers to chunks rather than inputs. You use it exactly like any other pipeline.

Common mistakes and gotchas#

  • Output shape depends on input shape. One string gives [{...}]; a list gives [[{...}], [{...}]]. Code that does out[0]["generated_text"] on a list result silently gets the wrong thing. Index accordingly, or always pass lists.
  • device and device_map together fail. A model loaded through Accelerate carries a device map, and the pipeline refuses an extra device argument on top of it. Pick one.
  • Batching on CPU rarely helps. The tutorial says not to. If you're on CPU, leave batch_size at its default and spend the effort on a smaller model or half precision instead.
  • A default max_new_tokens of 256 applies to the image-text-to-text and any-to-any pipelines unless the model's generation config overrides it. Set it yourself for predictable latency.
  • Half precision needs PyTorch. dtype=torch.float16 and friends only work with PyTorch-backed models.
  • Shadowing the factory. The official examples write pipeline = pipeline(...), which replaces the imported function. It works once. The second call in the same session fails. Use a different variable name.
  • sentiment-analysis is not a separate model type. It loads the same text classification pipeline, so any sequence classification model works under either name.
  • OOM is your problem to catch. The docs expect you to handle out-of-memory errors when batching. Wrap the loop and retry with a smaller batch.

Quick reference#

Need What to pass
Pick a task pipeline(task="text-generation", model="...")
Let the task be inferred pipeline(model="...")
First GPU device=0
Force CPU device="cpu" or device=-1
Specific accelerator device="cuda:1"
Spread a big model device_map="auto" (requires Accelerate, exclusive with device)
Half precision dtype=torch.float16 or torch.bfloat16
8-bit weights model_kwargs={"quantization_config": BitsAndBytesConfig(load_in_8bit=True)}
Batch inputs batch_size=N on construction or on the call
Stream a dataset pipe(KeyDataset(dataset, "text"), batch_size=8)
Word timestamps (ASR) return_timestamps="word"
Only the new text return_full_text=False
Cap generation max_new_tokens=N

Before shipping a pipeline call, check these:

  1. The model is named explicitly and matches the task.
  2. You know which device it landed on; print the pipeline's device when in doubt.
  3. You handle both single-input and list-input output shapes.
  4. Generation length is capped.
  5. If you batch, you measured the speedup and you catch OOM errors.
  6. The pipeline is created once, not inside the request handler.

Quick answers

How do I use a Hugging Face pipeline for summarization?

The call pattern is the same as the text-generation examples above: pass the task identifier and a model fine-tuned for summarization, then call the pipeline with your text. Look up the summarization pipeline's identifier, default model and parameters on the Transformers pipelines reference page, since those details change between releases.

What is the difference between text-generation and sentiment-analysis pipelines?

text-generation continues a prompt and returns generated_text; sentiment-analysis is an alias for the text-classification pipeline and returns a label with a score. They load different model types, so a model fine-tuned for one won't work for the other.

Can I run Hugging Face pipelines on a CPU?

Yes. Pass device="cpu" or device=-1 to force CPU; if no accelerator is available the pipeline falls back to CPU on its own. The official tutorial advises against batching on CPU.

Does the Hugging Face pipeline work with LangChain?

The Transformers pipeline docs don't cover LangChain. A pipeline is a plain Python callable that returns lists of dicts, so any framework that can wrap a Python function can call it; check LangChain's own documentation for its current integration.

Where is the official Hugging Face pipeline documentation?

Two pages: the pipeline tutorial covers usage, devices and batching, and the pipelines reference page lists every task-specific pipeline with its identifier and parameters. Both are linked in the article.

Did this solve it?

One tap. No account.

Saved you an hour? Send a tip.

USDC or ETH on Base, Ethereum, Arbitrum and more. Keeps the notes free and the examples running.

Base

Network

0xc783bc5c3fa14cEC3f09A22284bC91C5AF0d59e1
Open in wallet · 5 USDC

On a computer? Scan the code with your phone wallet, or copy the address.

Pick the network your wallet or exchange uses. USDC works on all six; ETH on Base, Ethereum, Arbitrum and Optimism. Don't send on Tron or Solana: this address doesn't exist there. Tips are optional and unlock nothing; every guide stays free.

Discussion

Start the discussion

Indra Wijaya

Builds and runs AI agents, bots and content pipelines, and writes down what works and what broke.

About · Email · RSS

Keep reading

New notes, no spam.

One post at a time, only when there's something worth reading. Follow in any feed reader.

Subscribe via RSS