vicinity
Approximate nearest-neighbor search.
vicinity provides Rust indexes and Python bindings for vector search. HNSW is
the default in-memory index. IVF-PQ is the compressed in-memory index. Other
indexes are feature-gated and documented in
docs/algorithms.md.
Install
[]
= { = "0.11.0", = ["hnsw"] }
Optional features enable additional indexes:
= { = "0.11.0", = ["ivf_pq"] }
= { = "0.11.0", = ["diskann"] }
= { = "0.11.0", = ["hnsw", "serde"] }
HNSW
HNSW is the default index for dense vectors that fit in memory. Cosine distance
expects unit-norm vectors unless auto_normalize(true) is set.
use HNSWIndex;
let mut index = builder
.m
.ef_search
.auto_normalize
.build?;
index.add_slice?;
index.add_slice?;
index.build?;
let results = index.search?;
// Vec<(doc_id, distance)>; lower distance is closer.
Use DistanceMetric when you need L2, angular, or inner-product distance:
use ;
let index = builder
.metric
.build?;
IVF-PQ
IVF-PQ stores compressed vectors and searches an inverted file. Use it when raw vectors dominate memory and lower recall is acceptable.
use ;
let params = IVFPQParams ;
let mut index = new?;
for in dataset.iter.enumerate
index.build?;
let compressed = index.search?;
let reranked = index.search_reranked?;
search() uses PQ distances and works after compact(). search_reranked()
keeps raw vectors and reranks a candidate pool with exact cosine distance.
See examples/ivf_pq_demo.rs for a runnable example.
Python
The Python package is pyvicinity.
=
=
, =
, =
For compressed search:
=
, =
Runnable Python examples are in examples/python/. The
package ships .pyi stubs and a py.typed marker.
Python exposes the common HNSW constructor subset, HNSW JSON save/load, IVF-PQ
directory save/load, and IVF-PQ file search. Mmap-backed IVF-PQ search is
available in normal Python builds because the python feature includes
persistence; Rust builds need the persistence feature for mmap=True.
New Python APIs should first have stable Rust benchmarks, persistence behavior,
and examples; the bindings are not intended to mirror every experimental Rust
module.
Rust-only surfaces include DiskANN, store::UpdatableIndex, FreshGraph,
filtered search/update APIs, and HNSW binary segments.
Persistence
HNSW supports JSON save/load with the serde feature:
index.save_to_file?;
let loaded = load_from_file?;
The persistence feature adds a binary segment format for HNSW. The store
feature adds store::UpdatableIndex, a segmented index with add/delete,
checkpoint, compaction, and crash recovery. See
examples/updatable_store.rs.
Benchmarks
The benchmark runner writes JSONL rows with recall, QPS, build time, RSS, and latency percentiles:
Selected GloVe-25 rows. Current validation rows are full-corpus builds with a 500-query cap recorded in JSONL metadata; historical rows predate the current schema.
| Algorithm | Recall@10 | QPS |
|---|---|---|
| HNSW (M=16, high-recall historical row) | 100.0% | 2,857 |
IVF-PQ nprobe=32 (current validation) |
95.42% | 2,941 |
| IVF-PQ, rerank 500 (current validation) | 96.58% | 2,806 |
| RP-Forest (historical row) | 58.5% | 4,221 |
Current run commands and result interpretation are in
docs/benchmark-results.md.
Choosing an Index
| Workload | Start with | Try next |
|---|---|---|
| Small corpus (<10K vectors) | Brute force | HNSW when scale or latency requires |
| Dense vectors that fit in memory | HNSW | NSW or Vamana |
| Raw vectors dominate RAM | HNSW, then IVF-PQ | IVF-PQ with reranking |
| Frequent writes/deletes | Evaluate store::UpdatableIndex |
Compare FreshGraph, in-place HNSW, and LSM HNSW on churn rows |
| Metadata filters | HNSW with post-filtering | ACORN, Curator, and FilteredGraph need selectivity sweeps |
| Sparse learned retrieval | SparseMIPS | Workload-specific sparse baseline |
| File-backed graph search | Evaluate DiskANN | Promote after full-corpus mmap/file rows |
| File-backed compressed search | IVF-PQ file or mmap searcher | Add rerank only when the raw-vector locality cost is acceptable |
The full algorithm table is in docs/algorithms.md.
Limits
- Search is approximate; tune recall with
ef_search,nprobe, and rerank pool sizes. - HNSW cosine and angular search need normalized vectors unless
auto_normalize(true)is enabled. - DiskANN is available but still experimental for production file-backed search.
- Some algorithms are research paths, not recommended defaults.
Documentation
License
MIT OR Apache-2.0