Skip to main content

Fast vector quantization with 2-4 bit compression and SIMD search

Project description

turbovec

Fast vector quantization in Rust with Python bindings. Compresses vectors to 2-4 bits per dimension with near-optimal distortion. Implementation of TurboQuant (Google Research, ICLR 2026).

Unlike trained methods like FAISS PQ, TurboQuant is data-oblivious — no training step, no codebook retraining when data changes, and new vectors can be added at any time. This means faster index creation, simpler infrastructure, and comparable or higher recall.

Python

pip install turbovec
from turbovec import TurboQuantIndex

index = TurboQuantIndex(dim=1536, bit_width=4)
index.add(vectors)
index.add(more_vectors)

scores, indices = index.search(query, k=10)

index.write("my_index.tq")
loaded = TurboQuantIndex.load("my_index.tq")

Rust

cargo add turbovec
use turbovec::TurboQuantIndex;

let mut index = TurboQuantIndex::new(1536, 4);
index.add(&vectors);
let results = index.search(&queries, 10);
index.write("index.tv").unwrap();
let loaded = TurboQuantIndex::load("index.tv").unwrap();

Recall

TurboQuant vs FAISS IndexPQFastScan (100K vectors, k=64). FAISS PQ configurations sized to match TurboQuant compression ratios.

Recall d=1536

Recall d=3072

Both converge to 1.0 by k=4-8. At d=3072 2-bit, TurboQuant recall exceeds FAISS (0.912 vs 0.903). At d=1536 2-bit, FAISS is slightly ahead (0.882 vs 0.870). The recall discrepancy between TQ and FAISS varies by dimension and bit width — this requires further investigation. Full results: d=1536 2-bit, d=1536 4-bit, d=3072 2-bit, d=3072 4-bit, GloVe 2-bit, GloVe 4-bit.

No FAISS FastScan comparison for GloVe d=200 (dimension not compatible with FastScan's m%32 requirement).

Compression

Compression

Search Speed

All benchmarks: 100K vectors, 1K queries, k=64, median of 5 runs.

ARM (Apple M3 Max)

ARM Speed — Single-threaded

ARM Speed — Multi-threaded

On ARM, TurboQuant beats FAISS FastScan by 13–20% across every config.

x86 (Intel Sapphire Rapids, 4 vCPUs)

x86 Speed — Single-threaded

x86 Speed — Multi-threaded

On x86, TurboQuant is 10–29% behind FAISS. Optimization is ongoing.

How it works

Each vector is a direction on a high-dimensional hypersphere. TurboQuant compresses these directions using a simple insight: after applying a random rotation, every coordinate follows a known distribution -- regardless of the input data.

1. Normalize. Strip the length (norm) from each vector and store it as a single float. Now every vector is a unit direction on the hypersphere.

2. Random rotation. Multiply all vectors by the same random orthogonal matrix. After rotation, each coordinate independently follows a Beta distribution that converges to Gaussian N(0, 1/d) in high dimensions. This holds for any input data -- the rotation makes the coordinate distribution predictable.

3. Lloyd-Max scalar quantization. Since the distribution is known, we can precompute the optimal way to bucket each coordinate. For 2-bit, that's 4 buckets; for 4-bit, 16 buckets. The Lloyd-Max algorithm finds bucket boundaries and centroids that minimize mean squared error. These are computed once from the math, not from the data.

4. Bit-pack. Each coordinate is now a small integer (0-3 for 2-bit, 0-15 for 4-bit). Pack these tightly into bytes. A 1536-dim vector goes from 6,144 bytes (FP32) to 384 bytes (2-bit). That's 16x compression.

Search. Instead of decompressing every database vector, we rotate the query once into the same domain and score directly against the codebook values. The scoring kernel uses SIMD intrinsics (NEON on ARM, AVX2 on x86) with nibble-split lookup tables for maximum throughput.

The paper proves this achieves distortion within a factor of 2.7x of the information-theoretic lower bound (Shannon's distortion-rate limit). You cannot do much better for a given number of bits.

Building

Python (via maturin)

pip install maturin
cd turbovec-python
RUSTFLAGS="-C target-cpu=native" maturin build --release
pip install target/wheels/*.whl

Rust

cargo build --release

Running benchmarks

Download datasets:

python3 benchmarks/download_data.py all            # all datasets
python3 benchmarks/download_data.py glove          # GloVe d=200
python3 benchmarks/download_data.py openai-1536    # OpenAI DBpedia d=1536
python3 benchmarks/download_data.py openai-3072    # OpenAI DBpedia d=3072

Each benchmark is a self-contained script in benchmarks/suite/. Run any one individually:

python3 benchmarks/suite/speed_d1536_2bit_arm_mt.py
python3 benchmarks/suite/recall_d1536_2bit.py
python3 benchmarks/suite/compression.py

Run all benchmarks for a category:

for f in benchmarks/suite/speed_*arm*.py; do python3 "$f"; done    # all ARM speed
for f in benchmarks/suite/speed_*x86*.py; do python3 "$f"; done    # all x86 speed
for f in benchmarks/suite/recall_*.py; do python3 "$f"; done       # all recall
python3 benchmarks/suite/compression.py                            # compression

Results are saved as JSON to benchmarks/results/. Regenerate charts:

python3 benchmarks/create_diagrams.py

References

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

turbovec-0.1.2.tar.gz (37.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

turbovec-0.1.2-cp39-abi3-manylinux_2_28_x86_64.whl (787.3 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ x86-64

turbovec-0.1.2-cp39-abi3-manylinux_2_28_aarch64.whl (899.7 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ ARM64

turbovec-0.1.2-cp39-abi3-macosx_11_0_arm64.whl (760.5 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

Details for the file turbovec-0.1.2.tar.gz.

File metadata

  • Download URL: turbovec-0.1.2.tar.gz
  • Upload date:
  • Size: 37.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for turbovec-0.1.2.tar.gz
Algorithm Hash digest
SHA256 6417839f534dfb6f8c641ca49e7005138e92f5301a06f658be78cc5a0e13bbe5
MD5 9396327dec14da3c1884f058334efa51
BLAKE2b-256 e439d1f5df4ca5fa40dcb04ed2d7d312a4a418a728791e54398b96ccd21ed03b

See more details on using hashes here.

Provenance

The following attestation bundles were made for turbovec-0.1.2.tar.gz:

Publisher: release.yml on RyanCodrai/turbovec

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file turbovec-0.1.2-cp39-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for turbovec-0.1.2-cp39-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a10662e347b84a7f7cb0ba785511905d4ac33d07b0d30b0f050a930f30247bff
MD5 68eca677904d40784a74e259cb52ba33
BLAKE2b-256 f212d3246895555a9e13251713c1ffc292ccb6ce00b0703ba9f8254b51821516

See more details on using hashes here.

Provenance

The following attestation bundles were made for turbovec-0.1.2-cp39-abi3-manylinux_2_28_x86_64.whl:

Publisher: release.yml on RyanCodrai/turbovec

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file turbovec-0.1.2-cp39-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for turbovec-0.1.2-cp39-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 506cda1f7ac32d3cb7be4a5f0c95c3923a1f863a2c6494cd0c0e1c57922ac97f
MD5 310635376dbd4c26dfdb36fd86ef9e87
BLAKE2b-256 b294c54a5edec6d7110b16ba6fe6a763128ae81686e2ab63fbcd9f0fc5972fb9

See more details on using hashes here.

Provenance

The following attestation bundles were made for turbovec-0.1.2-cp39-abi3-manylinux_2_28_aarch64.whl:

Publisher: release.yml on RyanCodrai/turbovec

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file turbovec-0.1.2-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for turbovec-0.1.2-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 97ce70905fa6796c83fec4186cda426fee95ceb81b747e1df3cfb7d090374810
MD5 5ae0bce4d31529dd76290cf77f6f5a36
BLAKE2b-256 dea3a2beff219723855320b9a74c3473b072100d1c54a51ae0752e782a6f95d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for turbovec-0.1.2-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on RyanCodrai/turbovec

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page