Соберёте векторный поиск на pgvector и Qdrant и сможете цифрой показать, сколько нужных документов теряет индекс, сжатие или фильтр по сравнению с точным поиском. Векторный поиск ломается тихо. Фильтр по доступу поверх HNSW порой отдаёт 0 строк из 10, а замер на маленькой таблице показывает recall 1,0, хотя планировщик обошёл индекс. Ставить ничего не нужно: решения запускаются в песочнице с PostgreSQL, pgvector 0.8 и готовыми векторами модели e5-small. Ключи API не нужны.
Индекс быстрее перебора, потому что не читает часть базы. Сколько нужных документов он при этом теряет, без замера не скажет никто. В курсе цену экономии меряют двумя числами на одном наборе: recall@10 против точного перебора и сколько векторов реально прочитано.
В лабе вы пишете IVF на numpy: k-means без sklearn и faiss, инвертированные списки, проход по nprobe ближайшим кластерам. В нашем прогоне на 1000 векторах при nprobe 8 recall@10 вышел 0,955, прочитано 265 векторов. При nprobe 32 читается вся база плюс центроиды, и это дороже перебора.
Сначала EXPLAIN: на таблице в тысячу строк PostgreSQL обходит индекс полным перебором, и замер честно показывает recall 1,0, хотя индекс ни при чём. В pgvector рычаг тот же: число кластеров (lists) задают при построении, а сколько из них читать (probes), задают в запросе. При lists 30 для recall 0,96 хватило probes 4, а проверка следит, чтобы с меньшим значением планка не бралась.
Решения пишутся на Python, в одном файле solution.py. Если ваш основной язык Go, хватит базового Python: циклы, списки, словари.
numpy: матричное умножение @, argsort, срезы. Про argpartition расскажем в курсе.
SQL на уровне SELECT, WHERE, ORDER BY и CREATE INDEX. Подключение из Python через psycopg 3 показано в теории.
Эмбеддинги и метрики близости знать заранее не нужно: курс начинается с них.
Скалярная квантизация int8 уменьшает вектор с 1536 до 384 байт. Но часть нужных документов теряется: на тех же 1000 векторах и 50 запросах recall@10 падает до 0,812.
Пересчёт возвращает их. По int8 берут 30 кандидатов, считают для них расстояние по float32 и оставляют 10 лучших. Recall@10 поднимается до 0,996.
Ловушка лабы: произведение int8 на int8 переполняет тип, и порядок кандидатов превращается в шум. Считать нужно в int32, иначе решение не примут. Локальный Qdrant принимает quantization_config, но не квантует, поэтому механику вы воспроизводите в numpy.
Точный перебор, IVF и PQ сравниваются на одном наборе. У каждого четыре числа: recall, время, сколько векторов прочитано и сколько байт уходит на вектор.
Выбор делается в два шага: сначала отсекают варианты по жёстким ограничениям, потом берут лучший по одному критерию. Если нужен recall не ниже 0,90 при минимуме чтений, выбирают IVF: перебор тоже проходит, но читает всю базу. При лимите в 100 байт остаётся только PQ с 48 байтами и recall 0,608.
Требование «recall 0,99 и не больше 100 байт» не выполняет никто. Правильный ответ в лабе null. Наименее плохой вариант молча нарушил бы требование. Дальше меняют nprobe и M или пересматривают требования. Так же выбирают индекс на работе: сначала требования, потом замер, и честное «не получится», если требования несовместимы.
pgvector берут, когда записи уже лежат в PostgreSQL и нужны транзакции и JOIN. Qdrant подходит для больших коллекций, квантизации и векторов на диске. Одни и те же задачи курс разбирает для обеих баз: метрика, индекс, фильтр, сжатие, смена модели без простоя. Картинка выше показывает, как каждая называется в pgvector и в Qdrant.
Последняя лаба про расчёт памяти: сырые векторы плюс связи графа. По формулам курса 5 млн векторов размерности 384 в float32 занимают 7,75 GiB и в бюджет 2 GiB не помещаются. С PQ-кодами по 48 байт выходит 0,82 GiB, но recall на нашем наборе падает до 0,608. Цена экономии видна сразу. В pgvector своего PQ нет, там экономят через halfvec и bit, а PQ есть в Qdrant.
Формулу проверяют на живой таблице: модель размера таблицы на 1100 векторах должна разойтись с pg_relation_size не больше чем на 2%. Индекс HNSW в pgvector хранит копию векторов, поэтому на диске он занимает примерно вдвое больше, чем сами векторы.
Бэкенд-разработчикам, которым к PostgreSQL добавили поиск по смыслу и нужно понять, почему выдача с фильтром по доступу короче LIMIT.
Инженерам данных, которые загружают и переиндексируют эмбеддинги: без дублей при повторном запуске и без простоя при смене модели.
Тем, кто выбирает между pgvector и Qdrant и должен обосновать выбор цифрами памяти и recall.
Вопросы по курсу можно задать поддержке в Telegram: t.me/mentorix_support.
Модулей: 5, уроков: 21. Задачи с кодом проверяются автоматически.
Стоимость курса: 7990 ₽