Выполнение векторного поиска в Yandex Managed Service for PostgreSQL с помощью vector
Вы можете хранить векторные данные и выполнять векторный поиск в Yandex Managed Service for PostgreSQL с помощью расширения vector.
Расширение поддерживает:
- Точный и приблизительный поиск ближайших соседей.
- Различные типы векторов: одинарной точности, половинной точности, бинарные и разреженные векторы.
- Несколько метрик сравнения векторов: L2 (евклидово расстояние), косинусное расстояние, скалярное произведение, L1 (манхэттенское расстояние), расстояние Хэмминга и Жаккара.
- Работу с любым языком программирования, который поддерживает подключение к PostgreSQL.
Векторный поиск можно комбинировать с привычными возможностями PostgreSQL и SQL.
По умолчанию в vector выполняется точный поиск, при котором сравниваются все векторы. Для больших объемов данных можно создавать векторные индексы и использовать приблизительный поиск. В этом случае поиск выполняется быстрее, но результаты могут быть менее точными.
В vector поддерживается два типа индексов:
- HNSW — организует векторы в структуру данных, которая позволяет быстро переходить от одного похожего вектора к другому и находить ближайших соседей без проверки всей таблицы. В основе этой структуры лежит многослойный граф.
- IVFFlat — разбивает все векторы на несколько групп (списков). Во время поиска проверяются не все группы, а только те, которые наиболее близки к искомому вектору. По сравнению с HNSW этот индекс строится быстрее и использует меньше памяти, но уступает по качеству и скорости поиска.
Расширение vector доступно в кластерах Managed Service for PostgreSQL версии 13 и выше. Подробнее о расширении vector читайте в его документации
Чтобы выполнить векторный поиск в Managed Service for PostgreSQL:
- Подготовьте инфраструктуру.
- Подготовьте тестовые данные.
- Выполните поисковые запросы.
- Создайте индекс для ускорения поиска.
Если созданные ресурсы вам больше не нужны, удалите их.
Перед началом работы
Зарегистрируйтесь в Yandex Cloud и создайте платежный аккаунт:
- Перейдите в консоль управления
, затем войдите в Yandex Cloud или зарегистрируйтесь. - На странице Yandex Cloud Billing
убедитесь, что у вас подключен платежный аккаунт, и он находится в статусеACTIVEилиTRIAL_ACTIVE. Если платежного аккаунта нет, создайте его и привяжите к нему облако.
Если у вас есть активный платежный аккаунт, вы можете создать или выбрать каталог, в котором будет работать ваша инфраструктура, на странице облака
Подробнее об облаках и каталогах.
Необходимые платные ресурсы
- Кластер Managed Service for PostgreSQL: использование выделенных хостам вычислительных ресурсов, объем хранилища и резервных копий (тарифы Managed Service for PostgreSQL).
- Публичные IP-адреса, если для хостов кластера включен публичный доступ (тарифы Yandex Virtual Private Cloud).
Подготовьте инфраструктуру
-
Создайте облачную сеть с именем
demo-network.При создании сети автоматически создаются три подсети в разных зонах доступности.
-
В сети
demo-networkсоздайте группу безопасностиmpg-sgдля кластера Managed Service for PostgreSQL и добавьте в группу правило для входящего трафика, которое разрешает подключение к кластеру через интернет:- Диапазон портов —
6432. - Протокол —
TCP. - Назначение —
Диапазон адресов. - IPv4 CIDR —
0.0.0.0/0.
- Диапазон портов —
-
Создайте кластер Managed Service for PostgreSQL любой подходящей конфигурации со следующими настройками:
-
Версия —
13или выше. -
Сеть —
demo-network. -
Группа безопасности —
mpg-sg. -
База данных —
pgdb.
При создании кластера включите публичный доступ к хостам.
Примечание
Публичный доступ к хостам кластера нужен, если вы планируете подключаться к кластеру через интернет. Этот вариант подключения более простой, и его рекомендуется использовать для прохождения руководства. К хостам без публичного доступа тоже можно подключиться, но только с виртуальных машин Yandex Cloud, расположенных в той же облачной сети, что и кластер.
-
-
В кластере Managed Service for PostgreSQL добавьте расширение
vectorв базу данныхpgdb.
Подготовьте тестовые данные
-
Создайте столбец-вектор размером
3:CREATE TABLE items ( id bigserial PRIMARY KEY, embedding vector(3) ); -
Добавьте векторы:
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]'), ('[7,8,9]'), ('[10,11,12]'), ('[13,14,15]'), ('[16,17,18]');
Выполните поисковые запросы
-
Найдите трех ближайших соседей на расстоянии L2:
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 3;Для получения расстояния в расширении
vectorиспользуются следующие функции:<->— расстояние L2 (евклидово расстояние);<#>— отрицательное скалярное произведение;<=>— косинусное расстояние;<+>— расстояние L1 (манхэттенское расстояние);<~>— расстояние Хэмминга (для бинарных векторов);<%>— расстояние Жаккара (для бинарных векторов).
-
Найдите три строки, наиболее похожие на первую:
SELECT * FROM items WHERE id != 1 ORDER BY embedding <-> ( SELECT embedding FROM items WHERE id = 1 ) LIMIT 3; -
Найдите строки, находящиеся в пределах заданного расстояния:
SELECT * FROM items WHERE embedding <-> '[3,1,2]' < 15; -
Получите расстояние, на котором находится каждый вектор от вектора
[3,1,2]:SELECT embedding <-> '[3,1,2]' AS distance FROM items; -
Чтобы рассчитать скалярное произведение, умножьте результат на
-1, т. к. оператор<#>возвращает отрицательное скалярное произведение:SELECT (embedding <#> '[3,1,2]') * -1 AS inner_product FROM items; -
Чтобы узнать, насколько каждый вектор похож на вектор
[3,1,2]по косинусному сходству, используйте1 - cosine distance:SELECT 1 - (embedding <=> '[3,1,2]') AS cosine_similarity FROM items; -
Найдите средний вектор:
SELECT AVG(embedding) FROM items;
Создайте индекс для ускорения поиска
Создайте индекс каждого типа: HNSW и IVFFlat.
HNSW
-
Создайте индекс HNSW для поиска по расстоянию L2:
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops) WITH ( m = 16, ef_construction = 64 );Где:
m— максимальное количество связей, которое может иметь вершина графа на каждом уровне. По умолчанию —16.ef_construction— количество кандидатов, рассматриваемых при построении графа. По умолчанию —64. Чем выше значение, тем выше вероятность найти наиболее подходящие записи, но индекс строится дольше и операции вставки выполняются медленнее.
Эти параметры задаются один раз при создании индекса. Чтобы изменить их значения, пересоздайте индекс.
Для каждой функции расчета расстояния нужно создавать свой индекс HNSW. Подробнее в документации
расширенияvector. -
Настройте параметры поиска:
SET hnsw.ef_search = 3;Где
ef_search— количество векторов, которые алгоритм рассматривает во время поиска. По умолчанию —40. Чем выше значение, тем выше вероятность найти наиболее похожие записи, но запрос будет выполняться медленнее.В отличие от параметров индекса
mиef_construction, параметр поискаef_searchможно изменять перед выполнением запросов. -
Выполните поиск ближайших соседей:
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 3;Если результаты поиска оказались недостаточно точными, увеличьте значение
ef_searchи повторите запрос.
IVFFlat
-
Создайте индекс IVFFlat для поиска по расстоянию L2:
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH ( lists = 3 );Где
lists— количество групп (списков), на которые будут разделены векторы. Рекомендуемое значение зависит от объема данных. Чем больше групп, тем быстрее поиск, но качество поиска может снизиться.Этот параметр задается один раз при создании индекса. Чтобы изменить его значение, пересоздайте индекс.
Для каждой функции расчета расстояния нужно создавать свой индекс IVFFlat. Подробнее в документации
расширенияvector. -
Настройте параметры поиска:
SET ivfflat.probes = 1;Где
probes— количество групп (списков), просматриваемых при выполнении поиска. По умолчанию используется1. Чем больше значение, тем выше вероятность найти наиболее похожие записи, но ниже скорость выполнения запроса.В отличие от параметра индекса
lists, параметр поискаprobesможно изменять перед выполнением запросов. -
Выполните поиск ближайших соседей:
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 3;Если результаты поиска оказались недостаточно точными, увеличьте значение
probesи повторите запрос.
Удалите созданные ресурсы
Если не планируете больше использовать кластер Managed Service for PostgreSQL, удалите его, чтобы за него не списывалась плата.