ann-search¶
Approximate nearest-neighbour search built for single-cell and computational biology workloads. The Rust crate does the work. This is a thin scikit-learn shaped layer over it.
Twenty-seven indices, all behind the same four-method surface: thirteen on the CPU, eleven over quantised storage, three on the GPU. No CUDA runtime to install, since the GPU backend is wgpu, so it runs on Metal, Vulkan or DX12 and ships in the ordinary wheel.
Install¶
uv pip install ann-search # numpy only
uv pip install "ann-search[sparse]" # adds scipy, for kneighbors_graph
Wheels are built for Linux x86_64 and macOS on both architectures, against Python 3.10 and up.
Thirty seconds¶
import numpy as np
import ann_search as ann
X = np.random.default_rng(0).standard_normal((50_000, 50)).astype(np.float32)
index = ann.HnswIndex(n_neighbors=15, metric="cosine").fit(X)
distances, indices = index.kneighbors() # self-kNN graph, fast path
distances, indices = index.kneighbors(X[:1000]) # cross-set query
graph = index.kneighbors_graph() # scipy CSR
kneighbors returns distances first, matching scikit-learn and FAISS.
The estimators implement get_params, set_params, fit and transform, so
they drop into scikit-learn pipelines and anywhere a KNeighborsTransformer is
expected, scanpy included. scikit-learn isn't an install requirement for any of
that.
Where to go next¶
- Choosing an index if you don't already know which one you want. Twenty-seven is a lot of choice and most of them are wrong for your problem.
- Quickstart for worked examples over the synthetic generators, including how to measure your own recall.
- Quantised for the eleven compressed indices, when memory is what's binding.
- GPU for the three device-resident indices and what they cost you.
- Guide for metrics, padding, threads, persistence and the sharp edges.
- API reference for every parameter of every index, with what
each
Nonedefault resolves to.