Inference Backends
ollama-classifier supports four inference backends, all behind a single
unified LLMClassifier. Create a
backend and wrap it in a classifier:
from ollama_classifier import LLMClassifier
from ollama_classifier.backends import OllamaBackend # or VLLMBackend, etc.
backend = OllamaBackend(model="llama3.2")
classifier = LLMClassifier(backend)
All backends communicate with their inference engine via HTTP. OllamaBackend
uses the native Ollama Python SDK; VLLMBackend, SGLangBackend, and
LlamaCppBackend communicate via the OpenAI-compatible chat completions API.
Each backend translates the high-level constrain_labels parameter to its
native constraint mechanism so the classifier code stays identical regardless
of engine.
Ollama
Backend wrapping the Ollama runtime (≥v0.12) via the official Python SDK.
Important
OllamaBackend requires Ollama runtime v0.12 or later for logprobs
support. The ollama Python SDK is an optional dependency — install it
with pip install "ollama-classifier[ollama]".
Constraint mechanism: JSON Schema enum via the format parameter. The
model generates {"label": "<chosen_label>"}; structural JSON tokens
({, "label", :, ", }) are filtered during trie
reconstruction. tokenize() uses context-dependent tokenization so the
label is tokenized within the JSON prefix it appears in, ensuring the trie
matches the actual response tokens.
Because Ollama wraps labels in JSON, its
supports_bare_label_constraint
property is False.
from ollama_classifier import LLMClassifier
from ollama_classifier.backends import OllamaBackend
# Local (defaults to http://localhost:11434)
backend = OllamaBackend(model="llama3.2")
# Remote
backend = OllamaBackend(model="llama3.2", host="http://remote-host:11434")
classifier = LLMClassifier(backend)
vLLM
High-throughput serving engine for LLMs. Supports guided decoding and logprobs out of the box.
Constraint mechanism: ``guided_choice`` — constrains the model to generate
exactly one of the provided label strings, as bare label text (no JSON
wrapper). Logprobs are pre-mask (raw model logits before guided-decoding
masking). supports_bare_label_constraint is True.
Local server:
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.2-3B-Instruct \
--host 0.0.0.0 --port 8000
Connect:
from ollama_classifier.backends import VLLMBackend
backend = VLLMBackend(
model="meta-llama/Llama-3.2-3B-Instruct",
base_url="http://localhost:8000/v1",
)
Remote server:
backend = VLLMBackend(
model="your-model",
base_url="https://your-vllm-server.com/v1",
api_key="your-api-key", # if auth is required
)
SGLang
Fast serving system for large language models with efficient radix attention.
Constraint mechanism: regex — builds a regex from the escaped labels
(("label1|label2|...")) so the model generates bare label text with no
JSON wrapper. Logprobs are pre-mask (raw model logits before regex masking).
supports_bare_label_constraint is True.
Local server:
python -m sglang.launch_server \
--model-path meta-llama/Llama-3.2-3B-Instruct \
--host 0.0.0.0 --port 30000
Connect:
from ollama_classifier.backends import SGLangBackend
backend = SGLangBackend(
model="meta-llama/Llama-3.2-3B-Instruct",
base_url="http://localhost:30000/v1",
)
llama.cpp
Lightweight inference via llama-server. Ideal for CPU or mixed
CPU/GPU environments.
Constraint mechanism: GBNF grammar — builds a grammar rule that allows exactly one of the provided labels:
root ::= "label1" | "label2" | "label3"
This generates bare label text with no JSON wrapper, so logprob
reconstruction is clean. llama-server accepts a non-standard grammar
field on the /v1/chat/completions endpoint (response_format with JSON
schema is buggy in llama.cpp). supports_bare_label_constraint is True.
Local server:
./llama-server -m model.gguf --host 0.0.0.0 --port 8080 -c 4096
Connect:
from ollama_classifier.backends import LlamaCppBackend
backend = LlamaCppBackend(
model="model",
base_url="http://localhost:8080/v1",
)
Note
Logprobs and grammar constraints require llama.cpp to be compiled
with the appropriate flags (e.g. LLAMA_SUPPORT_LOGPROBS).
Constraint Mechanisms Summary
Each backend translates the high-level constrain_labels parameter to its
native constraint mechanism:
supports_bare_label_constraint
Each backend exposes a
supports_bare_label_constraint
property that tells the classifier how to tokenize labels for trie
construction:
``True`` (vLLM, SGLang, llama.cpp):
chat()generates bare label text with no wrapper. Labels are tokenized standalone (context=None).``False`` (Ollama):
chat()wraps labels in JSON. Labels are tokenized within the JSON prefix (context='{"label": "') so the trie matches the actual response tokens.
This is handled automatically by LLMClassifier — you do not need to
inspect it directly.
Backend Configuration
All backends share common configuration options:
Parameter |
Default |
Description |
|---|---|---|
|
(required) |
Model identifier |
|
Engine-specific |
Base URL of the inference server |
|
|
API key for authentication (not used by Ollama) |
|
|
Request timeout in seconds |
|
Maximum tokens to generate |
|
|
Extra parameters merged into every request body |
|
OllamaBackend additionally accepts a host parameter (defaults to
http://localhost:11434) and accepts pre-initialized sync_client /
async_client instances for testing or connection reuse.
Switching Backends
The LLMClassifier exposes the same API regardless of which backend
you use, making it trivial to switch between engines:
from ollama_classifier.backends import (
OllamaBackend, VLLMBackend, SGLangBackend, LlamaCppBackend,
)
from ollama_classifier import LLMClassifier
# Switch just by changing the backend
backends = [
OllamaBackend(model="llama3.2"),
VLLMBackend(model="my-model", base_url="http://localhost:8000/v1"),
SGLangBackend(model="my-model", base_url="http://localhost:30000/v1"),
LlamaCppBackend(model="my-model", base_url="http://localhost:8080/v1"),
]
for backend in backends:
classifier = LLMClassifier(backend)
result = classifier.classify(
text="Hello world!",
choices=["a", "b", "c"],
)
print(f"{backend.__class__.__name__}: {result.prediction}")