MODELCATALOG

You supply the categories at query time. No training.

Zero-shot classification

Classify against labels you supply at query time. No training data needed.

Browse live models for this task →

What it is

The model was trained on natural language inference — deciding whether one sentence implies another. That gets repurposed cleverly: your document becomes the premise, and each candidate label becomes a hypothesis like 'This text is about fraud.' The label whose hypothesis is most entailed wins.

Which explains both its strength and its cost. You can change categories by editing a list, but each label needs its own forward pass, so ten categories is ten times the compute of a fine-tuned classifier that would score all ten at once.

Model families 3

Sub-categories within this task. The distinction that matters is not which is best, but which fits your constraints.

NLI-based zero-shot

400M–900M. GPU recommended.
Use when
No labelled data, categories described well by short phrases, moderate volume. The standard choice.
Avoid when
Real-time or high throughput.
Examples
facebook/bart-large-mnliMoritzLaurer/deberta-v3-large-zeroshot-v2.0

Embedding similarity

30M–500M.
Use when
You want speed. Embed the document once and compare against pre-embedded label descriptions — that scales to many labels at almost no extra cost.
Avoid when
Labels are subtle or need negation. Similarity is a blunter instrument than entailment.
Examples
sentence-transformers/all-mpnet-base-v2BAAI/bge-m3

LLM with a prompt

7B and up.
Use when
Categories need explanation or reasoning, or you want a justification alongside the label.
Avoid when
Cost or reproducibility matter.
Examples
Any instruct LLM

In a bank 3

The third line in each is the part that makes it harder than the textbook version.

Standing up a new complaint taxonomy

A product launches, complaints arrive, and you have no labelled examples in the new categories yet.

The wrinkleThe realistic play is to use zero-shot for the first few weeks, have analysts correct the output, and use those corrections as the training set for a proper classifier. Zero-shot as a bootstrap, not a destination.

Policy and control mapping

Tag internal documents against a control framework whose categories change as regulation changes.

The wrinkleRetraining a classifier every time the framework is revised is untenable. Editing a label list is not.

Exploratory triage of an unfamiliar corpus

You inherit a document store and need a rough sense of what is in it before deciding what to build.

The wrinkleTreat the output as a hypothesis to check, not a measurement. Sample and read before you quote any number from it to a stakeholder.

Code 2

Named functions and the arguments that actually change the outcome. Comments flag the traps.

Basic use, and why label wording dominates

The single biggest lever here is not the model. It is how you phrase the labels.

from transformers import pipeline

zs = pipeline("zero-shot-classification",
              model="facebook/bart-large-mnli")

text = "I was charged an overdraft fee even though my balance was positive."

# Terse labels - ambiguous to the model
print(zs(text, candidate_labels=["fees", "fraud", "service", "technical"]))

# Descriptive labels - materially better, same model, same cost
print(zs(text, candidate_labels=[
    "an incorrect or unexpected fee charged to the account",
    "unauthorised transactions or suspected fraud",
    "poor customer service or communication",
    "a technical fault with the app or website",
]))

# multi_label=True scores each label independently rather than forcing
# the scores to sum to 1. Use it when a document can belong to several
# categories at once - complaints frequently do.
print(zs(text, candidate_labels=[...], multi_label=True))

The bootstrap workflow this is actually best at

Label a sample cheaply, have humans correct it, train something fast and auditable on the result.

import pandas as pd
from transformers import pipeline

zs = pipeline("zero-shot-classification",
              model="facebook/bart-large-mnli", device=0)

LABELS = {
    "fees":      "an incorrect or unexpected fee charged to the account",
    "fraud":     "unauthorised transactions or suspected fraud",
    "service":   "poor customer service or communication",
    "technical": "a technical fault with the app or website",
}
descriptions = list(LABELS.values())
back = {v: k for k, v in LABELS.items()}

sample = df.sample(2000, random_state=42)
results = zs(sample["text"].tolist(), candidate_labels=descriptions,
             batch_size=16)

sample["proposed"]   = [back[r["labels"][0]] for r in results]
sample["confidence"] = [r["scores"][0] for r in results]

# Send the uncertain ones to review first - that is where the model is
# wrong, and where a human correction teaches you the most.
sample.sort_values("confidence").to_csv("for_review.csv", index=False)

What catches people out 3

  1. Label wording is a hyperparameter

    'fees' and 'an incorrect fee charged to the account' can differ by twenty points of accuracy on identical data. Write labels as full descriptive phrases and test several wordings — this is the cheapest tuning available to you.

  2. Scores are relative, not probabilities

    With multi_label=False the scores are softmaxed across your candidate set, so they are forced to sum to one. Add an irrelevant label and every other score moves. Never threshold these as if they were calibrated probabilities.

  3. There is no 'none of these' option

    The model always returns a ranking, even for a document that fits no category. Add an explicit catch-all label such as 'unrelated to banking' or use multi_label with a floor.