AlloyDB Omni และ EmbeddingGemma พร้อม Gemma 4 ใน Kubernetes

1. บทนำ

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีติดตั้งใช้งาน AlloyDB Omni ใน Google Kubernetes Engine (GKE) และใช้กับโมเดลแบบเปิด เช่น EmbeddingGemma และ Gemma 4 สำหรับการฝังและการคาดการณ์ การเรียกใช้ทั้งฐานข้อมูลและโมเดลในคลัสเตอร์เดียวกันจะช่วยลดเวลาในการตอบสนองของเครือข่ายและหลีกเลี่ยงการพึ่งพาบริการของบุคคลที่สาม นอกจากนี้ ยังช่วยให้เป็นไปตามข้อกำหนดด้านการปฏิบัติตามข้อกำหนดและถิ่นที่อยู่ของข้อมูล เนื่องจากข้อมูลของคุณจะไม่ออกจากสภาพแวดล้อมของคุณ

แผนภาพสถาปัตยกรรมของ AlloyDB Omni และ EmbeddingGemma ใน GKE

ข้อกำหนดเบื้องต้น

  • ความเข้าใจพื้นฐานเกี่ยวกับ Google Cloud และคอนโซล Google Cloud
  • ความรู้พื้นฐานเกี่ยวกับ Kubernetes และ GKE
  • ความคุ้นเคยกับอินเทอร์เฟซบรรทัดคำสั่งและ Google Cloud Shell

สิ่งที่คุณจะได้เรียนรู้

  • วิธีติดตั้งใช้งาน AlloyDB Omni ในคลัสเตอร์ GKE
  • วิธีเชื่อมต่อกับ AlloyDB Omni
  • วิธีโหลดข้อมูลลงใน AlloyDB Omni
  • วิธีทำให้โมเดล AI (การฝังและ LLM) ใช้งานได้ใน GKE
  • วิธีลงทะเบียนโมเดล AI ใน AlloyDB Omni
  • วิธีสร้างการฝังสำหรับการค้นหาเชิงความหมาย
  • วิธีเรียกใช้คำค้นหาเชิงความหมายใน AlloyDB Omni
  • วิธีสร้างและใช้ดัชนีเวกเตอร์ใน AlloyDB Omni

สิ่งที่คุณต้องมี

  • บัญชี Google Cloud และโปรเจ็กต์ Google Cloud
  • เว็บเบราว์เซอร์ เช่น Chrome

2. การตั้งค่าและข้อกำหนด

การตั้งค่าโปรเจ็กต์

  1. ลงชื่อเข้าใช้คอนโซล Google Cloud หากยังไม่มีบัญชี Gmail หรือ Google Workspace ให้สร้างบัญชี ใช้บัญชีส่วนตัวแทนบัญชีงานหรือบัญชีโรงเรียน
  1. สร้างโปรเจ็กต์ใหม่หรือเลือกโปรเจ็กต์ที่มีอยู่ ในส่วนหัวของคอนโซล Google Cloud ให้คลิกเลือกโปรเจ็กต์ แล้วคลิกโปรเจ็กต์ใหม่

กล่องโต้ตอบเลือกโปรเจ็กต์ในคอนโซล Google Cloud

ในหน้าต่างเลือกโปรเจ็กต์ ให้คลิกโปรเจ็กต์ใหม่เพื่อเปิดกล่องโต้ตอบการสร้างโปรเจ็กต์

กล่องโต้ตอบการสร้างโปรเจ็กต์ใหม่

ในกล่องโต้ตอบ ให้ป้อนชื่อโปรเจ็กต์ แล้วเลือกองค์กรหรือสถานที่ตั้ง

ช่องป้อนข้อมูลรายละเอียดโปรเจ็กต์

  • ชื่อโปรเจ็กต์คือชื่อที่แสดงสำหรับผู้เข้าร่วมของโปรเจ็กต์นี้ Google APIs ไม่ได้ใช้ชื่อโปรเจ็กต์ และคุณเปลี่ยนชื่อได้ทุกเมื่อ
  • รหัสโปรเจ็กต์จะไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมดและเปลี่ยนแปลงไม่ได้ (คุณจะเปลี่ยนไม่ได้หลังจากตั้งค่าแล้ว) คอนโซล Google Cloud จะสร้างรหัสที่ไม่ซ้ำกันโดยอัตโนมัติ หรือคุณจะระบุรหัสของคุณเองก็ได้ ใน Codelab นี้ คุณจะอ้างอิงรหัสโปรเจ็กต์ด้วยตัวยึดตำแหน่ง
  • หมายเลขโปรเจ็กต์เป็นตัวระบุที่ 3 ที่ API บางรายการใช้ ดูข้อมูลเพิ่มเติมได้ในเอกสารประกอบของ Resource Manager

เปิดใช้การเรียกเก็บเงิน

หากตั้งค่าการเรียกเก็บเงินโดยใช้เครดิต Google Cloud คุณสามารถข้ามขั้นตอนนี้ได้

หากต้องการตั้งค่าบัญชีสำหรับการเรียกเก็บเงินส่วนบุคคล ให้เปิดใช้การเรียกเก็บเงินในคอนโซล Google Cloud

  • การทำ Lab นี้ให้เสร็จสมบูรณ์มีค่าใช้จ่ายน้อยกว่า $5 USD ในทรัพยากร Google Cloud
  • ทำตามขั้นตอนการล้างข้อมูลที่ส่วนท้ายของห้องปฏิบัติการนี้เพื่อลบทรัพยากรและหลีกเลี่ยงการเรียกเก็บเงินเพิ่มเติม
  • ผู้ใช้ใหม่มีสิทธิ์รับช่วงทดลองใช้ฟรีมูลค่า$300 USD

เริ่มต้น Cloud Shell

ใน Codelab นี้ คุณจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์

จากคอนโซล Google Cloud ให้คลิกไอคอนเปิดใช้งาน Cloud Shell บนแถบเครื่องมือด้านขวาบน

ปุ่มเปิดใช้งาน Cloud Shell

หรือกด G แล้วกด S หรือเปิด Google Cloud Shell โดยตรง

เมื่อเชื่อมต่อแล้ว Cloud Shell จะแสดงพรอมต์เทอร์มินัลดังนี้

ภาพหน้าจอของเทอร์มินัล Google Cloud Shell

Cloud Shell มีพื้นที่เก็บข้อมูลถาวรและเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ คุณสามารถเรียกใช้ขั้นตอนทั้งหมดใน Codelab นี้จากเบราว์เซอร์ได้

3. เปิดใช้ API

หากต้องการใช้ Google Kubernetes Engine (GKE) สำหรับ AlloyDB Omni และการติดตั้งใช้งานโมเดล ให้เปิดใช้ Compute Engine และ GKE API ในโปรเจ็กต์ที่อยู่ในระบบคลาวด์ของ Google

ใน Cloud Shell ให้ตรวจสอบว่าได้กำหนดค่ารหัสโปรเจ็กต์แล้ว โดยทำดังนี้

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

หากไม่ได้กำหนดรหัสโปรเจ็กต์ ให้กำหนดค่าโดยทำดังนี้

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

เปิดใช้ API ที่จำเป็น ดังนี้

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

ผลลัพธ์ที่คาดหวัง:

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.

คุณอ่านข้อมูลเกี่ยวกับ API ที่เปิดใช้แต่ละรายการได้ในเอกสารประกอบ

4. ติดตั้งใช้งาน AlloyDB Omni ใน GKE

หากต้องการติดตั้งใช้งาน AlloyDB Omni ใน GKE ให้เตรียมคลัสเตอร์ Kubernetes ตามข้อกำหนดของผู้ให้บริการ AlloyDB Omni

สร้างคลัสเตอร์ GKE

ติดตั้งใช้งานคลัสเตอร์ GKE Autopilot เพื่อเรียกใช้ AlloyDB Omni, โอเปอเรเตอร์ และคอนเทนเนอร์การตรวจสอบ การใช้ Autopilot จะช่วยให้เราทำให้การติดตั้งใช้งานง่ายขึ้น โดยระบบจะกำหนดทรัพยากรทั้งหมดสำหรับโอเปอเรเตอร์ คลัสเตอร์ และคอมโพเนนต์อื่นๆ ของ AlloyDB Omni โดยอัตโนมัติ

เลือกภูมิภาคที่คุณติดตั้งใช้งานทรัพยากร เลือกภูมิภาคที่อยู่ใกล้กับสถานที่ตั้งของคุณทางภูมิศาสตร์ ดังนี้

export LOCATION=<your region>

ตั้งค่าตัวแปรสภาพแวดล้อมสำหรับการติดตั้งใช้งาน ดังนี้

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

สร้างคลัสเตอร์ GKE Autopilot โดยทำดังนี้

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

เอาต์พุตคอนโซลที่คาดไว้:

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

เตรียมคลัสเตอร์

ติดตั้งคอมโพเนนต์ที่จำเป็น เช่น cert-manager ซึ่งเป็นตัวควบคุมใบรับรองสำหรับ Kubernetes โปรดดูรายละเอียดในเอกสารประกอบการติดตั้ง cert-manager

Cloud Shell มีเครื่องมือบรรทัดคำสั่ง Kubernetes kubectl และ helm รับข้อมูลเข้าสู่ระบบคลัสเตอร์โดยใช้ gcloud:

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

ติดตั้ง cert-manager โดยใช้ 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

ผลลัพธ์คอนโซลที่คาดไว้ (ปกปิด):

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

ติดตั้งโอเปอเรเตอร์ AlloyDB Omni โดยใช้ Helm

ดาวน์โหลดและติดตั้งแผนภูมิโอเปอเรเตอร์ AlloyDB Omni โดยทำดังนี้

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

ผลลัพธ์คอนโซลที่คาดไว้ (ปกปิด):

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

ติดตั้งใช้งานคลัสเตอร์ฐานข้อมูล

ไฟล์ Manifest ต่อไปนี้จะกำหนดค่าคลัสเตอร์ฐานข้อมูลโดยเปิดใช้ googleMLExtension และตัวจัดสรรภาระงานภายใน

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

ค่ารหัสผ่านลับคือการแสดงค่า VeryStrongPassword ในรูปแบบ Base64 ในสภาพแวดล้อมฮาร์ดแวร์และซอฟต์แวร์ ให้ใช้ Google Secret Manager เพื่อจัดการรหัสผ่าน โปรดดูรายละเอียดในเอกสารประกอบของ Secret Manager

ระบบจะบันทึกไฟล์ Manifest เป็น my-omni.yaml ใน Cloud Shell ให้คลิกเปิดเครื่องมือแก้ไขที่มุมขวาบนของหน้าต่างเทอร์มินัล แล้วอ่านไฟล์

เปิดเครื่องมือแก้ไขใน Cloud Shell

หลังจากอ่านไฟล์ Manifest ของ my-omni.yaml แล้ว ให้คลิกเปิดเทอร์มินัลเพื่อกลับไปที่ Command Prompt

เปิดเทอร์มินัลใน Cloud Shell

ใช้ไฟล์ Manifest my-omni.yaml ดังนี้

kubectl apply -f my-omni.yaml

เอาต์พุตคอนโซลที่คาดไว้:

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

ตรวจสอบสถานะของคลัสเตอร์ my-omni โดยทำดังนี้

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

ในระหว่างการติดตั้งใช้งาน คลัสเตอร์ฐานข้อมูลจะเปลี่ยนผ่านระยะการตั้งค่าต่างๆ จนกว่าจะถึงสถานะ DBClusterReady

เอาต์พุตคอนโซลที่คาดไว้:

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

คุณสามารถตรวจสอบการติดตั้งใช้งานคลัสเตอร์ได้โดยใช้คำสั่ง kubectl log ดังนี้

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

เชื่อมต่อกับ AlloyDB Omni

เมื่อคลัสเตอร์พร้อมแล้ว ให้เชื่อมต่อกับพ็อดฐานข้อมูลโดยใช้ไคลเอ็นต์ PostgreSQL (psql) รหัสผ่านคือ VeryStrongPassword ตามที่กำหนดไว้ใน my-omni.yaml

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

ตัวอย่างเอาต์พุตคอนโซล

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

ออกจากเซสชัน psql โดยพิมพ์ \q แล้วกด Enter

postgres=# \q

5. ทำให้โมเดล EmbeddingGemma ใช้งานได้ใน GKE

หากต้องการทดสอบการผสานรวม AI ของ AlloyDB Omni กับโมเดลในเครื่อง ให้ติดตั้งใช้งานโมเดลการฝังในคลัสเตอร์ GKE บทแนะนำนี้ใช้โมเดล EmbeddingGemma ของ Google

รับโทเค็น Hugging Face

บทแนะนำนี้จะทำให้โมเดล EmbeddingGemma จาก Hugging Face ใช้งานได้ หากต้องการเข้าถึงน้ำหนักของโมเดล ให้สร้างโทเค็นเพื่อการเข้าถึง Hugging Face โดยทำดังนี้

  1. ลงชื่อเข้าใช้หรือสร้างบัญชีใน Hugging Face
  2. ไปที่โปรไฟล์ของคุณ > โทเค็นเพื่อการเข้าถึง
  3. คลิกสร้างโทเค็นใหม่
  4. ป้อนชื่อโทเค็นและเลือกบทบาทอ่าน
  5. คลิกสร้างโทเค็น แล้วคัดลอกค่าโทเค็นที่สร้างขึ้น
  6. ยอมรับข้อกำหนดของโมเดลในหน้าโมเดล EmbeddingGemma หากยังไม่ได้ดำเนินการ

สร้างข้อมูลลับ Kubernetes ที่มีโทเค็น Hugging Face ใน Cloud Shell (แทนที่ตัวยึดตำแหน่งโทเค็นด้วยโทเค็นของคุณ) โดยทำดังนี้

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 -

เตรียมไฟล์ Manifest สำหรับการติดตั้งใช้งาน

หากต้องการทำให้โมเดลใช้งานได้ ให้ใช้แพ็กเกจคอนเทนเนอร์ Text Embeddings Inference (TEI) ของ Hugging Face ดูข้อมูลเพิ่มเติมได้ที่เอกสารประกอบของ Hugging Face GKE TEI

โคลนที่เก็บการติดตั้งใช้งานจาก GitHub โดยทำดังนี้

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

ตรวจสอบและแก้ไขไฟล์ Manifest ของการกำหนดค่า CPU ดังนี้

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

ไฟล์ Manifest การอัปเดตสำหรับการติดตั้งใช้งาน CPU

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"

บันทึกการเปลี่ยนแปลงโดยกด ctrl+s แล้วเปลี่ยนกลับไปที่เทอร์มินัล

ทำให้โมเดลใช้งานได้

ใช้ไฟล์ Manifest เพื่อติดตั้งใช้งานเซิร์ฟเวอร์ TEI โดยทำดังนี้

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

ตรวจสอบการติดตั้งใช้งานจนกว่าจะอยู่ในสถานะพร้อมใช้งาน

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'

ตรวจสอบบริการ Kubernetes ของ tei-service ดังนี้

kubectl get service tei-service

ผลลัพธ์ที่คาดหวัง:

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

บริการ CLUSTER-IP จะแสดงคำขอภายในที่ http://34.118.233.48:8080/embed

ทดสอบปลายทางโมเดลในเครื่องโดยใช้ kubectl port-forward:

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

เปิดแท็บ Cloud Shell แท็บที่ 2 โดยคลิก + ที่ด้านบนของเทอร์มินัล

เพิ่มแท็บ Cloud Shell

ในแท็บใหม่ ให้ทดสอบการสร้างการฝังด้วย curl โดยทำดังนี้

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

ผลลัพธ์ที่คาดหวัง (อาร์เรย์เวกเตอร์):

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]]

หยุดการส่งต่อพอร์ตในแท็บแรกโดยกด ctrl+c

6. ลงทะเบียนโมเดลการฝังใน AlloyDB Omni

หากต้องการใช้โมเดลที่ติดตั้งใช้งานจาก AlloyDB Omni ให้สร้างฐานข้อมูล กำหนดฟังก์ชันการเปลี่ยนรูปแบบ และลงทะเบียนปลายทางของโมเดล

สร้าง VM และฐานข้อมูลไคลเอ็นต์

สร้างอินสแตนซ์ VM ของ Compute Engine ใน VPC เดียวกันเพื่อทำหน้าที่เป็นโฮสต์แบบ Jump ของไคลเอ็นต์ โดยทำดังนี้

แผนภาพสถาปัตยกรรมเครือข่ายที่แสดง VM ของไคลเอ็นต์และ AlloyDB Omni

สร้าง VM ของไคลเอ็นต์ใน Cloud Shell โดยทำดังนี้

export ZONE=${LOCATION}-a
gcloud compute instances create instance-1 \
  --zone=$ZONE

ดึงข้อมูล IP ปลายทางของ AlloyDB Omni โดยทำดังนี้

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

ผลลัพธ์ที่คาดหวัง:

INSTANCE_IP=10.128.0.33

ค่า INSTANCE_IP คือ IP ของตัวจัดสรรภาระงานภายในสำหรับคลัสเตอร์ AlloyDB Omni ในตัวอย่างนี้คือ 10.131.0.33

เชื่อมต่อกับอินสแตนซ์ VM โดยใช้ SSH ดังนี้

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

ในเซสชัน SSH บน instance-1 ให้ติดตั้งไคลเอ็นต์ PostgreSQL โดยทำดังนี้

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

ส่งออก IP ของตัวจัดสรรภาระงาน AlloyDB Omni (แทนที่ด้วย IP PRIMARYENDPOINT ของคุณ)

export INSTANCE_IP=10.131.0.33

เชื่อมต่อกับ AlloyDB Omni โดยใช้ psql (รหัสผ่านคือ VeryStrongPassword)

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

ในเซสชัน psql ให้สร้างฐานข้อมูล demo โดยทำดังนี้

CREATE DATABASE demo;

เปลี่ยนไปใช้ฐานข้อมูล demo โดยทำดังนี้

\c demo

สร้างฟังก์ชันการเปลี่ยนรูปแบบ

ปลายทางการฝังที่กำหนดเองต้องใช้ฟังก์ชันการเปลี่ยนรูปแบบอินพุตและเอาต์พุตเพื่อปรับรูปแบบข้อมูลระหว่าง AlloyDB Omni และ API ของโมเดล

สร้างฟังก์ชันการเปลี่ยนรูปแบบอินพุตโดยทำดังนี้

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;
$$;

ผลลัพธ์ที่คาดหวัง:

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

สร้างฟังก์ชันการเปลี่ยนรูปแบบเอาต์พุตเพื่อแยกวิเคราะห์การตอบกลับอาร์เรย์เวกเตอร์ ดังนี้

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;
$$;

ผลลัพธ์ที่คาดหวัง:

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

ลงทะเบียนโมเดล

ลงทะเบียนโมเดลใน AlloyDB Omni โดยใช้ขั้นตอน google_ml.create_model ระบุ http://tei-service:8080/embed เป็น model_request_url เพื่อกำหนดเส้นทางคำขอไปยังบริการคลัสเตอร์ Kubernetes ดังนี้

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');

ผลลัพธ์ที่คาดหวัง:

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

ทดสอบโมเดลที่ลงทะเบียนด้วยการค้นหา SQL ตัวอย่าง ดังนี้

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

ฟังก์ชันจะแสดงผลการนําเสนออาร์เรย์จำนวนจริงที่สร้างโดยโมเดล EmbeddingGemma ในเครื่องที่ทำงานบน GKE

กด q เพื่อกลับไปที่พรอมต์เซสชัน psql

ออกจากเซสชัน psql โดยทำดังนี้

\q

7. ทดสอบโมเดลด้วยข้อมูลจากการสุ่มตัวอย่าง

โหลดข้อมูลตัวอย่าง

บทแนะนำนี้ใช้ชุดข้อมูลค้าปลีกของ Cymbal เพื่อสาธิตการค้นหาความคล้ายคลึงกันของเวกเตอร์ คุณจะใช้ Google Cloud SDK และไคลเอ็นต์ PostgreSQL เพื่อนำเข้าข้อมูลไปยัง AlloyDB Omni

ในเซสชัน SSH บน instance-1 ให้เชื่อมต่อกับฐานข้อมูลสาธิตและเปิดใช้ส่วนขยาย vector โดยทำดังนี้

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

ในเซสชัน psql ให้ทำดังนี้

CREATE EXTENSION IF NOT EXISTS vector;

ออกจากเซสชัน psql โดยทำดังนี้

\q

ดาวน์โหลดและใช้สคีมาเพื่อสร้างตารางในฐานข้อมูล demo โดยทำดังนี้

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

ผลลัพธ์ที่คาดหวัง:

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:~$

ยืนยันตารางที่สร้างขึ้นโดยทำดังนี้

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

ผลลัพธ์ที่คาดหวัง:

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)

โหลดข้อมูลไปยังตาราง 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"

ผลลัพธ์ที่คาดหวัง:

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:~$ 

ต่อไปนี้เป็นตัวอย่างของแถวบางส่วนจากตาราง 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"

ผลลัพธ์ที่คาดหวัง:

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:~$ 

โหลดข้อมูลไปยังตาราง 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"

ผลลัพธ์ที่คาดหวัง:

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:~$ 

ต่อไปนี้เป็นตัวอย่างของแถวบางส่วนจากตาราง cymbal_inventory

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

เอาต์พุต:

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:~$ 

โหลดข้อมูลไปยังตาราง 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"

เอาต์พุตคอนโซลที่คาดไว้:

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:~$

ตัวอย่างแถวบางส่วนจากตาราง cymbal_stores มีดังนี้

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

เอาต์พุต:

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:~$ 

สร้างการฝัง

เชื่อมต่อกับฐานข้อมูลสาธิตโดยใช้ psql และสร้างการฝังสำหรับผลิตภัณฑ์ที่อธิบายไว้ในตาราง cymbal_products โดยอิงตามคำอธิบายผลิตภัณฑ์

เชื่อมต่อกับฐานข้อมูลสาธิตโดยทำดังนี้

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

ใช้คอลัมน์ embedding ของประเภท vector เพื่อจัดเก็บการฝังข้อความที่สร้างขึ้นสำหรับรายละเอียดสินค้า

เปิดใช้การกำหนดเวลาการค้นหา

\timing

สร้างการฝังสำหรับคำอธิบายผลิตภัณฑ์แต่ละรายการและจัดเก็บไว้ในตาราง cymbal_embedding ดังนี้

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

ผลลัพธ์ที่คาดหวัง:

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

เรียกใช้คำค้นหาเชิงความหมาย

ในเซสชัน psql ให้ค้นหาผลิตภัณฑ์ 5 อันดับแรกที่ตรงกับคำถาม "What kind of fruit trees grow well here?" โดยใช้ระยะทางโคไซน์ (<=>) ดังนี้

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;

ผลลัพธ์ที่คาดหวัง:

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

การค้นหาทำงานเป็นเวลา 83 มิลลิวินาทีและแสดงรายการต้นไม้จากตาราง cymbal_products ที่ตรงกับคำขอและมีสินค้าคงคลังพร้อมจำหน่ายในร้านค้าหมายเลข 1583

สร้างดัชนี ANN

ชุดข้อมูลขนาดเล็กช่วยให้ใช้การค้นหาแบบตรงทั้งหมดที่สแกนการฝังทั้งหมดได้ง่าย แต่เมื่อข้อมูลเพิ่มขึ้น เวลาในการโหลดและการตอบสนองก็จะเพิ่มขึ้นด้วย คุณสามารถสร้างดัชนีในข้อมูลการฝังเพื่อปรับปรุงประสิทธิภาพได้ ต่อไปนี้คือตัวอย่างวิธีดำเนินการโดยใช้ดัชนี Google ScaNN สำหรับข้อมูลเวกเตอร์

เชื่อมต่อกับฐานข้อมูลสาธิตอีกครั้งหากการเชื่อมต่อขาดหายไป โดยทำดังนี้

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

เปิดใช้ส่วนขยาย alloydb_scann:

CREATE EXTENSION IF NOT EXISTS alloydb_scann;

สร้างดัชนี ScaNN ในคอลัมน์ embedding:

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

เรียกใช้คำค้นหาเชิงความหมายอีกครั้งเพื่อเปรียบเทียบประสิทธิภาพการดำเนินการ

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;

ผลลัพธ์ที่คาดหวัง:

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

เวลาในการดำเนินการค้นหาลดลงเล็กน้อย และจะเห็นผลลัพธ์ได้ชัดเจนยิ่งขึ้นเมื่อใช้ชุดข้อมูลขนาดใหญ่ขึ้น ข้อมูลที่แสดงผลควรเหมือนหรือคล้ายกับข้อมูลที่เราได้รับโดยไม่มีดัชนีมาก

ลองใช้การค้นหาอื่นๆ และอ่านข้อมูลเพิ่มเติมเกี่ยวกับการเพิ่มประสิทธิภาพดัชนีเวกเตอร์ในเอกสารประกอบ

ออกจากเซสชัน psql โดยทำดังนี้

\q

กลับไปที่ Google Cloud Shell โดยยกเลิกการเชื่อมต่อจากเซสชัน instance-1 ssh โดยกด CTRL+D หรือพิมพ์ exit

8. ทำให้ Gemma ใช้งานได้ด้วย vLLM

เพิ่ม Node Pool สำหรับ Gemma

ก่อนอื่น ให้ตรวจสอบประเภทโหนดที่พร้อมใช้งานในภูมิภาคของคุณ โดยทำดังนี้

gcloud compute accelerator-types list --filter="zone:${LOCATION}"

คุณควรเห็นรายการประเภท Accelerator ที่ใช้ได้ ซึ่งรวมถึง Accelerator nvidia-l4

สร้างไฟล์ Manifest การติดตั้งใช้งานสำหรับโมเดล Google Gemini 4 12B โดยใช้ 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

ใช้การติดตั้งใช้งาน gemma-12b-gpu-vllm-deployment.yaml ที่บันทึกไว้ โดยทำดังนี้

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

ผลลัพธ์ที่คาดหวัง:

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

รอจนกว่าการติดตั้งใช้งานจะเสร็จสมบูรณ์และโหลดโมเดลแล้ว ซึ่งอาจใช้เวลาหลายนาที

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'

ผลลัพธ์ที่คาดหวัง:

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

ทดสอบโมเดล เปิดใช้การส่งต่อพอร์ตเพื่อเข้าถึงโมเดล โดยทำดังนี้

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

ในหน้าต่างเทอร์มินัลอื่น ให้ใช้ curl เพื่อส่งพรอมต์ไปยังโมเดล

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'

ผลลัพธ์ที่คาดหวัง:

  % 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.

หยุดการส่งต่อพอร์ตในเทอร์มินัลแรก (หากยังทำงานอยู่) โดยกด Ctrl+C

9. ลงทะเบียนโมเดล Gemma 4 ใน AlloyDB Omni

ลงทะเบียนโมเดล Gemma 12B ใน AlloyDB Omni โดยใช้ขั้นตอน google_ml.create_model ระบุ http://gemma-12b-gpu-vllm-service:8000/v1/chat/completions เป็น model_request_url เพื่อกำหนดเส้นทางคำขอไปยังบริการคลัสเตอร์ Kubernetes ดังนี้

ดึงข้อมูล IP ปลายทางของ AlloyDB Omni โดยทำดังนี้

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

เชื่อมต่อกับอินสแตนซ์ VM โดยใช้ SSH ดังนี้

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

หลังจากเชื่อมต่อกับ VM แล้ว ให้ส่งออกตัวแปร INSTANCE_IP จากขั้นตอนก่อนหน้า (ค่า 10.128.0.33 เป็นเพียงตัวอย่างเท่านั้น ให้แทนที่ด้วย IP ของคุณ)

export INSTANCE_IP=10.128.0.33

ส่งออกรหัสผ่าน AlloyDB:

export PGPASSWORD=VeryStrongPassword

เชื่อมต่อกับฐานข้อมูล demo โดยทำดังนี้

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

ลงทะเบียนโมเดลในเซสชัน psql โดยทำดังนี้

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');

ทดสอบโมเดลด้วยการค้นหา SQL ตัวอย่าง ดังนี้

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';

กด q เพื่อออกจากหน้าต่างผลลัพธ์และกลับไปที่พรอมต์ psql

รวมการค้นหาเวกเตอร์เข้ากับ LLM RAG ใน AlloyDB Omni

ใช้การค้นหาเวกเตอร์กับคำขอ LLM เพื่อสาธิต RAG (Retrieval-Augmented Generation) ด้วย LLM

เรียกใช้การค้นหา SQL ใน plsql:

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;

ผลลัพธ์ที่คาดหวัง:

----------------------------------------------------------------------------------------------------------------------------------------------
 "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)

คำค้นหาจะเสริมพรอมต์ไปยัง LLM ด้วยผลการค้นหาเวกเตอร์

ลองใช้คำค้นหาอื่นๆ และทดลองใช้รูปแบบ RAG ข้อดีของสถาปัตยกรรมที่นำเสนอคือความสามารถในการพึ่งพาตนเองได้อย่างสมบูรณ์ ระบบจะไม่ส่งข้อมูลออกนอกคลัสเตอร์และสามารถทำงานในสภาพแวดล้อมที่แยกต่างหากโดยสมบูรณ์

ออกจากเซสชัน psql โดยทำดังนี้

\q

ยกเลิกการเชื่อมต่อจากเซสชัน SSH ไปยัง VM โดยทำดังนี้

exit

อย่าลืมว่า AlloyDB Omni มีฟีเจอร์และห้องทดลองเพิ่มเติม

10. ล้างสภาพแวดล้อม

โปรดลบทรัพยากรที่สร้างใน Codelab นี้เพื่อหลีกเลี่ยงการเรียกเก็บเงินที่เกิดขึ้นอย่างต่อเนื่องในบัญชี Google Cloud

ลบคลัสเตอร์ GKE

ลบคลัสเตอร์ GKE ใน 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}

ผลลัพธ์ที่คาดหวัง:

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

ลบ VM ของไคลเอ็นต์

ใน Cloud Shell ให้ลบอินสแตนซ์ Compute Engine โดยทำดังนี้

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

ผลลัพธ์ที่คาดหวัง:

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

หากสร้างโปรเจ็กต์ใหม่สำหรับ Codelab นี้ คุณจะลบทั้งโปรเจ็กต์ใน Google Cloud Resource Manager ได้ (ไม่บังคับ)

11. ขอแสดงความยินดี

ขอแสดงความยินดีที่ทำ Codelab เสร็จสมบูรณ์

สิ่งที่คุณได้พูดถึงไปแล้ว

  • วิธีติดตั้งใช้งาน AlloyDB Omni ในคลัสเตอร์ GKE
  • วิธีเชื่อมต่อกับ AlloyDB Omni
  • วิธีโหลดข้อมูลลงใน AlloyDB Omni
  • วิธีทำให้โมเดล AI (การฝังและ LLM) ใช้งานได้ใน GKE
  • วิธีลงทะเบียนโมเดล AI ใน AlloyDB Omni
  • วิธีสร้างการฝังสำหรับการค้นหาเชิงความหมาย
  • วิธีเรียกใช้คำค้นหาเชิงความหมายใน AlloyDB Omni
  • วิธีสร้างและใช้ดัชนีเวกเตอร์ใน AlloyDB Omni

อ่านข้อมูลเพิ่มเติมเกี่ยวกับการทำงานกับ AI ใน AlloyDB Omni ได้ในเอกสารประกอบ

แบบสำรวจ

เอาต์พุต:

คุณจะใช้บทแนะนำนี้อย่างไร

อ่านอย่างเดียว อ่านและทำแบบฝึกหัด