ЛЕКЦІЯ 3

Векторні бази даних та AI

Основи баз даних

VTFK • 2025

Що вже вивчили

Лекція 2: Типи та моделі БД

  • Коли обираємо реляційні vs NoSQL
  • Базовий CRUD у реляційних БД
  • Перший погляд на гнучкі схеми

План лекції

  • Навіщо векторні БД
  • Як працює пошук за схожістю
  • Архітектура та індекси (HNSW, IVF)
  • Демо та домашнє завдання

Фокус: пошук по ембеддингах та інтеграція з ML

Проблематика

Що таке векторна БД?

Vector Database

СУБД, оптимізована для зберігання та швидкого пошуку ембеддингів (векторів ознак) за метриками схожості.

Аналогія: Як бібліотека, де книги відсортовані не за назвою, а за змістовною близькістю.

Потік даних у векторній БД

Від сирих даних до відповіді

%%{init: {"theme": "neutral", "mermaid": {"version": "11.12.2"}}}%% flowchart LR; Data[Текст/зображення]-->Embedder[Модель ембеддингів]; Embedder-->Vec[(Вектори)]; Vec-->Index[Індекс HNSW/IVF]; Query[Запит користувача]-->EmbedQ[Ембеддинг запиту]; EmbedQ-->Index; Index-->TopK[Top-K найближчих]; TopK-->App[Відповідь/рекомендації];

Запит схожості (узагальнено)

SELECT id, distance(vector, :query_vec) AS score FROM vectors ORDER BY score ASC LIMIT k;
distance — метрика (cosine/L2)
ORDER BY score — найближчі вектори першими
LIMIT k — Top-K результатів
distance — метрика (cosine/L2)
ORDER BY score — найближчі вектори першими
LIMIT k — Top-K результатів
distance — метрика (cosine/L2)
ORDER BY score — найближчі вектори першими
LIMIT k — Top-K результатів

Індекс HNSW (спрощено)

Граф наближеного пошуку

%%{init: {"theme": "neutral", "mermaid": {"version": "11.12.2"}}}%% graph TB; L3[Шар 3: грубий граф]-->L2[Шар 2]; L2-->L1[Шар 1: щільний граф]; L1-->Entry[Вставка/пошук]; Entry-->Neighbors[Обхід сусідів];

Мінімальний запит з FAISS (Python)

Створюємо індекс і робимо пошук

import faiss, numpy as np

# 3 вектори по 4 ознаки
xb = np.array([[0.1, 0.2, 0.0, 0.3],
               [0.9, 0.1, 0.2, 0.0],
               [0.0, 0.3, 0.4, 0.2]], dtype='float32')
index = faiss.IndexFlatL2(4)  # L2-метрика
index.add(xb)

query = np.array([[0.05, 0.25, 0.05, 0.35]], dtype='float32')
score, ids = index.search(query, k=2)
print(ids, score)  # два найближчих вектори

Примітка: Для продакшн використовують HNSW/IVF для швидкості

Основні операції

Операція Призначення
INSERT Додати вектор + метадані
UPDATE Перезаписати вектор або payload
DELETE Видалити вектор з індексу
SEARCH kNN Top-K найближчих
FILTER + SEARCH Пошук з фільтрами по метаданих

Життєвий цикл даних

Векторизація → індексація → пошук

T0

Інгест

Отримуємо сирі документи

T1

Ембеддинг

Обчислюємо вектори

T2

Індекс

Додаємо у HNSW/IVF

T3

Пошук

kNN з фільтрами

T4

Оновлення

Ребілд/реплікація за потреби

Продуктивність та обмеження

Best practices

Помилка: пошук без нормалізації

⚠️ ЗАСТЕРЕЖЕННЯ

Вектори різної довжини спотворюють cosine

❌ Неправильно

index.add(raw_vectors)  # без нормалізації

Довгі вектори домінують у відстані

✓ Правильно

norm = raw_vectors / np.linalg.norm(raw_vectors, axis=1, keepdims=True)
index.add(norm)

Нормалізація робить cosine коректним

Міні-вікторина

Що робить HNSW у пошуку?

  • Точний перебір усіх векторів
  • Швидкий наближений пошук через граф шарів
  • Компресує текст у токени
✅ Правильна відповідь: Швидкий наближений пошук через граф шарів
💡 Пояснення:

HNSW будує багаторівневий граф для швидкого наближеного kNN.

Міні ТЗ: пошук по знаньбазі

Проєктування рішення

Кроки для ТЗ

%%{init: {"theme": "neutral", "mermaid": {"version": "11.12.2"}}}%% flowchart TB; Prep[Збір FAQ]-->Embed[Обчислити ембеддинги]; Embed-->Index[Побудувати індекс]; Index-->Query[Запит користувача]; Query-->Retrieve[Top-3 відповіді]; Retrieve-->Review[Оцінити якість];

Налаштування середовища

Встановлення FAISS та sentence-transformers

pip install faiss-cpu sentence-transformers
python - <<'PY'
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
print(model.encode(['hi']).shape)
PY

Примітка: На mac M1/M2 можна ставити faiss-cpu; для GPU потрібен інший пакет

Live coding: збірка pipeline

$

Що будемо робити:

Показати: ембеддинг → індекс → запит

Action Items:

encode текстів
index.add(vectors)
index.search(query, k=3)

Готові? Почали кодити!

Аналіз результатів

Крок Очікування Перевірка
Ембеддинг Форма (N, d) print(shape)
Індекс Розмір = N index.ntotal
Запит Top-3 релевантні ручна валідація
Latency < 100 мс time search

Підсумковий код демо

Код:

from sentence_transformers import SentenceTransformer
import faiss, numpy as np

docs = ['Що таке SQL?', 'Як працює JOIN?', 'Що таке векторна БД?']
model = SentenceTransformer('all-MiniLM-L6-v2')
vecs = model.encode(docs, normalize_embeddings=True).astype('float32')
index = faiss.IndexFlatIP(vecs.shape[1])
index.add(vecs)
query = model.encode(['поясни векторні бази'], normalize_embeddings=True).astype('float32')
scores, ids = index.search(query, k=2)
print([docs[i] for i in ids[0]])

Пояснення:

  • Ембедимо документи та нормалізуємо
  • Створюємо індекс dot-product (cosine)
  • Шукаємо top-2 відповіді

Підсумки

  • Векторні БД = швидкий пошук за схожістю
  • Індекси (HNSW/IVF) дають баланс швидкість/точність
  • Нормалізація та якісні ембеддинги критичні

Далі — реляційна модель та ключі

Домашнє завдання

Наступна лекція:

Лекція 4: Реляційна модель

📚 Корисні ресурси:

📚 Корисні ресурси:

Дякую за увагу! 💾

← Повернутися до списку лекцій