AlloyDB Omni und EmbeddingGemma mit Gemma 4 in Kubernetes

1. Einführung

In diesem Codelab erfahren Sie, wie Sie AlloyDB Omni in Google Kubernetes Engine (GKE) bereitstellen und mit offenen Modellen wie EmbeddingGemma und Gemma 4 für Einbettungen und Vorhersagen verwenden. Wenn Sie sowohl die Datenbank als auch die Modelle im selben Cluster ausführen, wird die Netzwerklatenz reduziert und Abhängigkeiten von Drittanbieterdiensten werden vermieden. Außerdem können Sie damit Compliance- und Datenstandortanforderungen erfüllen, da Ihre Daten Ihre Umgebung nie verlassen.

Architekturdiagramm von AlloyDB Omni und EmbeddingGemma in GKE

Vorbereitung

  • Grundlegende Kenntnisse von Google Cloud und der Google Cloud Console
  • Grundkenntnisse in Kubernetes und GKE
  • Vertrautheit mit der Befehlszeile und Google Cloud Shell

Lerninhalte

  • AlloyDB Omni in einem GKE-Cluster bereitstellen
  • Verbindung zu AlloyDB Omni herstellen
  • Daten in AlloyDB Omni laden
  • KI-Modelle (Einbettung und LLM) in GKE bereitstellen
  • KI-Modelle in AlloyDB Omni registrieren
  • Einbettungen für die semantische Suche generieren
  • Semantische Suchanfragen in AlloyDB Omni ausführen
  • Vektorindexe in AlloyDB Omni erstellen und verwenden

Voraussetzungen

  • Ein Google Cloud-Konto und ein Google Cloud-Projekt
  • Ein Webbrowser wie Chrome

2. Einrichtung und Anforderungen

Projekt einrichten

  1. Melden Sie sich in der Google Cloud Console an. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, erstellen Sie eines. Verwenden Sie stattdessen ein privates Konto.
  1. Erstellen Sie ein neues Projekt oder wählen Sie ein vorhandenes aus. Klicken Sie in der Kopfzeile der Google Cloud Console auf Projekt auswählen und dann auf Neues Projekt.

Dialogfeld „Projekt auswählen“ in der Google Cloud Console

Klicken Sie im Fenster Projekt auswählen auf Neues Projekt, um das Dialogfeld zum Erstellen von Projekten zu öffnen.

Dialogfeld „Neues Projekt erstellen“

Geben Sie im Dialogfeld einen Projektname ein und wählen Sie Ihre Organisation oder Ihren Standort aus.

Eingabefelder für Projektdetails

  • Der Projektname ist der Anzeigename für die Teilnehmer dieses Projekts. Der Projektname wird von Google APIs nicht verwendet und kann jederzeit geändert werden.
  • Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich. Sie kann also nicht mehr geändert werden, nachdem sie festgelegt wurde. In der Google Cloud Console wird automatisch eine eindeutige ID generiert. Sie können aber auch eine eigene ID angeben. In diesem Codelab wird auf Ihre Projekt-ID mit dem Platzhalter verwiesen.
  • Die Projektnummer ist eine dritte Kennung, die von einigen APIs verwendet wird. Weitere Informationen finden Sie in der Resource Manager-Dokumentation.

Abrechnung aktivieren

Wenn Sie die Abrechnung mit Google Cloud-Guthaben einrichten, können Sie diesen Schritt überspringen.

Wenn Sie ein privates Rechnungskonto einrichten möchten, aktivieren Sie die Abrechnung in der Google Cloud Console.

  • Die für dieses Lab anfallenden Kosten für Google Cloud-Ressourcen betragen weniger als 5 $.
  • Führen Sie die Bereinigungsschritte am Ende dieses Labs aus, um Ressourcen zu löschen und weitere Kosten zu vermeiden.
  • Neue Nutzer haben Anspruch auf den kostenlosen Testzeitraum mit einem Guthaben von 300 $.

Cloud Shell starten

In diesem Codelab verwenden Sie Google Cloud Shell, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.

Klicken Sie in der Google Cloud Console in der Symbolleiste rechts oben auf das Symbol Cloud Shell aktivieren:

Button „Cloud Shell aktivieren“

Alternativ können Sie die Tasten „G“ und „S“ drücken oder Google Cloud Shell direkt öffnen.

Wenn die Verbindung hergestellt ist, wird in Cloud Shell die Terminal-Eingabeaufforderung angezeigt:

Screenshot des Google Cloud Shell-Terminals

Cloud Shell umfasst nichtflüchtigen Speicher und Entwicklertools. Sie können alle Schritte in diesem Codelab in Ihrem Browser ausführen.

3. APIs aktivieren

Wenn Sie Google Kubernetes Engine (GKE) für AlloyDB Omni und Modelldepoloyments verwenden möchten, aktivieren Sie die Compute Engine- und GKE-APIs in Ihrem Google Cloud-Projekt.

Prüfen Sie in Cloud Shell, ob Ihre Projekt-ID konfiguriert ist:

PROJECT_ID=$(gcloud config get-value project)
echo $PROJECT_ID

Wenn Ihre Projekt-ID nicht definiert ist, konfigurieren Sie sie:

export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID

Aktivieren Sie die erforderlichen APIs:

gcloud services enable compute.googleapis.com
gcloud services enable container.googleapis.com

Erwartete Ausgabe:

student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=test-project-001-402417
student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417
Updated property [core/project].
student@cloudshell:~ (test-project-001-402417)$ gcloud services enable compute.googleapis.com
gcloud services enable container.googleapis.com
Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.

Informationen zu den einzelnen aktivierten APIs finden Sie in der Dokumentation.

4. AlloyDB Omni in GKE bereitstellen

Wenn Sie AlloyDB Omni in GKE bereitstellen möchten, bereiten Sie einen Kubernetes-Cluster gemäß den Anforderungen an den AlloyDB Omni-Operator vor.

GKE-Cluster erstellen

Stellen Sie einen GKE-Standardcluster mit Kapazität für die Ausführung von AlloyDB Omni, dem Operator und Monitoring-Containern bereit. Für AlloyDB Omni sind mindestens zwei CPUs und 8 GB RAM erforderlich. In dieser Anleitung wird der Maschinentyp n2-standard-4 verwendet.

Legen Sie die Umgebungsvariablen für Ihre Bereitstellung fest:

export PROJECT_ID=$(gcloud config get-value project)
export LOCATION=us-central1
export CLUSTER_NAME=alloydb-ai-gke
export MACHINE_TYPE=n2-standard-4

Erstellen Sie den GKE-Standardcluster:

gcloud container clusters create ${CLUSTER_NAME} \
  --project=${PROJECT_ID} \
  --region=${LOCATION} \
  --workload-pool=${PROJECT_ID}.svc.id.goog \
  --release-channel=rapid \
  --machine-type=${MACHINE_TYPE} \
  --num-nodes=1

Erwartete Konsolenausgabe:

student@cloudshell:~ (test-project-001-402417)$ export PROJECT_ID=$(gcloud config get project)
export LOCATION=us-central1
export CLUSTER_NAME=alloydb-ai-gke
export MACHINE_TYPE=n2-standard-4
Your active configuration is: [test-project-001-402417]
student@cloudshell:~ (test-project-001-402417)$ gcloud container clusters create ${CLUSTER_NAME} \
  --project=${PROJECT_ID} \
  --region=${LOCATION} \
  --workload-pool=${PROJECT_ID}.svc.id.goog \
  --release-channel=rapid \
  --machine-type=${MACHINE_TYPE} \
  --num-nodes=1
Note: Your Pod address range (`--cluster-ipv4-cidr`) can accommodate at most 1008 node(s).
Creating cluster alloydb-ai-gke in us-central1... Cluster is being health-checked (Kubernetes Control Plane is healthy)...done.                                                                                            
Created [https://container.googleapis.com/v1/projects/test-project-001-402417/zones/us-central1/clusters/alloydb-ai-gke].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1/alloydb-ai-gke?project=test-project-001-402417
kubeconfig entry generated for alloydb-ai-gke.
NAME: alloydb-ai-gke
LOCATION: us-central1
MASTER_VERSION: 1.36.3-gke.1640000
MASTER_IP: 34.121.243.65
MACHINE_TYPE: n2-standard-4
NODE_VERSION: 1.36.3-gke.1640000
NUM_NODES: 3
STATUS: RUNNING
STACK_TYPE: IPV4

Cluster vorbereiten

Installieren Sie die erforderlichen Komponenten wie cert-manager, den nativen Zertifikate-Controller für Kubernetes. Weitere Informationen finden Sie in der Installationsdokumentation für cert-manager.

Cloud Shell enthält das Kubernetes-Befehlszeilentool kubectl. Clusteranmeldedaten mit gcloud abrufen:

gcloud container clusters get-credentials ${CLUSTER_NAME} --region=${LOCATION}

Installieren Sie cert-manager mit kubectl:

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.21.1/cert-manager.yaml

Erwartete Konsolenausgabe (redigiert):

student@cloudshell:~$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.21.1/cert-manager.yaml
namespace/cert-manager created
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created
...
validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created

AlloyDB Omni-Operator installieren

Installieren Sie den AlloyDB Omni-Operator mit Helm.

Laden Sie das AlloyDB Omni-Operator-Diagramm herunter und installieren Sie es:

helm install alloydbomni-operator oci://gcr.io/alloydb-omni/alloydbomni-operator \
--version 1.8.1 \
--create-namespace \
--namespace alloydb-omni-system \
--atomic \
--timeout 5m

Erwartete Konsolenausgabe (redigiert):

student@cloudshell:~$ helm install alloydbomni-operator oci://gcr.io/alloydb-omni/alloydbomni-operator \
> --version 1.8.0 \
> --create-namespace \
> --namespace alloydb-omni-system \
> --atomic \
> --timeout 5m
Flag --atomic has been deprecated, use --rollback-on-failure instead
Pulled: gcr.io/alloydb-omni/alloydbomni-operator:1.8.0
Digest: sha256:f2d98fa7a3b08dfc1e83b811582718b94e5c017b81aade700c83e917c59f0395
NAME: alloydbomni-operator
LAST DEPLOYED: Thu Aug 27 17:57:30 2026
NAMESPACE: alloydb-omni-system
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None

Stellen Sie den Datenbankcluster bereit.

Das folgende Manifest konfiguriert einen Datenbankcluster mit aktivierter googleMLExtension und einem internen Load-Balancer:

cat << 'EOF' > my-omni.yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-pw-my-omni
type: Opaque
data:
  my-omni: "VmVyeVN0cm9uZ1Bhc3N3b3Jk"
---
apiVersion: alloydbomni.dbadmin.goog/v1
kind: DBCluster
metadata:
  name: my-omni
spec:
  databaseVersion: "18.3.0"
  primarySpec:
    adminUser:
      passwordRef:
        name: db-pw-my-omni
    features:
      googleMLExtension:
        enabled: true
    resources:
      cpu: 1
      memory: 8Gi
      disks:
      - name: DataDisk
        size: 20Gi
        storageClass: standard
    dbLoadBalancerOptions:
      annotations:
        networking.gke.io/load-balancer-type: "internal"
  allowExternalIncomingTraffic: true
EOF

Der Secret-Wert für das Passwort ist die Base64-Darstellung von VeryStrongPassword. In Produktionsumgebungen sollten Sie Google Secret Manager zum Verwalten von Passwörtern verwenden. Weitere Informationen finden Sie in der Secret Manager-Dokumentation.

Das Manifest wird als my-omni.yaml gespeichert. Klicken Sie in Cloud Shell oben rechts im Terminalfenster auf Editor öffnen und lesen Sie die Datei.

Editor in Cloud Shell öffnen

Klicken Sie nach dem Lesen des my-omni.yaml-Manifests auf Terminal öffnen, um zur Eingabeaufforderung zurückzukehren.

Terminal in Cloud Shell öffnen

Wenden Sie das my-omni.yaml-Manifest an:

kubectl apply -f my-omni.yaml

Erwartete Konsolenausgabe:

secret/db-pw-my-omni created
dbcluster.alloydbomni.dbadmin.goog/my-omni created

Prüfen Sie den Status des my-omni-Clusters:

kubectl get dbclusters.alloydbomni.dbadmin.goog my-omni -n default

Während der Bereitstellung durchläuft der Datenbankcluster Einrichtungsphasen, bis er den Status DBClusterReady erreicht.

Erwartete Konsolenausgabe:

$ kubectl get dbclusters.alloydbomni.dbadmin.goog my-omni -n default
NAME      PRIMARYENDPOINT   PRIMARYPHASE   DBCLUSTERPHASE   HAREADYSTATUS   HAREADYREASON
my-omni   10.131.0.33        Ready          DBClusterReady

Optional können Sie die Clusterbereitstellung mit dem Befehl kubectl log überwachen:

kubectl logs -l alloydbomni.internal.dbadmin.goog/dbcluster=my-omni --all-containers -f

Verbindung zu AlloyDB Omni herstellen

Wenn der Cluster bereit ist, stellen Sie mit dem PostgreSQL-Client (psql) eine Verbindung zum Datenbank-Pod her. Das Passwort ist VeryStrongPassword, wie in my-omni.yaml definiert:

DB_CLUSTER_NAME=my-omni
DB_CLUSTER_NAMESPACE=default
DBPOD=`kubectl get pod --selector=alloydbomni.internal.dbadmin.goog/dbcluster=$DB_CLUSTER_NAME,alloydbomni.internal.dbadmin.goog/task-type=database -n $DB_CLUSTER_NAMESPACE -o jsonpath='{.items[0].metadata.name}'`
kubectl exec -ti $DBPOD -n $DB_CLUSTER_NAMESPACE -c database -- psql -h localhost -U postgres

Beispiel für die Konsolenausgabe:

DB_CLUSTER_NAME=my-omni
DB_CLUSTER_NAMESPACE=default
DBPOD=`kubectl get pod --selector=alloydbomni.internal.dbadmin.goog/dbcluster=$DB_CLUSTER_NAME,alloydbomni.internal.dbadmin.goog/task-type=database -n $DB_CLUSTER_NAMESPACE -o jsonpath='{.items[0].metadata.name}'`
kubectl exec -ti $DBPOD -n $DB_CLUSTER_NAMESPACE -c database -- psql -h localhost -U postgres
Password for user postgres:
psql (18.3)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_128_GCM_SHA256, compression: off, ALPN: postgresql)
Type "help" for help.

postgres=#

Beenden Sie die psql-Sitzung, indem Sie \q eingeben und die Eingabetaste drücken:

postgres=# \q

5. EmbeddingGemma-Modell in GKE bereitstellen

Wenn Sie die KI-Integration von AlloyDB Omni mit lokalen Modellen testen möchten, stellen Sie ein Einbettungsmodell im GKE-Cluster bereit. In dieser Anleitung wird das Modell EmbeddingGemma von Google verwendet.

Knotenpool für das Modell erstellen

Bereiten Sie einen dedizierten Knotenpool vor, um die Modellinferenz auszuführen. Sie können einen reinen CPU-Knotenpool oder einen GPU-beschleunigten Knotenpool (z. B. g2-standard-8 mit einer NVIDIA L4-GPU) verwenden. In dieser Anleitung wird ein CPU-basierter Knotenpool mit c3-standard-8-Maschinentypen verwendet.

So erstellen Sie einen CPU-Knotenpool mit einem Knoten:

export PROJECT_ID=$(gcloud config get-value project)
export LOCATION=us-central1
export CLUSTER_NAME=alloydb-ai-gke
gcloud container node-pools create cpupool \
  --project=${PROJECT_ID} \
  --location=${LOCATION} \
  --node-locations=${LOCATION}-a \
  --cluster=${CLUSTER_NAME} \
  --machine-type=c3-standard-8 \
  --num-nodes=1

Erwartete Ausgabe:

student@cloudshell$ export PROJECT_ID=$(gcloud config get project)
Your active configuration is: [pant]
export LOCATION=us-central1
export CLUSTER_NAME=alloydb-ai-gke
student@cloudshell$ gcloud container node-pools create cpupool \
>   --project=${PROJECT_ID} \
>   --location=${LOCATION} \
>   --node-locations=${LOCATION}-a \
>   --cluster=${CLUSTER_NAME} \
>   --machine-type=c3-standard-8 \
>   --num-nodes=1
Creating node pool cpupool...done.
Created [https://container.googleapis.com/v1/projects/gleb-test-short-003-483115/zones/us-central1/clusters/alloydb-ai-gke/nodePools/cpupool].
NAME     MACHINE_TYPE    DISK_SIZE_GB  NODE_VERSION
cpupool  c3-standard-8  100           1.34.1-gke.3355002

Hugging Face-Token abrufen

In dieser Anleitung wird das Modell EmbeddingGemma von Hugging Face bereitgestellt. So greifen Sie auf die Modellgewichte zu: Erstellen Sie ein Hugging Face-Zugriffstoken:

  1. Melden Sie sich bei Hugging Face an oder erstellen Sie ein Konto.
  2. Rufen Sie Mein Profil > Zugriffstokens auf.
  3. Klicken Sie auf Neues Token erstellen.
  4. Geben Sie einen Namen für das Token ein und wählen Sie die Rolle Lesen aus.
  5. Klicken Sie auf Token erstellen und kopieren Sie den generierten Tokenwert.
  6. Akzeptieren Sie die Modellbedingungen auf der Seite zum EmbeddingGemma-Modell, falls Sie dies noch nicht getan haben.

Erstellen Sie in Cloud Shell ein Kubernetes-Secret, das Ihr Hugging Face-Token enthält. Ersetzen Sie dabei den Token-Platzhalter durch Ihr Token:

export HF_TOKEN=<YOUR_HUGGING_FACE_TOKEN>
kubectl create secret generic hf-secret \
  --from-literal=hf_api_token=$HF_TOKEN \
  --dry-run=client -o yaml | kubectl apply -f -

Bereitstellungsmanifest vorbereiten

Verwenden Sie zum Bereitstellen des Modells das TEI-Containerpaket (Text Embeddings Inference) von Hugging Face. Weitere Informationen finden Sie in der Hugging Face GKE TEI-Dokumentation.

Klonen Sie das Bereitstellungs-Repository von GitHub:

git clone https://github.com/huggingface/Google-Cloud-Containers

Manifest für die CPU-Konfiguration prüfen und ändern:

edit Google-Cloud-Containers/examples/gke/tei-deployment/cpu-config/deployment.yaml

Das aktualisierte Manifest für die CPU-Bereitstellung:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tei-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tei-server
  template:
    metadata:
      labels:
        app: tei-server
        hf.co/model: Google--embeddinggemma-300m
        hf.co/task: text-embeddings
    spec:
      containers:
        - name: tei-container
          image: ghcr.io/huggingface/text-embeddings-inference:cpu-latest
          resources:
            requests:
              cpu: "6"
              memory: "24Gi"
            limits:
              cpu: "6"
              memory: "24Gi"
          env:
            - name: MODEL_ID
              value: google/embeddinggemma-300m
            - name: NUM_SHARD
              value: "1"
            - name: PORT
              value: "8080"
            - name: HF_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
          volumeMounts:
            - mountPath: /tmp
              name: tmp
      volumes:
        - name: tmp
          emptyDir: {}
      nodeSelector:
        cloud.google.com/machine-family: "c3"

Speichern Sie die Änderungen, indem Sie ctrl+s drücken, und wechseln Sie zurück zum Terminal.

Modell bereitstellen

Wenden Sie das Manifest an, um den TEI-Server bereitzustellen:

kubectl apply -f Google-Cloud-Containers/examples/gke/tei-deployment/cpu-config

Überwachen Sie die Bereitstellung, bis sie bereit ist:

printf "Waiting for model to load..."; until kubectl logs -l app=tei-server --tail=50 2>/dev/null | grep -q "Ready"; do printf "."; sleep 3; done; printf '\n\033[1;32m========================================\n[SUCCESS] Model is loaded and ready!\nYou can now proceed to the next step.\n========================================\033[0m\n'

Prüfen Sie den tei-service-Kubernetes-Dienst:

kubectl get service tei-service

Erwartete Ausgabe:

student@cloudshell$ kubectl get service tei-service
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
tei-service   ClusterIP   34.118.233.48   <none>        8080/TCP   10m

Der Dienst CLUSTER-IP verarbeitet Anfragen intern unter http://34.118.233.48:8080/embed.

Testen Sie den Modellendpunkt lokal mit kubectl port-forward:

kubectl port-forward service/tei-service 8080:8080

Öffnen Sie einen zweiten Cloud Shell-Tab, indem Sie oben im Terminal auf + klicken:

Cloud Shell-Tab hinzufügen

Testen Sie im neuen Tab die Einbettungserstellung mit curl:

curl http://localhost:8080/embed \
  -X POST \
  -d '{"inputs":"Test"}' \
  -H 'Content-Type: application/json'

Erwartete Ausgabe (Vektor-Array):

curl http://localhost:8080/embed \
>     -X POST \
>     -d '{"inputs":"Test"}' \
>     -H 'Content-Type: application/json'
[[-0.018975832,0.0071419072,0.06347208,0.022992613,0.014205903
...
-0.03677433,0.01636146,0.06731572]]

Beenden Sie die Portweiterleitung auf dem ersten Tab, indem Sie ctrl+c drücken.

6. Embedding-Modell in AlloyDB Omni registrieren

Wenn Sie das bereitgestellte Modell in AlloyDB Omni verwenden möchten, erstellen Sie eine Datenbank, definieren Sie Transformationsfunktionen und registrieren Sie den Modellendpunkt.

Client-VM und Datenbank erstellen

Erstellen Sie eine Compute Engine-VM-Instanz in derselben VPC, die als Client-Jump Host fungiert:

Architekturdiagramm des Netzwerks mit Client-VM und AlloyDB Omni

Erstellen Sie in Cloud Shell die Client-VM:

export ZONE=us-central1-a
gcloud compute instances create instance-1 \
  --zone=$ZONE

Rufen Sie die IP-Adresse des AlloyDB Omni-Endpunkts ab:

echo "INSTANCE_IP=$(kubectl get dbclusters.alloydbomni.dbadmin.goog my-omni -n default -o jsonpath='{.status.primary.endpoint}')"

Erwartete Ausgabe:

INSTANCE_IP=10.128.0.33

Der Wert INSTANCE_IP ist die IP-Adresse des internen Load-Balancers für den AlloyDB Omni-Cluster. In diesem Beispiel ist das 10.131.0.33.

Stellen Sie eine SSH-Verbindung zur VM-Instanz her.

gcloud compute ssh instance-1 --zone=$ZONE

Installieren Sie in der SSH-Sitzung auf instance-1 den PostgreSQL-Client:

sudo apt-get update && sudo apt-get install --yes postgresql-client 

Exportieren Sie die IP-Adresse des AlloyDB Omni-Load-Balancers (ersetzen Sie PRIMARYENDPOINT durch Ihre IP-Adresse):

export INSTANCE_IP=10.131.0.33

Verbindung zu AlloyDB Omni mit psql herstellen (das Passwort ist VeryStrongPassword):

psql "host=$INSTANCE_IP user=postgres sslmode=require"

Erstellen Sie in der psql-Sitzung die Datenbank demo:

CREATE DATABASE demo;

Wechseln Sie zur Datenbank demo:

\c demo

Transformationsfunktionen erstellen

Für benutzerdefinierte Einbettungsendpunkte sind Transformationsfunktionen für Ein- und Ausgabe erforderlich, um Datenformate zwischen AlloyDB Omni und der Modell-API anzupassen.

Eingabetransformationsfunktion erstellen:

CREATE OR REPLACE FUNCTION tei_text_input_transform(model_id VARCHAR(100), input_text TEXT)
RETURNS JSON
LANGUAGE plpgsql
AS $$
DECLARE
  transformed_input JSON;
BEGIN
  SELECT json_build_object('inputs', input_text, 'truncate', true)::JSON INTO transformed_input;
  RETURN transformed_input;
END;
$$;

Erwartete Ausgabe:

demo=# CREATE OR REPLACE FUNCTION tei_text_input_transform(model_id VARCHAR(100), input_text TEXT)
RETURNS JSON
LANGUAGE plpgsql
AS $$
DECLARE
  transformed_input JSON;
BEGIN
  SELECT json_build_object('inputs', input_text, 'truncate', true)::JSON INTO transformed_input;
  RETURN transformed_input;
END;
$$;
CREATE FUNCTION
demo=#

Erstellen Sie die Ausgabetransformationsfunktion zum Parsen der Vektorarray-Antwort:

CREATE OR REPLACE FUNCTION tei_text_output_transform(model_id VARCHAR(100), response_json JSON)
RETURNS REAL[]
LANGUAGE plpgsql
AS $$
DECLARE
  transformed_output REAL[];
BEGIN
  SELECT ARRAY(SELECT json_array_elements_text(response_json->0)) INTO transformed_output;
  RETURN transformed_output;
END;
$$;

Erwartete Ausgabe:

demo=# CREATE OR REPLACE FUNCTION tei_text_output_transform(model_id VARCHAR(100), response_json JSON)
RETURNS REAL[]
LANGUAGE plpgsql
AS $$
DECLARE
  transformed_output REAL[];
BEGIN
  SELECT ARRAY(SELECT json_array_elements_text(response_json->0)) INTO transformed_output;
  RETURN transformed_output;
END;
$$;
CREATE FUNCTION
demo=#

Modell registrieren

Registrieren Sie das Modell in AlloyDB Omni mit der Prozedur google_ml.create_model. Geben Sie http://tei-service:8080/embed als model_request_url an, um Anfragen an den Kubernetes-Clusterdienst weiterzuleiten:

CALL
  google_ml.create_model(
    model_id => 'embeddinggemma',
    model_request_url => 'http://tei-service:8080/embed',
    model_provider => 'custom',
    model_type => 'text_embedding',
    model_in_transform_fn => 'tei_text_input_transform',
    model_out_transform_fn => 'tei_text_output_transform');

Erwartete Ausgabe:

demo=# CALL
  google_ml.create_model(
    model_id => 'embeddinggemma',
    model_request_url => 'http://tei-service:8080/embed',
    model_provider => 'custom',
    model_type => 'text_embedding',
    model_in_transform_fn => 'tei_text_input_transform',
    model_out_transform_fn => 'tei_text_output_transform');
CALL
demo=#

Registriertes Modell mit einer Beispiel-SQL-Abfrage testen:

SELECT google_ml.embedding('embeddinggemma', 'What is AlloyDB Omni?');

Die Funktion gibt die Arraydarstellung der reellen Zahlen zurück, die vom lokalen EmbeddingGemma-Modell generiert wird, das in GKE ausgeführt wird.

Drücken Sie q, um zur Eingabeaufforderung für die psql-Sitzung zurückzukehren.

Beenden Sie die psql-Sitzung:

\q

7. Modell mit Beispieldaten testen

Beispieldaten laden

In dieser Anleitung wird das Cymbal-Einzelhandelsdataset verwendet, um die Vektorsuche nach Ähnlichkeit zu demonstrieren. Sie verwenden das Google Cloud SDK und den PostgreSQL-Client, um Daten in AlloyDB Omni zu importieren.

Stellen Sie in der SSH-Sitzung auf instance-1 eine Verbindung zur Demodatenbank her und aktivieren Sie die Erweiterung vector:

psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"

In der psql-Sitzung:

CREATE EXTENSION IF NOT EXISTS vector;

Beenden Sie die psql-Sitzung:

\q

Laden Sie das Schema herunter und wenden Sie es an, um Tabellen in der Datenbank demo zu erstellen:

gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=demo"

Erwartete Ausgabe:

student@cloudshell:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=demo"
Password for user postgres:
SET
SET
SET
SET
SET
 set_config
------------

(1 row)

SET
SET
SET
SET
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
ALTER SEQUENCE
ALTER TABLE
ALTER TABLE
ALTER TABLE
student@cloudshell:~$

Erstellte Tabellen prüfen:

psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\dt+"

Erwartete Ausgabe:

student@cloudshell:~$ psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\dt+"
Password for user postgres: 
                                           List of relations
 Schema |       Name       | Type  |  Owner   | Persistence | Access method |    Size    | Description 
--------+------------------+-------+----------+-------------+---------------+------------+-------------
 public | cymbal_embedding | table | postgres | permanent   | heap          | 8192 bytes | 
 public | cymbal_inventory | table | postgres | permanent   | heap          | 8192 bytes | 
 public | cymbal_products  | table | postgres | permanent   | heap          | 8192 bytes | 
 public | cymbal_stores    | table | postgres | permanent   | heap          | 8192 bytes | 
(4 rows)

Laden Sie Daten in die Tabelle cymbal_products:

gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_products from stdin csv header"

Erwartete Ausgabe:

student@cloudshell:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_products from stdin csv header"
COPY 941
student@cloudshell:~$ 

Hier sehen Sie ein Beispiel für einige Zeilen aus der Tabelle cymbal_products.

psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT uniq_id,left(product_name,30),left(product_description,50),sale_price FROM cymbal_products limit 3"

Erwartete Ausgabe:

student@cloudshell:~$ psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT uniq_id,left(product_name,30),left(product_description,50),sale_price FROM cymbal_products limit 3"
Password for user postgres: 
             uniq_id              |              left              |                        left                        | sale_price 
----------------------------------+--------------------------------+----------------------------------------------------+------------
 a73d5f754f225ecb9fdc64232a57bc37 | Laundry Tub Strainer Cup       |   Laundry tub strainer cup Chrome For 1-.50, drain |      11.74
 41b8993891aa7d39352f092ace8f3a86 | LED Starry Star Night Light La |  LED Starry Star Night Light Laser Projector 3D Oc |      46.97
 ed4a5c1b02990a1bebec908d416fe801 | Surya Horizon HRZ-1060 Area Ru |  The 100% polypropylene construction of the Surya  |       77.4
(3 rows)
student@cloudshell:~$ 

Laden Sie Daten in die Tabelle cymbal_inventory:

gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_inventory from stdin csv header"

Erwartete Ausgabe:

student@cloudshell:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_inventory from stdin csv header"
Password for user postgres: 
COPY 263861
student@cloudshell:~$ 

Hier sehen Sie ein Beispiel für einige Zeilen aus der Tabelle cymbal_inventory.

psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT * FROM cymbal_inventory LIMIT 3"

Ausgabe:

student@cloudshell:~$ psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT * FROM cymbal_inventory LIMIT 3"
Password for user postgres: 
 store_id |             uniq_id              | inventory 
----------+----------------------------------+-----------
     1583 | adc4964a6138d1148b1d98c557546695 |         5
     1490 | adc4964a6138d1148b1d98c557546695 |         4
     1492 | adc4964a6138d1148b1d98c557546695 |         3
(3 rows)
student@cloudshell:~$ 

Laden Sie Daten in die Tabelle cymbal_stores:

gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_stores from stdin csv header"

Erwartete Konsolenausgabe:

student@cloudshell:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_stores from stdin csv header"
Password for user postgres: 
COPY 4654
student@cloudshell:~$

Hier sehen Sie ein Beispiel für einige Zeilen aus der Tabelle cymbal_stores.

psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT store_id, name, zip_code FROM cymbal_stores limit 3"

Ausgabe:

student@cloudshell:~$ psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT store_id, name, zip_code FROM cymbal_stores limit 3"
Password for user postgres: 
 store_id |       name        | zip_code 
----------+-------------------+----------
     1990 | Mayaguez Store    |      680
     2267 | Ware Supercenter  |     1082
     4359 | Ponce Supercenter |      780
(3 rows)
student@cloudshell:~$ 

Einbettungen erstellen

Stellen Sie mit psql eine Verbindung zur Demodatenbank her und erstellen Sie Einbettungen für die Produkte in der Tabelle „cymbal_products“ auf Grundlage der Produktbeschreibungen.

Stellen Sie eine Verbindung zur Demodatenbank her:

psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"

Verwenden Sie die Spalte embedding vom Typ vector, um die generierten Texteinbettungen für Produktbeschreibungen zu speichern.

Abfragezeitmessung aktivieren:

\timing

Erstellen Sie Einbettungen für jede Produktbeschreibung und speichern Sie sie in der Tabelle cymbal_embedding:

INSERT INTO cymbal_embedding (uniq_id, embedding)
SELECT uniq_id, google_ml.embedding('embeddinggemma', product_description)::vector
FROM cymbal_products;

Erwartete Ausgabe:

demo=# INSERT INTO cymbal_embedding(uniq_id,embedding)  SELECT uniq_id, google_ml.embedding('embeddinggemma',product_description)::vector FROM cymbal_products;
INSERT 0 941
Time: 497878.136 ms (08:17.878)
demo=#

Semantische Suchanfragen ausführen

Suchen Sie in der Sitzung psql mithilfe der Kosinus-Distanz (<=>) nach den fünf Produkten, die am besten zur Frage "What kind of fruit trees grow well here?" passen:

SELECT
    cp.product_name,
    left(cp.product_description, 80) AS description,
    cp.sale_price,
    cs.zip_code,
    (ce.embedding <=> google_ml.embedding('embeddinggemma', 'What kind of fruit trees grow well here?')::vector) AS distance
FROM
    cymbal_products cp
JOIN cymbal_embedding ce ON ce.uniq_id = cp.uniq_id
JOIN cymbal_inventory ci ON ci.uniq_id = cp.uniq_id
JOIN cymbal_stores cs ON cs.store_id = ci.store_id
WHERE
    ci.inventory > 0
    AND cs.store_id = 1583
ORDER BY
    distance ASC
LIMIT 5;

Erwartete Ausgabe:

demo=# SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        (ce.embedding <=> google_ml.embedding('embeddinggemma','What kind of fruit trees grow well here?')::vector) as distance
FROM
        cymbal_products cp
JOIN cymbal_embedding ce on ce.uniq_id=cp.uniq_id
JOIN cymbal_inventory ci on ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on cs.store_id=ci.store_id
WHERE
    ci.inventory > 0
    AND cs.store_id = 1583
ORDER BY
    distance ASC
LIMIT 5;
     product_name      |                                   description                                    | sale_price | zip_code |      distance
-----------------------+----------------------------------------------------------------------------------+------------+----------+--------------------
 Cherry Tree           | This is a beautiful cherry tree that will produce delicious cherries. It is an d |      75.00 |    93230 | 0.5210549378080666
 California Lilac      | This is a beautiful lilac tree that can grow to be over 10 feet tall. It is an d |       5.00 |    93230 | 0.5639421771781971
 Toyon                 | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e |      10.00 |    93230 | 0.5670010914504852
 Rose Bush             | This is a beautiful rose bush that will produce fragrant roses. It is a perennia |      50.00 |    93230 | 0.5731542622882957
 California Peppertree | This is a beautiful peppertree that can grow to be over 30 feet tall. It is an e |      25.00 |    93230 | 0.5750934653011995
(5 rows)

Time: 83.610 ms
demo=#

Die Abfrage wurde in 83 ms ausgeführt und hat eine Liste von Bäumen aus der Tabelle „cymbal_products“ zurückgegeben, die der Anfrage entsprechen und für die im Geschäft mit der Nummer 1583 Inventar verfügbar ist.

ANN-Index erstellen

Bei einem kleinen Datensatz ist es einfach, die genaue Suche mit dem Scannen aller Einbettungen zu verwenden. Wenn die Daten jedoch wachsen, erhöhen sich auch die Lade- und Antwortzeiten. Sie können die Leistung verbessern, indem Sie Indizes für Ihre Einbettungsdaten erstellen. Hier sehen Sie ein Beispiel dafür, wie Sie das mit dem Google ScaNN-Index für Vektordaten tun können.

Stellen Sie die Verbindung zur Demodatenbank wieder her, wenn sie unterbrochen wurde:

psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"

Aktivieren Sie die Erweiterung „alloydb_scann“:

CREATE EXTENSION IF NOT EXISTS alloydb_scann;

Erstellen Sie den ScaNN-Index für die Spalte embedding:

CREATE INDEX cymbal_products_embeddings_scann ON cymbal_embedding
  USING scann (embedding cosine)
  WITH (num_leaves=10, max_num_levels = 1);

Führen Sie die semantische Suchanfrage noch einmal aus, um die Ausführungsleistung zu vergleichen:

SELECT
    cp.product_name,
    left(cp.product_description, 80) AS description,
    cp.sale_price,
    cs.zip_code,
    (ce.embedding <=> google_ml.embedding('embeddinggemma', 'What kind of fruit trees grow well here?')::vector) AS distance
FROM
    cymbal_products cp
JOIN cymbal_embedding ce ON ce.uniq_id = cp.uniq_id
JOIN cymbal_inventory ci ON ci.uniq_id = cp.uniq_id
JOIN cymbal_stores cs ON cs.store_id = ci.store_id
WHERE
    ci.inventory > 0
    AND cs.store_id = 1583
ORDER BY
    distance ASC
LIMIT 5;

Erwartete Ausgabe:

demo=# SELECT
    cp.product_name,
    left(cp.product_description,80) as description,
    cp.sale_price,
    cs.zip_code,
    (ce.embedding <=> google_ml.embedding('embeddinggemma', 'What kind of fruit trees grow well here?')::vector) AS distance
FROM
    cymbal_products cp
JOIN cymbal_embedding ce ON ce.uniq_id = cp.uniq_id
JOIN cymbal_inventory ci ON ci.uniq_id = cp.uniq_id
JOIN cymbal_stores cs ON cs.store_id = ci.store_id
WHERE
    ci.inventory > 0
    AND cs.store_id = 1583
ORDER BY
    distance ASC
LIMIT 5;
     product_name      |                                   description                                    | sale_price | zip_code |      distance
-----------------------+----------------------------------------------------------------------------------+------------+----------+--------------------
 Cherry Tree           | This is a beautiful cherry tree that will produce delicious cherries. It is an d |      75.00 |    93230 | 0.5210549378080666
 California Lilac      | This is a beautiful lilac tree that can grow to be over 10 feet tall. It is an d |       5.00 |    93230 | 0.5639421771781971
 Toyon                 | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e |      10.00 |    93230 | 0.5670010914504852
 Rose Bush             | This is a beautiful rose bush that will produce fragrant roses. It is a perennia |      50.00 |    93230 | 0.5731542622882957
 California Peppertree | This is a beautiful peppertree that can grow to be over 30 feet tall. It is an e |      25.00 |    93230 | 0.5750934653011995
(5 rows)

Time: 64.783 ms

Die Ausführungszeit der Abfrage hat sich leicht verkürzt. Bei größeren Datasets ist die Verbesserung deutlicher. Die zurückgegebenen Daten sollten mit den Daten ohne Index übereinstimmen oder ihnen sehr ähnlich sein.

Probieren Sie andere Anfragen aus und lesen Sie in der Dokumentation mehr über die Optimierung von Vektorindexen.

psql-Sitzung beenden:

\q

Kehren Sie zu Google Cloud Shell zurück, indem Sie die Verbindung zur instance-1-SSH-Sitzung mit Strg + D trennen oder exit eingeben.

8. Gemma mit vLLM bereitstellen

Knotenpool für Gemma hinzufügen

Prüfen Sie zuerst, welche Knotentypen in Ihrer Region verfügbar sind:

export LOCATION=us-central1-a
gcloud compute accelerator-types list --filter="zone:${LOCATION}"

Sie sollten eine Liste der verfügbaren Beschleunigertypen sehen, einschließlich des nvidia-l4-Beschleunigers. Erstellen Sie nun einen Knotenpool mit dem Beschleunigertyp „nvidia-l4“:

export PROJECT_ID=$(gcloud config get project)
export LOCATION=us-central1
export CLUSTER_NAME=alloydb-ai-gke
gcloud container node-pools create gpupool \
    --accelerator type=nvidia-l4,count=1,gpu-driver-version=latest \
    --project=${PROJECT_ID} \
    --location=${LOCATION} \
    --node-locations=${LOCATION}-a \
    --cluster=${CLUSTER_NAME} \
    --machine-type=g2-standard-8 \
    --num-nodes=1

Erstellen Sie ein Bereitstellungsmanifest für das Google Gemini 4 12B-Modell mit vLLM:

cat << 'EOF' > gemma-12b-gpu-vllm-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gemma-12b-gpu-vllm-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gemma-12b-gpu-vllm
  template:
    metadata:
      labels:
        app: gemma-12b-gpu-vllm
        ai.gke.io/model: gemma-4-12b-it
        ai.gke.io/inference-server: vllm
        examples.ai.gke.io/source: user-guide
    spec:
      containers:
      - name: inference-server
        image: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:latest
        resources:
          requests:
            cpu: "4"
            memory: "16Gi"
            ephemeral-storage: "30Gi"
            nvidia.com/gpu: "1"
          limits:
            cpu: "8"
            memory: "24Gi"
            ephemeral-storage: "30Gi"
            nvidia.com/gpu: "1"
        command: ["python3", "-m", "vllm.entrypoints.api_server"]
        args:
          - --model=$(MODEL_ID)
          - --host=0.0.0.0
          - --port=8000
          - --tensor-parallel-size=1
          - --enable-log-requests
          - --enable-chunked-prefill
          - --enable-prefix-caching
          - --enable-auto-tool-choice
          - --generation-config=auto
          - --tool-call-parser=gemma4
          - --dtype=bfloat16
          - --max-num-seqs=16
          - --max-model-len=32768
          - --gpu-memory-utilization=0.95
          - --reasoning-parser=gemma4
          - --trust-remote-code
          - --quantization=fp8
        env:
        - name: LD_LIBRARY_PATH
          value: ${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64
        - name: MODEL_ID
          value: google/gemma-4-12b-it
        - name: HF_TOKEN
          valueFrom:
            secretKeyRef:
              name: hf-secret
              key: hf_api_token
        volumeMounts:
        - mountPath: /dev/shm
          name: dshm
      volumes:
      - name: dshm
        emptyDir:
            medium: Memory
      nodeSelector:
        cloud.google.com/gke-accelerator: nvidia-l4
        cloud.google.com/gke-gpu-driver-version: latest
---
apiVersion: v1
kind: Service
metadata:
  name: gemma-12b-gpu-vllm-service
spec:
  selector:
    app: gemma-12b-gpu-vllm
  type: ClusterIP
  ports:
    - protocol: TCP
      port: 8000
      targetPort: 8000
EOF

Wenden Sie die gespeicherte gemma-12b-gpu-vllm-deployment.yaml Bereitstellung an:

kubectl apply -f gemma-12b-gpu-vllm-deployment.yaml

Erwartete Ausgabe:

$ kubectl apply -f gemma-12b-gpu-vllm-deployment.yaml
deployment.apps/gemma-12b-gpu-vllm-deployment created
service/gemma-12b-gpu-vllm-service created

Warten Sie, bis die Bereitstellung abgeschlossen und das Modell geladen ist. Das kann einige Minuten dauern.

printf "Waiting for model to load..."; until kubectl logs -l app=gemma-12b-gpu-vllm --tail=50 2>/dev/null | grep -q "Application startup complete"; do printf "."; sleep 3; done; printf '\n\033[1;32m========================================\n[SUCCESS] Model is loaded and ready!\nYou can now proceed to the next step.\n========================================\033[0m\n'

Erwartete Ausgabe:

Waiting for model to load...
========================================
[SUCCESS] Model is loaded and ready!
You can now proceed to the next step.
========================================

Modell testen Aktivieren Sie die Portweiterleitung, um auf das Modell zuzugreifen:

kubectl port-forward svc/gemma-12b-gpu-vllm-service 8090:8000

Verwenden Sie in einem anderen Terminalfenster „curl“, um einen Prompt an das Modell zu senden:

curl http://localhost:8090/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"role": "system", "content": "You are a helpful assistant running on GKE."},
      {"role": "user", "content": "What is AlloyDB Omni."}
    ],
    "temperature": 0.7
  }' | jq -r '.choices[0].message.content'

Erwartete Ausgabe:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3957  100  3761  100   196     85      4  0:00:49  0:00:43  0:00:06   830
**AlloyDB Omni** is a fully managed, PostgreSQL-compatible database engine from Google Cloud that can be run **on-premises, in other clouds, or in your own data centers.**

To understand it simply: It allows you to run the high-performance, enterprise-grade capabilities of Google's **AlloyDB** (a cloud-native database) on your own infrastructure.

Here is a breakdown of what makes it significant:

### 1. The "Best of Both Worlds" Architecture
Normally, you have to choose between:
*   **Managed Cloud Databases:** Easy to scale and manage, but you are locked into the cloud provider's infrastructure.
*   **Self-Managed Databases:** You have full control over the hardware/location, but you are responsible for scaling, patching, and high availability.

**AlloyDB Omni** bridges this gap. It provides the advanced features of a cloud-native database (like intelligent indexing, high availability, and massive scalability) while allowing you to run it anywhere.

Stoppen Sie die Portweiterleitung im ersten Terminal (falls sie noch läuft) durch Drücken von Ctrl+C.

9. Gemma 4-Modell in AlloyDB Omni registrieren

Registrieren Sie das Gemma 12B-Modell in AlloyDB Omni mithilfe der google_ml.create_model-Prozedur. Geben Sie http://gemma-12b-gpu-vllm-service:8000/v1/chat/completions als model_request_url an, um Anfragen an den Kubernetes-Clusterdienst weiterzuleiten:

Rufen Sie die IP-Adresse des AlloyDB Omni-Endpunkts ab:

echo "INSTANCE_IP=$(kubectl get dbclusters.alloydbomni.dbadmin.goog my-omni -n default -o jsonpath='{.status.primary.endpoint}')"

Stellen Sie eine SSH-Verbindung zur VM-Instanz her.

export ZONE=us-central1-a
gcloud compute ssh instance-1 --zone=$ZONE

Nachdem Sie eine Verbindung zur VM hergestellt haben, exportieren Sie die Variable INSTANCE_IP aus dem vorherigen Schritt. Der Wert 10.128.0.33 ist ein Beispiel. Ersetzen Sie ihn durch Ihre IP-Adresse:

export INSTANCE_IP=10.128.0.33

AlloyDB-Passwort exportieren:

export PGPASSWORD=VeryStrongPassword

Stellen Sie eine Verbindung zur Datenbank demo her:

psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"

Registrieren Sie das Modell in der psql-Sitzung:

CALL
  google_ml.create_model(
    model_id => 'gemma-12b-gpu',
    model_request_url => 'http://gemma-12b-gpu-vllm-service:8000/v1/chat/completions',
    model_provider => 'custom',
    model_type => 'llm');

Testen Sie das Modell mit einer SQL-Beispielabfrage:

SELECT google_ml.predict_row(
  model_id => 'gemma-12b-gpu',
  request_body => json_build_object(
    'messages', json_build_array(
      json_build_object('role', 'user', 'content', 'What is AlloyDB Omni?'))))->'choices'->0->'message'->'content';

Drücken Sie q, um das Ergebnisfenster zu schließen und zum psql-Prompt zurückzukehren.

Vektorsuche mit LLM RAG in AlloyDB Omni kombinieren

Verwenden Sie die Vektorsuche mit der LLM-Anfrage, um RAG (Retrieval-Augmented Generation) mit dem LLM zu demonstrieren.

Führen Sie die SQL-Abfrage in PL/SQL aus:

WITH trees AS (
SELECT
        cp.product_name,
        cp.product_description AS description,
        cp.sale_price,
        cs.zip_code,
        cp.uniq_id AS product_id
FROM
    cymbal_products cp
JOIN cymbal_embedding ce ON ce.uniq_id = cp.uniq_id
JOIN cymbal_inventory ci ON ci.uniq_id = cp.uniq_id
JOIN cymbal_stores cs ON cs.store_id = ci.store_id
WHERE
        ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        (ce.embedding <=> embedding('embeddinggemma',
        'What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1),
prompt AS (
SELECT
        'You are a friendly advisor helping to find a product based on the customer''s needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","product_description":"some description","sale_price":10}
Here is the list of products:' || json_agg(trees) || 'The customer asked "What kind of fruit trees grow well here?"
You should give information about the product, price and some supplemental information' AS prompt_text
FROM
        trees),
response AS (
SELECT
        google_ml.predict_row(
          model_id =>'gemma-12b-gpu',
          request_body => json_build_object(
            'messages', json_build_array(
              json_build_object('role', 'user', 'content',prompt_text)
            )))->'choices'->0->'message'->'content' AS resp
FROM
        prompt)
SELECT
REPLACE(resp::text, '\n', CHR(10))
FROM
        response;

Erwartete Ausgabe:

----------------------------------------------------------------------------------------------------------------------------------------------
 "Hello there! I'd be happy to help you find the perfect tree for your garden.                                                               +
                                                                                                                                             +
 Based on your location, we have a wonderful option that would grow beautifully in your area:                                                +
                                                                                                                                             +
 **Cherry Tree**                                                                                                                             +
 *   **Price:** $75.00                                                                                                                       +
 *   **Description:** This is a stunning deciduous tree that not only provides a beautiful landscape but also produces delicious cherries.   +
 *   **Supplemental Information:**                                                                                                           +
     *   **Growth:** It grows to about 15 feet tall.                                                                                         +
     *   **Appearance:** You can look forward to dark green leaves in the summer that transform into a vibrant red in the fall.              +
     *   **Benefits:** It's a great choice if you're looking for both fruit and extra shade or privacy in your yard.                         +
     *   **Care Tips:** It performs best in a cool, moist climate with sandy soil. Since you are in a suitable zone, it should thrive nicely!+
                                                                                                                                             +
 Would you like more details on how to plant this, or would you like to proceed with an order?"
(1 row)

Die Anfrage ergänzt den Prompt für das LLM um die Ergebnisse der Vektorsuche.

Probieren Sie andere Anfragen aus und experimentieren Sie mit den RAG-Mustern. Der Vorteil der vorgestellten Architektur ist ihre vollständige Autarkie. Die Daten werden nicht außerhalb Ihres Clusters gesendet und können in vollständig isolierten Umgebungen ausgeführt werden.

psql-Sitzung beenden:

\q

Trennen Sie die Verbindung zur SSH-Sitzung zur VM:

exit

AlloyDB Omni bietet noch mehr Funktionen und Labs.

10. Umgebung bereinigen

Löschen Sie die in diesem Codelab erstellten Ressourcen, um zu vermeiden, dass Ihrem Google Cloud-Konto laufende Gebühren in Rechnung gestellt werden.

GKE-Cluster löschen

Löschen Sie den GKE-Cluster in Cloud Shell:

export PROJECT_ID=$(gcloud config get-value project)
export LOCATION=us-central1
export CLUSTER_NAME=alloydb-ai-gke
gcloud container clusters delete ${CLUSTER_NAME} \
  --project=${PROJECT_ID} \
  --region=${LOCATION}

Erwartete Ausgabe:

student@cloudshell:~$ gcloud container clusters delete ${CLUSTER_NAME} \
>   --project=${PROJECT_ID} \
>   --region=${LOCATION}
The following clusters will be deleted.
 - [alloydb-ai-gke] in [us-central1]

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

Deleting cluster alloydb-ai-gke...done.
Deleted

Client-VM löschen

Löschen Sie die Compute Engine-Instanz in Cloud Shell:

export PROJECT_ID=$(gcloud config get-value project)
export ZONE=us-central1-a
gcloud compute instances delete instance-1 \
  --project=${PROJECT_ID} \
  --zone=${ZONE}

Erwartete Ausgabe:

student@cloudshell:~$ export PROJECT_ID=$(gcloud config get project)
export ZONE=us-central1-a
gcloud compute instances delete instance-1 \
  --project=${PROJECT_ID} \
  --zone=${ZONE}
Your active configuration is: [cloudshell-5399]
The following instances will be deleted. Any attached disks configured to be auto-deleted will be deleted unless they are attached to any other instances or the `--keep-disks` flag is given and specifies them for keeping. Deleting a disk 
is irreversible and any data on the disk will be lost.
 - [instance-1] in [us-central1-a]

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

Deleted

Wenn Sie ein neues Projekt für dieses Codelab erstellt haben, können Sie das gesamte Projekt optional im Google Cloud Resource Manager löschen.

11. Glückwunsch

Herzlichen Glückwunsch zum Abschluss des Codelabs!

Behandelte Themen

  • AlloyDB Omni in einem GKE-Cluster bereitstellen
  • Verbindung zu AlloyDB Omni herstellen
  • Daten in AlloyDB Omni laden
  • KI-Modelle (Einbettung und LLM) in GKE bereitstellen
  • KI-Modelle in AlloyDB Omni registrieren
  • Einbettungen für die semantische Suche generieren
  • Semantische Suchanfragen in AlloyDB Omni ausführen
  • Vektorindexe in AlloyDB Omni erstellen und verwenden

Weitere Informationen zum Arbeiten mit KI in AlloyDB Omni finden Sie in der Dokumentation.

Umfrage

Ausgabe:

Wie werden Sie diese Anleitung verwenden?

Nur durchlesen Lesen und Übungen machen