turbovec: векторный индекс на Rust, который бьёт FAISS
turbovec сжимает 10 млн векторов с 31 ГБ до 4 ГБ и обгоняет FAISS по скорости — на базе алгоритма TurboQuant от Google Research.
31 ГБ уходит, остаётся 4 ГБ — и поиск становится быстрее
Корпус из 10 миллионов документов занимает 31 ГБ оперативной памяти в формате float32. turbovec вмещает его в 4 ГБ — и при этом ищет быстрее, чем FAISS. Проект появился как open-source библиотека от независимого разработчика Райана Кодраи и опирается на академический алгоритм Google Research. На момент публикации репозиторий набрал более 3 500 звёзд на GitHub и 315 форков — впечатляющий результат для столь молодой библиотеки.
Что такое TurboQuant и почему он особенный
TurboQuant — это онлайн-алгоритм квантизации векторов для сжатия высокоразмерных евклидовых векторов с сохранением их геометрической структуры. Он предложен в 2025 году Амиром Зандием, Маджидом Далири, Маджидом Хадианом и Вахабом Мирrokни. Зандий и Мирrokни аффилированы с Google Research, Далири — с NYU, Хадиан — с Google DeepMind.
TurboQuant — алгоритм из семейства Product Quantization (PQ) с чёткой теоретической основой: к каждому вектору применяется случайное ортогональное вращение, что равномерно перераспределяет дисперсию по координатам. После вращения каждая координата приближается к гауссовскому распределению с одинаковой дисперсией, а затем квантизируется независимо с помощью фиксированной таблицы представительных значений (Lloyd-Max codebook).
Ключевое отличие от традиционных подходов — TurboQuant не требует обучения и ни одного прохода по данным. В отличие от Product Quantization в FAISS, которому нужно обучение кодовой книги через k-means и периодическое переобучение при изменении корпуса, TurboQuant использует аналитический подход на основе случайного вращения, делающего распределение координат предсказуемым.
«Алгоритм достигает близкой к оптимальной скорости искажения во всех битовых ширинах и измерениях» — из аннотации к статье TurboQuant (arXiv 2504.19874, ICLR 2026)
Как работает turbovec
turbovec реализует TurboQuant в виде векторного индекса на Rust с привязками к Python. Вот упрощённый pipeline обработки каждого вектора:
graph TD
A[Исходный float32 вектор] --> B[Нормализация — убираем норму, сохраняем как float]
B --> C[Случайное вращение — умножение на ортогональную матрицу]
C --> D[TQ+ калибровка — подгонка квантилей под Beta-распределение]
D --> E[Lloyd-Max квантизация — 2-bit: 4 бакета, 4-bit: 16 бакетов]
E --> F[Сжатый вектор в индексе]
F --> G[SIMD-поиск NEON / AVX-512BW]
Самое интересное — не просто «сжатие занимает меньше места». Сжатое представление и является представлением для поиска. turbovec не сжимает для хранения, а потом разворачивает каждого кандидата обратно в float32 во время поиска.
Производительность: сравнение с FAISS
Написанные вручную NEON-ядра (ARM) и AVX-512BW-ядра (x86) обгоняют FAISS IndexPQFastScan на 10–19% на ARM; на x86 выигрывают в конфигурациях 4-bit и немного уступают в 2-bit.
| Платформа | Конфигурация | turbovec vs FAISS FastScan |
|---|---|---|
| ARM (Apple M3 Max) | 2-bit, 4-bit | +10–19% быстрее |
| x86 (Intel Xeon Sapphire Rapids) | 4-bit | +1–6% быстрее |
| x86 (Intel Xeon Sapphire Rapids) | 2-bit single-thread | ~паритет (−1%) |
| x86 (Intel Xeon Sapphire Rapids) | 2-bit multi-thread | −2–8% медленнее |
По метрике recall, TurboQuant и FAISS расходятся не более чем на 0–1 пункт по R@1 на эмбеддингах OpenAI при d=1536 и d=3072. Оба сходятся к recall 1.0 к k=4–8.
Степень сжатия: вектор размерностью 1536 в float32 занимает 6 144 байта, а при 2-bit квантизации — всего 384 байта. Это сжатие в 16 раз.
Быстрый старт на Python
Установка — одна команда:
pip install turbovec
Базовый пример:
from turbovec import TurboQuantIndex
# dim=1536 — типичная размерность OpenAI embeddings
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")
Для сценариев с удалением документов есть IdMapIndex — индекс со стабильными внешними uint64-идентификаторами:
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)
index.remove(1002) # O(1) по id
Удаление работает за O(1) по идентификатору — это полезно для хранилищ документов, где векторы часто обновляются или удаляются.
Фильтрованный поиск (Hybrid Retrieval)
Можно передать в search() список разрешённых id (или битовую маску слотов), и ядро учтёт его напрямую. Вы всегда получаете до k результатов из разрешённого множества — без избыточной выборки и без потери recall на избирательных фильтрах.
Это особенно важно для мультитенантных RAG-систем, где разные пользователи имеют доступ к разным подмножествам документов.
import numpy as np
from turbovec import IdMapIndex
idx = IdMapIndex(dim=1536, bit_width=4)
idx.add_with_ids(vectors, ids)
# Шаг 1: внешняя система (SQL, BM25, ACL) сужает кандидатов
allowed = np.array(
db.execute("SELECT id FROM docs WHERE tenant=?", (t,)).fetchall(),
dtype=np.uint64
)
# Шаг 2: плотный rerank внутри кандидатного множества
scores, result_ids = idx.search(query, k=10, allowlist=allowed)
Интеграция с популярными фреймворками
turbovec интегрируется с LangChain (pip install turbovec[langchain]), LlamaIndex (pip install turbovec[llama-index]) и Haystack (pip install turbovec[haystack]). Библиотека является drop-in заменой для встроенных хранилищ этих фреймворков — достаточно поменять импорт.
| Фреймворк | Команда установки | Заменяет |
|---|---|---|
| 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 |
Место в экосистеме
Вокруг turbovec уже формируется сообщество — появляются расширения для Postgres (pg_turbovec), RAG-пайплайны на LangGraph и сравнительные бенчмарки с FAISS. На GitHub уже более 14 производных репозиториев.
Авторы TurboQuant в своей статье отмечают, что алгоритм превосходит существующие методы product quantization по recall при поиске ближайших соседей, одновременно сводя время индексации практически к нулю. turbovec превращает этот академический результат в инструмент, готовый к production-использованию.
Для команд, строящих локальные или on-premise RAG-системы с ограничениями по памяти или требованиями к конфиденциальности данных, turbovec выглядит как одно из самых практичных решений 2026 года.
Ссылки: GitHub-репозиторий turbovec · PyPI · Статья TurboQuant (arXiv)