Если строишь RAG-систему и не хочешь гнать эмбеддинги в облако — посмотри на Turbovec. Это локальный векторный индекс на Rust с Python-биндингами, построенный поверх алгоритма TurboQuant от Google Research.
Почему это интересно
TurboQuant — data-oblivious квантизатор с почти оптимальным искажением и без отдельной фазы обучения. Это значит:
- Добавляешь векторы — они сразу в индексе. Никакого
train(), никакой перестройки при росте корпуса. - Корпус из 10 миллионов документов в
float32занимает 31 ГБ RAM. Turbovec укладывает его в 4 ГБ. - Скорость поиска на ARM (NEON): быстрее
FAISS IndexPQFastScanна 10–19%. На x86 (AVX-512BW): выигрывает на 4-битных конфигах, чуть уступает на 2-битных.
Базовое использование (Python)
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.tv")
loaded = TurboQuantIndex.load("my_index.tv")
Стабильные идентификаторы и удаление
Если нужны внешние uint64-идентификаторы, которые переживают удаления — есть IdMapIndex:
import numpy as np
from turbovec import IdMapIndex
index = IdMapIndex(dim=1536, bit_width=4)
index.add_with_ids(vectors, np.array([1001, 1002, 1003], dtype=np.uint64))
scores, ids = index.search(query, k=10) # возвращает твои uint64 id
index.remove(1002) # O(1) по id
index.write("my_index.tvim")
Фильтрация при поиске
Можно передать список допустимых id прямо в search() — фильтр работает внутри SIMD-ядра, а не поверх результатов:
allowed = np.array(
db.execute("SELECT id FROM docs WHERE tenant=?", (t,)).fetchall(),
dtype=np.uint64
)
scores, ids = idx.search(query, k=10, allowlist=allowed)
Блоки из 32 векторов без допустимых слотов пропускаются целиком — никаких лишних LUT-вычислений. Если allowlist меньше k, вернётся ровно len(allowed) результатов, без паддинга.
Интеграции с фреймворками
Turbovec предлагает drop-in замены стандартных in-memory хранилищ:
- LangChain —
pip install turbovec[langchain]· заменяетInMemoryVectorStore - LlamaIndex —
pip install turbovec[llama-index]· заменяетSimpleVectorStore - Haystack —
pip install turbovec[haystack]· заменяетInMemoryDocumentStore - Agno —
pip install turbovec[agno]· заменяетLanceDb
Тот же публичный интерфейс, та же семантика персистентности — меняешь импорт и идёшь дальше.
Rust API
use turbovec::TurboQuantIndex;
let mut index = TurboQuantIndex::new(1536, 4).unwrap();
index.add(&vectors);
let results = index.search(&queries, 10);
index.write("index.tv").unwrap();
Recall vs FAISS
На тестах (100K векторов, k=64) TurboQuant обходит FAISS IndexPQ на 0.2–1.9 пункта R@1 на OpenAI-размерностях (d=1536 и d=3072) при 2-битном и 4-битном квантовании. На GloVe d=200 — сложнее: выигрывает 0.9 п. на 4-битном, практически вровень (±0.1 п.) на 2-битном.
Важная деталь: сравнение идёт с FAISS IndexPQ (LUT256, nbits=8, float32 LUT) — это более сильный baseline, чем тот, что использовался в оригинальной статье по TurboQuant.
Всё остаётся на твоей машине или внутри VPC — никакого managed-сервиса, никакой утечки данных 🦆. Полный air-gapped RAG-стек в связке с любой open-source моделью эмбеддингов.

