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

Python · 15 lines
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

NameTypeDefaultNotes
model_namestr"nomic-embed-text"Looked up in the module-level MODEL_SPECS dict for known dimension info; unknown models still work, with dimension auto-detected on first call
base_urlstr"http://127.0.0.1:11434"Trailing slash stripped
timeoutint60Per-request timeout (seconds)
max_retriesint3Per-text retry count in _embed_single
retry_delayfloat1.0Multiplied by attempt number (linear, not exponential, backoff here — retry_delay * attempt)
auto_start_serverboolTrueIf the server isn't reachable, attempts subprocess.Popen(["ollama", "serve"], ...)
server_start_waitfloat3.0Seconds to poll for server readiness after attempting to start it

MODEL_SPECS (module-level dict, not a class attribute)

ModelDimensionsMax tokensArabic support
nomic-embed-text7688192good
mxbai-embed-large1024512basic
all-minilm384256basic
snowflake-arctic-embed1024512basic
bge-m310248192excellent

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:

  1. GET /api/version (3s timeout) — if it returns HTTP 200, proceed immediately.
  2. If unreachable and auto_start_server=False, raises ConnectionError telling the user to run ollama serve manually.
  3. If unreachable and auto_start_server=True, launches ollama serve as a detached background process (platform-specific flags for Windows vs. POSIX). Raises ConnectionError if the ollama executable isn't found on PATH.
  4. Polls /api/version every 0.5s up to server_start_wait seconds; raises ConnectionError if it never comes up.

Raises

  • ImportError if requests isn't installed.
  • ConnectionError if the server can't be reached or started (see above).

encode()

Python · 6 lines
encode(
    texts: Union[str, List[str]],
    show_progress_bar: bool = False,
    convert_to_numpy: bool = True,
    **kwargs,
) -> np.ndarray

Behavior

  1. Tracks whether input was a single string (for unwrapping the result at the end).
  2. If show_progress_bar (or self.show_progress) is set and tqdm is importable, iterates over all texts flattened, calling _embed_single() per text, then breaks out of the outer batch loop entirely after one pass — meaning batch_size is effectively ignored for embedding calls whenever progress display is active (there is no batch endpoint call either way; _embed_single always sends one text per HTTP request regardless of this branch).
  3. 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_size here only affects loop/log granularity, not actual request batching, since Ollama's /api/embeddings endpoint used here accepts a single prompt per call).
  4. Auto-detects self._embedding_dim from the first successful response if it wasn't already known from MODEL_SPECS.
  5. 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)

  • ConnectionError if the server becomes unreachable mid-request (after exhausting retries).
  • TimeoutError if the request times out (after exhausting retries).
  • ValueError for 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() → adds base_url, model_spec (if known), server_info, and model_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

Python · 16 lines
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 pages