ann_router.backends.faiss_backend module

FAISS backend (IVF + PQ) — scale, quantisation, optional GPU.

FAISS earns its place at the large volume + batch (+ GPU) end of the policy: an IVF coarse quantiser prunes the search to a few cells, and optional Product Quantisation compresses vectors ~8-16x so billions fit in RAM. The trade is a training step and lower recall than a graph index at small/medium N — which is precisely why the router only reaches for FAISS once the corpus is big enough for those wins to matter, and prefers HNSW/turbovec below that.

The adapter auto-scales nlist and, for very large corpora, switches from a flat IVF to IVF-PQ. Ids are handled through an IndexIDMap2 wrapper so external ids survive.

Consumes: faiss (optional, pip install 'ann-router[faiss]' → faiss-cpu). Produces: FaissIndex.

Author: Warith Harchaoui <warith.harchaoui@deraison.ai>

class ann_router.backends.faiss_backend.FaissIndex(dim, metric='cosine', **kwargs)[source]

Bases: ANNIndex

FAISS IVF(-PQ) index with id mapping and auto-sized coarse quantiser.

Parameters:
  • dim (int) – Embedding dimensionality.

  • metric ({"cosine", "l2", "ip"}, optional) – Distance metric. Defaults to "cosine".

  • nlist (int, optional) – Number of IVF cells. Defaults to auto (~sqrt(n)*4, clamped).

  • nprobe (int, optional) – Cells probed at query time (recall/latency trade). Defaults to 16.

  • use_pq (bool or "auto", optional) – Enable Product Quantisation. "auto" (default) turns it on above pq_threshold vectors.

  • m (int, optional) – PQ sub-quantiser count (must divide dim). Defaults to a divisor near dim/2.

  • kwargs (object)

Examples

>>> FaissIndex.capabilities().name
'faiss'
add(vectors)[source]

Append vectors with the next contiguous ids.

Parameters:

vectors (numpy.ndarray) – Shape (m, dim).

Return type:

None

add_with_ids(vectors, ids)[source]

Append vectors with explicit ids (index must already be trained).

Parameters:
  • vectors (numpy.ndarray) – Shape (m, dim).

  • ids (numpy.ndarray) – Shape (m,) integer ids.

Raises:

NotSupported – If called before build() (IVF needs training first).

Return type:

None

build(vectors, ids=None)[source]

Train and populate the IVF(-PQ) index.

Parameters:
  • vectors (numpy.ndarray) – Shape (n, dim).

  • ids (numpy.ndarray, optional) – Shape (n,); defaults to range(n).

Returns:

self.

Return type:

FaissIndex

classmethod capabilities()[source]

Return the FAISS capability descriptor (GPU-capable, add/remove ok).

Return type:

Capabilities

classmethod is_available()[source]

Return True if faiss is importable.

Examples

>>> isinstance(FaissIndex.is_available(), bool)
True
Return type:

bool

load(path)[source]

Load an index written by save().

Parameters:

path (str) – Source path produced by save().

Returns:

self, populated from disk.

Return type:

FaissIndex

remove(ids)[source]

Remove vectors by id via the id map.

Parameters:

ids (numpy.ndarray) – Shape (m,) integer ids to drop.

Return type:

None

save(path)[source]

Persist via faiss.write_index.

Parameters:

path (str) – Destination file path.

Return type:

None

search(queries, k)[source]

Return approximate top-k neighbours per query.

Parameters:
  • queries (numpy.ndarray) – Shape (q, dim).

  • k (int) – Neighbours per query.

Returns:

  • ids (numpy.ndarray) – Shape (q, k) neighbour ids.

  • distances (numpy.ndarray) – Shape (q, k) distances under the index metric.

Return type:

tuple[ndarray, ndarray]