# turbovec: TurboQuant 알고리즘을 Rust로 구현한 학습이 필요 없는 벡터 인덱스

**URL:** https://discuss.pytorch.kr/t/turbovec-turboquant-rust/10295
**Category:** 읽을거리&정보공유
**Tags:** faiss, turbovec, rag, turboquant, rust, quantization, vector-search
**Created:** [5월 21, 2026, 9:30오후 UTC](https://discuss.pytorch.kr/t/turbovec-turboquant-rust/10295 "2026-05-21T21:30:44Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![9bow](https://discuss.pytorch.kr/user_avatar/discuss.pytorch.kr/9bow/32/16301_2.png) [@9bow](https://discuss.pytorch.kr/u/9bow)
#### Post date: [5월 21, 2026, 9:30오후 UTC](https://discuss.pytorch.kr/t/turbovec-turboquant-rust/10295/1 "2026-05-21T21:30:44Z")

</div>

![turbovec의 TurboQuant 기반 벡터 검색 헤더 이미지](https://discuss.pytorch.kr/uploads/default/original/3X/b/3/b3c3f3e3621813bade20a80fc067aba0ee3999e9.jpeg)

## turbovec 소개

turbovec는 Google Research가 ICLR 2026에서 공개한 [TurboQuant](https://arxiv.org/abs/2504.19874) 알고리즘을 Rust로 구현하고 Python 바인딩으로 노출한 **벡터 인덱스(vector index) 라이브러리** 입니다. 핵심 주장은 단순합니다. _1,000만 건 규모의 임베딩(embedding)을 float32로 저장하면 31GB가 필요하지만, turbovec은 같은 데이터를 4GB에 담으면서 FAISS보다 빠르게 검색한다._ 사용자는 별도의 코드북(codebook) 학습이나 캘리브레이션 패스 없이 벡터를 그대로 인덱스에 추가하기만 하면 됩니다.

기존 FAISS의 PQ(Product Quantization) 계열 양자화는 _데이터 의존적(data-dependent) k-means 코드북 학습_ 이 필요합니다. 데이터가 늘어나거나 도메인이 바뀌면 코드북을 다시 학습하고 인덱스를 재구축해야 했고, 멀티 테넌트 RAG처럼 임베딩 분포가 자주 변하는 환경에서는 이 과정이 운영의 큰 부담이었습니다. TurboQuant는 이 문제를 _데이터에 무관한(data-oblivious) 양자화기_ 로 풀어냅니다. 입력 벡터에 무작위 직교 회전(random orthogonal rotation)을 한 번 적용하면, 회전된 좌표의 분포가 입력과 상관없이 _알려진 Beta 분포_ 가 되어 고차원에서 Gaussian으로 수렴한다는 정리에 기반합니다. 이 분포는 사전에 알고 있으므로, Lloyd-Max 알고리즘으로 각 좌표를 양자화하는 _최적 버킷(bucket)_ 도 데이터를 보지 않고 미리 계산해 둘 수 있습니다.

라이선스는 [MIT License](https://github.com/RyanCodrai/turbovec/blob/main/LICENSE) 로 공개되어 있으며, PyPI(`turbovec`)와 [crates.io](http://crates.io)(`turbovec`) 양쪽으로 배포됩니다. Python 측에서는 LangChain, LlamaIndex, Haystack, Agno 네 가지 RAG 프레임워크용 _드롭인 어댑터(drop-in adapter)_ 까지 함께 제공되어, 기존 파이프라인에서 `import` 한 줄만 바꿔도 인메모리 벡터 스토어를 그대로 대체할 수 있도록 설계되어 있습니다. turbovec은 관리형 서비스나 외부 API 호출 없이 _순수 로컬(pure local)_ 로 동작하도록 만들어졌으며, 오픈소스 임베딩 모델과 짝지으면 데이터가 사용자의 머신이나 VPC 밖으로 나가지 않는 _완전 에어갭(air-gapped) RAG 스택_ 을 구성할 수 있습니다.

## turbovec 압축률과 메모리 효과

 ![turbovec의 비트폭별 압축률 비교 차트](https://discuss.pytorch.kr/uploads/default/original/3X/9/8/98f62985dbec5ab21a0dfdc928b2c1692f0c3acc.png)

turbovec은 OpenAI 임베딩 차원(d=1536) 기준 다음 절감 효과를 보입니다.

- **2비트 양자화** : 1,536차원 float32 벡터 한 개의 원본 크기 6,144바이트가 **384바이트** 로 줄어 약 **16배 압축** 입니다.
- **4비트 양자화** : 동일 벡터가 768바이트가 되어 약 8배 압축이며, 회복률은 2비트 대비 훨씬 안정적입니다.
- **10M 코퍼스 메모리** : float32 그대로 보관하면 약 31GB가 필요한데, 2비트 양자화로는 4GB 수준에 들어옵니다.

이 압축은 단순히 비트수만 줄이는 것이 아닙니다. 양자화는 일반적으로 _내적(inner product)_ 을 체계적으로 과소 추정하는 경향이 있는데, turbovec은 인코딩 시점에 _벡터당 길이 재정규화 스칼라(length-renormalization scalar)_ 를 함께 계산해 저장합니다. 검색 커널은 후보별 점수에 이 스칼라를 곱하므로 _내적 추정기(inner-product estimator)_ 가 검색 시점 비용 0과 추가 저장 0으로 _편향이 사라진(unbiased)_ 형태로 동작합니다. 인코딩 비용은 벡터당 한 번의 `d`차원 내적이 추가되는 정도이며, 1M × d=1536 기준 1초 미만의 _원샷(one-shot) 비용_ 입니다.

## turbovec 검색 속도와 회복률

 ![turbovec과 FAISS의 d=1536 회복률 비교](https://discuss.pytorch.kr/uploads/default/original/3X/9/2/925f09cab2463b5d9168f756332477b2449e6244.png)

벤치마크는 100K 벡터, 1K 쿼리, k=64, 다섯 번 실행의 중앙값을 기준으로 측정되었습니다. 비교 대상은 _프로덕션 수준 PQ의 표준 선택지_ 로 자주 쓰이는 FAISS `IndexPQ` (LUT256, nbits=8, float32 LUT)입니다.

회복률 측면에서는 다음 패턴이 확인됩니다.

- **OpenAI d=1536 / d=3072** : TurboQuant가 R@1 기준 FAISS 대비 0.4~3.4점 우위이며, 2비트·4비트 모두 k=4 시점에는 양쪽이 1.0으로 수렴합니다.
- **GloVe d=200** : 저차원에서는 Beta 분포 가정의 점근적 근사가 다소 약해져, 4비트에서는 turbovec이 0.3점 앞서고 2비트에서는 1.2점 뒤집니다. 다만 두 곡선 모두 k≈16에서 FAISS와 만납니다.

 ![turbovec의 ARM(Apple M3 Max) 단일 스레드 속도 비교](https://discuss.pytorch.kr/uploads/default/original/3X/1/d/1db89ea8ffbba96a7fc06694b768c7519d6ed61d.png)

속도 측면에서 turbovec의 SIMD 커널은 다음과 같이 동작합니다.

- **ARM (Apple M3 Max, NEON 커널)**: 모든 설정에서 FAISS FastScan 대비 12~20% 빠릅니다.
- **x86 (Intel Xeon Platinum 8481C, AVX-512BW 커널)**: 4비트 설정에서는 1~6% 우위, 2비트 단일 스레드에서는 FAISS와 ~1% 이내, 2비트 멀티스레드 d=1536/3072 두 케이스에서만 FAISS의 AVX-512 VBMI 경로에 2~4% 뒤집니다.

 ![turbovec의 x86(Sapphire Rapids) 단일 스레드 속도 비교](https://discuss.pytorch.kr/uploads/default/original/3X/f/8/f86864704ba50e746d996c56e1c8a954959edbfd.png)

x86 빌드는 `x86-64-v3` (AVX2 기반, Haswell 2013+) 을 기본 타깃으로 하고, AVX-512 경로는 런타임 `is_x86_feature_detected!` 매크로로 감지해 자동 전환됩니다. 즉, AVX-512가 없는 머신에서도 AVX2 폴백 커널로 동일한 코드를 그대로 돌릴 수 있습니다.

## turbovec의 핵심 알고리즘 흐름

turbovec이 적용하는 다섯 단계는 README의 _How it works_ 섹션에 단순한 형태로 정리되어 있습니다.

1. **정규화(normalize)**: 각 벡터의 길이(norm)를 떼어 단일 float으로 저장하고, 본체는 단위 방향(unit direction)으로 처리합니다.
2. **무작위 직교 회전(random rotation)**: 모든 벡터에 동일한 무작위 직교 행렬을 곱합니다. 회전 후 각 좌표는 입력과 상관없이 알려진 Beta 분포를 따르며, 고차원에서 N(0, 1/d) Gaussian에 수렴합니다.
3. **Lloyd-Max 스칼라 양자화** : 분포가 알려져 있으므로 _Lloyd-Max 알고리즘_ 으로 평균 제곱 오차(MSE)를 최소화하는 버킷 경계와 중심값을 _데이터를 보지 않고_ 한 번에 계산합니다. 2비트는 4버킷, 4비트는 16버킷입니다.
4. **비트 패킹(bit-packing)**: 각 좌표가 0~3 또는 0~15의 작은 정수가 되었으므로 비트 단위로 패킹합니다. d=1536 기준 6,144바이트 → 384바이트(2비트)로 떨어집니다.
5. **길이 재정규화 점수(length-renormalized scoring)**: 인코딩 시점에 한 번 계산해 저장한 `||v|| / ⟨u, x̂⟩` 스칼라를 검색 커널이 후보별 점수에 곱해, 내적 추정기를 검색 시점 비용 0에 편향이 없는 형태로 만듭니다.

Lloyd-Max 코드북은 _섀넌(Shannon) 정보 이론_ 의 왜곡-비트율 하한 대비 2.7배 이내의 왜곡(distortion)에 도달하고, 길이 재정규화 단계가 코드북 자체가 만들어내는 잔존 편향을 제거하는 구조입니다.

검색 시점에는 데이터베이스 벡터를 _복원하지 않습니다._ 쿼리를 동일한 무작위 직교 행렬로 한 번 회전한 뒤, 회전된 쿼리와 코드북 중심값을 직접 점수화합니다. 스코어링 커널은 ARM에서는 NEON, 최신 x86에서는 AVX-512BW, 그 외 x86에서는 AVX2 폴백 SIMD intrinsic을 사용하며, 처리량을 최대화하기 위해 _nibble-split lookup table_ 을 채택합니다. x86 커널의 패킹 레이아웃, 니블 LUT 스코어링, u16 누산 전략은 FAISS의 FastScan 구현에서 차용한 부분이며, README의 References 섹션에 출처가 명시되어 있습니다.

## turbovec Python API와 RAG 통합

Python 사용 측면에서는 두 가지 인덱스가 제공됩니다. 기본 `TurboQuantIndex` 는 추가 순서대로 슬롯 인덱스를 부여하고, `IdMapIndex` 는 사용자 지정 `uint64` 외부 ID를 유지해 _삭제(remove)_ 가 O(1)에 가능합니다.

```python
import numpy as np
from turbovec import TurboQuantIndex, IdMapIndex

# 1) 기본 인덱스 - 슬롯 인덱스 기반
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")

# 2) 외부 uint64 ID를 보존하는 인덱스
idmap = IdMapIndex(dim=1536, bit_width=4)
idmap.add_with_ids(vectors, np.array([1001, 1002, 1003], dtype=np.uint64))
idmap.remove(1002) # O(1) 삭제
scores, ids = idmap.search(query, k=10) # ids 는 사용자 ID

# 3) 외부 시스템이 좁힌 후보 집합으로 필터링하는 하이브리드 검색
allowed = np.array(
    db.execute("SELECT id FROM docs WHERE tenant=?", (tenant_id,)).fetchall(),
    dtype=np.uint64,
)
scores, ids = idmap.search(query, k=10, allowlist=allowed)

```

세 번째 예시인 _allowlist 필터링_ 이 turbovec의 차별점 중 하나입니다. 필터링은 32-벡터 블록 단위로 SIMD 커널 내부에서 수행되며, 허용된 슬롯이 하나도 없는 블록은 LUT 조회·점수 계산을 _단락(short-circuit)_ 합니다. 선택적 필터(인덱스 대비 작은 비율만 허용되는 경우)는 SIMD 비용 대부분을 회피하므로, _후처리 필터링_ 대비 비용 절감 효과가 큽니다. 출력 길이는 `min(k, len(allowed))` 로, 허용 집합이 `k` 보다 작으면 정확히 그 크기만큼만 결과가 반환됩니다.

프레임워크 통합은 모두 `pip install turbovec[<integration>]` 형태로 설치합니다.

- **LangChain** : `pip install turbovec[langchain]` - `langchain_core.vectorstores.InMemoryVectorStore` 대체
- **LlamaIndex** : `pip install turbovec[llama-index]` - `llama_index.core.vector_stores.SimpleVectorStore` 대체
- **Haystack** : `pip install turbovec[haystack]` - `haystack.document_stores.in_memory.InMemoryDocumentStore` 대체
- **Agno** : `pip install turbovec[agno]` - `agno.vectordb.lancedb.LanceDb` 대체

## turbovec Rust 사용 예시

turbovec은 Rust 크레이트로도 동일한 API 표면을 제공합니다. Python 바인딩이 PyO3를 통해 같은 코어를 호출하므로, 임베딩 파이프라인이 Rust 서비스 안에 있다면 별도 변환 없이 그대로 사용할 수 있습니다.

```rust
use turbovec::{TurboQuantIndex, IdMapIndex};

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();

// 외부 ID 보존 및 O(1) 삭제가 필요한 경우
let mut id_index = IdMapIndex::new(1536, 4);
id_index.add_with_ids(&vectors, &[1001, 1002, 1003]);
let (scores, ids) = id_index.search(&queries, 10);
id_index.remove(1002);
id_index.write("index.tvim").unwrap();

```

크레이트는 `cargo add turbovec` 으로 설치하며, x86\_64 빌드는 `.cargo/config.toml` 을 통해 `x86-64-v3` (AVX2 기반, Haswell 2013+) 을 기본 타깃으로 합니다. AVX-512 커널은 런타임 `is_x86_feature_detected!` 매크로로 감지해 자동 전환되므로, AVX-512 미지원 CPU에서도 AVX2 폴백 커널로 동일한 코드를 그대로 실행할 수 있습니다.

## 라이선스

turbovec은 [MIT License](https://github.com/RyanCodrai/turbovec/blob/main/LICENSE) 로 공개되어 있습니다. 상업적 활용·수정·재배포가 자유로우며, 저장소에 동봉된 라이선스 파일과 저작권 고지를 그대로 유지하면 됩니다. 또한 turbovec은 [TurboQuant 논문(arXiv:2504.19874)](https://arxiv.org/abs/2504.19874) 의 알고리즘, [RaBitQ 논문(SIGMOD 2024)](https://arxiv.org/abs/2405.12497) 의 길이 재정규화 보정, 그리고 [FAISS FastScan](https://github.com/facebookresearch/faiss/wiki/Fast-accumulation-of-PQ-and-AQ-codes-(FastScan)) 의 패킹 레이아웃·니블 LUT·u16 누산 전략을 결합한 구현체임을 README의 References 섹션이 명시하고 있어, 학술적·공학적 출처와의 관계가 명확합니다.

## 📜 TurboQuant 논문 (ICLR 2026, arXiv:2504.19874)

> **[TurboQuant: Online Vector Quantization with Near-optimal Distortion Rate](https://arxiv.org/abs/2504.19874)**
>
> Vector quantization, a problem rooted in Shannon's source coding theory, aims to quantize high-dimensional Euclidean vectors while minimizing distortion in their geometric structure. We propose TurboQuant to address both mean-squared error (MSE) and...

## 📜 RaBitQ 논문 (SIGMOD 2024, arXiv:2405.12497)

> **[RaBitQ: Quantizing High-Dimensional Vectors with a Theoretical Error Bound...](https://arxiv.org/abs/2405.12497)**
>
> Searching for approximate nearest neighbors (ANN) in the high-dimensional Euclidean space is a pivotal problem. Recently, with the help of fast SIMD-based implementations, Product Quantization (PQ) and its variants can often efficiently and...

## :github: turbovec 프로젝트 GitHub 저장소

> **[GitHub - RyanCodrai/turbovec: A vector index built on TurboQuant, written in...](https://github.com/RyanCodrai/turbovec)**
>
> A vector index built on TurboQuant, written in Rust with Python bindings

## 더 읽어보기

- [turboquant-pytorch: Google의 TurboQuant를 PyTorch로 처음부터 직접 구현한 LLM KV 캐시 양자화 라이브러리](https://discuss.pytorch.kr/t/turboquant-pytorch-google-turboquant-pytorch-llm-kv/9448)

- [Vectorlite: SQLite용 Vector 검색 확장 (feat. HNSW)](https://discuss.pytorch.kr/t/vectorlite-sqlite-vector-feat-hnsw/4824)

- [벡터 유사도 검색이 무엇인가요? (What is Vector Similarity Search?)](https://discuss.pytorch.kr/t/what-is-vector-similarity-search/2475)

- [[GN] Vector Database가 무엇인가요?](https://discuss.pytorch.kr/t/gn-vector-database/1516)

- [Advanced RAG Cookbooks: RAG 기술에 대한 종합 가이드 (feat. Athina.AI)](https://discuss.pytorch.kr/t/advanced-rag-cookbooks-rag-feat-athina-ai/5654)

* * *

_이 글은 GPT 모델로 정리한 글을 바탕으로 한 것으로, 원문의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 원문도 함께 참고해주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 덧글로 알려주시기를 부탁드립니다._ 🤗

[:pytorch:파이토치 한국 사용자 모임🇰🇷](https://pytorch.kr/)이 정리한 이 글이 유용하셨나요? [회원으로 가입](https://discuss.pytorch.kr/signup)하시면 주요 글들을 이메일💌로 보내드립니다! (기본은 Weekly지만 [Daily로 변경도 가능](https://discuss.pytorch.kr/my/preferences/emails)합니다.)

🎁 아래↘쪽에 좋아요👍를 눌러주시면 새로운 소식들을 정리하고 공유하는데 힘이 됩니다~ 🤩
