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

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

Управление стоимостью хранения миллиарда векторов требует комбинации методов: сжатие векторов (Quantization|Product Quantization), многоуровневое хранение (tiered storage), алгоритмы для дисковых индексов (DiskANN) и pruning (удаление дубликатов и нерелевантных данных). Целевая метрика — cost per vector в месяц менее $0.001. Выбор стратегии зависит от компромисса между точностью поиска, latency и бюджетом.


1. Термин: Векторная база данных (Vector DB) и стоимость хранения

Векторная БД — это система, оптимизированная для хранения и поиска эмбеддингов (векторов). При масштабе в миллиард векторов (например, 768-мерные эмбеддинги в FP32) сырой объём данных составляет:

  • 1 млрд × 768 × 4 байта ≈ 3 ТБ (только векторы).
  • С учётом индексов (HNSW, IVF) и метаданных — до 6–10 ТБ.

Стоимость хранения складывается из:

  • Оперативной памяти (RAM) — для in-memory индексов (HNSW).
  • SSD/NVMe — для гибридных решений (DiskANN).
  • Облачных объектных хранилищ (S3) — для холодных данных.

Без оптимизации хранение миллиарда векторов в RAM обойдётся в десятки тысяч долларов в месяц. Основные методы снижения cost:


2. Product Quantization (PQ) — сжатие векторов

Product Quantization — метод сжатия, при котором вектор разбивается на подвекторы, каждый квантуется в код из книги квантования (codebook). Размер сжатия: от FP32 (32 бита) до 4–8 бит на подвектор.

Как работает

  1. Вектор размерности D делится на M подвекторов размерности D/M.
  2. Для каждого подвектора строится codebook из k центроидов (обычно k=256, 8 бит).
  3. Каждый подвектор заменяется индексом ближайшего центроида.
  4. Исходный вектор представляется как M индексов (M × log2(k) бит).

Пример сжатия

  • D=768, M=96, k=256 → каждый подвектор кодируется 8 битами.
  • Размер сжатого вектора: 96 × 8 = 768 бит = 96 байт.
  • Исходный FP32: 768 × 4 = 3072 байта.
  • Коэффициент сжатия: 3072 / 96 ≈ 32x.

Влияние на точность

  • PQ вносит ошибку квантования, снижая recall на 1–5% (зависит от M и k).
  • Для компенсации используют OPQ (Optimized Product Quantization) — вращение пространства перед квантованием.

Код (FAISS):

import faiss
import numpy as np

# Исходные векторы (N=1e6, D=768)
vectors = np.random.rand(1_000_000, 768).astype(np.float32)

# PQ сжатие: M=96, k=256
pq = faiss.ProductQuantizer(768, 96, 8)  # 8 бит на подвектор
pq.train(vectors)
codes = pq.compute_codes(vectors)  # сжатые коды (N, 96)

# Индекс с PQ
index = faiss.IndexPQ(768, 96, 8)
index.train(vectors)
index.add(vectors)

Cost per vector после PQ

  • Сжатый вектор: ~96 байт.
  • При 1 млрд векторов: 96 ГБ (вместо 3 ТБ).
  • Стоимость RAM (AWS: ~$0.2/ГБ/мес) → ~$19/мес (против $600+ без сжатия).

3. Tiered Storage — многоуровневое хранение

Tiered storage разделяет векторы по частоте запросов (access pattern) на уровни:

УровеньНосительВременной диапазонLatencyCost/ГБ/мес
HotRAM / SSDПоследние 3 месяца<10 мс~$0.2–0.5
WarmNVMe / SSD3–12 месяцев10–50 мс~$0.05–0.1
ColdS3 / HDD>12 месяцев1–10 с~$0.01–0.02

Реализация

  • Hot tier: векторы в RAM с HNSW-индексом (или PQ-сжатые в RAM).
  • Warm tier: векторы на NVMe с DiskANN-индексом (см. раздел 4).
  • Cold tier: векторы в S3 в сжатом формате (PQ или бинарные). При запросе — поиск по метаданным (например, по дате) или перезагрузка в warm при необходимости.

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

  • Milvus поддерживает multi-tier storage через конфигурацию storage.tier.
  • Данные автоматически перемещаются между hot (локальный SSD) и cold (S3) на основе segment.row_count и segment.ttl.

Cost per vector при tiered storage:

  • 70% данных в cold (S3), 20% в warm (NVMe), 10% в hot (RAM).
  • Средневзвешенная стоимость: 0.7×0.015 + 0.2×0.08 + 0.1×0.3 ≈ $0.056/ГБ/мес.
  • Для 96 ГБ (сжатых PQ): ~$5.4/мес.

4. DiskANN — алгоритм для дисковых индексов

DiskANN (Microsoft) — алгоритм приближённого поиска ближайших соседей (ANN), оптимизированный для хранения векторов на SSD/NVMe, а индекса — в RAM.

Принцип

  • Индекс в RAM: граф (Vamana) с узлами — векторами, но хранятся только ссылки (ID + адрес на диске). Размер индекса ~2–4 байта на вектор.
  • Векторы на диске: сжатые (PQ) или исходные. При поиске подгружаются только необходимые страницы.

Сравнение с HNSW (in-memory):

ПараметрHNSW (RAM)DiskANN (SSD + RAM)
RAM на 1 млрд векторов (FP32)~3 ТБ~4 ГБ (только индекс)
RAM на 1 млрд векторов (PQ 96 байт)~96 ГБ~4 ГБ
Latency (p99)1–5 мс10–50 мс
Recall@100.98+0.95–0.98
Cost (RAM)ВысокийНизкий

Реализация

  • FAISS поддерживает DiskANN через IndexIVFPQ + IndexShards с дисковым хранилищем.
  • Milvus 2.3+ использует DiskANN как один из типов индекса (index_type: DISKANN).

Cost per vector при DiskANN

  • Индекс в RAM: 4 ГБ × $0.2 = $0.8/мес.
  • Векторы на SSD: 96 ГБ × $0.08 = $7.7/мес.
  • Итого: ~$8.5/мес (против $96/мес для HNSW с PQ в RAM).

5. Pruning — удаление нерелевантных данных

Pruning — удаление векторов, которые никогда не ретривятся или являются дубликатами.

Методы

  • Дедупликация: удаление точных дубликатов (cosine similarity >0.99) или near-duplicates (MinHash, SimHash).
  • Удаление нерелевантных документов: документы с нулевым числом ретривов за N дней (например, 30 дней). Можно автоматизировать через логи.
  • Фильтрация по метаданным: удаление устаревших документов (по дате, версии).

Пример (SQL-подобный запрос в векторной БД):

-- Удалить векторы, которые не были запрошены за 90 дней
DELETE FROM vectors WHERE last_accessed < NOW() - INTERVAL '90 days';

Эффект

  • Удаление 20–30% векторов снижает cost хранения пропорционально.
  • Важно не удалить релевантные данные — используйте soft delete с TTL.

Cost per vector после pruning

  • Если удалено 30% векторов, cost снижается на 30%.

6. Метрика cost per vector в месяц

Целевая метрика: cost per vector в месяц < $0.001.

Формула

cost_per_vector = (общая стоимость хранения в месяц) / (количество векторов)

Пример расчёта для 1 млрд векторов:

  • PQ сжатие до 96 байт → 96 ГБ.
  • Tiered storage: 10% hot (RAM), 20% warm (NVMe), 70% cold (S3).
  • Hot: 9.6 ГБ × $0.3 = $2.88
  • Warm: 19.2 ГБ × $0.08 = $1.54
  • Cold: 67.2 ГБ × $0.015 = $1.01
  • Индекс DiskANN: 4 ГБ × $0.2 = $0.8
  • Итого: ~$6.23/мес.
  • cost_per_vector = $6.23 / 1e9 ≈ $6.23e-9 = 0.00000000623 (значительно меньше $0.001).

Без оптимизации (FP32, HNSW in RAM):

  • 3 ТБ RAM × $0.2 = $600/мес.
  • cost_per_vector = $600 / 1e9 = $6e-7 = 0.0000006 (всё ещё < $0.001, но на порядок выше).

Вывод Даже без оптимизации cost per vector может быть ниже $0.001 при использовании облачных цен, но сжатие и tiered storage снижают cost на 2–3 порядка.


7. Сравнение стратегий (таблица)

СтратегияСнижение costВлияние на recallВлияние на latencyСложность внедрения
PQ сжатие (96 байт)32x-1..5%+0% (in-memory)Средняя
Tiered storage3–10x0%+ (при переходе между tiers)Высокая
DiskANN10–20x (vs HNSW)-1..3%+5..50 мсСредняя
Pruning1.2–1.5x0% (если корректно)0%Низкая
Комбинация всех100–1000x-2..8%+10..100 мсОчень высокая

8. Trade-offs: точность vs стоимость vs latency

  • PQ сжатие: уменьшает cost, но снижает recall. Для компенсации можно увеличить k (число возвращаемых результатов) или использовать re-ranking (точный поиск по top-N сжатых результатов).
  • Tiered storage: данные на cold tier имеют высокую latency. Для критичных запросов можно кэшировать горячие данные или использовать predictive preloading.
  • DiskANN: компромисс между latency и cost. Подходит для сценариев, где допустима задержка 10–50 мс (чат-боты, поиск документов).

Пример выбора

  • Real-time (latency <10 мс): HNSW + PQ в RAM (cost ~$19/мес).
  • Batch / аналитика (latency <1 с): DiskANN + PQ + tiered storage (cost ~$6/мес).
  • Архив (редкие запросы): PQ + S3 + cold index (cost <$2/мес).

9. Инструменты и библиотеки

ИнструментПоддержка PQTiered storageDiskANNPruning
FAISSДа (ProductQuantizer)Нет (только RAM/диск)Да (IndexIVFPQ + дисковый)Нет (ручная реализация)
MilvusДа (IVF_PQ, DiskANN)Да (multi-tier)Да (DISKANN)Да (TTL, delete)
PineconeДа (автоматически)Да (pod-based)Нет (in-memory)Да (delete by metadata)
WeaviateДа (PQ)Да (multi-tenancy)НетДа (TTL)
QdrantДа (ProductQuantization)Да (snapshots + S3)НетДа (points delete)

10. Best practices

  1. Начинайте с PQ сжатия — самый простой способ снизить cost без изменения архитектуры.
  2. Используйте tiered storage для данных с разной частотой доступа. Автоматизируйте перемещение через TTL.
  3. Применяйте DiskANN если latency до 50 мс приемлема, а RAM ограничен.
  4. Регулярно pruning — удаляйте дубликаты и нерелевантные данные. Логируйте access patterns.
  5. Мониторьте cost per vector — настройте алерты при превышении порога $0.001.
  6. Тестируйте recall после каждого изменения (PQ, DiskANN). Используйте A/B тесты на продакшене.
  7. Рассмотрите гибридный подход: горячие данные (последние 3 месяца) — HNSW + PQ в RAM, остальные — DiskANN на SSD.

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

Задача Симулировать управление cost для 10 млн векторов (768-мерные) с использованием PQ и tiered storage.

Инструменты Python, FAISS, NumPy, boto3 (для S3), time.

Шаги:

  1. Сгенерируйте 10 млн случайных векторов.
  2. Разделите на 3 tier: hot (10%), warm (30%), cold (60%).
  3. Для hot: создайте HNSW-индекс с PQ (M=96, k=256). Измерьте RAM и recall.
  4. Для warm: сохраните векторы на локальный SSD (имитация NVMe) и создайте DiskANN-индекс (FAISS IndexIVFPQ с дисковым хранилищем).
  5. Для cold: сожмите векторы PQ и загрузите в S3 (имитация через локальную папку). Реализуйте поиск по метаданным (например, по дате).
  6. Рассчитайте cost per vector на основе цен AWS (RAM $0.2/ГБ, SSD $0.08/ГБ, S3 $0.015/ГБ).
  7. Сравните recall@10 и latency для каждого tier.

Ожидаемый результат

  • cost per vector < $0.001.
  • recall@10 > 0.95 для hot, > 0.9 для warm, > 0.8 для cold.
  • latency: hot <10 мс, warm <50 мс, cold <5 с.

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

ВопросТема
520Выбор векторной БД для масштаба
521Индексация векторов (HNSW, IVF, DiskANN)
522Шардирование и партиционирование
523Кэширование результатов поиска
524Компрессия эмбеддингов (бинарные, int8)
526Мониторинг стоимости и производительности

Навигация