Решения

Векторные БД на GPU: FAISS, cuVS и RAFT

Задача страницы. Показать, как проектировать и эксплуатировать векторный поиск на GPU: выбор индексов (FAISS‑GPU, cuVS/RAFT), подбор параметров (nlist/nprobe, PQ‑коды, графовые индексы), оценка throughput/latency/recall, хранение и шардирование.

TL;DR

  • Для онлайн‑RAG GPU даёт кратный прирост: быстрый FLAT/IVF‑поиск, быстрая тренировка IVF/PQ, высокий QPS при низкой p95.
  • Начинайте с IVF‑Flat или IVF‑PQ на GPU; при огромных коллекциях добавляйте PQ‑коды и фильтры по метаданным.
  • Ключевые ручки качества/задержки: nprobe (IVF), параметры PQ (m, bits), размер батча запросов.
  • Для стабильного SLA: батчируйте запросы, ограничивайте topK, используйте шардирование и мониторинг recall@K / p95 latency.

Связанные разделы:
/solutions/rag//solutions/embeddings//solutions/rag/evaluation//solutions/llm-inference/observability//solutions/llm-inference/costs/

Когда нужен GPU‑поиск (и когда хватит CPU)

GPU выбирайте, если:

  • онлайн‑RAG с p95 ≤ 1–1.5 с и поток ≥ сотен запросов/мин;
  • коллекции ≥ 10⁵–10⁷ чанков и нужно держать low‑latency топ‑K;
  • требуется быстрый ингест (тренировка IVF/PQ, массовые добавления).

CPU достаточно, если: коллекция мала (≤ 10⁵), QPS низкий, можно обойтись HNSW/FLAT с кэшами.

Типы индексов и выбор

FLAT (точный поиск)

  • Полный скан по всем векторам. На GPU приемлем при средних N (до ~10⁶) и умеренном topK.
  • Плюс — максимальная точность (recall≈1). Минус — растущая задержка при увеличении N.

IVF‑Flat (inverted file)

  • К‑средних (centroids) делит пространство на nlist кластеров, поиск — в ближайших nprobe списках.
  • Хороший баланс latency/recall, строится и ищет на GPU очень быстро.

IVF‑PQ (Product Quantization)

  • Как IVF, но в списках хранятся PQ‑коды (сильная экономия памяти) вместо fp16/fp32.
  • Контролируете компрессию параметрами m (число подпространств) и bits (бит/субвектор).

Графовые индексы (GPU‑варианты, RAFT)

  • «Граф‑поиск» (CAGRA/HNSW‑подобные концепции) с быстрым онлайн‑поиском.
  • Полезно при очень больших N, когда IVF‑параметры уже исчерпаны; требует тщательной настройки памяти.

Гибрид (BM25 + вектор)

  • Сперва быстро сузить кандидатов лексикой/метаданными, затем ANN‑поиск на GPU. Полезно для кода/длинных документов.
Метрики качества и производительности
  • Recall@K — доля истинных ближайших соседей, найденных индексом.
  • Latency p50/p95/p99 — задержки запроса (важно для SLA).
  • Throughput/QPS — пропускная способность при батчинге запросов.
  • Память индекса — VRAM + (опц.) RAM/NVMe для тёплых слоёв.
  • Время тренировки/ингеста — скорость построения IVF/PQ и добавления векторов.

См. оценку качества: /solutions/rag/evaluation/. Наблюдаемость: /solutions/llm-inference/observability/.

Память: прикидки и формулы

Векторы без компрессии

Mem_vectors ≈ N × dim × bytes_per_elem

# fp16: 2 байта | fp32: 4 байта

IVF‑PQ (приближённо)

Mem_total ≈ (nlist × dim × bytes_centroid) + (N × m × bits/8) + overhead

# m — число субвекторов PQ (обычно 16–64), bits — 4..8Пример. N=10M, dim=768, m=32, bits=8:
— коды ≈ 10M × 32 × 1 байт ≈ 320 МБ + словари/центроиды/оверхед → всего обычно ≤ 1–2 ГБ, тогда как fp16 хранилище без PQ ≈ 10M × 768 × 2 байта ≈ ~14.3 ГБ.

Практика FAISS‑GPU: IVF‑PQ за минуты

				
					import faiss, numpy as np

# Данные (fp32/fp16)
dim = 768
x_train = np.load("train.npy").astype('float32')   # 100k-1M векторов для тренировки
x_base  = np.load("base.npy").astype('float32')    # N векторов индекса
x_query = np.load("query.npy").astype('float32')   # Q запросов

# Параметры IVF-PQ
nlist = 4096          # число кластеров (см. §7)
m     = 32            # субвекторы PQ
nbits = 8             # бит/субвектор (4/6/8)

# CPU-индекс по фабрике, затем перенос на GPU
index = faiss.index_factory(dim, f"IVF{nlist},PQ{m}x{nbits}")
gpu_res = faiss.StandardGpuResources()
gpu_index = faiss.index_cpu_to_gpu(gpu_res, 0, index)

# Тренировка и добавление
gpu_index.train(x_train)      # k-means + PQ-кодбуки (на GPU быстро)
gpu_index.add(x_base)         # добавление N векторов

# Поиск: nprobe управляет компромиссом latency/recall
gpu_index.nprobe = 64
D, I = gpu_index.search(x_query, k=10)   # D — расстояния, I — индексы

				
			

Советы

  • Нормируйте эмбеддинги (cosine ~ dot product при норме=1).
  • Храните base в fp16 (где возможно), train делайте на репрезентативной подвыборке.
  • nprobe подбирайте из диапазона 32–256, балансируя recall/latency.

Практика cuVS/RAFT: быстрый IVF‑Flat / IVF‑PQ / графовые

				
					# Псевдокод (API может отличаться по версиям)
from cuvs.neighbors import ivf_pq, ivf_flat  # и др. варианты
# build
index = ivf_pq.build(
    dataset=x_base, nlist=4096,
    pq_bits=8, pq_subspaces=32,
    metric="ip"  # cosine при нормированных векторах
)
# search
res = ivf_pq.search(index, queries=x_query, k=10, nprobe=64, batch_size=512)
# update
ivf_pq.add(index, new_vectors)

				
			

Почему GPU‑станок удобен

  • Тренировка k-means и PQ‑кодбуков — минуты вместо часов.
  • Высокий QPS при батч‑поиске (batch_size 256–1024).
  • Готовые примитивы RAFT для метрик, кластеризации, редукций.

Подбор параметров (быстрые эвристики)

IVF (nlist, nprobe)

  • nlist порядка O(√N) (типично 1–8×√N). Для N=10M разумно 4–16k.
  • nprobe: 1–2% от nlist как старт; затем грид‑поиск по p95/recall.
  • Больше nprobe → выше recall и latency.

PQ (m, bits)

  • m: 16–64; больше m → точнее, но тяжелее память/поиск.
  • bits: 4/6/8; больше bits → лучше recall, больше память.
  • Начните с m=32, bits=8; для агрессивной экономии — m=32, bits=4/6.

Графовые индексы

  • Контролируйте степень/плотность и параметры поиска (efSearch‑подобные); балансируйте память и p95.

Общее

  • Измеряйте recall@K и latency p95 на валидационном наборе запросов (см. /solutions/rag/evaluation/).
  • Батчируйте запросы (256–1024) для лучшей утилизации GPU.

Онлайн‑поиск: конвейер и бюджет задержек

T_total ≈ T_embed_q + T_search + T_rerank + T_LLM

  • T_embed_q — эмбеддинг запроса (см. /solutions/embeddings/).
  • T_search — наш индекс (цель ≤ 50–150 мс p95).
  • T_rerank — опционально (≤ 80–200 мс).
  • T_LLM — генерация (см. /solutions/llm-inference/costs/).

Делайте гибрид: метаданные → вектор → (опц.) rerank; стримьте ответ (/solutions/llm-inference/streaming/).

Инкрементальные обновления и удаление

  • Append‑only: добавляйте новые чанки батчами; периодически выполняйте переобучение центроидов ночью.
  • Удаления/редакции: помечайте «deleted» в метаданных и фильтруйте; делайте периодический ребилд.
  • Для PQ‑индексов точность может немного «плыть» — планируйте re‑train каждые X добавлений.

Шардирование и multi‑GPU

  • By‑ID / By‑Tenant / By‑Time — распределяйте коллекции по шартам (независимые IVF/PQ), агрегируйте top‑K по шартам.
  • При multi‑GPU храните независимые индексы на каждой карте; собирайте топ‑K на CPU/GPU‑редьюсом.
  • Следите за NVLink/PCIe — крупные nprobe и большие topK увеличивают трафик.

Хранение, персист и кэш

  • Сохраняйте индекс на диск (NVMe) и держите «горячие» структуры в VRAM.
  • Делайте кэш запросов (нормализация строк → сигнатуры n‑gram) и кэш результатов для популярных запросов.
  • Для FAISS — храните сериализованные индексы (write_index/read_index), для cuVS — родные чекпоинты.

Наблюдаемость и алерты

Метрики (минимум):

  • latency_p50/p95/p99 по поиску; qps; batch_size; topK.
  • recall@K на оффлайн‑наборе; деградации при обновлениях.
  • Память VRAM/RAM, доля «deleted», доля пустых результатов.
  • Ошибки: out‑of‑memory, неверная размерность, тайм‑ауты.

Детали — в /solutions/llm-inference/observability/ и /solutions/monitoring-logging/.

Траблшутинг

  • Низкий recall. Увеличьте nprobe, m/bits PQ, добавьте rerank, улучшите чанкование (см. /solutions/rag/).
  • Высокая p95. Снизьте nprobe, уменьшите topK, включите батчирование, используйте гибрид с метаданными.
  • OOM на GPU. Понизьте bits PQ, разделите индекс на шарды, уменьшите размер батча, используйте fp16.
  • Плохое качество после добавлений. Переобучите центроиды (re‑train), пересоберите индекс ночью.
  • Вариативность latency. Выделите отдельные пулы short/long, ограничьте длинные запросы, стабилизируйте batch size.

Как запускать это в cloudcompute.ru

  • Шаблон “RAG‑VectorDB (GPU)” в /solutions/templates/:
    – профили IVF‑Flat / IVF‑PQ / FLAT;
    – тренировка/ингест на GPU, батч‑поиск, сохранение индексов;
    – метрики latency/recall/QPS, алерты, бэкапы.
  • Интеграция: эмбеддинги — /solutions/embeddings/; LLM — /solutions/llm-inference/; экономика — /solutions/llm-inference/costs/.

Чек‑лист перед продом

  • Выбран тип индекса: IVF‑Flat / IVF‑PQ / FLAT / графовый.
  • Настроены параметры (nlist/nprobe, m/bits, topK) по замерам recall/latency.
  • Организован ингест: батчи, ночной re‑train, стратегия удалений.
  • Шардирование/репликация и персист индексов; кэши запросов/результатов.
  • Метрики/алерты и оффлайн‑оценка recall@K; план деградации.
  • Интеграция с LLM‑сервисами и стримингом (SSE/WS) настроена.