RaBitQ-rs
Pure Rust implementation of advanced vector quantization and search algorithms:
- RaBitQ quantization with IVF (Inverted File) search - Production ready
- MSTG (Multi-Scale Tree Graph) index - ⚠️ Experimental (v0.5.0)
Up to 32× memory compression with significantly higher accuracy than traditional Product Quantization (PQ) or Scalar Quantization (SQ).
Why RaBitQ?
RaBitQ delivers exceptional compression-accuracy trade-offs for approximate nearest neighbor search:
- vs. Raw Vectors: Achieve up to 32× memory reduction with configurable compression ratios
- vs. PQ/SQ: Substantially higher accuracy, especially at high recall targets (90%+)
- How it Works: Combines 1-bit binary codes with multi-bit refinement codes for precise distance estimation
The quantization applies to residual vectors (data - centroid), enabling accurate reconstruction even at extreme compression rates.
Why This Rust Implementation?
This library provides a feature-complete RaBitQ + IVF search engine with all optimizations from the original C++ implementation:
- ✅ Faster Config Mode: 100-500× faster index building with <1% accuracy loss
- ✅ FHT Rotation: Fast Hadamard Transform for efficient orthonormal rotations
- ✅ SIMD Accelerated: Optimized distance computations on modern CPUs
- ✅ Memory Safe: No segfaults, no unsafe code in dependencies
- ✅ Complete IVF Pipeline: Training (built-in k-means or FAISS-compatible), search, persistence
MSTG: Multi-Scale Tree Graph Index (⚠️ Experimental)
New in v0.5.0: MSTG is an experimental hybrid index combining hierarchical clustering with graph navigation.
⚠️ Experimental Status: MSTG is under active development and lacks comprehensive testing and tuning. For production workloads, we recommend using the battle-tested IVF+RaBitQ index. MSTG is provided for research and experimentation purposes.
Key Features
- Hierarchical Balanced Clustering: Adaptive multi-scale clustering with configurable branching factor
- Closure Assignment: Vectors can belong to multiple clusters (RNG rule) for better recall
- HNSW Graph Navigation: Fast approximate nearest centroid search
- Flexible Precision: FP32, BF16, FP16, or INT8 for centroids
- Dynamic Pruning: Adaptive cluster selection based on query-centroid distances
- Python Bindings: Seamless integration with NumPy and ann-benchmarks
When to Use MSTG vs IVF+RaBitQ
| Feature | IVF+RaBitQ | MSTG (Experimental) |
|---|---|---|
| Maturity | ✅ Production Ready | ⚠️ Experimental |
| Testing | ✅ Comprehensive | ⚠️ Limited |
| Best For | All use cases (10K-10M+) | Research & experimentation |
| Recall | 85-95% (well-tuned) | 90-98% (theoretical) |
| Build Time | Fast (k-means) | Moderate (hierarchical) |
| Query Speed | Fast | Very Fast (HNSW navigation) |
| Memory | Low | Low-Medium (configurable) |
| Stability | ✅ Stable | ⚠️ API may change |
| Documentation | ✅ Complete | 🚧 In progress |
Recommendation: Use IVF+RaBitQ for production workloads. It's well-tested, documented, and optimized. Consider MSTG only if you're researching advanced indexing techniques or willing to help with testing and tuning.
Quick Start
Add to your Cargo.toml:
[]
= "0.5"
IVF+RaBitQ Index (Recommended for Production)
Build an IVF+RaBitQ index and search in ~10 lines:
use ;
use *;
MSTG Index (⚠️ Experimental - For Research Only)
Build an MSTG index and search in ~10 lines:
use ;
use *;
⚠️ Note: MSTG is experimental and not recommended for production use. Use IVF+RaBitQ for stable, well-tested performance.
Usage
IVF+RaBitQ Index
Training with Built-in K-Means
use ;
let index = train?;
Training with Pre-computed Clusters (FAISS-Compatible)
If you already have centroids and cluster assignments from FAISS or another tool:
use ;
let index = train_with_clusters?;
Using Faster Config for Large Datasets
For datasets >100K vectors, enable faster_config to accelerate training by 100-500× with minimal accuracy loss (<1%):
let index = train?;
Searching
use SearchParams;
let params = new;
let results = index.search?;
for result in results.iter.take
Parameter Tuning:
nprobe: Higher = better recall, slower search (typical: 10-1024)top_k: Number of neighbors to returntotal_bits: More bits = higher accuracy, larger index (typical: 3-7)
Saving and Loading
// Save index to disk (with CRC32 checksum)
index.save?;
// Load index from disk
let loaded_index = load?;
MSTG Index (⚠️ Experimental)
Building an MSTG Index
use ;
use Metric;
let mut config = default;
// Configure clustering
config.max_posting_size = 5000; // Max vectors per cluster
config.branching_factor = 10; // Hierarchical branching
config.balance_weight = 1.0; // Balance vs purity trade-off
// Configure closure assignment (multi-assignment)
config.closure_epsilon = 0.15; // Distance threshold
config.max_replicas = 8; // Max assignments per vector
// Configure quantization
config.rabitq_bits = 7; // 3-8 bits (7 recommended)
config.faster_config = true; // Fast mode
config.metric = L2; // or Metric::InnerProduct
// Configure HNSW graph
config.hnsw_m = 32; // Connectivity
config.hnsw_ef_construction = 200; // Build quality
config.centroid_precision = BF16; // FP32/BF16/FP16/INT8
let index = build?;
Searching
use SearchParams;
// Option 1: Pre-defined modes
let params = high_recall; // 95%+ recall
let params = balanced; // ~90% recall (default)
let params = low_latency; // ~80% recall, fastest
// Option 2: Custom parameters
let params = new;
let results = index.search;
for result in results.iter.take
Parameter Tuning:
ef_search: Higher = better recall, slower (typical: 50-300)pruning_epsilon: Higher = more clusters searched (typical: 0.4-0.8)max_posting_size: Smaller = more clusters, better balance (typical: 3000-10000)rabitq_bits: More bits = higher accuracy (typical: 5-7)
⚠️ Reminder: MSTG is experimental. For production use, refer to the IVF+RaBitQ documentation above.
CLI Tool: Benchmark on GIST-1M
The ivf_rabitq binary lets you evaluate RaBitQ on standard datasets like GIST-1M:
1. Download GIST-1M Dataset
2. Build Index
3. Run Benchmark
This performs an automatic nprobe sweep and reports:
nprobe | QPS | Recall@100
-------|---------|------------
5 | 12500 | 45.2%
10 | 8200 | 62.8%
20 | 5100 | 75.4%
...
Alternative: Pre-cluster with FAISS
For C++ library compatibility, generate clusters using the provided Python helper:
Python Bindings
RaBitQ-RS provides Python bindings for the MSTG (Multi-Scale Tree Graph) index, enabling seamless integration with Python machine learning workflows and ann-benchmarks.
Installation
# Install dependencies
# Build and install from source
Quick Start (Python)
# Generate sample data
=
=
# Create and build index
=
# Search
=
# Results: numpy array of shape (k, 2) with [id, distance]
Configuration Parameters
Index Parameters (Build Time):
dimension: Vector dimensionality (required)metric: Distance metric - "euclidean" (L2) or "angular" (inner product)max_posting_size: Maximum vectors per cluster (default: 5000)rabitq_bits: Quantization bits, 3-8 (default: 7)faster_config: Fast quantization mode (default: True)centroid_precision: Centroid storage - "fp32", "bf16", "fp16", "int8" (default: "bf16")hnsw_m: HNSW connectivity (default: 32)hnsw_ef_construction: HNSW build quality (default: 200)
Query Parameters (Search Time):
ef_search: Centroid candidates to explore (default: 150)pruning_epsilon: Dynamic pruning threshold (default: 0.6)k: Number of neighbors to return
Batch Queries
# Query multiple vectors efficiently
=
=
# Returns list of numpy arrays, one per query
Memory Usage
=
ann-benchmarks Integration
RaBitQ-RS includes a complete ann-benchmarks wrapper for standardized evaluation:
# Run benchmarks
See ann_benchmarks/README.md for detailed benchmark configuration and usage.
Testing
Run the test suite before committing changes:
# Rust tests
# Python tests
All tests use seeded RNGs for reproducible results.
Citation
If you use RaBitQ in your research, please cite the original paper:
Original C++ Implementation: VectorDB-NTU/RaBitQ-Library
License
Licensed under the Apache License, Version 2.0. See LICENSE for details.