AlloyDB Omni und EmbeddingGemma mit Gemma 4 in Kubernetes

1. Einführung

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

Architekturdiagramm von AlloyDB Omni und EmbeddingGemma in der GKE

Vorbereitung

  • Grundlegendes Verständnis von Google Cloud und der Google Cloud Console
  • Grundkenntnisse zu 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 der 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 ein privates Konto anstelle eines Arbeitskontos oder eines Kontos einer Bildungseinrichtung.
  1. Erstellen Sie ein neues Projekt oder wählen Sie ein vorhandenes Projekt 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 eines Projekts zu öffnen.

Dialogfeld „Neues Projekt erstellen“

Geben Sie im Dialogfeld einen Projektnamen 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 nicht von Google APIs verwendet und kann jederzeit geändert werden.
  • Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich (sie kann nach dem Festlegen nicht mehr geändert werden). Die Google Cloud Console generiert automatisch eine eindeutige ID. Sie können aber auch eine eigene angeben. In diesem Codelab verweisen Sie mit dem Platzhalter auf Ihre Projekt-ID.
  • Die Projektnummer ist eine dritte Kennung, die von einigen APIs verwendet wird. Weitere Informationen finden Sie in der Dokumentation zu Resource Manager.

Abrechnung aktivieren

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

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

  • Die Kosten für die Google Cloud-Ressourcen, die Sie für dieses Lab benötigen, 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 können die kostenlose Testversion mit einem Guthaben von 300 $ nutzen.

Cloud Shell starten

In diesem Codelab verwenden Sie die 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 die Google Kubernetes Engine (GKE) für AlloyDB Omni und Modellbereitstellungen verwenden möchten, aktivieren Sie die Compute Engine API und die GKE API 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 der GKE bereitstellen

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

GKE-Cluster erstellen

Stellen Sie einen GKE Autopilot-Cluster bereit, um AlloyDB Omni, den Operator und Monitoring-Container auszuführen. Mit Autopilot vereinfachen wir die Bereitstellung. Alle Ressourcen für den AlloyDB Omni-Operator, den Cluster und andere Komponenten werden automatisch zugewiesen.

Wählen Sie die Region aus, in der Sie Ihre Ressourcen bereitstellen. Wählen Sie eine Region in der Nähe Ihres Standorts aus:

export LOCATION=<your region>

Legen Sie die Umgebungsvariablen für Ihre Bereitstellung fest:

export PROJECT_ID=$(gcloud config get-value project)
export CLUSTER_NAME=alloydb-ai-gke

Erstellen Sie den GKE-Autopilot-Cluster:

gcloud container clusters create-auto ${CLUSTER_NAME} \
  --project=${PROJECT_ID} \
  --region=${LOCATION}

Erwartete Konsolenausgabe:

student@cloudshell:~ (test-project-001-402417)$ export PROJECT_ID=$(gcloud config get project)
export CLUSTER_NAME=alloydb-ai-gke
Your active configuration is: [test-project-001-402417]
student@cloudshell:~ (test-project-001-402417)$ gcloud container clusters create-auto ${CLUSTER_NAME} \
>   --project=${PROJECT_ID} \
>   --region=${LOCATION}
Creating cluster alloydb-ai-gke in us-east4... Cluster is being health-checked.
..⠹
Creating cluster alloydb-ai-gke in us-east4... Cluster is being health-checked
(Kubernetes Control Plane is healthy)...done.
Created [https://container.googleapis.com/v1/projects/gleb-genai-002/zones/us-east4/clusters/alloydb-ai-gke].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-east4/alloydb-ai-gke?project=gleb-genai-002
kubeconfig entry generated for alloydb-ai-gke.
NAME            LOCATION  MASTER_VERSION      MASTER_IP      MACHINE_TYPE   NODE_VERSION        NUM_NODES  STATUS   STACK_TYPE
alloydb-ai-gke  us-east4  1.36.4-gke.1391002  34.145.214.51  ek-standard-8  1.36.4-gke.1391002  3          RUNNING  IPV4

Cluster vorbereiten

Installieren Sie die erforderlichen Komponenten, z. B. cert-manager, den Zertifikats-Controller für Kubernetes. Weitere Informationen finden Sie in der Installationsdokumentation für cert-manager.

Cloud Shell enthält das Kubernetes-Befehlszeilentool kubectl und helm. Rufen Sie die Clusteranmeldedaten mit gcloud ab:

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

Installieren Sie cert-manager mit helm:

helm install \
  cert-manager oci://quay.io/jetstack/charts/cert-manager \
  --version v1.21.2 \
  --namespace cert-manager \
  --create-namespace \
  --set featureGates="ServerSideApply=true" \
  --set global.leaderElection.namespace=cert-manager \
  --set "extraArgs={--certificate-request-minimum-backoff-duration=15s,--certificate-request-maximum-backoff-duration=5m}" \
  --set crds.enabled=true

Erwartete Konsolenausgabe (bearbeitet):

student@cloudshell:~$ elm install \
>   cert-manager oci://quay.io/jetstack/charts/cert-manager \
>   --version v1.21.2 \
>   --namespace cert-manager \
>   --create-namespace \
>  --set featureGates="ServerSideApply=true" \
>  --set global.leaderElection.namespace=cert-manager \
>  --set "extraArgs={--certificate-request-minimum-backoff-duration=15s,--certificate-request-maximum-backoff-duration=5m}" \
>   --set crds.enabled=true
Pulled: quay.io/jetstack/charts/cert-manager:v1.21.2
Digest: sha256:634dce9c13b56677a2c05e2ab76c312d0be2664022d5dd05815da67e1fd5f610
I1016 12:25:06.128464   30644 warnings.go:107] "Warning: autopilot-default-resources-mutator:Autopilot updated Deployment cert-manager/cert-manager-cainjector: defaulted unspecified 'cpu' resource for containers [cert-manager-cainjector] (see http://g.co/gke/autopilot-defaults)."
I1016 12:25:06.129972   30644 warnings.go:107] "Warning: autopilot-default-resources-mutator:Autopilot updated Deployment cert-manager/cert-manager: defaulted unspecified 'cpu' resource for containers [cert-manager-controller] (see http://g.co/gke/autopilot-defaults)."
I1016 12:25:06.134580   30644 warnings.go:107] "Warning: autopilot-default-resources-mutator:Autopilot updated Deployment cert-manager/cert-manager-webhook: defaulted unspecified 'cpu' resource for containers [cert-manager-webhook] (see http://g.co/gke/autopilot-defaults)."
I1016 12:25:06.250590   30644 warnings.go:107] "Warning: AdmissionWebhookController: mutated namespaceselector of the webhooks to enforce GKE Autopilot policies."
I1016 12:25:09.758249   30644 warnings.go:107] "Warning: autopilot-default-resources-mutator:Autopilot updated Job cert-manager/cert-manager-startupapicheck: defaulted unspecified 'cpu' resource for containers [cert-manager-startupapicheck] (see http://g.co/gke/autopilot-defaults)."
NAME: cert-manager
LAST DEPLOYED: Fri Oct 16 12:24:57 2026
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
cert-manager v1.21.2 has been deployed successfully!

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.9.0 \
--create-namespace \
--namespace alloydb-omni-system \
$(helm install --help | grep -q -- '--rollback-on-failure' && echo '--rollback-on-failure' || echo '--atomic') \
--timeout 5m

Erwartete Konsolenausgabe (bearbeitet):

student@cloudshell:~$ helm install alloydbomni-operator oci://gcr.io/alloydb-omni/alloydbomni-operator \
> --version 1.9.0 \
> --create-namespace \
> --namespace alloydb-omni-system \
> $(helm install --help | grep -q -- '--rollback-on-failure' && echo '--rollback-on-failure' || echo '--atomic') \
> --timeout 5m

Pulled: gcr.io/alloydb-omni/alloydbomni-operator:1.9.0
Digest: sha256:4f6cc3f0c1fbe003ab7d0119afee516e5c67ec950cd2909b418e5a3f6f09d1f6
I1016 12:28:50.088533   30982 warnings.go:107] "Warning: autopilot-default-resources-mutator:Autopilot updated Deployment alloydb-omni-system/fleet-controller-manager: adjusted 'cpu' resource to meet requirements for containers [fleet-manager] (see http://g.co/gke/autopilot-defaults)."
I1016 12:28:50.092917   30982 warnings.go:107] "Warning: autopilot-default-resources-mutator:Autopilot updated Deployment alloydb-omni-system/local-controller-manager: adjusted 'cpu' resource to meet requirements for containers [local-manager] (see http://g.co/gke/autopilot-defaults)."
I1016 12:28:50.229717   30982 warnings.go:107] "Warning: AdmissionWebhookController: mutated namespaceselector of the webhooks to enforce GKE Autopilot policies."
I1016 12:28:50.238578   30982 warnings.go:107] "Warning: AdmissionWebhookController: mutated namespaceselector of the webhooks to enforce GKE Autopilot policies."
NAME: alloydbomni-operator
LAST DEPLOYED: Fri Oct 16 12:28:45 2026
NAMESPACE: alloydb-omni-system
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None

Stellen Sie den Datenbankcluster bereit.

Mit dem folgenden Manifest wird ein Datenbankcluster mit aktiviertem googleMLExtension und einem internen Load Balancer konfiguriert:

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.4.0"
  primarySpec:
    adminUser:
      passwordRef:
        name: db-pw-my-omni
    features:
      googleMLExtension:
        enabled: true
    resources:
      cpu: 1
      memory: 8Gi
      disks:
      - name: DataDisk
        size: 20Gi
    dbLoadBalancerOptions:
      annotations:
        networking.gke.io/load-balancer-type: "internal"
  allowExternalIncomingTraffic: true
EOF

Der Secret-Wert des Passworts ist die Base64-Darstellung von VeryStrongPassword. In Produktionsumgebungen sollten Sie Google Secret Manager verwenden, um Passwörter zu verwalten. 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

Nachdem Sie das Manifest my-omni.yaml gelesen haben, klicken Sie 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 Clusters my-omni:

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.4)
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 der GKE bereitstellen

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

Hugging Face-Token abrufen

In dieser Anleitung wird das EmbeddingGemma-Modell von Hugging Face bereitgestellt. Generieren Sie ein Hugging Face-Zugriffstoken, um auf die Modellgewichtungen zuzugreifen:

  1. Melden Sie sich in Ihrem Hugging Face-Konto 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 EmbeddingGemma-Modellseite, falls Sie dies noch nicht getan haben.

Erstellen Sie in Cloud Shell ein Kubernetes-Secret, das Ihr Hugging Face-Token enthält (ersetzen Sie 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 Containerpaket „Text Embeddings Inference“ (TEI) von Hugging Face. Weitere Informationen finden Sie in der Hugging Face GKE TEI-Dokumentation.

Klonen Sie das Deployment-Repository von GitHub:

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

Prüfen und ändern Sie das CPU-Konfigurationsmanifest:

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 den Status „Bereit“ hat:

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 Kubernetes-Dienst tei-service:

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 Einbettungsgenerierung 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 im ersten Tab, indem Sie ctrl+c drücken.

6. Einbettungsmodell in AlloyDB Omni registrieren

Wenn Sie das bereitgestellte Modell aus 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:

Netzwerkarchitekturdiagramm mit Client-VM und AlloyDB Omni

Erstellen Sie in Cloud Shell die Client-VM:

export ZONE=${LOCATION}-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 es 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 sie durch Ihre PRIMARYENDPOINT-IP-Adresse):

export INSTANCE_IP=10.131.0.33

Stellen Sie über psql eine Verbindung zu AlloyDB Omni her (das Passwort lautet 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

Benutzerdefinierte Einbettungsendpunkte erfordern Eingabe- und Ausgabe-Transformationsfunktionen, um Datenformate zwischen AlloyDB Omni und der Modell-API anzupassen.

Erstellen Sie die Eingabetransformationsfunktion:

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, um die Vektorarray-Antwort zu parsen:

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=#

Testen Sie das registrierte Modell mit einer SQL-Beispielabfrage:

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 wurde, das in der GKE ausgeführt wird.

Drücken Sie q, um zur Eingabeaufforderung der psql-Sitzung zurückzukehren.

Beenden Sie die psql-Sitzung:

\q

7. Modell mit Beispieldaten testen

Beispieldaten laden

In dieser Anleitung wird das Cymbal Retail-Dataset verwendet, um die Vektorähnlichkeitssuche 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:~$

Prüfen Sie die erstellten Tabellen:

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, die in der Tabelle „cymbal_products“ beschrieben sind, basierend auf den Produktbeschreibungen.

Stellen Sie eine Verbindung zur Demo-Datenbank 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.

Abfrage-Timing aktivieren:

\timing

Generieren 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 die fünf besten Produkte, die der Frage "What kind of fruit trees grow well here?" entsprechen, mithilfe der Kosinus-Distanz (<=>):

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 83 ms lang ausgeführt und hat eine Liste von Bäumen aus der Tabelle „cymbal_products“ zurückgegeben, die der Anfrage entsprechen und im Geschäft mit der Nummer 1583 verfügbar sind.

ANN-Index erstellen

Bei einem kleinen Datensatz ist es einfach, die exakte Suche zu verwenden, bei der alle Einbettungen gescannt werden. Wenn die Datenmenge jedoch zunimmt, steigen auch die Lade- und Antwortzeiten. Zur Leistungsverbesserung können Sie Indexe für Ihre Einbettungsdaten erstellen. Hier ist 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, falls sie unterbrochen wurde:

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

Erweiterung „alloydb_scann“ aktivieren:

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 verringert. Bei größeren Datasets ist der Gewinn deutlicher. Die zurückgegebenen Daten sollten mit den Daten, die wir ohne Index erhalten haben, identisch oder sehr ähnlich sein.

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

Beenden Sie die psql-Sitzung:

\q

Kehren Sie zur Google Cloud Shell zurück, indem Sie die Verbindung zur SSH-Sitzung instance-1 trennen. Drücken Sie dazu Strg + D oder geben Sie exit ein.

8. Gemma mit vLLM bereitstellen

Knotenpool für Gemma hinzufügen

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

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 mit vLLM ein Bereitstellungsmanifest für das Google Gemini 4 12B-Modell:

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.

Beenden Sie die Portweiterleitung im ersten Terminal (falls sie noch ausgeführt wird), indem Sie Ctrl+C drücken.

9. Gemma 4-Modell in AlloyDB Omni registrieren

Registrieren Sie das Gemma 12B-Modell in AlloyDB Omni mit der Prozedur google_ml.create_model. 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.

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 wird als Beispiel angegeben. 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 zur Eingabeaufforderung psql 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 plsql 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 Abfrage ergänzt den Prompt an das LLM um die Suchergebnisse der Vektorsuche.

Probieren Sie andere Abfragen 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.

Beenden Sie die psql-Sitzung:

\q

Trennen Sie die SSH-Verbindung zur VM:

exit

Denken Sie daran, dass AlloyDB Omni weitere Funktionen und Labs bietet.

10. Umgebung bereinigen

Damit Ihrem Google Cloud-Konto keine laufenden Kosten entstehen, löschen Sie die in diesem Codelab erstellten Ressourcen.

GKE-Cluster löschen

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

export PROJECT_ID=$(gcloud config get-value project)
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-east4]

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

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

Client-VM löschen

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

export PROJECT_ID=$(gcloud config get-value project)
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-east4-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-east4-a]

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

Deleted

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

11. Glückwunsch

Herzlichen Glückwunsch zum Abschluss des Codelabs!

Was Sie behandelt haben

  • AlloyDB Omni in einem GKE-Cluster bereitstellen
  • Verbindung zu AlloyDB Omni herstellen
  • Daten in AlloyDB Omni laden
  • KI-Modelle (Einbettung und LLM) in der 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 Durchlesen und die Übungen machen