1. Einführung
Dank der jüngsten Fortschritte im Bereich Deep Learning ist es möglich, Text und andere Daten so darzustellen, dass die semantische Bedeutung erfasst wird. Das hat zu einem neuen Ansatz für die Suche geführt, der als Vektorsuche bezeichnet wird. Dabei werden Vektordarstellungen von Text (sogenannte Einbettungen) verwendet, um Dokumente zu finden, die für die Anfrage eines Nutzers am relevantesten sind. Die Vektorsuche wird gegenüber der herkömmlichen Suche für Anwendungen wie die Suche nach Bekleidung bevorzugt, bei denen Nutzer oft nach Artikeln anhand ihrer Beschreibung, ihres Stils oder ihres Kontexts suchen und nicht nach genauen Produkt- oder Markennamen. Wir können die Cloud Spanner-Datenbank in Vector Search einbinden, um Vektorähnlichkeitsvergleiche durchzuführen. Durch die gemeinsame Verwendung von Spanner und Vector Search können Kunden eine leistungsstarke Integration erstellen, die die Verfügbarkeit, Zuverlässigkeit und Skalierbarkeit von Spanner mit den erweiterten Funktionen für die Ähnlichkeitssuche von Vertex AI Vector Search kombiniert. Bei dieser Suche werden Einbettungen von Elementen im Vektorsuchindex verglichen und die ähnlichsten Treffer zurückgegeben.
Anwendungsfall
Stellen Sie sich vor, Sie sind Data Scientist bei einem Modehändler und müssen mit den sich schnell ändernden Trends, Produktsuchen und Empfehlungen Schritt halten. Die Herausforderung besteht darin, dass Sie nur begrenzte Ressourcen und Datensilos haben. In diesem Blogbeitrag wird gezeigt, wie Sie einen Anwendungsfall für Bekleidungsempfehlungen mithilfe eines Ähnlichkeitssuchansatzes für Bekleidungsdaten implementieren.Die folgenden Schritte werden behandelt:
- Daten aus Spanner
- Vektoren, die mit ML.PREDICT für die Bekleidungsdaten generiert und in Spanner gespeichert wurden
- Cloud Spanner-Vektordaten, die mithilfe von Dataflow- und Workflow-Jobs in die Vektorsuche integriert werden
- Vektorsuche, um eine Ähnlichkeitsübereinstimmung für die vom Nutzer eingegebenen Daten zu finden
Wir erstellen eine Demo-Webanwendung, mit der anhand von Nutzereingabetext nach Kleidung gesucht werden kann. Mit der Anwendung können Nutzer nach Bekleidung suchen, indem sie eine Textbeschreibung eingeben.
Spanner-zu-Vektorsuchindex:
Die Daten für die Suche nach Bekleidung werden in Spanner gespeichert. Wir rufen die Vertex AI Embeddings API im ML.PREDICT-Konstrukt direkt aus Spanner-Daten auf. Anschließend nutzen wir die Dataflow- und Workflow-Jobs, mit denen diese Daten (Inventar und Einbettungen) in die Vektorsuche von Vertex AI hochgeladen und der Index aktualisiert wird.
Nutzeranfragen für den Index ausführen:
Wenn ein Nutzer eine Beschreibung für Kleidung eingibt, generiert die App die Einbettungen in Echtzeit mithilfe der Text Embeddings API. Diese wird dann als Eingabe an die Vector Search API gesendet, um 10 relevante Produktbeschreibungen aus dem Index zu finden und das entsprechende Bild anzuzeigen.
Überblick über die Architektur
Die Architektur der Spanner-Vector Search-Anwendung ist im folgenden zweiteiligen Diagramm dargestellt:
Spanner-zu-Vektorsuchindex : 
Client-App zum Ausführen von Nutzeranfragen für den Index:
Umfang
Spanner zu Vektorindex:
- Spanner-Datenbank zum Speichern und Verwalten von Quelldaten und den entsprechenden Einbettungen
- Ein Workflow-Job, mit dem Daten (ID und Einbettungen) in die Vertex AI Vector Search-Datenbank hochgeladen werden.
- Eine Vector Search API, mit der relevante Produktbeschreibungen aus dem Index abgerufen werden.
Nutzeranfragen für den Index ausführen:
- Eine Webanwendung, in der Nutzer Textbeschreibungen von Kleidungsstücken eingeben können. Die Anwendung führt eine Ähnlichkeitssuche mit dem bereitgestellten Index-Endpunkt durch und gibt die Kleidungsstücke zurück, die der Eingabe am ähnlichsten sind.
So gehts
Wenn ein Nutzer eine Textbeschreibung von Bekleidung eingibt, sendet die Webanwendung die Beschreibung an die Vector Search API. Die Vector Search API verwendet dann die Einbettungen der Bekleidungsbeschreibungen, um die relevantesten Produktbeschreibungen aus dem Index zu finden. Die Produktbeschreibungen und entsprechenden Bilder werden dann dem Nutzer angezeigt. Dies ist der allgemeine Workflow:
- Einbettungen für in Spanner gespeicherte Daten generieren.
- Einbettungen in einen Vektorsuchindex exportieren und hochladen
- Fragen Sie den Vektorsuchindex nach ähnlichen Elementen ab, indem Sie eine Suche nach dem nächsten Nachbarn durchführen.
2. Voraussetzungen
Hinweis
- Wählen Sie in der Google Cloud Console auf der Seite zur Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.
- Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für ein Projekt aktiviert ist
- Prüfen Sie, ob alle erforderlichen APIs (Cloud Spanner, Vertex AI, Google Cloud Storage) aktiviert sind.
- Sie verwenden Cloud Shell, eine Befehlszeilenumgebung, die in Google Cloud ausgeführt wird und in der gcloud vorinstalliert ist. Informationen zu gcloud-Befehlen und deren Verwendung finden Sie in der Dokumentation. Wenn Ihr Projekt nicht festgelegt ist, verwenden Sie den folgenden Befehl, um es festzulegen:
gcloud config set project <YOUR_PROJECT_ID>
- Rufen Sie mit Ihrem aktiven Google Cloud-Projekt die Seite Cloud Spanner auf, um loszulegen.
3. Backend: Spanner-Datenquelle und ‑Einbettungen erstellen
In diesem Anwendungsfall enthält die Spanner-Datenbank das Inventar der Bekleidung mit den entsprechenden Bildern und Beschreibungen. Achten Sie darauf, dass Sie Einbettungen für die Textbeschreibung generieren und sie als ARRAY<float64> in Ihrer Spanner-Datenbank speichern.
- Spanner-Daten erstellen
Erstellen Sie eine Instanz mit dem Namen „spanner-vertex“ und eine Datenbank mit dem Namen „spanner-vertex-embeddings“. So erstellen Sie eine Tabelle mit der 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);
- Daten mit INSERT SQL in die Tabelle einfügen
Hier finden Sie Einfügeskripts für Beispieldaten.
- Modell für Texteinbettungen erstellen
Das ist erforderlich, damit wir Einbettungen für die Inhalte in der Eingabe generieren können. Im Folgenden finden Sie die DDL dafür:
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');
- Texteinbettungen für die Quelldaten generieren
Erstellen Sie eine Tabelle zum Speichern der Einbettungen und fügen Sie die generierten Einbettungen ein. In einer realen Datenbankanwendung wäre das Laden der Daten in Spanner bis zu Schritt 2 transaktional. Um die Best Practices für das Design beizubehalten, ziehe ich es vor, die Transaktionstabellen zu normalisieren und eine separate Tabelle für Einbettungen zu erstellen.
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)
) ;
Nachdem die Bulk-Inhalte und Einbettungen fertig sind, erstellen wir einen Vektorsuchindex und ‑endpunkt, um die Einbettungen zu speichern, die für die Vektorsuche verwendet werden.
4. Workflow-Job: Spanner-Daten in Vector Search exportieren
- Cloud Storage-Bucket erstellen
Dies ist erforderlich, um Einbettungen aus Spanner in einem GCS-Bucket in einem JSON-Format zu speichern, das von Vector Search als Eingabe erwartet wird. Erstellen Sie einen Bucket in derselben Region wie Ihre Daten in Spanner. Erstellen Sie bei Bedarf einen Ordner und darin eine leere Datei namens „empty.json“.
- Cloud Workflow einrichten
So richten Sie einen Batch-Export von Spanner in einen Vertex AI Vector Search-Index ein:
Leeren Index erstellen:
Der Vektorsuchindex muss sich in derselben Region wie Ihr Cloud Storage-Bucket und die Daten befinden. Folgen Sie den 11 Schritten auf dem Tab „Console“ im Abschnitt Index für Batch-Update erstellen auf der Seite „Indexe verwalten“. Erstellen Sie im Ordner, der an „contentsDeltaUri“ übergeben wird, eine leere Datei namens „empty.json“, da Sie ohne diese Datei keinen Index erstellen können. Dadurch wird ein leerer Index erstellt.
Wenn Sie bereits einen Index haben, können Sie diesen Schritt überspringen. Der Workflow überschreibt Ihren Index.
Hinweis: Sie können keinen leeren Index für einen Endpunkt bereitstellen. Wir verschieben den Schritt, die Funktion auf einem Endpunkt bereitzustellen, auf einen späteren Zeitpunkt, nachdem die Vektordaten nach Cloud Storage exportiert wurden.
Dieses Git-Repository klonen: Es gibt mehrere Möglichkeiten, ein Git-Repository zu klonen. Eine Möglichkeit ist, den folgenden Befehl mit der GitHub-Befehlszeile auszuführen. Führen Sie die folgenden zwei Befehle im Cloud Shell-Terminal aus:
gh repo clone cloudspannerecosystem/spanner-ai
cd spanner-ai/vertex-vector-search/workflows
Dieser Ordner enthält zwei Dateien
batch-export.yaml: Dies ist die Workflow-Definition.sample-batch-input.json: Dies ist ein Beispiel für die Workflow-Eingabeparameter.
input.json aus der Beispieldatei einrichten:Kopieren Sie zuerst das JSON-Beispiel.
cp sample-batch-input.json input.json
Bearbeiten Sie dann input.json mit den Details für Ihr Projekt. In diesem Fall sollte Ihr JSON so aussehen:
{
"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>>"
}
}
Berechtigungen einrichten
Für Produktionsumgebungen empfehlen wir dringend, ein neues Dienstkonto zu erstellen und ihm eine oder mehrere IAM-Rollen zuzuweisen, die die erforderlichen Mindestberechtigungen für die Verwaltung von Diensten enthalten. Die folgenden Rollen sind erforderlich, um den Workflow zum Exportieren von Daten aus Spanner (Einbettungen) in den Vector Search-Index einzurichten:
Standardmäßig wird das Compute Engine-Standarddienstkonto verwendet.
Wenn Sie ein manuell konfiguriertes Dienstkonto verwenden, müssen Sie die folgenden Rollen einbeziehen:
So lösen Sie einen Dataflow-Job aus: Dataflow-Administrator, Dataflow-Worker.
Um die Identität eines Dataflow-Worker-Dienstkontos zu übernehmen: Dienstkontonutzer.
Zum Schreiben von Logs: Logautor.
So lösen Sie den Neuaufbau der Vertex AI-Vektorsuche aus: Vertex AI-Nutzer.
Wenn Sie ein manuell konfiguriertes Dienstkonto verwenden, müssen Sie die folgenden Rollen einbeziehen:
Dataflow-Administrator (Dataflow Admin), Dataflow-Worker (Dataflow Worker) Daten aus Spanner lesen: Cloud Spanner Database Reader Schreibzugriff auf die ausgewählte GCS Container Registry: GCS Storage Bucket Owner
- Cloud-Workflow bereitstellen
Stellen Sie die YAML-Datei des Workflows in Ihrem Google Cloud-Projekt bereit. Sie können die Region oder den Ort konfigurieren, an dem der Workflow ausgeführt wird.
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"
Der Workflow sollte jetzt auf der Seite Workflows in der Google Cloud Console sichtbar sein.
Hinweis: Sie können den Workflow auch über die Google Cloud Console erstellen und bereitstellen. Folgen Sie der Anleitung in der Cloud Console. Kopieren Sie für die Workflow-Definition den Inhalt von „batch-export.yaml“ und fügen Sie ihn ein.
Führen Sie dann den Workflow aus, damit der Datenexport beginnt.
- Cloud-Workflow ausführen
Führen Sie den folgenden Befehl aus, um den Workflow auszuführen:
gcloud workflows execute vector-export-workflow --data="$(cat input.json)"
Die Ausführung sollte auf dem Tab „Ausführungen“ in Workflows angezeigt werden. Dadurch sollten Ihre Daten in die Vektorsuchdatenbank geladen und indexiert werden.
Hinweis: Sie können die Ausführung auch über die Schaltfläche „Ausführen“ in der Console starten. Folgen Sie der Anleitung und kopieren Sie den Inhalt Ihrer benutzerdefinierten Datei „input.json“ und fügen Sie ihn ein.
5. Vektorsuchindex bereitstellen
Index auf einem Endpunkt bereitstellen
So stellen Sie den Index bereit:
- Auf der Seite Vector Search-Indexe sollte neben dem Index, den Sie im vorherigen Abschnitt in Schritt 2 erstellt haben, die Schaltfläche „DEPLOY“ (BEREITSTELLEN) angezeigt werden. Alternativ können Sie die Seite mit den Indexinformationen aufrufen und auf die Schaltfläche „IN ENDPUNKT BEREITSTELLEN“ klicken.
- Geben Sie die erforderlichen Informationen an und stellen Sie den Index auf einem Endpunkt bereit.
Alternativ können Sie sich dieses Notebook ansehen, um es an einem Endpunkt bereitzustellen (fahren Sie mit dem Bereitstellungsteil des Notebooks fort). Notieren Sie sich nach der Bereitstellung die ID des bereitgestellten Index und die Endpunkt-URL.
6. Frontend: Nutzerdaten für die Vektorsuche
Wir erstellen eine einfache Python-Anwendung mit einer auf Gradio basierenden Benutzeroberfläche, um unsere Implementierung schnell zu testen. Die Implementierung finden Sie hier. Sie können diese Demoanwendung in Ihrem eigenen Colab-Notebook implementieren.
- Wir verwenden das aiplatform-Python-SDK, um die Embeddings API aufzurufen und den Vektorsuchindex-Endpunkt aufzurufen.
# [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()
- Wir verwenden Gradio, um die KI-Anwendung zu demonstrieren, die wir schnell und einfach mit einer Benutzeroberfläche erstellen. Starten Sie die Laufzeit neu, bevor Sie diesen Schritt ausführen.
!pip install gradio
import gradio as gr
- Rufen Sie die Embeddings API über die Web-App bei Nutzereingabe auf. Wir verwenden das Texteinbettungsmodell: textembedding-gecko@latest.
Mit der folgenden Methode wird das Texteinbettungsmodell aufgerufen und die Vektoreinbettungen für den vom Nutzer eingegebenen Text zurückgegeben:
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
Testen
text_embedding("red shorts for girls")
Sie sollten eine Ausgabe ähnlich der folgenden sehen (das Bild ist in der Höhe beschnitten, sodass Sie nicht die gesamte Vektorantwort sehen können):

- Bereitgestellte Index-ID und Endpunkt-ID deklarieren
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')
- Definieren Sie die Vektorsuchmethode, um den Indexendpunkt aufzurufen und das Ergebnis mit den 10 nächsten Übereinstimmungen für die Einbettungsantwort anzuzeigen, die dem Nutzereingabetext entspricht.
In der folgenden Methodendefinition für die Vektorsuche wird die Methode „find_neighbors“ aufgerufen, um die 10 nächsten Vektoren zu ermitteln.
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
Außerdem sehen Sie den Aufruf der Methode „spanner_read_data“. Sehen wir uns das im nächsten Schritt an.
- Definieren Sie die Implementierung der Methode zum Lesen von Spanner-Daten, die die Methode „execute_sql“ aufruft, um die Bilder zu extrahieren, die den IDs der Vektoren der nächsten Nachbarn entsprechen, die im letzten Schritt zurückgegeben wurden.
!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)
Es sollten die URLs der Bilder zurückgegeben werden, die den ausgewählten Vektoren entsprechen.
- Fügen wir nun die einzelnen Teile auf einer Benutzeroberfläche zusammen und lösen wir den Vektorsuchprozess aus.
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)
Das Ergebnis sollte so aussehen:

Bild: Link
7. Bereinigen
So vermeiden Sie, dass Ihrem Google Cloud-Konto die in diesem Beitrag verwendeten Ressourcen in Rechnung gestellt werden:
- Wechseln Sie in der Google Cloud Console zur Seite Ressourcen verwalten.
- Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie dann auf „Löschen“.
- Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf „Beenden“, um das Projekt zu löschen.
- Wenn Sie das Projekt nicht löschen möchten, löschen Sie die Spanner-Instanz. Rufen Sie dazu die Instanz auf, die Sie gerade für dieses Projekt erstellt haben, und klicken Sie oben rechts auf der Seite „Instanzübersicht“ auf die Schaltfläche „INSTANZ LÖSCHEN“.
- Sie können auch zum Vektorsuchindex navigieren, die Bereitstellung des Endpunkts und des Index aufheben und den Index löschen.
8. Fazit
Glückwunsch! Sie haben die Implementierung von Spanner – Vertex Vector Search abgeschlossen, indem Sie
- Spanner-Datenquelle und Einbettungen für Anwendungen erstellen, die aus der Spanner-Datenbank stammen.
- Vektorsuchdatenbankindex wird erstellt.
- Vektordaten aus Spanner in Vector Search einbinden – mit Dataflow- und Workflow-Jobs
- Index auf einem Endpunkt bereitstellen
- Schließlich wird die Vektorsuche für die Nutzereingabe in einer Python-basierten Implementierung des Vertex AI SDK aufgerufen.
Sie können die Implementierung gerne auf Ihren eigenen Anwendungsfall ausweiten oder den aktuellen Anwendungsfall mit neuen Funktionen improvisieren. Weitere Informationen zu den Machine-Learning-Funktionen von Spanner