Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 158 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,178 @@
# The RaBitQ Library
# RaBitQ Library

> **New:** We have recently open-sourced the GPU implementation of RaBitQ for high-dimensional vector search. See [cuvs_rabitq](https://github.com/Stardust-SJF/cuvs_rabitq/tree/cuvs_ivf_rabitq).
[![C++ tests](https://github.com/VectorDB-NTU/RaBitQ-Library/actions/workflows/test.yaml/badge.svg)](https://github.com/VectorDB-NTU/RaBitQ-Library/actions/workflows/test.yaml)
[![Python tests](https://github.com/VectorDB-NTU/RaBitQ-Library/actions/workflows/python.yml/badge.svg)](https://github.com/VectorDB-NTU/RaBitQ-Library/actions/workflows/python.yml)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)

The RaBitQ Library provides efficient and lightweight implementations of the RaBitQ quantization algorithm ([1-bit version](https://arxiv.org/abs/2405.12497) and [multi-bit version](https://arxiv.org/abs/2409.09913)) and its applications in high-dimensional vector search. It also provides a [GPU implementation](https://github.com/Stardust-SJF/cuvs_rabitq/tree/cuvs_ivf_rabitq). The core algorithm RaBitQ is based on the research from [VectorDB group](https://vectordb-ntu.github.io/) at Nanyang Technological University, Singapore.
RaBitQ Library is a C++17 library with Python bindings for compact, accurate
vector quantization and approximate nearest-neighbor search. It provides:

The library is developped by Yutong Gou, Jianyang Gao, Yuexuan Xu, Jifan Shi and Zhonghao Yang.
- the [1-bit](https://arxiv.org/abs/2405.12497) and
[multi-bit](https://arxiv.org/abs/2409.09913) RaBitQ quantizers;
- IVF, HNSW, and [SymphonyQG](https://dl.acm.org/doi/abs/10.1145/3709730)
indexes powered by RaBitQ;
- Euclidean distance, inner product, and cosine similarity estimation; and
- optimized AVX2 and AVX-512 kernels with runtime CPU dispatch.

The library provides the following key features:
RaBitQ is developed by the
[VectorDB group](https://vectordb-ntu.github.io/) at Nanyang Technological
University, Singapore. A GPU implementation is also available in
[cuvs_rabitq](https://github.com/Stardust-SJF/cuvs_rabitq/tree/cuvs_ivf_rabitq).

* **RaBitQ** - a vector quantization algorithm as a drop-in replacement of binary and scalar quantization, offering an optimal theoretical error bound
* **RaBitQ for Vector Search** - a reference implementation of RaBitQ's combination with popular vector search indexes
## Quick start

RaBitQLib supports estimating similarity metrics including Euclidean distance, inner product and cosine similarity.
### Python

## RaBitQ
#### Requirements

RaBitQ is a vector quantization algorithm as a drop-in replacement of binary and scalar quantization. The key advantages of RaBitQ include
- Python 3.9 or newer
- a C++17 compiler
- CMake 3.15 or newer
- OpenMP
- an x86-64 CPU with AVX2 and FMA support

- **High Accuracy with Tiny Space** - RaBitQ achieves the state-of-the-art accuracy under diverse bit-width for the estimation of similarity metrics. It produces promising accuracy with even **1-bit per dimension**.
- **Fast Distance Estimation** - RaBitQ supports to estimate the similarity metrics with high efficiency based on bitwise operations or [FastScan](https://arxiv.org/abs/1704.07355).
- **Theoretical Error Bound** - RaBitQ provides an asymptotically optimal error bound for the estimation of distances and inner product. The error bound can be used for reliable ordering and reranking.
AVX2 and FMA are the baseline SIMD requirements. On CPUs that also support
AVX-512F, AVX-512BW, and AVX-512DQ, RaBitQ selects its AVX-512 kernels at
runtime. AVX-512 VPOPCNTDQ provides additional acceleration when available.

In this library, we provide simple interfaces to support advanced features of RaBitQ. The details are presented in the documentation.
On Ubuntu or Debian, install the system build tools and then install RaBitQ
from the repository:

```bash
sudo apt-get update
sudo apt-get install -y build-essential cmake libomp-dev

git clone https://github.com/VectorDB-NTU/RaBitQ-Library.git
cd RaBitQ-Library
python -m pip install .
```

## RaBitQ for Vector Search
In the library, RaBitQ is combined with IVF, HNSW and QG to deliever different trade-offs among time, space and accuracy.
The following complete example builds a small IVF index and searches it. It
uses deterministic synthetic data, so no dataset download is required.

Using RaBitQ with IVF and HNSW targets a balance between memory consumption and query performance. Only the quantization codes produced by RaBitQ are stored and the raw data vectors are not accessed during querying. Thus, these methods consume less memory than the raw dataset.
Using **4-bit, 5-bit and 7-bit** quantization usually suffices to produce **90%, 95% and 99% recall** respectively without reranking.
```python
import numpy as np
from rabitqlib import IvfIndex

rng = np.random.default_rng(42)
data = rng.standard_normal((500, 64)).astype(np.float32)
queries = rng.standard_normal((5, 64)).astype(np.float32)

# Assign vectors to five clusters and calculate their centroids.
cluster_ids = (np.arange(len(data)) % 5).astype(np.uint32)
centroids = np.stack(
[data[cluster_ids == cluster].mean(axis=0) for cluster in range(5)]
).astype(np.float32)

Using RaBitQ with QG targets the best query performance by using more memory. It creates multiple quantization codes for every vector to optimize the data access pattern. Thus, QG usually consumes 2x memory of the raw dataset.
index = IvfIndex(
dim=64,
max_elements=len(data),
num_clusters=5,
nbits=4,
metric="l2",
)
index.build(data, centroids, cluster_ids)

## RaBitQ in Industry
ids, distances = index.search(queries, k=10, nprobe=5)
print(ids.shape, distances.shape) # (5, 10) (5, 10)
print(ids[0])
```

The RaBitQ algorithm has been implemented in many real-world systems in industry including
Python bindings are also available for `HnswIndex` and `SymqgIndex`. See the
[Python examples](sample/python/) for index construction, querying, and index
persistence.

- [Milvus](https://github.com/milvus-io/milvus) - IVF + RaBitQ (C++)
- [Faiss](https://github.com/facebookresearch/faiss) - IVF + RaBitQ (C++)
- [VSAG](https://github.com/antgroup/vsag) - HGraph + RaBitQ (C++)
- [VectorChord](https://github.com/tensorchord/VectorChord) - IVF + RaBitQ (Rust)
- [Volcengine OpenSearch](https://www.volcengine.com/docs/6465/1553583) - DiskANN + RaBitQ
- [CockroachDB](https://github.com/cockroachdb/cockroach) - CSPANN + RaBitQ (Golang)
- [ElasticSearch](https://github.com/elastic/elasticsearch) - HNSW + RaBitQ (Java - the algorithm is adopted with some minor modifications and renamed as "BBQ")
- [Lucene](https://github.com/apache/lucene) - HNSW + RaBitQ (Java - the algorithm is adopted with some minor modifications and renamed as "BBQ")
- [turbopuffer](https://turbopuffer.com/blog/ann-v3#:~:text=ANN%20v3%20employs%20the%20RaBitQ) - SPFresh + RaBitQ
- [Zvec](https://github.com/alibaba/zvec) - HNSW/IVF + RaBitQ (C++)
### C++

## Acknowledgement
#### Requirements

We acknowledge Alexandr Guzhva, Li Liu, Chao Gao, Silu Huang, Jiabao Jin, Xiaoyao Zhong and Jinjing Zhou for valuable feedbacks.
- CMake 3.10 or newer
- a C++17 compiler with OpenMP support
- an x86-64 CPU with AVX2 and FMA support

## Reference
Please provide a reference of our paper if it helps in your systems or research projects.
AVX2 and FMA are the baseline SIMD requirements. On CPUs that also support
AVX-512F, AVX-512BW, and AVX-512DQ, RaBitQ selects its AVX-512 kernels at
runtime. AVX-512 VPOPCNTDQ provides additional acceleration when available.

<pre style="white-space: pre-wrap; word-break: break-word; font-family: monospace; background: #f5f5f5; padding: 1em; border-radius: 5px; font-size: 0.85em;">
Jianyang Gao, Yutong Gou, Yuexuan Xu, Yongyi Yang, Cheng Long, Raymond Chi-Wing Wong,
"Practical and Asymptotically Optimal Quantization of High-Dimensional Vectors in Euclidean Space for Approximate Nearest Neighbor Search",
SIGMOD 2025, available at https://arxiv.org/abs/2409.09913
</pre>
Clone and build the library and example programs:

```bash
git clone https://github.com/VectorDB-NTU/RaBitQ-Library.git
cd RaBitQ-Library

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
```

The index example executables are written to `bin/`. Their source code shows
the complete indexing and querying workflows:

- [IVF + RaBitQ](sample/cpp/ivf_rabitq_indexing.cpp)
- [HNSW + RaBitQ](sample/cpp/hnsw_rabitq_indexing.cpp)
- [SymphonyQG](sample/cpp/symqg_indexing.cpp)

A separate [RaBitQ quantization example](sample/cpp/quantizer.cpp) demonstrates
the lower-level quantizer API; it is provided as source and is not currently a
CMake target.

To build and run the C++ test suite:

```bash
cmake -S . -B build -DRABITQ_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
ctest --test-dir build --output-on-failure
```

GoogleTest is downloaded during test configuration. For a full benchmark on
the GIST dataset, see [`example.sh`](example.sh). More detailed API and
algorithm guidance is available in the [documentation](docs/docs/index.md).

## Why RaBitQ?

- **High accuracy with tiny codes.** RaBitQ provides state-of-the-art
similarity estimation across different bit widths and remains effective at
one bit per dimension.
- **Fast distance estimation.** Its kernels use bitwise operations and
[FastScan](https://arxiv.org/abs/1704.07355) for efficient search.
- **Theoretical error bounds.** RaBitQ provides an asymptotically optimal error
bound that can support reliable ordering and reranking.
- **Multiple index trade-offs.** IVF and HNSW prioritize memory efficiency,
while SymphonyQG uses additional memory to optimize query performance.

In typical workloads, 4-bit, 5-bit, and 7-bit quantization can achieve roughly
90%, 95%, and 99% recall, respectively, without reranking. Actual results
depend on the dataset, index configuration, and search parameters.

## RaBitQ in industry

RaBitQ has been adopted by vector databases, search engines, and libraries:

- [Milvus](https://github.com/milvus-io/milvus) — IVF + RaBitQ (C++)
- [Faiss](https://github.com/facebookresearch/faiss) — IVF + RaBitQ (C++)
- [VSAG](https://github.com/antgroup/vsag) — HGraph + RaBitQ (C++)
- [VectorChord](https://github.com/tensorchord/VectorChord) — IVF + RaBitQ (Rust)
- [Volcengine OpenSearch](https://www.volcengine.com/docs/6465/1553583) — DiskANN + RaBitQ
- [CockroachDB](https://github.com/cockroachdb/cockroach) — CSPANN + RaBitQ (Go)
- [Elasticsearch](https://github.com/elastic/elasticsearch) — HNSW + BBQ, a modified RaBitQ implementation (Java)
- [Lucene](https://github.com/apache/lucene) — HNSW + BBQ, a modified RaBitQ implementation (Java)
- [turbopuffer](https://turbopuffer.com/blog/ann-v3#:~:text=ANN%20v3%20employs%20the%20RaBitQ) — SPFresh + RaBitQ
- [Zvec](https://github.com/alibaba/zvec) — HNSW/IVF + RaBitQ (C++)

## Citation

If RaBitQ helps your research or system, please cite:

> Jianyang Gao, Yutong Gou, Yuexuan Xu, Yongyi Yang, Cheng Long, and Raymond
> Chi-Wing Wong. “Practical and Asymptotically Optimal Quantization of
> High-Dimensional Vectors in Euclidean Space for Approximate Nearest Neighbor
> Search.” SIGMOD 2025. [arXiv:2409.09913](https://arxiv.org/abs/2409.09913).

## Acknowledgements

RaBitQ Library is developed by Yutong Gou, Jianyang Gao, Yuexuan Xu, Jifan Shi,
and Zhonghao Yang. We thank Alexandr Guzhva, Li Liu, Chao Gao, Silu Huang,
Jiabao Jin, Xiaoyao Zhong, and Jinjing Zhou for their valuable feedback.

## License

RaBitQ Library is available under the [Apache License 2.0](LICENSE).
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ version = "0.1.1"
description = "RaBitQ Python bindings for HNSW, IVF, and SymQG"
readme = "README.md"
requires-python = ">=3.9"
dependencies = ["numpy"]

[project.optional-dependencies]
test = ["pytest>=7", "numpy"]
Expand Down
Loading