English translation is not available yet. Showing Russian content.

Как вы управляете cost хранения векторной БД при миллиарде векторов?

Краткий тезис

Управление стоимостью хранения векторной БД при масштабе миллиарда векторов требует комбинации сжатия векторов (например, Product Quantization (PQ)) и tiered storage (многоуровневого хранения) с автоматическим перемещением данных между горячим (SSD), тёплым (NVMe) и холодным (S3) слоями. Ключевые техники — PQ (сжатие до 1/8 исходного размера) и использование DiskANN в качестве разреженного индекса для холодных данных. Такой подход позволяет снизить затраты на хранение на 80–90% без существенной потери качества поиска (recall падает на 1–3%).


1. Проблема: стоимость хранения миллиарда векторов

Вектор эмбеддинга (обычно float32, размерность 768–1536) занимает от 3 КБ до 6 КБ. Для миллиарда векторов:

  • Размерность 768 × 4 байта = 3072 байта ≈ 3 КБ на вектор.
  • Итого: 1e9 × 3 КБ ≈ 3 ТБ без индекса.
  • С учётом индекса (IVF, HNSW) и метаданных — 5–10 ТБ.

Хранение такого объёма на быстрых SSD (например, NVMe) обходится дорого. Основные драйверы cost:

  • Ёмкость (GB/TB);
  • IOPS и latency (быстрое хранилище стоит дороже);
  • Репликация для отказоустойчивости;
  • Резервное копирование.

Цель: минимизировать cost при сохранении требуемого recall@k и latency.


2. Product Quantization (PQ) – основное сжатие

Product Quantization — метод сжатия векторов путём их разбиения на подпространства и квантования каждого подпространства отдельным кодбуком. Результат: каждый вектор заменяется компактным кодом (обычно 8–32 бита на подпространство). Сжатие в 8–16 раз.

Как работает PQ:

  1. Делим вектор размерности D на M подпространств (например, M=8, каждое размерностью D/M).
  2. Для каждого подпространства обучаем кодбук из k центроидов (обычно k=256 → 8 бит).
  3. Каждый вектор квантуется: для каждого подпространства записывается номер ближайшего центроида.
  4. Итоговый код — M чисел по 8 бит = M байт. Для M=8 это 8 байт вместо 768×4=3072 байт (сжатие в 384 раза).

На практике используют OPQ (Optimized Product Quantization) для улучшения качества.

Trade-off: чем сильнее сжатие, тем ниже точность поиска. Обычно выбирают M так, чтобы код был 32–64 байта (сжатие в 50–100 раз), что даёт падение recall на 1–3% при правильной настройке.

Применение в индексах: PQ используется в IVF+PQ (Faiss) и DiskANN (Microsoft). В DiskANN векторы хранятся сжатыми, а при поиске вычисляется приблизительное расстояние через кодбуки.

Пример конфигурации Faiss:

import faiss

dim = 768
m = 16  # количество подпространств
nbits = 8  # бит на подпространство
pq = faiss.ProductQuantizer(dim, m, nbits)
# Обучаем на выборке векторов
pq.train(x_train)
# Кодируем
codes = pq.compute_codes(x)
# Декодируем (с потерями)
x_decoded = pq.decode(codes)

Экономия: 1 млрд векторов размерности 768 → без сжатия: 3 ТБ. С PQ (m=16, 16 байт на вектор) → 16 ГБ (в 188 раз меньше). Даже с overhead индекса — экономия колоссальная.


3. Tiered storage (многоуровневое хранение)

Второй ключевой приём — разделение данных по слоям в зависимости от частоты доступа:

УровеньХранилищеТипичный размер векторовLatencyCost за GB
HotNVMe SSD / RAM (in-memory)Последние 3 месяца (10–20% данных)<1 msВысокий
WarmNVMe SSD / SATA SSD3–12 месяцев (30–40% данных)1–10 msСредний
ColdS3 / HDD / Tape>12 месяцев (остальное)10–100 msНизкий

Механизм перемещения:

  • Автоматическая политика на основе времени последнего доступа (LRU) или метаданных документа (дата создания).
  • Для hot-слоя используется быстрый индекс (HNSW, IVF) без сжатия или с низким сжатием.
  • Для cold-слоя — DiskANN или IVF+PQ с высоким сжатием, данные на S3.

DiskANN — библиотека от Microsoft, оптимизированная для SSD и разреженных графов. Она хранит сжатые векторы (PQ) и граф на диске, при поиске подгружает только необходимые страницы. Позволяет работать с данными на S3 с приемлемой latency (10–50 ms) за счёт prefetch и кэширования.

Пример архитектуры:

Hot (NVMe, 200 млн векторов, HNSW+float32)
    |
    | автоматическая выгрузка по возрасту
    v
Warm (SSD, 400 млн, IVF+PQ с factor 8)
    |
    | выгрузка после [[12. Как вы фильтруете документы по метаданным в векторной БД\|12]] мес
    v
Cold (S3, 400 млн, DiskANN с PQ factor 32, граф на SSD/NVMe кэш)

4. DiskANN – ключевая технология для cold tier

DiskANN (Disk-based Approximate Nearest Neighbor) сочетает:

  • PQ сжатие для хранения векторов;
  • Vamana граф (разреженный, построенный так, чтобы минимизировать дисковые чтения);
  • Beam search с параллельной загрузкой страниц.

Особенности:

  • Индекс строится один раз, затем только обновляется (поддерживает вставки/удаления).
  • При поиске загружает со S3 только необходимые страницы графа и сжатые векторы.
  • Recall@k при 1 млрд векторов: 95–98% при latency 5–20 ms (с S3 через CDN).

Сравнение с in-memory индексами:

ПараметрIn-memory (HNSW)DiskANN (cold tier)
RAM~10 ТБ (1e9 floats)~100 ГБ (кэш + кодбуки)
StorageSSD/NVMeS3
Latency<1 ms5–50 ms
Cost ($/GB/мес)~0.20 (NVMe)0.023 (S3 Standard)
Recall99%+95–98%

Вывод: DiskANN позволяет хранить холодные данные на дешёвом S3, жертвуя 1–3% recall ради 90% экономии.


5. Дополнительные методы снижения cost

5.1 Снижение размерности эмбеддингов

  • Использование моделей с меньшей размерностью (например, text-embedding-3-small от OpenAI – 512 вместо 1536) снижает объём в 3 раза.
  • PCA или обучение мелких эмбеддингов (distillation) – даёт дополнительные 20–40% сжатия.

5.2 Sparsification (разреживание)

  • Замена плотных float32 на binary (1 бит на компоненту) – сжатие в 32 раза, но падение recall.
  • Binary quantization с расстоянием Хэмминга – быстро, дешево, но только для сценариев с высокой toleration к ошибкам.

5.3 Удаление дубликатов и устаревших векторов

  • Deduplication на основе эмбеддингов или хэшей (LSH) – сокращает объём на 10–30%.
  • TTL (time-to-live) для временных данных – автоматическое удаление.

5.4 Компрессия метаданных

  • Метаданные (текст, ID, таймстемпы) можно хранить в Parquet с colunar compression (snappy) или zstd – экономия 2–4x.

6. Влияние сжатия на качество поиска

Необходимо найти баланс между cost и recall. Пример bбенчмарка при 100 млн векторов (размерность 768):

МетодРазмер (GB)Recall@10Latency (ms)Cost/мес ($, 1e9 векторов)
float32 + HNSW30799.5%1~60,000
IVF+PQ (M=32)3298.2%5~6,500
DiskANN (M=16)1697.0%15~3,200 (cold tier S3)
Binary (1 bit)0.7585.0%0.5~150

Рекомендация: для hot tier использовать float32 или IVF+PQ с низким сжатием (M=4), для warm – IVF+PQ с M=16, для cold – DiskANN с M=32.


7. Автоматизация перемещения данных (tiering policy)

Инструменты:

  • Kubernetes + Argo Workflows для оркестрации batch-задач.
  • Custom scheduler на основе Python + boto3 для S3.
  • Векторные БД с поддержкой tiering: например, Milvus (поддержка multi-tier storage), Qdrant (плагины S3).

Простая политика:

  • Новые векторы попадают в hot tier.
  • После 30 дней без обращений – перемещаются в warm.
  • После 6 месяцев – в cold (с перестроением индекса в DiskANN).
  • При запросе к cold – временно кэшируются в hot tier (LRU).

Мониторинг:


8. Сравнение total cost of ownership (TCO)

Рассчитаем TCO для 1 млрд векторов (768d) на AWS (цены 2025):

КомпонентВариант 1: всё in-memory (NVMe)Вариант 2: multi-tier с PQЭкономия
Storage (NVMe gp3)100 TB × 0.08 $/GB/мес = 8000 $20 TB (hot+warm) × 0.08 = 1600 $ + 10 TB (S3 cold) × 0.023 = 230 $~77%
Compute (EC2)20 × r7gd.16xlarge = ~15,000 $10 × r7gd.8xlarge + 5 × c7g.4xlarge (DiskANN) = ~8,500 $~43%
Data transfer~500 $~1,000 $ (S3 запросы)+
Total~23,500 $/мес~10,330 $/мес~56%

Вывод: multi-tier с PQ и DiskANN даёт экономию 50–60% при сохранении приемлемого качества (recall 97%+).


Пет-проект для закрепления

Задача: Спроектировать прототип минимальной векторной БД для 10 млн векторов с tiered storage на AWS (или локально с эмуляцией S3 через MinIO).

Инструменты: Python, FAISS, boto3, MinIO (local S3), pandas, numpy.

Шаги:

  1. Сгенерировать 10 млн случайных векторов размерности 768 (float32).
  2. Разделить их на 3 группы по времени (имитация: первые 7 млн – старые, 2 млн – средние, 1 млн – новые).
  3. Построить индекс для новых (hot): HNSW (FAISS), хранить в оперативной памяти.
  4. Для средних: IVF+PQ (m=8), сохранить на локальный SSD.
  5. Для старых: обучить PQ (m=16) и построить DiskANN-подобный граф (можно использовать lightweight реализацию DiskANN в FAISSfaiss.IndexIVFPQ с use_float16=False и mmap).
  6. Реализовать search: при запросе сначала искать в hot, затем в warm (с fallback), затем в cold. Возвращать top-k из всех.
  7. Измерить recall@10 и latency для каждого слоя.
  8. Подсчитать условную стоимость (ёмкость в GB × цена AWS).

Ожидаемый результат: Рабочий скрипт, который демонстрирует, что cold-tier с PQ и mmap на SSD даёт recall 95%+ при ~10x экономии памяти.

Расширение: Добавить автоматический перенос данных между слоями по возрасту (хранить метаданные в SQLite).


Связь с другими вопросами

ВопросТема
265Выбор векторной БД для масштаба
266Компрессия эмбеддингов (quantization)
268Пайплайн синхронизации данных
272Мониторинг производительности векторной БД
273Cost оптимизация inference
278Стратегии партиционирования (sharding)

Навигация