ExFastembed (ExFastembed v0.1.0)

Copy Markdown View Source

Loads FastEmbed text embedding and reranker models through fastembed-rs.

Use load/1 followed by embed_text/1 to generate vectors, or load_reranker/1 followed by rerank/3 to score documents for a query.

Each BEAM VM shares one embedding model and one independent reranker. Loading a replacement changes the model used by all processes; a failed load preserves the previous model. Calls using the same model run serially.

Model files are downloaded on first use and cached in .fastembed_cache. Set FASTEMBED_CACHE_DIR before loading a model to use another directory. If HF_HOME is exported when the VM starts, FastEmbed uses that directory instead. Partial downloads reuse the cached revision for consistent model files. Loading and inference block the caller while the native work runs on a dirty scheduler, allowing other BEAM processes to continue running.

All public functions return error tuples for invalid input. Strings must be valid UTF-8. Model names are matched case-insensitively against the bundled FastEmbed catalog, including the legacy aliases.

Summary

Model discovery

Returns text embedding model names accepted by load/1.

Resolves an accepted model name to its variant, metadata, and local cache status.

Lists distinct model variants with their repository, dimension, and cache status.

Returns reranker model names accepted by load_reranker/1.

Embeddings

Embeds a list of strings with the loaded text embedding model.

Loads a text embedding model and returns its embedding dimension.

Reranking

Loads a reranker model.

Reranks documents for a query using the loaded reranker model.

Types

A dense vector with the dimension reported by load/1.

An input, model-loading, or inference failure with a human-readable reason.

A distinct model variant and whether all its required files are cached.

The two supported model families.

A zero-based document index, relevance score, and optional document text.

Model discovery

embed_models()

@spec embed_models() :: [String.t()]

Returns text embedding model names accepted by load/1.

Includes repository names, explicit FastEmbed variant names, and legacy aliases. Names are matched case-insensitively.

The list is sorted and contains both full-precision and quantized variants. A repository shared by several variants selects its non-quantized model when available; use an explicit name such as EmbeddingGemma300MQ4 for a specific variant.

Examples

iex> "BGESmallENV15" in ExFastembed.embed_models()
true

model_info(name, kind)

@spec model_info(String.t(), model_kind()) :: {:ok, model_info()} | error()

Resolves an accepted model name to its variant, metadata, and local cache status.

kind must be :embedding or :reranker. Resolution follows the same aliases and case-insensitive matching as load/1 and load_reranker/1. See models/0 for the meaning of cached.

Examples

iex> {:ok, info} = ExFastembed.model_info("BAAI/bge-small-en-v1.5", :embedding)
iex> {info.name, info.dimension}
{"BGESmallENV15", 384}

models()

@spec models() :: [model_info()]

Lists distinct model variants with their repository, dimension, and cache status.

Checks the cache locally without network access or loading a model. cached means that the selected ONNX weights, additional data, and four tokenizer/config files are present and non-empty. It does not validate their contents or mean that the model is loaded in the VM. Call load/1 or load_reranker/1 before inference.

Uses FASTEMBED_CACHE_DIR, defaulting to .fastembed_cache. Embedding variants appear first, then rerankers, sorted by name within each family. Rerankers have a nil dimension.

Examples

iex> Enum.any?(ExFastembed.models(), &(&1.name == "BGESmallENV15"))
true

reranker_models()

@spec reranker_models() :: [String.t()]

Returns reranker model names accepted by load_reranker/1.

Includes repository names, explicit FastEmbed variant names, and legacy aliases. Names are matched case-insensitively.

Examples

iex> "BAAI/bge-reranker-base" in ExFastembed.reranker_models()
true

Embeddings

embed_text(texts)

@spec embed_text([String.t()]) :: {:ok, [embedding()]} | error()

Embeds a list of strings with the loaded text embedding model.

Call load/1 before calling this function. An empty list returns {:ok, []} without running inference.

Results preserve the input order, with one vector per text. A non-empty input returns an error if no embedding model is loaded. Tokenization and truncation follow the selected model's FastEmbed defaults.

Examples

iex> ExFastembed.embed_text([])
{:ok, []}

iex> ExFastembed.embed_text(["document", 123])
{:error, "Invalid input: texts must be a list of strings"}

load(model_name)

@spec load(String.t()) :: {:ok, pos_integer()} | error()

Loads a text embedding model and returns its embedding dimension.

A successful call replaces the embedding model shared by all processes. A failed download or initialization leaves the previous model available. See embed_models/0 for accepted names. The returned dimension is the length of each vector generated by embed_text/1.

Examples

{:ok, 384} = ExFastembed.load("BAAI/bge-small-en-v1.5")
iex> ExFastembed.load("invalid-model")
{:error, "Model not recognized or not implemented: invalid-model"}

Reranking

load_reranker(model_name)

@spec load_reranker(String.t()) :: {:ok, true} | error()

Loads a reranker model.

A successful call replaces the reranker shared by all processes, independently of the embedding model. A failed load preserves the previous reranker. See reranker_models/0 for accepted names.

Examples

{:ok, true} = ExFastembed.load_reranker("BAAI/bge-reranker-base")
iex> ExFastembed.load_reranker("invalid-reranker")
{:error, "Reranker model not recognized: invalid-reranker"}

rerank(query, documents, return_docs)

@spec rerank(String.t(), [String.t()], boolean()) ::
  {:ok, [rerank_result()]} | error()

Reranks documents for a query using the loaded reranker model.

Call load_reranker/1 before calling this function. An empty document list returns {:ok, []} without running inference.

Results are sorted by descending relevance score. Each result contains the document's zero-based index in the original list, its score, and its text when return_docs is true (nil otherwise). Scores are model-specific and are not necessarily probabilities. A non-empty input requires a loaded reranker.

Examples

iex> ExFastembed.rerank("query", [], false)
{:ok, []}

Types

embedding()

@type embedding() :: [float()]

A dense vector with the dimension reported by load/1.

error()

@type error() :: {:error, String.t()}

An input, model-loading, or inference failure with a human-readable reason.

model_info()

@type model_info() :: %{
  name: String.t(),
  kind: model_kind(),
  repository: String.t(),
  dimension: pos_integer() | nil,
  cached: boolean()
}

A distinct model variant and whether all its required files are cached.

model_kind()

@type model_kind() :: :embedding | :reranker

The two supported model families.

rerank_result()

@type rerank_result() :: {non_neg_integer(), float(), String.t() | nil}

A zero-based document index, relevance score, and optional document text.