turbovec은 turboquant 계열 벡터 양자화를 실제 검색 인덱스로 구현한 Rust/Python 라이브러리다. 10M 문서 임베딩을 FP32로 저장하면 31GB가 필요한데, turbovec은 이를 약 4GB 수준으로 줄이면서 로컬에서 빠르게 검색하는 것을 목표로 한다.
핵심 특징
| 특징 | 설명 |
|---|---|
| 훈련 없는 인덱싱 | codebook training 없이 벡터를 추가하면 바로 압축·색인 |
| 2~4비트 압축 | 고차원 임베딩을 bit-pack해 메모리 사용량 감소 |
| SIMD 커널 | ARM NEON, x86 AVX-512BW, AVX2 fallback |
| filtered search | allowlist 또는 bitmask로 후보 집합 제한 |
| Rust/Python 지원 | Rust core와 Python binding 제공 |
| 로컬 우선 | 관리형 벡터 DB 없이 air-gapped RAG 구성 가능 |
작동 방식
turbovec의 파이프라인은 TurboQuant의 수학을 검색 시스템에 맞게 바꾼 형태다.
- 벡터 길이(norm)를 분리해 저장한다.
- 무작위 직교 회전으로 각 좌표 분포를 예측 가능한 형태로 만든다.
- Lloyd-Max scalar quantization으로 좌표를 2~4비트 bucket에 매핑한다.
- 좌표를 bit-pack한다.
- 검색 시 query를 같은 회전 공간으로 옮기고, 압축 벡터를 풀지 않은 채 lookup table과 SIMD로 점수를 계산한다.
- 양자화가 내적을 낮게 추정하는 편향은 length-renormalized scoring으로 보정한다.
Python 사용 예
import numpy as np
from turbovec import TurboIndex
vectors = np.random.randn(100_000, 768).astype("float32")
index = TurboIndex(dim=768, bits=4)
index.add(vectors)
query = np.random.randn(768).astype("float32")
ids, scores = index.search(query, k=10)filtered search는 하이브리드 검색에서 특히 유용하다. BM25나 metadata filter가 후보 ID를 좁히고, turbovec이 그 후보 안에서 dense rerank를 수행할 수 있다.
FAISS와의 관계
turbovec은 FAISS 같은 범용 벡터 검색 엔진을 완전히 대체한다기보다, “로컬·저메모리·훈련 없는 압축 검색”에 초점을 맞춘다. README 기준 FAISS IndexPQ와 비교해 ARM에서 더 빠른 검색 속도를 보이고, x86에서도 match-or-beat를 목표로 한다.
언제 쓰면 좋은가
- 개인·팀 지식 베이스를 로컬에서 RAG로 검색할 때
- 임베딩 corpus가 커서 RAM 비용이 문제일 때
- 관리형 벡터 DB에 데이터를 보내기 어려운 보안 환경
- BM25 + dense rerank 하이브리드 검색을 직접 구성할 때
관련 문서
- turboquant — 근사 최적 온라인 벡터 양자화 알고리즘
- rag — 검색 증강 생성
- qmd — BM25·벡터·LLM reranking 기반 로컬 마크다운 검색
- inference-caching — LLM 추론과 벡터 압축의 메모리 절감 맥락
참고 자료
- RyanCodrai/turbovec — GitHub 공식 저장소