Мультимодальные вложения в AlloyDB

1. Введение

a7e7c1d2afe05e68.png

Эта лабораторная работа представляет собой руководство по развертыванию AlloyDB и использованию интеграции ИИ для семантического поиска с использованием мультимодальных вложений. Эта лабораторная работа входит в серию лабораторных работ, посвященных функциям ИИ в AlloyDB. Подробнее см. на странице документации, посвященной ИИ в AlloyDB .

Предпосылки

  • Базовое понимание Google Cloud, консоли
  • Базовые навыки работы с интерфейсом командной строки и Cloud Shell

Чему вы научитесь

  • Как развернуть AlloyDB для Postgres
  • Как использовать мультимодальный векторный поиск
  • Как включить операторы искусственного интеллекта AlloyDB
  • Как использовать различные операторы искусственного интеллекта AlloyDB для мультимодального поиска
  • Как использовать ИИ AlloyDB для объединения результатов поиска текста и изображений

Что вам понадобится

  • Учетная запись Google Cloud и проект Google Cloud
  • Веб-браузер, например Chrome , поддерживающий Google Cloud Console и Cloud Shell

2. Настройка и требования

Настройка среды для самостоятельного обучения

  1. Войдите в Google Cloud Console и создайте новый проект или используйте существующий. Если у вас ещё нет учётной записи Gmail или Google Workspace, вам необходимо её создать .

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • Название проекта — отображаемое имя участников проекта. Это строка символов, не используемая API Google. Вы можете изменить её в любой момент.
  • Идентификатор проекта уникален для всех проектов Google Cloud и неизменяем (нельзя изменить после установки). Cloud Console автоматически генерирует уникальную строку; обычно вам не важно, какой именно. В большинстве практических работ вам потребуется указать идентификатор проекта (обычно обозначаемый как PROJECT_ID ). Если вам не нравится сгенерированный идентификатор, вы можете сгенерировать другой случайный идентификатор. Вы также можете попробовать использовать свой собственный идентификатор и посмотреть, доступен ли он. После этого шага его нельзя будет изменить, и он останется на протяжении всего проекта.
  • К вашему сведению, существует третье значение — номер проекта , который используется некоторыми API. Подробнее обо всех трёх значениях можно узнать в документации .
  1. Далее вам нужно включить биллинг в Cloud Console для использования облачных ресурсов/API. Выполнение этой лабораторной работы не потребует больших затрат, если вообще потребует. Чтобы отключить ресурсы и избежать списания средств за пределами этого руководства, вы можете удалить созданные вами ресурсы или проект. Новые пользователи Google Cloud могут воспользоваться бесплатной пробной версией стоимостью 300 долларов США .

Запустить Cloud Shell

Хотя Google Cloud можно управлять удаленно с вашего ноутбука, в этой лабораторной работе вы будете использовать Google Cloud Shell — среду командной строки, работающую в облаке.

В консоли Google Cloud Console нажмите значок Cloud Shell на верхней правой панели инструментов:

55efc1aaa7a4d3ad.png

Подготовка и подключение к среде займёт всего несколько минут. После завершения вы увидите примерно следующее:

7ffe5cbb04455448.png

Эта виртуальная машина содержит все необходимые инструменты разработки. Она предоставляет постоянный домашний каталог объёмом 5 ГБ и работает в облаке Google Cloud, что значительно повышает производительность сети и аутентификацию. Всю работу в этой лабораторной работе можно выполнять в браузере. Вам не нужно ничего устанавливать.

3. Прежде чем начать

Включить API

Внутри Cloud Shell убедитесь, что настроен идентификатор вашего проекта:

gcloud config set project [YOUR-PROJECT-ID]

Установите переменную среды PROJECT_ID:

PROJECT_ID=$(gcloud config get-value project)

Включите все необходимые службы:

gcloud services enable alloydb.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com \
                       discoveryengine.googleapis.com \
                       secretmanager.googleapis.com

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

student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417
Updated property [core/project].
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-14650]
student@cloudshell:~ (test-project-001-402417)$ 
student@cloudshell:~ (test-project-001-402417)$ gcloud services enable alloydb.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com
Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.

4. Развертывание AlloyDB

Создайте кластер AlloyDB и основной экземпляр. Ниже описана процедура создания кластера и экземпляра AlloyDB с помощью Google Cloud SDK. Если вы предпочитаете консольный подход, следуйте документации здесь .

Перед созданием кластера AlloyDB нам понадобится доступный диапазон частных IP-адресов в нашей VPC, который будет использоваться будущим экземпляром AlloyDB. Если у нас его нет, нам нужно создать его и назначить для использования внутренними сервисами Google, после чего мы сможем создать кластер и экземпляр.

Создать частный диапазон IP-адресов

Нам необходимо настроить доступ к частному сервису в нашей VPC для AlloyDB. Предполагается, что в проекте есть сеть VPC «по умолчанию», которая будет использоваться для всех действий.

Создайте диапазон частных IP-адресов:

gcloud compute addresses create psa-range \
    --global \
    --purpose=VPC_PEERING \
    --prefix-length=24 \
    --description="VPC private service access" \
    --network=default

Создайте частное соединение, используя выделенный диапазон IP-адресов:

gcloud services vpc-peerings connect \
    --service=servicenetworking.googleapis.com \
    --ranges=psa-range \
    --network=default

Ожидаемый вывод консоли:

student@cloudshell:~ (test-project-402417)$ gcloud compute addresses create psa-range \
    --global \
    --purpose=VPC_PEERING \
    --prefix-length=24 \
    --description="VPC private service access" \
    --network=default
Created [https://www.googleapis.com/compute/v1/projects/test-project-402417/global/addresses/psa-range].

student@cloudshell:~ (test-project-402417)$ gcloud services vpc-peerings connect \
    --service=servicenetworking.googleapis.com \
    --ranges=psa-range \
    --network=default
Operation "operations/pssn.p24-4470404856-595e209f-19b7-4669-8a71-cbd45de8ba66" finished successfully.

student@cloudshell:~ (test-project-402417)$

Создать кластер AlloyDB

В этом разделе мы создаем кластер AlloyDB в регионе us-central1.

Задайте пароль для пользователя Postgres. Вы можете задать свой пароль или использовать функцию случайной генерации.

export PGPASSWORD=`openssl rand -hex 12`

Ожидаемый вывод консоли:

student@cloudshell:~ (test-project-402417)$ export PGPASSWORD=`openssl rand -hex 12`

Сохраните пароль PostgreSQL для дальнейшего использования.

echo $PGPASSWORD

Этот пароль понадобится вам в будущем для подключения к экземпляру как пользователь postgres. Рекомендую записать его или скопировать куда-нибудь для дальнейшего использования.

Ожидаемый вывод консоли:

student@cloudshell:~ (test-project-402417)$ echo $PGPASSWORD
bbefbfde7601985b0dee5723

Создайте бесплатный пробный кластер

Если вы ранее не использовали AlloyDB, вы можете создать бесплатный пробный кластер:

Определите регион и имя кластера AlloyDB. Мы будем использовать регион us-central1 и имя кластера alloydb-aip-01:

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01

Выполните команду для создания кластера:

gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION \
    --subscription-type=TRIAL

Ожидаемый вывод консоли:

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION \
    --subscription-type=TRIAL
Operation ID: operation-1697655441138-6080235852277-9e7f04f5-2012fce4
Creating cluster...done.                                                                                                                                                                                                                                                           

Создайте основной экземпляр AlloyDB для нашего кластера в том же сеансе Cloud Shell. При отсутствии подключения вам потребуется заново определить переменные среды региона и имени кластера.

gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=8 \
    --region=$REGION \
    --cluster=$ADBCLUSTER

Ожидаемый вывод консоли:

student@cloudshell:~ (test-project-402417)$ gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=8 \
    --region=$REGION \
    --availability-type ZONAL \
    --cluster=$ADBCLUSTER
Operation ID: operation-1697659203545-6080315c6e8ee-391805db-25852721
Creating instance...done.                                                                                                                                                                                                                                                     

Создать стандартный кластер AlloyDB

Если это не первый кластер AlloyDB в проекте, приступайте к созданию стандартного кластера.

Определите регион и имя кластера AlloyDB. Мы будем использовать регион us-central1 и имя кластера alloydb-aip-01:

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01

Выполните команду для создания кластера:

gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION

Ожидаемый вывод консоли:

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION 
Operation ID: operation-1697655441138-6080235852277-9e7f04f5-2012fce4
Creating cluster...done.                                                                                                                                                                                                                                                           

Создайте основной экземпляр AlloyDB для нашего кластера в том же сеансе Cloud Shell. При отсутствии подключения вам потребуется заново определить переменные среды региона и имени кластера.

gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=2 \
    --region=$REGION \
    --cluster=$ADBCLUSTER

Ожидаемый вывод консоли:

student@cloudshell:~ (test-project-402417)$ gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=2 \
    --region=$REGION \
    --availability-type ZONAL \
    --cluster=$ADBCLUSTER
Operation ID: operation-1697659203545-6080315c6e8ee-391805db-25852721
Creating instance...done.                                                                                                                                                                                                                                                     

5. Подготовить базу данных

Нам необходимо создать базу данных, включить интеграцию Vertex AI, создать объекты базы данных и импортировать данные.

Предоставьте необходимые разрешения для AlloyDB

Добавьте разрешения Vertex AI к агенту службы AlloyDB.

Откройте еще одну вкладку Cloud Shell, нажав на знак «+» вверху.

4ca978f5142bb6ce.png

На новой вкладке облачной оболочки выполните:

PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"

Ожидаемый вывод консоли:

student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-11039]
student@cloudshell:~ (test-project-001-402417)$ gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"
Updated IAM policy for project [test-project-001-402417].
bindings:
- members:
  - serviceAccount:service-4470404856@gcp-sa-alloydb.iam.gserviceaccount.com
  role: roles/aiplatform.user
- members:
...
etag: BwYIEbe_Z3U=
version: 1
 

Закройте вкладку, выполнив команду «выход» во вкладке:

exit

Подключиться к AlloyDB Studio

В следующих главах все команды SQL, требующие подключения к базе данных, можно также выполнить в AlloyDB Studio. Для выполнения команды необходимо открыть веб-интерфейс консоли кластера AlloyDB, щёлкнув по основному экземпляру.

ef4bfbcf0ed2ef3a.png

Затем нажмите на AlloyDB Studio слева:

5c155cbcd7d43a1.png

Выберите базу данных Postgres, пользователя Postgres и введите пароль, указанный при создании кластера. Затем нажмите кнопку «Аутентифицировать».

1c9dab73c6836798.png

Откроется интерфейс AlloyDB Studio. Для выполнения команд в базе данных нажмите на вкладку «Редактор 1» справа.

b36c28f8165119ca.png

Открывает интерфейс, в котором можно запускать команды SQL.

cf43aa20f292797e.png

Создать базу данных

Быстрый старт по созданию базы данных.

В редакторе AlloyDB Studio выполните следующую команду.

Создать базу данных:

CREATE DATABASE quickstart_db

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

Statement executed successfully

Подключиться к quickstart_db

Повторно подключитесь к студии, используя кнопку переключения пользователя/базы данных.

e826ad973eb23a74.png

Выберите из раскрывающегося списка новую базу данных quickstart_db и используйте того же пользователя и пароль, что и раньше.

1ca70c59b5aea8c1.png

Откроется новое соединение, в котором вы сможете работать с объектами из базы данных quickstart_db.

6. Образец данных

Теперь нам нужно создать объекты в базе данных и загрузить данные. Мы будем использовать вымышленное хранилище «Cymbal» с вымышленными данными.

Перед импортом данных необходимо включить расширения, поддерживающие типы данных и индексы. Нам понадобятся два расширения: одно с поддержкой векторного типа данных, а другое — с поддержкой индекса AlloyDB ScaNN.

В студии AlloyDB Studio, подключающейся к quickstart_db, выполните:

CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS alloydb_scann;

Набор данных подготовлен и размещен в виде SQL-файла, который можно загрузить в базу данных через интерфейс импорта. В облачной оболочке выполните следующие команды:

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
gcloud alloydb clusters import $ADBCLUSTER --region=$REGION --database=quickstart_db --gcs-uri='gs://sample-data-and-media/ecomm-retail/ecom_generic_vectors.sql' --user=postgres --sql

Команда использует AlloyDB SDK и создает пользователя с именем agentspace_user, а затем импортирует образцы данных непосредственно из контейнера GCS в базу данных, создавая все необходимые объекты и вставляя данные.

После импорта мы можем проверить таблицы в AlloyDB Studio. Таблицы находятся в схеме ecomm:

9ee57986d4cdf20f.png

И проверьте количество строк в одной из таблиц.

51c3c55881157da3.png

Мы успешно импортировали наши образцы данных и можем перейти к следующим шагам.

7. Семантический поиск с использованием встраивания текста

В этой главе мы попытаемся использовать семантический поиск с использованием встраивания текста и сравним его с традиционным текстовым и полнотекстовым поиском Postgres.

Давайте сначала попробуем классический поиск, используя стандартный PostgreSQL SQL с оператором LIKE.

Если мы попытаемся найти дождевик, используя следующий запрос:

SET session.my_search_var='%wet%conditions%jacket%';
SELECT
  name,
  product_description,
  retail_price,   replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url
FROM
  ecomm.products
WHERE
  name ILIKE current_setting('session.my_search_var')
  OR product_description ILIKE current_setting('session.my_search_var')
LIMIT
  10;

Запрос не возвращает ни одной строки, поскольку для этого необходимо, чтобы в названии товара или его описании присутствовали точные слова, например, «для влажных условий» и «куртка». Кроме того, «куртка для влажных условий» — это не то же самое, что «куртка для дождливых условий».

Мы можем попробовать включить в поиск все возможные варианты. Давайте попробуем включить всего два слова. Например:

SELECT
  name,
  product_description,
  retail_price,
   replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url
FROM
  ecomm.products
WHERE
  name ILIKE '%wet%jacket%'
  OR name ILIKE '%jacket%wet%'
  OR name ILIKE '%jacket%'
  OR name ILIKE '%%wet%'
  OR product_description ILIKE '%wet%jacket%'
  OR product_description ILIKE '%jacket%wet%'
  OR product_description ILIKE '%jacket%'
  OR product_description ILIKE '%wet%'
LIMIT
  10;

Это вернёт несколько строк, но не все из них идеально соответствуют нашему запросу о куртках, и сортировка по релевантности будет сложной. Например, если добавить дополнительные условия, например, «для мужчин» и другие, это значительно усложнит запрос. В качестве альтернативы можно попробовать полнотекстовый поиск, но даже в этом случае мы столкнёмся с ограничениями, связанными с более или менее точными словами и релевантностью ответа.

Теперь мы можем выполнить аналогичный поиск, используя вложения. Мы уже рассчитали вложения для наших товаров с использованием разных моделей. Мы будем использовать последнюю модель Google gemini-embedding-001. Мы сохранили их в столбце « product_embedding » таблицы ecomm.products . Если мы выполним запрос по нашему условию поиска «мужская куртка-дождевик» с помощью следующего запроса:

SELECT
  name,
  product_description,
  retail_price,
   replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
  product_embedding <=> embedding ('gemini-embedding-001','wet conditions jacket for men')::vector AS distance
FROM
  ecomm.products
ORDER BY distance
LIMIT
  10;

Он не только вернет куртки для влажных условий, но и отсортирует все результаты, поместив наиболее релевантные результаты вверху.

Запрос с встраиванием возвращает результаты за 90–150 мс, при этом часть времени уходит на получение данных из модели встраивания в облако. Если посмотреть на план выполнения, запрос к модели включается во время планирования. Часть запроса, выполняющая сам поиск, довольно короткая. Поиск по 29 тысячам записей с использованием индекса AlloyDB ScaNN занимает менее 7 мс.

Limit  (cost=2709.20..2718.82 rows=10 width=490) (actual time=6.966..7.049 rows=10 loops=1)
   ->  Index Scan using embedding_scann on products  (cost=2709.20..30736.40 rows=29120 width=490) (actual time=6.964..7.046 rows=10 loops=1)
         Order By: (product_embedding <=> '[-0.0020264734,-0.016582033,0.027258193
...
-0.0051468653,-0.012440448]'::vector)
         Limit: 10
 Planning Time: 136.579 ms
 Execution Time: 6.791 ms
(6 rows)

Это был поиск с встраиванием текста, использующий модель встраивания только текста. Но у нас также есть изображения для наших товаров, и мы можем использовать их в поиске. В следующей главе мы покажем, как мультимодальная модель использует изображения для поиска.

8. Использование мультимодального поиска

Хотя текстовый семантический поиск полезен, описание сложных деталей может быть сложным. Мультимодальный поиск AlloyDB даёт преимущество, позволяя находить товары по изображениям. Это особенно полезно, когда визуальное представление лучше поясняет цель поиска, чем текстовые описания. Например, «найдите мне пальто, похожее на это на картинке».

Вернёмся к нашему примеру с курткой. Если у меня есть изображение куртки, похожее на то, что я хочу найти, я могу передать его в мультимодальную модель встраивания Google и сравнить её с встраиваниями изображений моих товаров. В нашей таблице мы уже рассчитали встраивания изображений товаров в столбце product_image_embedding , и вы можете увидеть используемую модель в столбце product_image_embedding_model .

Для нашего поиска мы можем использовать функцию image_embedding , чтобы получить встраивание изображения и сравнить его с предварительно рассчитанными встраиваниями. Чтобы включить эту функцию, необходимо убедиться, что мы используем правильную версию расширения google_ml_integration .

Давайте проверим текущую версию расширения. В AlloyDB Studio выполните:

SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
  

Если версия ниже 1.4.4, то выполните следующую процедуру.

CALL google_ml.upgrade_to_preview_version();

И ещё раз проверьте версию расширения. Она должна быть 1.4.4.

Вот мой пример изображения для поиска, но вы можете использовать любое другое изображение. Просто загрузите его в хранилище Google или другой общедоступный ресурс и укажите URI в запросе.

9f33ca0c73ea2b19.png

И он загружен на gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png

Поиск изображений по изображениям

Сначала пробуем искать только по изображению:

SELECT
  name,
  product_description,
  retail_price,
  replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
  product_image_embedding <=> google_ml.image_embedding (model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector AS distance
FROM
  ecomm.products
ORDER BY distance
LIMIT
  4;

И нам удалось найти в наличии несколько теплых курток.

Поиск по изображениям возвращает нам вещи, похожие на предоставленное нами изображение для сравнения. Как я уже упоминал, вы можете загрузить свои изображения в публичный каталог и посмотреть, найдёт ли он другие типы одежды.

Для поиска изображений мы использовали модель «multimodalembedding@001» от Google. Наша функция image_embedding отправляет изображение в Vertex AI, преобразует его в вектор и возвращает обратно для сравнения с сохранёнными векторами изображений в нашей базе данных.

Мы также можем проверить с помощью «EXPLAIN ANALYZE», насколько быстро работает наш индекс AlloyDB ScaNN.

Limit  (cost=971.70..975.55 rows=4 width=490) (actual time=2.453..2.477 rows=4 loops=1)
   ->  Index Scan using product_image_embedding_scann on products  (cost=971.70..28998.90 rows=29120 width=490) (actual time=2.451..2.475 rows=4 loops=1)
         Order By: (product_image_embedding <=> '[0.02119865,0.034206174,0.030682731,
...
,-0.010307034,-0.010053742]'::vector)
         Limit: 4
 Planning Time: 913.322 ms
 Execution Time: 2.517 ms
(6 rows)

И снова, как и в предыдущем примере, мы видим, что большая часть времени ушла на преобразование нашего изображения в вложения с использованием облачной конечной точки, а сам поиск вектора занял всего 2,5 мс.

Поиск изображений по тексту

С помощью мультимодального интерфейса мы также можем передать текстовое описание куртки, которую мы пытаемся найти, в модель, используя google_ml.text_embedding для той же модели, и сравнить с встраиваниями изображений, чтобы увидеть, какие изображения она возвращает.

SELECT
  name,
  product_description,
  retail_price,
  replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
  product_image_embedding <=> google_ml.text_embedding (model_id => 'multimodalembedding@001',content => 'puffy jacket for men, grey or dark colour')::vector AS distance
FROM
  ecomm.products
ORDER BY distance
LIMIT
  4;

И у нас есть комплект пуховиков серого или темного цвета.

Мы получили немного другой набор курток, но система правильно определила куртки на основе нашего описания и поиска по встроенным изображениям.

Давайте попробуем другой способ поиска среди описаний, используя наше встраивание для поискового изображения.

Поиск текста по изображениям

Мы попробовали найти изображения, передающие встраивание, для нашего изображения и сравнить их с предварительно рассчитанными встраиваниями изображений наших товаров. Мы также попробовали найти изображения, передающие встраивание, для нашего текстового запроса и выполнить поиск среди тех же встраиваний для изображений товаров. Давайте попробуем теперь использовать встраивание для нашего изображения и сравнить с текстовыми встраиваниями для описаний товаров. Встраивание хранится в столбце product_description_embedding и использует ту же модель multimodalembedding@001 .

Вот наш запрос:

SELECT
  name,
  product_description,
  retail_price,
  replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
  product_description_embedding <=> google_ml.image_embedding (model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector AS distance

FROM
  ecomm.products
ORDER BY distance
LIMIT
  4;

И здесь мы получили немного другой набор курток серых или темных цветов, некоторые из которых одинаковые или очень близкие, выбранные другим способом поиска.

И он возвращает те же куртки, что и выше, но в немного другом порядке. Основываясь на наших эмбеддингах для изображений, он может сравнить их с рассчитанными эмбеддингами для текстового описания и вернуть правильный набор товаров.

Вы также можете поэкспериментировать с комбинированием вложений текста и изображений, используя, например, метод взаимного рангового слияния. Вот пример такого запроса, где мы объединили два поиска, присвоив каждому рангу оценку и упорядочив результаты на основе комбинированной оценки.

WITH image_search AS (
            SELECT id,
                RANK () OVER (ORDER BY  product_image_embedding <=>google_ml.image_embedding(model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector) AS rank
                FROM ecomm.products
                ORDER BY product_image_embedding <=>google_ml.image_embedding(model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector LIMIT 5
        ),
      text_search AS (
            SELECT id,
                RANK () OVER (ORDER BY product_description_embedding <=>google_ml.text_embedding(model_id => 'multimodalembedding@001',content => 'puffy jacket for men, grey or dark colour'
    )::vector) AS rank
            FROM ecomm.products
            ORDER BY product_description_embedding <=>google_ml.text_embedding(model_id => 'multimodalembedding@001',content => 'puffy jacket for men, grey or dark colour'
    )::vector LIMIT 5
        ),
      rrf_score AS (
        SELECT
            COALESCE(image_search.id, text_search.id) AS id,
            COALESCE(1.0 / (60 + image_search.rank), 0.0) + COALESCE(1.0 / (60 + text_search.rank), 0.0) AS rrf_score
        FROM image_search FULL OUTER JOIN text_search ON image_search.id = text_search.id
        ORDER BY rrf_score DESC
      )
      SELECT 
        ep.name,
        ep.product_description,
        ep.retail_price,
        replace(ep.product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url
      FROM ecomm.products ep, rrf_score 
      WHERE 
        ep.id=rrf_score.id 
      ORDER by rrf_score DESC
      LIMIT 4;

Вы можете попробовать поиграться с различными параметрами в запросе и посмотреть, смогут ли они улучшить результаты поиска.

На этом лабораторная работа будет завершена, и во избежание непредвиденных расходов рекомендуется удалить неиспользуемые ресурсы.

В дополнение к этому вы можете использовать другие операторы ИИ для ранжирования результатов, как это описано в документации .

9. Очистите окружающую среду

Уничтожьте экземпляры AlloyDB и кластер, когда закончите работу с лабораторией.

Удалить кластер AlloyDB и все экземпляры

Кластер уничтожается с помощью опции force, которая также удаляет все экземпляры, принадлежащие кластеру.

В облачной оболочке определите переменные проекта и среды, если вы были отключены и все предыдущие настройки были утеряны:

gcloud config set project <your project id>
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
export PROJECT_ID=$(gcloud config get-value project)

Удалить кластер:

gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force

Ожидаемый вывод консоли:

student@cloudshell:~ (test-project-001-402417)$ gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force
All of the cluster data will be lost when the cluster is deleted.

Do you want to continue (Y/n)?  Y

Operation ID: operation-1697820178429-6082890a0b570-4a72f7e4-4c5df36f
Deleting cluster...done.   

Удалить резервные копии AlloyDB

Удалите все резервные копии AlloyDB для кластера:

for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done

Ожидаемый вывод консоли:

student@cloudshell:~ (test-project-001-402417)$ for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done
Operation ID: operation-1697826266108-60829fb7b5258-7f99dc0b-99f3c35f
Deleting backup...done.                                                                                                                                                                                                                                                            

10. Поздравления

Поздравляем с завершением практической работы. Вы научились использовать мультимодальный поиск в AlloyDB, используя функции встраивания для текстов и изображений. Вы можете протестировать мультимодальный поиск и улучшить его с помощью функции google_ml.rank, используя практическую работу по операторам искусственного интеллекта AlloyDB .

Что мы рассмотрели

  • Как развернуть AlloyDB для Postgres
  • Как использовать мультимодальный векторный поиск
  • Как включить операторы искусственного интеллекта AlloyDB
  • Как использовать различные операторы искусственного интеллекта AlloyDB для мультимодального поиска
  • Как использовать ИИ AlloyDB для объединения результатов поиска текста и изображений

11. Опрос

Выход:

Как вы будете использовать это руководство?

Только прочитайте это Прочитайте и выполните упражнения.