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 - High performance (v0.9.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
New in v0.5.0: MSTG is a high-performance hybrid index combining hierarchical clustering with graph navigation. Since v0.9.0, it is production-ready for large-scale vector search.
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 |
|---|---|---|
| Maturity | ✅ Production Ready | ✅ Production Ready |
| Testing | ✅ Comprehensive | ✅ Comprehensive |
| Best For | All use cases (10K-10M+) | Large-scale (100K-1B+) |
| Recall | 85-95% (well-tuned) | 90-99%+ |
| Build Time | Fast (k-means) | Moderate (hierarchical) |
| Query Speed | Fast | Very Fast (HNSW navigation) |
| Memory | Low | Low-Medium (configurable) |
| Stability | ✅ Stable | ✅ Stable |
| Documentation | ✅ Complete | ✅ Complete |
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.
Platform Support
x86_64 (Intel/AMD): ✅ Fully supported and tested
ARM64 (Apple Silicon, ARM servers): ⚠️ Known issues - See ARM64_KNOWN_ISSUES.md
ARM64 Notice: The current implementation has critical bugs on ARM64/AArch64 platforms that affect both L2 and Inner Product metrics. Distance calculations produce incorrect results, making the library unreliable on Apple Silicon Macs and ARM servers. We're actively investigating these issues. For now, production use on ARM64 is NOT recommended.
Quick Start
Add to your Cargo.toml:
[]
= "0.9"
IVF+RaBitQ Index (Recommended for Production)
Build an IVF+RaBitQ index and search in ~10 lines:
use ;
use *;
MSTG Index
Build an MSTG index and search in ~10 lines:
use ;
use *;
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
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)
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.