1. Einführung
In diesem Codelab erfahren Sie, wie Sie AlloyDB bereitstellen und die KI-Integration für die semantische Suche mit multimodalen Einbettungen nutzen. Dieses Lab ist Teil einer Lab-Sammlung, die sich mit AlloyDB AI-Funktionen befasst. Weitere Informationen
Voraussetzungen
- Grundkenntnisse in Google Cloud und der Console
- Grundkenntnisse in der Befehlszeile und Cloud Shell
Lerninhalte
- AlloyDB for Postgres bereitstellen
- Multimodale Vektorsuche verwenden
- AlloyDB AI-Operatoren aktivieren
- Verschiedene AlloyDB AI-Operatoren für die multimodale Suche verwenden
- So kombinieren Sie Text- und Bildsuchergebnisse mit AlloyDB AI
Voraussetzungen
- Ein Google Cloud-Konto und ein Google Cloud-Projekt
- Ein Webbrowser wie Chrome, der die Google Cloud Console und Cloud Shell unterstützt
2. Einrichtung und Anforderungen
Einrichtung der Umgebung im eigenen Tempo
- Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eins erstellen.
- Der Projektname ist der Anzeigename für die Teilnehmer dieses Projekts. Es handelt sich um einen String, der nicht von Google APIs verwendet wird. Sie können sie jederzeit aktualisieren.
- Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und kann nach dem Festlegen nicht mehr geändert werden. In der Cloud Console wird automatisch ein eindeutiger String generiert. Normalerweise ist es nicht wichtig, wie dieser String aussieht. In den meisten Codelabs müssen Sie auf Ihre Projekt-ID verweisen (in der Regel als
PROJECT_ID
angegeben). Wenn Ihnen die generierte ID nicht gefällt, können Sie eine andere zufällige ID generieren. Alternativ können Sie es mit einem eigenen Namen versuchen und sehen, ob er verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen. - Zur Information: Es gibt einen dritten Wert, die Projektnummer, die von einigen APIs verwendet wird. Weitere Informationen zu diesen drei Werten
- Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Cloud-Ressourcen/-APIs zu verwenden. Die Durchführung dieses Codelabs kostet wenig oder gar nichts. Wenn Sie Ressourcen herunterfahren möchten, um Kosten zu vermeiden, die über diese Anleitung hinausgehen, können Sie die erstellten Ressourcen oder das Projekt löschen. Neue Google Cloud-Nutzer können am Programm Kostenlose Testversion mit einem Guthaben von 300$ teilnehmen.
Cloud Shell starten
Während Sie Google Cloud von Ihrem Laptop aus per Fernzugriff nutzen können, wird in diesem Codelab Google Cloud Shell verwendet, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.
Klicken Sie in der Google Cloud Console in der Symbolleiste oben rechts auf das Cloud Shell-Symbol:
Die Bereitstellung und Verbindung mit der Umgebung dauert nur einen Moment. Anschließend sehen Sie in etwa Folgendes:
Diese virtuelle Maschine verfügt über sämtliche Entwicklertools, die Sie benötigen. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Alle Aufgaben in diesem Codelab können in einem Browser ausgeführt werden. Sie müssen nichts installieren.
3. Hinweis
API aktivieren
Prüfen Sie in Cloud Shell, ob Ihre Projekt-ID eingerichtet ist:
gcloud config set project [YOUR-PROJECT-ID]
Legen Sie die Umgebungsvariable PROJECT_ID fest:
PROJECT_ID=$(gcloud config get-value project)
Aktivieren Sie alle erforderlichen Dienste:
gcloud services enable alloydb.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
aiplatform.googleapis.com \
discoveryengine.googleapis.com \
secretmanager.googleapis.com
Erwartete Ausgabe
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 bereitstellen
AlloyDB-Cluster und primäre Instanz erstellen Im folgenden Verfahren wird beschrieben, wie Sie mit dem Google Cloud SDK einen AlloyDB-Cluster und eine AlloyDB-Instanz erstellen. Wenn Sie die Konsolenmethode bevorzugen, finden Sie hier die Dokumentation.
Bevor wir einen AlloyDB-Cluster erstellen, benötigen wir einen verfügbaren privaten IP-Adressbereich in unserer VPC, der von der zukünftigen AlloyDB-Instanz verwendet werden soll. Wenn wir sie nicht haben, müssen wir sie erstellen, sie für die Verwendung durch interne Google-Dienste zuweisen und erst dann können wir den Cluster und die Instanz erstellen.
Privaten IP-Bereich erstellen
Wir müssen den Zugriff auf private Dienste in unserer VPC für AlloyDB konfigurieren. Wir gehen hier davon aus, dass das VPC-Standardnetzwerk im Projekt vorhanden ist und für alle Aktionen verwendet wird.
Erstellen Sie den privaten IP-Bereich:
gcloud compute addresses create psa-range \
--global \
--purpose=VPC_PEERING \
--prefix-length=24 \
--description="VPC private service access" \
--network=default
Erstellen Sie eine private Verbindung mit dem zugewiesenen IP-Bereich:
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=psa-range \
--network=default
Erwartete Konsolenausgabe:
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-Cluster erstellen
In diesem Abschnitt erstellen wir einen AlloyDB-Cluster in der Region „us-central1“.
Legen Sie ein Passwort für den Postgres-Nutzer fest. Sie können ein eigenes Passwort definieren oder eine Zufallsfunktion verwenden, um eines zu generieren.
export PGPASSWORD=`openssl rand -hex 12`
Erwartete Konsolenausgabe:
student@cloudshell:~ (test-project-402417)$ export PGPASSWORD=`openssl rand -hex 12`
Notieren Sie sich das PostgreSQL-Passwort für die spätere Verwendung.
echo $PGPASSWORD
Sie benötigen dieses Passwort später, um als Postgres-Nutzer eine Verbindung zur Instanz herzustellen. Ich empfehle, sie aufzuschreiben oder zu kopieren, damit Sie sie später verwenden können.
Erwartete Konsolenausgabe:
student@cloudshell:~ (test-project-402417)$ echo $PGPASSWORD bbefbfde7601985b0dee5723
Cluster im kostenlosen Testzeitraum erstellen
Wenn Sie AlloyDB noch nicht verwendet haben, können Sie einen kostenlosen Testcluster erstellen:
Definieren Sie die Region und den Namen des AlloyDB-Clusters. Wir verwenden die Region „us-central1“ und „alloydb-aip-01“ als Clusternamen:
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
Führen Sie den folgenden Befehl aus, um den Cluster zu erstellen:
gcloud alloydb clusters create $ADBCLUSTER \
--password=$PGPASSWORD \
--network=default \
--region=$REGION \
--subscription-type=TRIAL
Erwartete Konsolenausgabe:
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.
Erstellen Sie in derselben Cloud Shell-Sitzung eine primäre AlloyDB-Instanz für den Cluster. Wenn die Verbindung getrennt wird, müssen Sie die Umgebungsvariablen für die Region und den Clusternamen noch einmal definieren.
gcloud alloydb instances create $ADBCLUSTER-pr \
--instance-type=PRIMARY \
--cpu-count=8 \
--region=$REGION \
--cluster=$ADBCLUSTER
Erwartete Konsolenausgabe:
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 Standard-Cluster erstellen
Wenn es nicht Ihr erster AlloyDB-Cluster im Projekt ist, fahren Sie mit der Erstellung eines Standardclusters fort.
Definieren Sie die Region und den Namen des AlloyDB-Clusters. Wir verwenden die Region „us-central1“ und „alloydb-aip-01“ als Clusternamen:
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
Führen Sie den folgenden Befehl aus, um den Cluster zu erstellen:
gcloud alloydb clusters create $ADBCLUSTER \
--password=$PGPASSWORD \
--network=default \
--region=$REGION
Erwartete Konsolenausgabe:
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.
Erstellen Sie in derselben Cloud Shell-Sitzung eine primäre AlloyDB-Instanz für den Cluster. Wenn die Verbindung getrennt wird, müssen Sie die Umgebungsvariablen für die Region und den Clusternamen noch einmal definieren.
gcloud alloydb instances create $ADBCLUSTER-pr \
--instance-type=PRIMARY \
--cpu-count=2 \
--region=$REGION \
--cluster=$ADBCLUSTER
Erwartete Konsolenausgabe:
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. Datenbank vorbereiten
Wir müssen eine Datenbank erstellen, die Vertex AI-Integration aktivieren, Datenbankobjekte erstellen und die Daten importieren.
Erforderliche Berechtigungen für AlloyDB erteilen
Fügen Sie dem AlloyDB-Dienst-Agent Vertex AI-Berechtigungen hinzu.
Öffnen Sie oben einen weiteren Cloud Shell-Tab, indem Sie auf das Pluszeichen (+) klicken.
Führen Sie im neuen Cloud Shell-Tab Folgendes aus:
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"
Erwartete Konsolenausgabe:
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
Schließen Sie den Tab, indem Sie entweder den Befehl „exit“ auf dem Tab ausführen:
exit
Verbindung zu AlloyDB Studio herstellen
In den folgenden Kapiteln können alle SQL-Befehle, für die eine Verbindung zur Datenbank erforderlich ist, alternativ in AlloyDB Studio ausgeführt werden. Um den Befehl auszuführen, müssen Sie die Webkonsolenschnittstelle für Ihren AlloyDB-Cluster öffnen. Klicken Sie dazu auf die primäre Instanz.
Klicken Sie dann links auf AlloyDB Studio:
Wählen Sie die Postgres-Datenbank und den Nutzer „postgres“ aus und geben Sie das Passwort an, das beim Erstellen des Clusters notiert wurde. Klicken Sie dann auf die Schaltfläche „Authentifizieren“.
Dadurch wird die AlloyDB Studio-Oberfläche geöffnet. Wenn Sie die Befehle in der Datenbank ausführen möchten, klicken Sie rechts auf den Tab „Editor 1“.
Dadurch wird eine Schnittstelle geöffnet, in der Sie SQL-Befehle ausführen können.
Datenbank erstellen
Schnellstart: Datenbank erstellen
Führen Sie im AlloyDB Studio-Editor den folgenden Befehl aus.
Datenbank erstellen:
CREATE DATABASE quickstart_db
Erwartete Ausgabe:
Statement executed successfully
Mit quickstart_db verbinden
Stellen Sie über die Schaltfläche zum Wechseln des Nutzers/der Datenbank eine neue Verbindung zum Studio her.
Wählen Sie in der Drop-down-Liste die neue Datenbank „quickstart_db“ aus und verwenden Sie denselben Nutzer und dasselbe Passwort wie zuvor.
Dadurch wird eine neue Verbindung geöffnet, über die Sie mit Objekten aus der Datenbank „quickstart_db“ arbeiten können.
6. Beispieldaten
Jetzt müssen wir Objekte in der Datenbank erstellen und Daten laden. Wir verwenden einen fiktiven „Cymbal“-Shop mit fiktiven Daten.
Bevor wir die Daten importieren, müssen wir Erweiterungen aktivieren, die Datentypen und Indexe unterstützen. Wir benötigen zwei Erweiterungen, von denen eine den Vektordatentyp und die andere den AlloyDB ScaNN-Index unterstützt.
Führen Sie in AlloyDB Studio eine Verbindung zur Datenbank „quickstart_db“ her.
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
Das Dataset wird vorbereitet und als SQL-Datei gespeichert, die über die Importschnittstelle in die Datenbank geladen werden kann. Führen Sie in Cloud Shell die folgenden Befehle aus:
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
Mit dem Befehl wird das AlloyDB SDK verwendet, um einen Nutzer mit dem Namen „agentspace_user“ zu erstellen. Anschließend werden Beispieldaten direkt aus dem GCS-Bucket in die Datenbank importiert, wobei alle erforderlichen Objekte erstellt und Daten eingefügt werden.
Nach dem Import können wir die Tabellen in AlloyDB Studio prüfen. Die Tabellen befinden sich im Schema „ecomm“:
Prüfen Sie die Anzahl der Zeilen in einer der Tabellen.
Wir haben unsere Beispieldaten erfolgreich importiert und können mit den nächsten Schritten fortfahren.
7. Semantische Suche mit Texteinbettungen
In diesem Kapitel werden wir versuchen, die semantische Suche mit Texteinbettungen zu verwenden und sie mit der herkömmlichen Postgres-Text- und Volltextsuche zu vergleichen.
Sehen wir uns zuerst die klassische Suche mit Standard-PostgreSQL-SQL und dem LIKE-Operator an.
Wenn wir mit der folgenden Anfrage nach einer Regenjacke suchen:
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;
Die Abfrage gibt keine Zeilen zurück, da genaue Wörter wie „nasse Bedingungen“ und „Jacke“ entweder im Produktnamen oder in der Beschreibung enthalten sein müssten. Eine „Jacke für nasse Bedingungen“ ist nicht dasselbe wie eine „Jacke für Regen“.
Wir können versuchen, alle möglichen Variationen in die Suche einzubeziehen. Versuchen wir es mit nur zwei Wörtern. Beispiel:
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;
Dadurch würden mehrere Zeilen zurückgegeben, aber nicht alle entsprechen unserer Anfrage nach Jacken. Außerdem ist es schwierig, nach Relevanz zu sortieren. Wenn wir beispielsweise weitere Bedingungen wie „für Männer“ hinzufügen, würde die Komplexität der Anfrage erheblich zunehmen. Alternativ können wir die Volltextsuche ausprobieren, aber auch hier stoßen wir auf Einschränkungen in Bezug auf mehr oder weniger genaue Wörter und die Relevanz der Antwort.
Jetzt können wir eine ähnliche Suche mit Einbettungen durchführen. Wir haben bereits Embeddings für unsere Produkte mit verschiedenen Modellen vorab berechnet. Wir verwenden das neueste Modell „gemini-embedding-001“ von Google. Wir haben sie in der Spalte product_embedding der Tabelle ecomm.products gespeichert. Wenn wir mit der folgenden Abfrage eine Abfrage für unsere Suchbedingung „Regenjacke für Herren“ ausführen:
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;
Es werden nicht nur die Jacken für nasse Bedingungen zurückgegeben, sondern alle Ergebnisse werden so sortiert, dass die relevantesten Ergebnisse oben stehen.
Die Abfrage mit Einbettungen gibt Ergebnisse in 90–150 ms zurück. Ein Teil der Zeit wird dafür benötigt, die Daten aus dem Cloud-Einbettungsmodell abzurufen. Wenn wir uns den Ausführungsplan ansehen, ist die Anfrage an das Modell in der Planungszeit enthalten. Der Teil der Abfrage, der die Suche selbst durchführt, ist recht kurz. Die Suche in 29.000 Datensätzen mit dem AlloyDB ScaNN-Index dauert weniger als 7 ms.
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)
Das war die Suche nach Texteinbettungen mit dem Einbettungsmodell, das nur Text verwendet. Wir haben aber auch Bilder für unsere Produkte und können diese für die Suche verwenden. Im nächsten Kapitel zeigen wir, wie das multimodale Modell Bilder für die Suche verwendet.
8. Multimodale Suche verwenden
Die textbasierte semantische Suche ist zwar nützlich, aber es kann schwierig sein, komplizierte Details zu beschreiben. Die multimodale Suche von AlloyDB bietet den Vorteil, dass Produkte über Bildeingaben gefunden werden können. Das ist besonders hilfreich, wenn die visuelle Darstellung die Suchintention besser verdeutlicht als reine Textbeschreibungen. Zum Beispiel: „Suche mir einen Mantel wie diesen auf dem Bild.“
Kehren wir zu unserem Beispiel mit der Jacke zurück. Wenn ich ein Bild einer Jacke habe, die der Jacke ähnelt, die ich suche, kann ich es an das multimodale Einbettungsmodell von Google übergeben und mit Einbettungen für Bilder meiner Produkte vergleichen. In unserer Tabelle haben wir bereits Embeddings für Bilder unserer Produkte in der Spalte product_image_embedding berechnet. Das verwendete Modell sehen Sie in der Spalte product_image_embedding_model.
Für die Suche können wir die Funktion image_embedding verwenden, um die Einbettung für unser Bild abzurufen und mit den vorab berechneten Einbettungen zu vergleichen. Damit die Funktion aktiviert werden kann, muss die richtige Version der Erweiterung google_ml_integration verwendet werden.
Sehen wir uns die aktuelle Erweiterungsversion an. Führen Sie sie in AlloyDB Studio aus.
SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
Wenn die Version niedriger als 1.4.4 ist, führen Sie die folgenden Schritte aus.
CALL google_ml.upgrade_to_preview_version();
Prüfen Sie dann noch einmal die Version der Erweiterung. Es sollte 1.4.4 sein.
Hier ist mein Beispielbild für die Suche. Sie können aber ein beliebiges benutzerdefiniertes Bild verwenden. Sie müssen die Datei nur in den Google-Speicher oder eine andere öffentlich verfügbare Ressource hochladen und den URI in die Anfrage einfügen.
Sie wird in gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png hochgeladen.
Bildersuche anhand von Bildern
Zuerst versuchen wir, nur anhand des Bildes zu suchen:
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;
Und wir konnten einige warme Jacken im Inventar finden.
Die Bildersuche liefert uns Elemente, die dem zum Vergleich bereitgestellten Bild ähneln. Wie bereits erwähnt, können Sie versuchen, Ihre eigenen Bilder in einen öffentlichen Bucket hochzuladen und zu sehen, ob verschiedene Arten von Kleidung gefunden werden können.
Für unsere Bildersuche haben wir das Modell „multimodalembedding@001“ von Google verwendet. Unsere Funktion „image_embedding“ sendet das Bild an Vertex AI, wandelt es in einen Vektor um und gibt es zurück, damit es mit den gespeicherten Vektoren für Bilder in unserer Datenbank verglichen werden kann.
Mit „EXPLAIN ANALYZE“ können wir auch prüfen, wie schnell es mit unserem AlloyDB ScaNN-Index funktioniert.
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)
Wie im vorherigen Beispiel sehen wir auch hier, dass der Großteil der Zeit für die Umwandlung unseres Bildes in Einbettungen über den Cloud-Endpunkt aufgewendet wurde und die Vektorsuche selbst nur 2,5 ms dauert.
Bildersuche anhand von Text
Mit multimodalen Modellen können wir auch eine Textbeschreibung der Jacke, nach der wir suchen, an das Modell übergeben. Dazu verwenden wir google_ml.text_embedding für dasselbe Modell und vergleichen die Ergebnisse mit den Bildeinbettungen, um zu sehen, welche Bilder zurückgegeben werden.
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;
Wir erhielten eine Reihe von Steppjacken in Grau oder dunklen Farben.
Wir haben eine etwas andere Auswahl an Jacken erhalten, aber es wurden anhand unserer Beschreibung und der Suche in den Bildeinbettungen korrekt Jacken ausgewählt.
Wir versuchen es mit einer anderen Methode, um anhand der Einbettung des Suchbilds in Beschreibungen zu suchen.
Textsuche anhand von Bildern
Wir haben versucht, Bilder zu finden, indem wir die Einbettung für unser Bild übergeben und mit den vorab berechneten Bildeinbettungen für unsere Produkte verglichen haben. Außerdem haben wir versucht, Bilder zu finden, indem wir das Embedding für unsere Textanfrage übergeben und in demselben Embedding nach den Produktbildern gesucht haben. Wir versuchen jetzt, die Einbettung für unser Bild zu verwenden und mit Texteinbettungen für die Produktbeschreibungen zu vergleichen. Die Einbettung wird in der Spalte product_description_embedding gespeichert und verwendet dasselbe Modell multimodalembedding@001.
Hier ist unsere Anfrage:
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;
Hier haben wir eine etwas andere Auswahl an Jacken in Grau- oder Dunkeltönen erhalten, von denen einige mit der vorherigen Auswahl übereinstimmen oder sehr ähnlich sind.
Es werden dieselben Jacken wie oben zurückgegeben, aber in einer leicht anderen Reihenfolge. Anhand der Einbettung für Bilder kann das System die Einbettungen für die Textbeschreibung vergleichen und die richtigen Produkte zurückgeben.
Hybride Text- und Bildersuche
Sie können auch versuchen, Text- und Bildeinbettungen zu kombinieren, z. B. mit der Methode der reziproken Rangfusion. Hier ist ein Beispiel für eine solche Abfrage, in der wir zwei Suchvorgänge kombiniert, jedem Rang eine Punktzahl zugewiesen und die Ergebnisse anhand der kombinierten Punktzahl sortiert haben.
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;
Sie können mit verschiedenen Parametern in der Anfrage experimentieren, um zu sehen, ob sich die Suchergebnisse dadurch verbessern.
Damit ist das Lab abgeschlossen. Um unerwartete Kosten zu vermeiden, sollten Sie nicht verwendete Ressourcen löschen.
Außerdem können Sie andere KI-Operatoren verwenden, um die Ergebnisse zu sortieren, wie in der Dokumentation beschrieben.
9. Umgebung bereinigen
AlloyDB-Instanzen und -Cluster löschen, wenn Sie mit dem Lab fertig sind
AlloyDB-Cluster und alle Instanzen löschen
Der Cluster wird mit der Option „force“ zerstört, wodurch auch alle Instanzen gelöscht werden, die zum Cluster gehören.
Definieren Sie in Cloud Shell die Projekt- und Umgebungsvariablen, wenn die Verbindung getrennt wurde und alle vorherigen Einstellungen verloren gegangen sind:
gcloud config set project <your project id>
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
export PROJECT_ID=$(gcloud config get-value project)
Löschen Sie den Cluster:
gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force
Erwartete Konsolenausgabe:
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-Sicherungen löschen
Löschen Sie alle AlloyDB-Sicherungen für den Cluster:
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
Erwartete Konsolenausgabe:
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. Glückwunsch
Herzlichen Glückwunsch zum Abschluss des Codelabs. Sie haben gelernt, wie Sie die multimodale Suche in AlloyDB mit Einbettungsfunktionen für Texte und Bilder verwenden. Sie können die multimodale Suche testen und mit der Funktion „google_ml.rank“ verbessern. Verwenden Sie dazu das Codelab für AlloyDB AI-Operatoren.
Behandelte Themen
- AlloyDB for Postgres bereitstellen
- Multimodale Vektorsuche verwenden
- AlloyDB AI-Operatoren aktivieren
- Verschiedene AlloyDB AI-Operatoren für die multimodale Suche verwenden
- So kombinieren Sie Text- und Bildsuchergebnisse mit AlloyDB AI
11. Umfrage
Ausgabe: