OllamaEmbedder
On this page
embeddings.ollama_embedder.OllamaEmbedder(BaseEmbedder) — client for a locally-running Ollama server's embedding endpoint.
Purpose
Calls Ollama's /api/embeddings HTTP endpoint over requests, with server health-checking, optional auto-start of ollama serve, retry logic per text, and model-management helpers (list_models, pull_model, is_model_available).
Constructor
OllamaEmbedder(
model_name: str = "nomic-embed-text", # from EmbedderConfig().embedding_model
base_url: str = "http://127.0.0.1:11434", # from EmbedderConfig().base_url
normalize_embeddings: bool = True,
batch_size: int = 32,
max_length: Optional[int] = 512,
cache_embeddings: bool = False,
show_progress: bool = False,
timeout: int = 60,
max_retries: int = 3,
retry_delay: float = 1.0,
auto_start_server: bool = True,
server_start_wait: float = 3.0,
**kwargs,
)
Parameters
MODEL_SPECS (module-level dict, not a class attribute)
Server lifecycle (_ensure_server_running)
Runs before super().__init__() is called, so device detection and other base-class setup only happen once the server is confirmed reachable:
GET /api/version(3s timeout) — if it returns HTTP 200, proceed immediately.- If unreachable and
auto_start_server=False, raisesConnectionErrortelling the user to runollama servemanually. - If unreachable and
auto_start_server=True, launchesollama serveas a detached background process (platform-specific flags for Windows vs. POSIX). RaisesConnectionErrorif theollamaexecutable isn't found onPATH. - Polls
/api/versionevery 0.5s up toserver_start_waitseconds; raisesConnectionErrorif it never comes up.
Raises
ImportErrorifrequestsisn't installed.ConnectionErrorif the server can't be reached or started (see above).
encode()
encode(
texts: Union[str, List[str]],
show_progress_bar: bool = False,
convert_to_numpy: bool = True,
**kwargs,
) -> np.ndarray
Behavior
- Tracks whether input was a single string (for unwrapping the result at the end).
- If
show_progress_bar(orself.show_progress) is set andtqdmis importable, iterates over all texts flattened, calling_embed_single()per text, then breaks out of the outer batch loop entirely after one pass — meaningbatch_sizeis effectively ignored for embedding calls whenever progress display is active (there is no batch endpoint call either way;_embed_singlealways sends one text per HTTP request regardless of this branch). - When not showing progress, iterates in
batch_size-sized chunks, calling_embed_single()once per text within each chunk (still one HTTP request per text —batch_sizehere only affects loop/log granularity, not actual request batching, since Ollama's/api/embeddingsendpoint used here accepts a singlepromptper call). - Auto-detects
self._embedding_dimfrom the first successful response if it wasn't already known fromMODEL_SPECS. - Stacks results, L2-normalizes if
normalize_embeddings=True, updates stats.
Returns
np.ndarray of shape (dim,) for single-string input, (n, dim) for list input — unwrapped correctly for the single-text case (embeddings_array[0] if single_text else embeddings_array).
Raises (via _embed_single)
ConnectionErrorif the server becomes unreachable mid-request (after exhausting retries).TimeoutErrorif the request times out (after exhausting retries).ValueErrorfor a 404 response (model not pulled) or if the response has no"embedding"field, or for a JSON decode failure.- Other HTTP errors are retried up to
max_retries, then re-raised.
_embed_single(text: str) -> np.ndarray
POSTs {"model": self.model_name, "prompt": text} to /api/embeddings. Retries connection errors, timeouts, and non-404 HTTP errors with linear backoff (retry_delay * attempt); a 404 is treated as "model not found" and raises immediately with a ollama pull <model> hint, without retrying.
embedding_dim (property)
Returns the known/auto-detected dimension if available; otherwise performs a one-off probe request encoding the literal string "hello" to determine it, logging the detected value.
Ollama-specific utilities
list_models() -> List[Dict[str, Any]]
GET /api/tags; returns the "models" list from the response. Raises ConnectionError if unreachable.
is_model_available(model_name=None) -> bool
Calls list_models() and checks whether the target name matches an available model's name (exact match on the part before :, or a startswith match). Returns False (rather than raising) if the server is unreachable.
pull_model(model_name=None) -> bool
POST /api/pull with {"name": target, "stream": False} and a 300s timeout. Per the docstring, this is a fire-and-forget trigger — for large models, progress should be monitored via the ollama pull <name> CLI rather than this method. Returns True/False based on whether the request succeeded; does not raise on failure.
get_server_info() -> Dict[str, Any]
GET /api/version; returns {"status": "offline", ...} or {"status": "error", ...} dicts on failure instead of raising.
Overrides of BaseEmbedder
_get_best_device()→ always returns"local"(no CUDA/MPS/CPU probing, since Ollama manages its own device placement).get_model_info()→ addsbase_url,model_spec(if known),server_info, andmodel_available.validate_connection(test_text, detailed)→ checks server reachability and model availability before calling the base class's actual encode-based validation; returns an early failure dict for either problem without attempting to encode.
Context manager
__enter__ returns self; __exit__ logs a stats summary and calls self.cleanup().
Examples
from zerda.embeddings import OllamaEmbedder
# Default model, auto-starts `ollama serve` if not already running
embedder = OllamaEmbedder()
vec = embedder.encode("مرحباً Hello")
# Explicit model + remote Ollama host, no auto-start
embedder = OllamaEmbedder(
model_name="bge-m3",
base_url="http://192.168.1.10:11434",
auto_start_server=False,
)
# Model management
if not embedder.is_model_available():
embedder.pull_model()
Related APIs
- BaseEmbedder — parent class
- HuggingFaceEmbedder, ArabicEmbedder — the other two "no API key required" embedders (fully in-process rather than over HTTP to a separate server)