1. Wprowadzenie
Niedawne postępy w rozwoju deep learning pozwalają na przedstawianie tekstu i innych danych w sposób, który pozwala uchwycić znaczenie semantyczne. Spowodowało to opracowanie nowego podejścia do wyszukiwania, zwanego wyszukiwaniem wektorowym. Polega ono na wektorach reprezentacji wektorowych tekstu (tzw. wektorach dystrybucyjnych) w celu znajdowania dokumentów najlepiej dopasowanych do zapytania użytkownika. Wyszukiwanie wektorowe jest preferowane w przypadku aplikacji takich jak wyszukiwanie odzieży, w których użytkownicy często szukają produktów według opisu, stylu lub kontekstu, a nie dokładnej nazwy produktu lub marki. Możemy zintegrować bazę danych Cloud Spanner z wyszukiwaniem wektorowym, aby przeprowadzać dopasowywanie podobieństw wektorowych. Korzystając z usługi Spanner i wyszukiwania wektorowego, klienci mogą uzyskać zaawansowaną integrację łączącą dostępność, niezawodność i skalę usługi Spanner z zaawansowanymi funkcjami wyszukiwania wektorowego wyszukiwania podobieństw Vertex AI. To wyszukiwanie jest wykonywane przez porównanie umieszczania elementów w indeksie wyszukiwania wektorowego i zwróceniu najbardziej podobnych dopasowań.
Przypadek użycia
Wyobraź sobie, że jesteś badaczem danych w firmie odzieżowej i chcesz nadążać za szybko zmieniającymi się trendami, wyszukiwaniem produktów i rekomendacjami. Wyzwanie polega na tym, że masz ograniczone zasoby i silosy danych. Ten post pokazuje, jak wdrożyć rekomendację dotyczącą odzieży za pomocą metody wyszukiwania podobieństw w przypadku danych o ubraniach.Omawiamy następujące kroki:
- Dane pochodzące z usługi Spanner
- Wektory dla danych dotyczących odzieży wygenerowane za pomocą ML.PREDICT i zapisane w Spanner
- Dane wektorowe Spannera zintegrowane z wyszukiwaniem wektorowym za pomocą zadań Dataflow i przepływu pracy
- Przeprowadzono wyszukiwanie wektorowe w celu znalezienia dopasowania podobieństw do danych wejściowych użytkownika
Przygotujemy demonstracyjną aplikację internetową do wyszukiwania odzieży na podstawie tekstu wpisanego przez użytkownika. Aplikacja umożliwia użytkownikom wyszukiwanie odzieży przez wpisanie opisu tekstowego.
Indeks wyszukiwania wektorowego ze Spannera na wektor:
Dane dotyczące wyszukiwania odzieży są przechowywane w usłudze Spanner. Wywołaj interfejs API Vertex AI Embeddings w konstrukcji ML.PREDICT bezpośrednio z danych Spannera. Następnie użyjemy zadań Dataflow i Workflow, które zbiorczo przesyłają te dane (zasoby reklamowe i reprezentacje właściwościowe) do usługi wyszukiwania wektorowego w Vertex AI i odświeżają indeks.
Uruchamianie zapytań użytkowników w indeksie:
Gdy użytkownik wpisuje opis odzieży, aplikacja generuje w czasie rzeczywistym wektory dystrybucyjne za pomocą interfejsu Text Embeddings API. Następnie są one wysyłane do interfejsu Vector Search API w celu znalezienia 10 odpowiednich opisów produktów z indeksu i wyświetlenia odpowiedniego zdjęcia.
Omówienie architektury
Architektura aplikacji Spanner – wyszukiwanie wektorowe przedstawiono na tym 2-częściowym schemacie:
Indeks wyszukiwania wektorowego opartego na spaner:
Aplikacja kliencka do uruchamiania zapytań użytkowników w indeksie:
Co utworzysz
Konwersja ze Spannera na indeks wektorów:
- Baza danych Spanner służąca do przechowywania danych źródłowych i odpowiednich wektorów dystrybucyjnych oraz zarządzania nimi
- Zadanie przepływu pracy, które zbiorczo przesyła dane (identyfikatory i wektory dystrybucyjne) do bazy danych wyszukiwania wektorowego Vertex AI.
- Interfejs API wyszukiwania wektorowego służący do wyszukiwania odpowiednich opisów produktów z indeksu.
Uruchamianie zapytań użytkowników w indeksie:
- Aplikacja internetowa, która umożliwia użytkownikom wpisywanie tekstowych opisów odzieży, przeprowadza wyszukiwanie podobieństw za pomocą wdrożonego punktu końcowego indeksu i zwraca najbliższą odzież w danych wejściowych.
Jak to działa
Gdy użytkownik wpisuje tekstowy opis odzieży, aplikacja internetowa wysyła go do interfejsu Vector Search API. Interfejs Vector Search API wykorzystuje wektory dystrybucyjne opisów ubrań do znajdowania najbardziej odpowiednich opisów produktów z indeksu. Następnie użytkownicy widzą opisy produktów i odpowiadające im zdjęcia. Ogólna procedura wygląda tak:
- Generuj wektory dystrybucyjne dla danych przechowywanych w usłudze Spanner.
- Eksportowanie i przesyłanie wektorów dystrybucyjnych do indeksu wyszukiwania wektorowego.
- Zapytanie o indeks wyszukiwania wektorowego dla podobnych elementów przez wyszukiwanie najbliższych sąsiadów.
2. Wymagania
Zanim zaczniesz
- Na stronie selektora projektów w konsoli Google Cloud wybierz lub utwórz projekt Google Cloud.
- Sprawdź, czy w projekcie Cloud włączone są płatności. Dowiedz się, jak sprawdzić, czy w projekcie są włączone płatności.
- Upewnij się, że wszystkie niezbędne interfejsy API (Cloud Spanner, Vertex AI, Google Cloud Storage) są włączone
- Użyjesz Cloud Shell – środowiska wiersza poleceń działającego w Google Cloud, które zawiera już zainstalowane narzędzie gcloud. Więcej informacji o poleceniach i sposobie korzystania z gcloud znajdziesz w dokumentacji. Jeśli Twój projekt nie jest skonfigurowany, ustaw go za pomocą tego polecenia:
gcloud config set project <YOUR_PROJECT_ID>
- Aby rozpocząć, otwórz stronę Cloud Spanner z aktywnym projektem Google Cloud
3. Backend: tworzenie źródła danych i wektorów dystrybucyjnych usługi Spanner
W tym przypadku baza danych Spanner zawiera asortyment odzieży z odpowiednimi obrazami i opisami. Pamiętaj, aby wygenerować wektory dystrybucyjne dla opisu tekstowego i zapisać je w bazie danych Spannera jako ARRAY<float64>.
- Tworzenie danych Spanner
Utwórz instancję o nazwie „spanner-vertex”. i bazę danych o nazwie „spanner-vertex-embeddings”. Utwórz tabelę za pomocą 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);
- Wstaw dane do tabeli za pomocą polecenia INSERT SQL
Skrypty z przykładowymi danymi znajdziesz tutaj.
- Tworzenie modelu umieszczania tekstu
Jest to wymagane do generowania wektorów dystrybucyjnych dla treści wejściowych. Poniżej znajdziesz DDL dla:
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');
- Generowanie wektorów dystrybucyjnych tekstu dla danych źródłowych
Utwórz tabelę do przechowywania wektorów dystrybucyjnych i wstawiania wygenerowanych wektorów dystrybucyjnych. W rzeczywistej aplikacji bazy danych wczytywanie danych do usługi Spanner do kroku 2 byłoby transakcyjne. Aby zachować zgodność ze sprawdzonymi metodami projektowania, wolę zachować normalizację tabel transakcyjnych, więc utwórz osobną tabelę na wektory dystrybucyjne.
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)
) ;
Po przygotowaniu treści zbiorczych i wektorów dystrybucyjnych możemy utworzyć indeks wyszukiwania wektorowego i punkt końcowy do przechowywania wektorów dystrybucyjnych, które pomogą w przeprowadzaniu wyszukiwania wektorowego.
4. Zadanie przepływu pracy: eksportowanie danych Spannera do wyszukiwania wektorowego
- Tworzenie zasobnika Cloud Storage
Jest to wymagane do przechowywania wektorów dystrybucyjnych z usługi Spanner w zasobniku GCS w formacie json, którego wyszukiwarka wektorowa oczekuje jako danych wejściowych. Utwórz zasobnik w tym samym regionie co dane w usłudze Spanner. W razie potrzeby utwórz w nim folder, ale przede wszystkim utwórz w nim pusty plik o nazwie empty.json.
- Skonfiguruj Cloud Workflow
Aby skonfigurować eksport wsadowy ze Spannera do indeksu wyszukiwania wektorowego Vertex AI:
Utwórz pusty indeks:
Sprawdź, czy indeks wyszukiwania wektorowego znajduje się w tym samym regionie co zasobnik Cloud Storage i dane. Postępuj zgodnie z 11 instrukcjami wyświetlanymi na karcie konsoli w sekcji Tworzenie indeksu do aktualizacji zbiorczej na stronie zarządzania indeksami. W folderze, który jest przekazywany do contentDeltaUri, utwórz pusty plik o nazwie empty.json, ponieważ bez tego pliku nie udałoby się utworzyć indeksu. Spowoduje to utworzenie pustego indeksu.
Jeśli masz już indeks, możesz pominąć ten krok. Ten proces zastąpi indeks.
Uwaga: nie możesz wdrożyć w punkcie końcowym pustego indeksu. Po wyeksportowaniu danych wektorowych do Cloud Storage odkładamy więc etap wdrażania w punkcie końcowym do późniejszego kroku.
Sklonowanie tego repozytorium git: istnieje wiele sposobów sklonowania repozytorium Git. Jeden z nich to uruchomienie poniższego polecenia za pomocą interfejsu wiersza poleceń GitHub. Uruchom w terminalu Cloud Shell te 2 polecenia:
gh repo clone cloudspannerecosystem/spanner-ai
cd spanner-ai/vertex-vector-search/workflows
Ten folder zawiera 2 pliki
batch-export.yaml
: to jest definicja przepływu pracy.sample-batch-input.json
: przykładowe parametry wejściowe przepływu pracy.
Skonfiguruj plikinput.json z przykładowego pliku: najpierw skopiuj przykładowy plik json.
cp sample-batch-input.json wejściowe.json
Następnie zmodyfikuj plik input.json
, podając szczegóły swojego projektu. W tym przypadku plik JSON powinien wyglądać tak:
{
"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>>"
}
}
Uprawnienia do konfiguracji
W przypadku środowisk produkcyjnych zdecydowanie zalecamy utworzenie nowego konta usługi i przypisanie do niego co najmniej 1 roli uprawnień zawierającej minimalne uprawnienia wymagane do zarządzania usługą. Te role są potrzebne do skonfigurowania przepływu pracy służącego do eksportowania danych z Spannera (umieszczania) do indeksu wyszukiwania wektorowego:
Domyślnie używane jest domyślne konto usługi Compute Engine.
Jeśli używasz ręcznie skonfigurowanego konta usługi, musisz uwzględnić te role:
Aby aktywować zadanie Dataflow: Administrator Dataflow, instancja robocza Dataflow.
Aby przyjąć tożsamość konta usługi instancji roboczej Dataflow: użytkownik kont usługi.
Aby zapisywać logi: Zapisujący logi.
Aby aktywować odbudowywanie wyszukiwania wektorowego Vertex AI: użytkownik Vertex AI.
Konto usługi instancji roboczej Dataflow:
Jeśli używasz ręcznie skonfigurowanego konta usługi, musisz uwzględnić te role:
Aby zarządzać przepływem danych: Administrator Dataflow, Zasób roboczy Dataflow. Aby odczytać dane z usługi Spanner: odczytujący bazy danych Cloud Spanner. Dostęp z możliwością zapisu w wybranym Container Registry GCS: właściciel zasobnika na dane GCS.
- Wdrażanie Cloud Workflow
wdrożyć plik yaml przepływu pracy w projekcie Google Cloud, Możesz skonfigurować region lub lokalizację, w której będzie uruchamiany przepływ pracy.
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"
Przepływ pracy powinien być teraz widoczny na stronie Przepływy pracy w konsoli Google Cloud.
Uwaga: przepływ pracy możesz też utworzyć i wdrożyć w konsoli Google Cloud. Postępuj zgodnie z instrukcjami wyświetlanymi w konsoli Cloud. Aby utworzyć definicję przepływu pracy, skopiuj i wklej zawartość plikubat-export.yaml.
Gdy skończysz, uruchom przepływ pracy, aby rozpocząć eksportowanie danych.
- Wykonywanie przepływu pracy w Cloud
Uruchom to polecenie, aby wykonać przepływ pracy:
gcloud workflows execute vector-export-workflow --data="$(cat input.json)"
Wykonanie powinno się pojawić na karcie Uruchomienia w przepływach pracy. Spowoduje to wczytanie danych do bazy danych wyszukiwania wektorowego i ich zindeksowanie.
Uwaga: możesz też uruchomić polecenie z poziomu konsoli, używając przycisku Wykonaj. Postępuj zgodnie z wyświetlanymi instrukcjami, a następnie skopiuj i wklej zawartość dostosowanego plikuinput.json.
5. Wdróż indeks wyszukiwania wektorowego
Wdrażanie indeksu w punkcie końcowym
Aby wdrożyć indeks, wykonaj te czynności:
- Na stronie Indeksy wyszukiwania wektorowego obok indeksu utworzonego w kroku 2 w poprzedniej sekcji powinien być widoczny przycisk WDRÓŻ. Możesz też przejść na stronę z informacjami o indeksie i kliknąć przycisk WDRÓŻ DO PUNKTU KOŃCOWEGO.
- Podaj niezbędne informacje i wdróż indeks w punkcie końcowym.
Możesz też skorzystać z tego notatnika, aby wdrożyć go w punkcie końcowym (przejdź do części notatnika dotyczącej wdrażania). Po wdrożeniu zanotuj wdrożony identyfikator indeksu i adres URL punktu końcowego.
6. Frontend: dane użytkownika do wyszukiwania wektorowego
Stwórzmy prostą aplikację w języku Python z interfejsem UX opartym na gradio, który umożliwia szybkie przetestowanie implementacji. Zapoznaj się z tą implementacją, aby wdrożyć aplikację w wersji demonstracyjnej we własnym notatniku colab.
- Do wywoływania interfejsu Embeddings API oraz do wywoływania punktu końcowego indeksu wyszukiwania wektorowego użyjemy pakietu SDK Aiplatforma w Pythonie.
# [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()
- Wykorzystamy gradio, aby zademonstrować aplikację AI, którą tworzymy szybko i łatwo za pomocą interfejsu. Zanim wdrożysz ten krok, uruchom ponownie środowisko wykonawcze.
!pip install gradio
import gradio as gr
- W aplikacji internetowej po wprowadzeniu przez użytkownika wywołaj interfejs Embeddings API, użyjemy modelu umieszczania tekstu: textembedding-gecko@latest
Poniższa metoda wywołuje model umieszczania tekstu i zwraca wektory wektorowe dla tekstu wpisanego przez użytkownika:
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
Przetestuj
text_embedding("red shorts for girls")
Dane wyjściowe powinny wyglądać podobnie do tego poniżej (pamiętaj, że obraz zostanie przycięty do wysokości, więc nie będzie widać całej odpowiedzi wektorowej):
- Zadeklaruj wdrożony identyfikator indeksu i identyfikator punktu końcowego
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')
- Określ metodę wyszukiwania wektorowego, aby wywoływać punkt końcowy indeksu i wyświetlić wynik z 10 najbliższymi dopasowaniami dla odpowiedzi wektora dystrybucyjnej odpowiadającej tekstowi wprowadzonemu przez użytkownika.
Zwróć uwagę na to, że w poniższej definicji metody wyszukiwania wektorowego metoda find_ sąsiad jest wywoływana w celu identyfikacji 10 najbliższych wektorów.
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
Zauważysz również wywołanie metody spanner_read_data. Omówimy to w następnym kroku.
- Zdefiniuj implementację metody odczytu danych Spannera, która wywołuje metodę generate_sql w celu wyodrębnienia obrazów odpowiadających identyfikatorom najbliższych wektorów sąsiadów zwróconych w ostatnim kroku.
!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)
Powinien zwracać adresy URL obrazów odpowiadających wybranym wektorom.
- Na koniec połączmy te elementy w interfejs i uruchommy proces wyszukiwania wektorowego.
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)
Wynik powinien być taki:
Obraz: link
Obejrzyj film z wynikami: tutaj.
7. Czyszczenie danych
Aby uniknąć obciążenia konta Google Cloud opłatami za zasoby zużyte w tym poście, wykonaj te czynności:
- W konsoli Google Cloud otwórz stronę Zarządzanie zasobami.
- Na liście projektów wybierz projekt do usunięcia, a potem kliknij Usuń.
- W oknie wpisz identyfikator projektu i kliknij Wyłącz, aby usunąć projekt.
- Jeśli nie chcesz usuwać projektu, usuń instancję Spannera. W tym celu przejdź do instancji utworzonej przed chwilą dla tego projektu i kliknij przycisk USUŃ INSTANCJĘ w prawym górnym rogu strony przeglądu instancji.
- Możesz też przejść do indeksu wyszukiwania wektorowego, wycofać wdrożenie punktu końcowego i indeksu oraz usunąć indeks.
8. Podsumowanie
Gratulacje! Udało Ci się wykonać implementację Spannera wektorowego wyszukiwania wektorowego przez
- Tworzenie źródła danych i wektorów dystrybucyjnych usługi Spanner dla aplikacji pozyskanych z bazy danych Spanner.
- Tworzę indeks bazy danych wyszukiwania wektorowego.
- Integracja danych wektorowych z usługi Spanner do wyszukiwania wektorowego za pomocą zadań Dataflow i przepływów pracy.
- Wdrażam indeks w punkcie końcowym.
- Na koniec wywołaj wyszukiwanie wektorowe na podstawie danych wejściowych użytkownika w obsługiwanej przez Pythona implementacji pakietu SDK Vertex AI.
Możesz rozszerzyć wdrożenie do własnego zastosowania lub wykorzystać obecny przypadek użycia, dodając nowe funkcje. Więcej informacji o możliwościach systemów uczących się dostępnych w usłudze Spanner znajdziesz tutaj.