1. Введение
Последние достижения в области глубокого обучения позволили представлять текст и другие данные таким образом, чтобы они отражали семантическое значение. Это привело к появлению нового подхода к поиску, называемого векторным поиском, который использует векторные представления текста (известные как встраивания) для поиска документов, наиболее соответствующих запросу пользователя. Векторный поиск предпочтительнее традиционного поиска в таких приложениях, как поиск одежды, где пользователи часто ищут товары по их описанию, стилю или контексту, а не по точным названиям продуктов или брендов. Мы можем интегрировать базу данных Cloud Spanner с векторным поиском для выполнения сопоставления векторов по сходству. Используя Spanner и Vector Search вместе, клиенты могут создать мощную интеграцию, которая сочетает в себе доступность, надежность и масштаб Spanner и расширенные возможности поиска по сходству Vertex AI Vector Search. Этот поиск выполняется путем сравнения вложений элементов в индексе векторного поиска и возврата наиболее похожих совпадений.
Вариант использования
Представьте, что вы специалист по данным в магазине модной одежды, пытающийся идти в ногу с быстро меняющимися тенденциями, поиском продуктов и рекомендациями. Проблема в том, что у вас ограничены ресурсы и хранилища данных. В этом сообщении блога показано, как реализовать вариант использования рекомендаций по одежде с использованием подхода поиска по сходству в данных об одежде. Описываются следующие шаги:
- Данные взяты из Spanner
- Векторы, созданные для данных об одежде с помощью ML.PREDICT и сохраненные в Spanner.
- Векторные данные гаечного ключа интегрированы с векторным поиском с использованием потоков данных и заданий рабочего процесса.
- Векторный поиск выполняется для поиска совпадений по сходству введенных пользователем данных.
Мы создадим демонстрационное веб-приложение для поиска одежды на основе введенного пользователем текста. Приложение позволяет пользователям искать одежду, вводя текстовое описание.
От гаечного ключа до индекса векторного поиска:
Данные для поиска одежды хранятся в Spanner. Мы будем вызывать API Vertex AI Embeddings в конструкции ML.PREDICT непосредственно из данных Spanner. Затем мы воспользуемся заданиями Dataflow и Workflow, которые массово загружают эти данные (инвентарь и внедрения) в векторный поиск Vertex AI и обновляют индекс.
Выполнение пользовательских запросов по индексу:
Когда пользователь вводит описание одежды, приложение генерирует встраивания в реальном времени с помощью API Text Embeddings. Затем это отправляется в качестве входных данных в API векторного поиска, чтобы найти 10 релевантных описаний продуктов из индекса и отобразить соответствующее изображение.
Обзор архитектуры
Архитектура приложения Spanner-Vector Search показана на следующей схеме, состоящей из двух частей:
От гаечного ключа до индекса векторного поиска:
Клиентское приложение для выполнения пользовательских запросов по индексу:
Что ты построишь
Ключ к векторному индексу:
- База данных Spanner для хранения исходных данных и соответствующих вложений и управления ими.
- Задание рабочего процесса, которое осуществляет массовую загрузку данных (идентификаторов и внедрений) в базу данных Vertex AI Vector Search.
- API векторного поиска, который используется для поиска соответствующих описаний продуктов в индексе.
Выполнение пользовательских запросов по индексу:
- Веб-приложение, которое позволяет пользователям вводить текстовые описания одежды, выполняет поиск по сходству с использованием развернутой конечной точки индекса и возвращает на вход ближайшие предметы одежды.
Как это работает
Когда пользователь вводит текстовое описание одежды, веб-приложение отправляет описание в API векторного поиска. Затем API векторного поиска использует встраивания описаний одежды, чтобы найти наиболее релевантные описания продуктов из индекса. Затем пользователю отображаются описания продуктов и соответствующие изображения. Общий порядок работы следующий:
- Создавайте внедрения для данных, хранящихся в Spanner.
- Экспортируйте и загружайте вложения в индекс векторного поиска.
- Запросите индекс векторного поиска на наличие похожих элементов, выполнив поиск ближайшего соседа.
2. Требования
Прежде чем начать
- В Google Cloud Console на странице выбора проекта выберите или создайте проект Google Cloud.
- Убедитесь, что для вашего облачного проекта включена оплата. Узнайте, как проверить, включена ли оплата в проекте.
- Убедитесь, что все необходимые API (Cloud Spanner, Vertex AI, Google Cloud Storage) включены.
- Вы будете использовать Cloud Shell , среду командной строки, работающую в Google Cloud, в которую предварительно загружен gcloud. Обратитесь к документации по командам и использованию gcloud. Если ваш проект не установлен, используйте следующую команду, чтобы установить его:
gcloud config set project <YOUR_PROJECT_ID>
- Перейдите на страницу Cloud Spanner с активным проектом Google Cloud, чтобы начать работу.
3. Серверная часть: создайте источник данных и встраивания Spanner.
В этом случае в базе данных Spanner хранится инвентарь одежды с соответствующими изображениями и описаниями. Обязательно сгенерируйте вложения для текстового описания и сохраните их в базе данных Spanner как ARRAY<float64>.
- Создайте данные гаечного ключа
Создайте экземпляр с именем «spanner-vertex» и базу данных с именем «spanner-vertex-embeddings». Создайте таблицу с помощью DDL:
CREATE TABLE
apparels ( id NUMERIC,
category STRING(100),
sub_category STRING(50),
uri STRING(200),
content STRING(2000),
embedding ARRAY<FLOAT64>
)
PRIMARY KEY
(id);
- Вставьте данные в таблицу с помощью INSERT SQL.
Скрипты вставки примеров данных доступны здесь .
- Создайте модель внедрения текста
Это необходимо, чтобы мы могли генерировать внедрения для содержимого на входе. Ниже приведен DDL для того же самого:
CREATE MODEL text_embeddings INPUT(content STRING(MAX))
OUTPUT(
embeddings
STRUCT<
statistics STRUCT<truncated BOOL, token_count FLOAT64>,
values ARRAY<FLOAT64>>
)
REMOTE OPTIONS (
endpoint = '//aiplatform.googleapis.com/projects/abis-345004/locations/us-central1/publishers/google/models/textembedding-gecko');
- Создание текстовых вложений для исходных данных
Создайте таблицу для хранения внедрений и вставьте сгенерированные внедрения. В реальном приложении базы данных загрузка данных в Spanner до шага 2 будет транзакционной. В целях сохранения лучших практик проектирования я предпочитаю сохранять транзакционные таблицы нормализованными , поэтому создаю отдельную таблицу для встраивания.
CREATE TABLE apparels_embeddings (id string(100), embedding ARRAY<FLOAT64>)
PRIMARY KEY (id);
INSERT INTO apparels_embeddings(id, embeddings)
SELECT CAST(id as string), embeddings.values
FROM ML.PREDICT(
MODEL text_embeddings,
(SELECT id, content from apparels)
) ;
Теперь, когда основной контент и внедрения готовы, давайте создадим индекс векторного поиска и конечную точку для хранения внедрений, которые помогут выполнить векторный поиск.
4. Задание рабочего процесса: экспорт данных гаечного ключа в векторный поиск
- Создайте сегмент облачного хранилища
Это необходимо для хранения внедрений из Spanner в сегменте GCS в формате json, который Vector Search ожидает в качестве входных данных. Создайте сегмент в том же регионе, где находятся ваши данные в Spanner. При необходимости создайте внутри папку, но в основном создайте в ней пустой файл с именем пустой.json.
- Настройка облачного рабочего процесса
Чтобы настроить пакетный экспорт из Spanner в индекс векторного поиска Vertex AI:
Создайте пустой индекс :
Убедитесь, что индекс векторного поиска находится в том же регионе, что и ваш сегмент облачного хранилища и данные. Следуйте 11 шагам инструкций на вкладке консоли в разделе «Создание индекса для пакетного обновления» на странице управления индексами. В папке, переданной в содержимоеDeltaUri, создайте пустой файл с именем пустой.json, поскольку без этого файла вы не сможете создать индекс. Это создает пустой индекс.
Если у вас уже есть индекс, вы можете пропустить этот шаг. Рабочий процесс перезапишет ваш index.
Примечание . Вы не можете развернуть пустой индекс в конечной точке. Поэтому мы откладываем этап развертывания его на конечной точке на более поздний этап, после экспорта векторных данных в Cloud Storage.
Клонировать этот репозиторий git . Существует несколько способов клонировать репозиторий git. Один из способов — запустить следующую команду с помощью интерфейса командной строки GitHub . Выполните следующие две команды из терминала Cloud Shell:
gh repo clone cloudspannerecosystem/spanner-ai
cd spanner-ai/vertex-vector-search/workflows
В этой папке находятся два файла
-
batch-export.yaml
: это определение рабочего процесса. -
sample-batch-input.json
: это образец входных параметров рабочего процесса.
Настройте input.json из файла примера: сначала скопируйте образец json.
cp sample-batch-input.json input.json
Затем отредактируйте input.json
, указав детали вашего проекта. В этом случае ваш json должен выглядеть так:
{
"project_id": "<<YOUR_PROJECT>>",
"location": "<<us-central1>>",
"dataflow": {
"temp_location": "gs://<<YOUR_BUCKET>>/<<FOLDER_IF_ANY>>/workflow_temp"
},
"gcs": {
"output_folder": "gs://<<YOUR_BUCKET>>/<<FOLDER_IF_ANY>>/workflow_output"
},
"spanner": {
"instance_id": "spanner-vertex",
"database_id": "spanner-vertex-embeddings",
"table_name": "apparels_embeddings",
"columns_to_export": "embedding,id"
},
"vertex": {
"vector_search_index_id": "<<YOUR_INDEX_ID>>"
}
}
Разрешения на установку
Для производственных сред мы настоятельно рекомендуем создать новую учетную запись службы и предоставить ей одну или несколько ролей IAM, которые содержат минимальные разрешения, необходимые для управления службой. Следующие роли необходимы для настройки рабочего процесса экспорта данных из Spanner (встраивания) в индекс векторного поиска:
Учетная запись службы облачных рабочих процессов :
По умолчанию он использует учетную запись службы Compute Engine по умолчанию.
Если вы используете учетную запись службы, настроенную вручную, необходимо включить следующие роли:
Чтобы запустить задание потока данных: администратор потока данных, работник потока данных.
Чтобы олицетворять учетную запись службы рабочего потока данных: Пользователь учетной записи службы.
Для записи журналов: Logs Writer.
Чтобы запустить перестроение векторного поиска Vertex AI: Пользователь Vertex AI.
Учетная запись службы рабочего потока данных :
Если вы используете учетную запись службы, настроенную вручную, необходимо включить следующие роли:
Для управления потоком данных: администратор потока данных , работник потока данных. Чтобы прочитать данные из Spanner: Cloud Spanner Database Reader. Доступ на запись к выбранному реестру контейнеров GCS: владелец сегмента хранилища GCS.
- Развертывание облачного рабочего процесса
Разверните файл yaml рабочего процесса в своем проекте Google Cloud. Вы можете настроить регион или местоположение, в котором будет запускаться рабочий процесс при выполнении.
gcloud workflows deploy vector-export-workflow --source=batch-export.yaml --location="us-central1" [--service account=<service_account>]
or
gcloud workflows deploy vector-export-workflow --source=batch-export.yaml --location="us-central1"
Рабочий процесс теперь должен быть виден на странице «Рабочие процессы» в консоли Google Cloud.
Примечание . Вы также можете создать и развернуть рабочий процесс из консоли Google Cloud. Следуйте инструкциям в облачной консоли. Для определения рабочего процесса скопируйте и вставьте содержимое файла Batch-export.yaml.
После завершения выполните рабочий процесс, чтобы начать экспорт данных.
- Выполните облачный рабочий процесс
Запустите следующую команду, чтобы выполнить рабочий процесс:
gcloud workflows execute vector-export-workflow --data="$(cat input.json)"
Выполнение должно отображаться на вкладке «Выполнения» в рабочих процессах. Это должно загрузить ваши данные в базу данных Vector Search и проиндексировать их.
Примечание . Вы также можете выполнить команду из консоли, используя кнопку «Выполнить». Следуйте инструкциям и для ввода скопируйте и вставьте содержимое настроенного вами input.json.
5. Развертывание индекса векторного поиска
Развертывание индекса в конечной точке
Чтобы развернуть индекс, вы можете выполнить следующие шаги:
- На странице индексов векторного поиска вы должны увидеть кнопку РАЗВЕРТЫВАТЬ рядом с индексом, который вы только что создали на шаге 2 предыдущего раздела. Альтернативно вы можете перейти на информационную страницу индекса и нажать кнопку РАЗВЕРТЫВАТЬ НА КОНЕЧНОЙ ТОЧКЕ.
- Предоставьте необходимую информацию и разверните индекс в конечной точке.
Альтернативно вы можете просмотреть этот блокнот, чтобы развернуть его на конечной точке (перейдите к части блокнота, посвященной развертыванию). После развертывания запишите идентификатор развернутого индекса и URL-адрес конечной точки.
6. Интерфейс: пользовательские данные для векторного поиска
Давайте создадим простое приложение Python с градиентным пользовательским интерфейсом, чтобы быстро протестировать нашу реализацию: вы можете обратиться к реализации здесь , чтобы реализовать это демонстрационное приложение в своем собственном блокноте Colab .
- Мы будем использовать SDK aiplatform python для вызова API Embeddings, а также для вызова конечной точки индекса векторного поиска.
# [START aiplatform_sdk_embedding]
!pip install google-cloud-aiplatform==1.35.0 --upgrade --quiet --user
import vertexai
vertexai.init(project=PROJECT_ID, location="us-central1")
from vertexai.language_models import TextEmbeddingModel
import sys
if "google.colab" in sys.modules:
# Define project information
PROJECT_ID = " " # Your project id
LOCATION = " " # Your location
# Authenticate user to Google Cloud
from google.colab import auth
auth.authenticate_user()
- Мы будем использовать Gradio, чтобы быстро и легко продемонстрировать приложение AI, которое мы создаем, с пользовательским интерфейсом. Перезапустите среду выполнения, прежде чем выполнять этот шаг.
!pip install gradio
import gradio as gr
- Из веб-приложения после ввода пользователя вызовите Embeddings API, мы будем использовать модель внедрения текста: textembedding-gecko@latest.
Приведенный ниже метод вызывает модель внедрения текста и возвращает векторные внедрения для текста, введенного пользователем:
def text_embedding(content) -> list:
"""Text embedding with a Large Language Model."""
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@latest")
embeddings = model.get_embeddings(content)
for embedding in embeddings:
vector = embedding.values
#print(f"Length of Embedding Vector: {len(vector)}")
return vector
Проверьте это
text_embedding("red shorts for girls")
Вы должны увидеть результат, аналогичный приведенному ниже (обратите внимание, что изображение обрезано по высоте, поэтому вы не можете увидеть весь векторный ответ):
- Объявите идентификатор развернутого индекса и идентификатор конечной точки.
from google.cloud import aiplatform
DEPLOYED_INDEX_ID = "spanner_vector1_1702366982123"
#Vector Search Endpoint
index_endpoint = aiplatform.MatchingEngineIndexEndpoint('projects/273845608377/locations/us-central1/indexEndpoints/2021628049526620160')
- Определите метод векторного поиска для вызова конечной точки индекса и отображения результата с 10 ближайшими совпадениями для ответа на внедрение, соответствующего введенному пользователем тексту.
Обратите внимание, что в приведенном ниже определении метода поиска векторов метод find_neighbors вызывается для идентификации 10 ближайших векторов.
def vector_search(content) -> list:
result = text_embedding(content)
#call_vector_search_api(content)
index_endpoint = aiplatform.MatchingEngineIndexEndpoint('projects/273845608377/locations/us-central1/indexEndpoints/2021628049526620160')
# run query
response = index_endpoint.find_neighbors(
deployed_index_id = DEPLOYED_INDEX_ID,
queries = [result],
num_neighbors = 10
)
out = []
# show the results
for idx, neighbor in enumerate(response[0]):
print(f"{neighbor.distance:.2f} {spanner_read_data(neighbor.id)}")
out.append(f"{spanner_read_data(neighbor.id)}")
return out
Вы также заметите вызов метода spanner_read_data. Давайте посмотрим на это на следующем этапе.
- Определите реализацию метода чтения данных Spanner, которая вызывает метод Execute_sql для извлечения изображений, соответствующих идентификаторам векторов ближайших соседей, возвращенным на последнем шаге.
!pip install google-cloud-spanner==3.36.0
from google.cloud import spanner
instance_id = "spanner-vertex"
database_id = "spanner-vertex-embeddings"
projectId = PROJECT_ID
client = spanner.Client()
client.project = projectId
instance = client.instance(instance_id)
database = instance.database(database_id)
def spanner_read_data(id):
query = "SELECT uri FROM apparels where id = " + id
outputs = []
with database.snapshot() as snapshot:
results = snapshot.execute_sql(query)
for row in results:
#print(row)
#output = "ID: {}, CONTENT: {}, URI: {}".format(*row)
output = "{}".format(*row)
outputs.append(output)
return "\n".join(outputs)
Он должен вернуть URL-адреса изображений, соответствующих выбранным векторам.
- Наконец, давайте соединим все части пользовательского интерфейса и запустим процесс векторного поиска.
from PIL import Image
def call_search(query):
response = vector_search(query)
return response
input_text = gr.Textbox(label="Enter your query. Examples: Girls Tops White Casual, Green t-shirt girls, jeans shorts, denim skirt etc.")
output_texts = [gr.Image(label="") for i in range(10)]
demo = gr.Interface(fn=call_search, inputs=input_text, outputs=output_texts, live=True)
resp = demo.launch(share = True)
Вы должны увидеть результат, как показано ниже:
Изображение: ссылка
Посмотреть видео результата: здесь .
7. Очистка
Чтобы избежать списания средств с вашей учетной записи Google Cloud за ресурсы, используемые в этом посте, выполните следующие действия:
- В консоли Google Cloud перейдите на страницу «Управление ресурсами» .
- В списке проектов выберите проект, который хотите удалить, и нажмите «Удалить».
- В диалоговом окне введите идентификатор проекта, а затем нажмите «Завершить работу», чтобы удалить проект.
- Если вы не хотите удалять проект, удалите экземпляр Spanner, перейдя к экземпляру, который вы только что создали для этого проекта, и нажмите кнопку «УДАЛИТЬ ЭКЗЕМПЛЯР» в правом верхнем углу страницы обзора экземпляра.
- Вы также можете перейти к индексу векторного поиска, отменить развертывание конечной точки и индекса и удалить индекс.
8. Заключение
Поздравляем! Вы успешно завершили реализацию Spanner — Vertex Vector Search.
- Создание источника данных Spanner и внедрений для приложений, полученных из базы данных Spanner.
- Создание индекса базы данных векторного поиска.
- Интеграция векторных данных из Spanner в векторный поиск с использованием заданий Dataflow и Workflow.
- Развертывание индекса в конечной точке.
- Наконец, вызов векторного поиска при вводе пользователем данных в реализации Vertex AI sdk на базе Python.
Не стесняйтесь расширять реализацию на свой собственный вариант использования или дополнять текущий вариант использования новыми функциями. Узнайте больше о возможностях машинного обучения Spanner здесь .