AlloyDB Omni و EmbeddingGemma به همراه Gemma 4 روی Kubernetes

۱. مقدمه

در این آزمایشگاه کد، شما یاد خواهید گرفت که چگونه AlloyDB Omni را روی موتور گوگل کوبرنتیز (GKE) مستقر کنید و از آن با مدل‌های باز مانند EmbeddingGemma و Gemma 4 برای جاسازی‌ها و پیش‌بینی‌ها استفاده کنید. اجرای پایگاه داده و مدل‌ها در یک خوشه، تأخیر شبکه را کاهش می‌دهد و از وابستگی به سرویس‌های شخص ثالث جلوگیری می‌کند. همچنین به برآورده شدن الزامات انطباق و اقامت داده‌ها کمک می‌کند زیرا داده‌های شما هرگز محیط شما را ترک نمی‌کنند.

نمودار معماری AlloyDB Omni و EmbeddingGemma در GKE

پیش‌نیازها

  • درک اولیه از گوگل کلود و کنسول گوگل کلود
  • آشنایی اولیه با Kubernetes و GKE
  • آشنایی با رابط خط فرمان و پوسته ابری گوگل

آنچه یاد خواهید گرفت

  • نحوه استقرار AlloyDB Omni در یک کلاستر GKE
  • نحوه اتصال به AlloyDB Omni
  • نحوه بارگذاری داده‌ها در AlloyDB Omni
  • نحوه استقرار مدل‌های هوش مصنوعی (جاسازی و LLM) در GKE
  • نحوه ثبت مدل‌های هوش مصنوعی در AlloyDB Omni
  • نحوه تولید جاسازی‌ها برای جستجوی معنایی
  • نحوه اجرای کوئری‌های جستجوی معنایی در AlloyDB Omni
  • نحوه ایجاد و استفاده از شاخص‌های برداری در AlloyDB Omni

آنچه نیاز دارید

  • یک حساب کاربری گوگل کلود و پروژه گوگل کلود
  • یک مرورگر وب مانند کروم

۲. تنظیمات و الزامات

راه‌اندازی پروژه

  1. وارد کنسول Google Cloud شوید. اگر از قبل حساب Gmail یا Google Workspace ندارید، یکی ایجاد کنید . به جای حساب کاری یا تحصیلی از یک حساب شخصی استفاده کنید.
  1. یک پروژه جدید ایجاد کنید یا یک پروژه موجود را انتخاب کنید. در سربرگ کنسول Google Cloud، روی « انتخاب یک پروژه» کلیک کنید، سپس روی «پروژه جدید» کلیک کنید.

یک پنجره محاوره‌ای پروژه را در کنسول گوگل کلود انتخاب کنید

در پنجره انتخاب پروژه ، روی «پروژه جدید» کلیک کنید تا کادر محاوره‌ای ایجاد پروژه باز شود.

پنجره ایجاد پروژه جدید

در کادر محاوره‌ای، نام پروژه را وارد کنید و سازمان یا مکان خود را انتخاب کنید.

فیلدهای ورودی جزئیات پروژه

  • نام پروژه ، نام نمایشی برای شرکت‌کنندگان این پروژه است. نام پروژه توسط APIهای گوگل استفاده نمی‌شود و شما می‌توانید آن را در هر زمانی تغییر دهید.
  • شناسه پروژه در تمام پروژه‌های گوگل کلود منحصر به فرد و غیرقابل تغییر است (پس از تنظیم، نمی‌توانید آن را تغییر دهید). کنسول گوگل کلود به طور خودکار یک شناسه منحصر به فرد تولید می‌کند، یا می‌توانید شناسه خودتان را وارد کنید. در این آزمایشگاه کد، شما شناسه پروژه خود را با جانگهدار
  • شماره پروژه ، شناسه سومی است که توسط برخی از APIها استفاده می‌شود. برای اطلاعات بیشتر، به مستندات Resource Manager مراجعه کنید.

فعال کردن صورتحساب

اگر صورتحساب را با استفاده از اعتبارهای Google Cloud تنظیم کرده‌اید، می‌توانید از این مرحله صرف نظر کنید.

برای تنظیم یک حساب پرداخت شخصی، پرداخت را در کنسول Google Cloud فعال کنید.

  • تکمیل این آزمایشگاه کمتر از ۵ دلار آمریکا از منابع ابری گوگل هزینه دارد.
  • برای حذف منابع و جلوگیری از هزینه‌های بیشتر، مراحل پاکسازی در انتهای این آزمایش را دنبال کنید.
  • کاربران جدید واجد شرایط استفاده از دوره آزمایشی رایگان ۳۰۰ دلاری هستند.

شروع پوسته ابری

در این آزمایشگاه کد، شما از Google Cloud Shell ، یک محیط خط فرمان که در فضای ابری اجرا می‌شود، استفاده می‌کنید.

از کنسول گوگل کلود ، روی آیکون فعال‌سازی پوسته کلود در نوار ابزار بالا سمت راست کلیک کنید:

دکمه فعال کردن پوسته ابری

روش دیگر این است که ابتدا G و سپس S را فشار دهید، یا مستقیماً Google Cloud Shell را باز کنید.

هنگام اتصال، Cloud Shell اعلان ترمینال را نمایش می‌دهد:

تصویر از ترمینال Google Cloud Shell

Cloud Shell شامل ابزارهای ذخیره‌سازی و توسعه پایدار است. می‌توانید تمام مراحل این codelab را از مرورگر خود اجرا کنید.

۳. فعال کردن APIها

برای استفاده از موتور کوبرنتیز گوگل (GKE) برای استقرارهای AlloyDB Omni و مدل، موتور محاسباتی و APIهای GKE را در پروژه Google Cloud خود فعال کنید.

در 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 فعال‌شده در مستندات مطالعه کنید.

۴. AlloyDB Omni را روی GKE مستقر کنید

برای استقرار AlloyDB Omni روی GKE، یک کلاستر Kubernetes مطابق با الزامات اپراتور AlloyDB Omni آماده کنید.

ایجاد یک کلاستر GKE

یک کلاستر استاندارد GKE با ظرفیت اجرای AlloyDB Omni، اپراتور و کانتینرهای نظارتی مستقر کنید. AlloyDB Omni حداقل به دو CPU و 8 گیگابایت رم نیاز دارد. در این آموزش از نوع ماشین n2-standard-4 استفاده شده است.

متغیرهای محیطی را برای استقرار خود تنظیم کنید:

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

خوشه استاندارد GKE را ایجاد کنید:

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

خروجی مورد انتظار کنسول:

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

خوشه را آماده کنید

اجزای مورد نیاز مانند cert-manager ، کنترل‌کننده‌ی گواهی‌های بومی برای Kubernetes، را نصب کنید. برای جزئیات بیشتر، به مستندات نصب cert-manager مراجعه کنید.

Cloud Shell شامل ابزار خط فرمان Kubernetes kubectl است. با استفاده از gcloud اعتبارنامه‌های کلاستر را دریافت کنید:

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

نصب cert-manager با استفاده از kubectl :

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

خروجی مورد انتظار کنسول (حذف شده):

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

اپراتور AlloyDB Omni را نصب کنید

اپراتور AlloyDB Omni را با استفاده از Helm نصب کنید.

نمودار عملگر AlloyDB Omni را دانلود و نصب کنید:

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

خروجی مورد انتظار کنسول (حذف شده):

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

خوشه پایگاه داده را مستقر کنید.

مانیفست زیر یک کلاستر پایگاه داده را با 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.3.0"
  primarySpec:
    adminUser:
      passwordRef:
        name: db-pw-my-omni
    features:
      googleMLExtension:
        enabled: true
    resources:
      cpu: 1
      memory: 8Gi
      disks:
      - name: DataDisk
        size: 20Gi
        storageClass: standard
    dbLoadBalancerOptions:
      annotations:
        networking.gke.io/load-balancer-type: "internal"
  allowExternalIncomingTraffic: true
EOF

مقدار رمز عبور مخفی، نمایش Base64 از VeryStrongPassword است. در محیط‌های عملیاتی، از Google Secret Manager برای مدیریت رمزهای عبور استفاده کنید. برای جزئیات بیشتر، به مستندات Secret Manager مراجعه کنید.

فایل مانیفست با نام my-omni.yaml ذخیره می‌شود. در Cloud Shell، روی گزینه Open Editor در گوشه بالا سمت راست پنجره ترمینال کلیک کنید و فایل را بخوانید.

ویرایشگر را در Cloud Shell باز کنید

پس از خواندن فایل my-omni.yaml manifest، برای بازگشت به خط فرمان، روی Open Terminal کلیک کنید.

ترمینال را در Cloud Shell باز کنید

فایل my-omni.yaml manifest را اعمال کنید:

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.3)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_128_GCM_SHA256, compression: off, ALPN: postgresql)
Type "help" for help.

postgres=#

با تایپ کردن \q و فشردن Enter از جلسه psql خارج شوید:

postgres=# \q

۵. مدل EmbeddingGemma را روی GKE مستقر کنید

برای آزمایش یکپارچه‌سازی AlloyDB Omni AI با مدل‌های محلی، یک مدل جاسازی را در خوشه GKE مستقر کنید. این آموزش از مدل EmbeddingGemma گوگل استفاده می‌کند.

ایجاد یک مخزن گره برای مدل

برای اجرای استنتاج مدل، یک گره اختصاصی آماده کنید. می‌توانید از یک گره فقط CPU یا یک گره شتاب‌یافته با GPU (مانند g2-standard-8 با پردازنده گرافیکی NVIDIA L4) استفاده کنید. این آموزش از یک گره مبتنی بر CPU با انواع ماشین‌های c3-standard-8 استفاده می‌کند.

یک استخر گره CPU تک گره ایجاد کنید:

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

خروجی مورد انتظار:

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

یک توکن چهره در آغوش گیرنده دریافت کنید

این آموزش مدل EmbeddingGemma را از Hugging Face مستقر می‌کند. برای دسترسی به وزن‌های مدل، یک توکن دسترسی Hugging Face ایجاد کنید:

  1. وارد حساب کاربری خود شوید یا در Hugging Face یک حساب کاربری ایجاد کنید.
  2. به نمایه خود > نشانه‌های دسترسی بروید.
  3. روی ایجاد توکن جدید کلیک کنید.
  4. یک نام برای توکن وارد کنید و نقش خواندن (Read ) را انتخاب کنید.
  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 -

مانیفست استقرار را آماده کنید

برای استقرار مدل، از بسته‌ی کانتینرِ استنتاج جاسازی متن (TEI) مربوط به Hugging Face استفاده کنید. برای اطلاعات بیشتر، به مستندات GKE TEI مربوط به Hugging Face مراجعه کنید.

مخزن استقرار را از گیت‌هاب کلون کنید:

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

مانیفست پیکربندی CPU را بررسی و اصلاح کنید:

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

مانیفست به‌روزرسانی‌شده برای استقرار 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 تغییرات را ذخیره کنید و به ترمینال برگردید.

مدل را مستقر کنید

برای استقرار سرور 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 دیگر باز کنید:

برگه 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 پورت فورواردینگ را در تب اول متوقف کنید.

۶. مدل جاسازی را در AlloyDB Omni ثبت کنید

برای استفاده از مدل پیاده‌سازی‌شده از AlloyDB Omni، یک پایگاه داده ایجاد کنید، توابع تبدیل را تعریف کنید و نقطه پایانی مدل را ثبت کنید.

ایجاد یک ماشین مجازی کلاینت و پایگاه داده

یک نمونه ماشین مجازی Compute Engine در همان VPC ایجاد کنید تا به عنوان یک میزبان پرش کلاینت عمل کند:

نمودار معماری شبکه که ماشین مجازی کلاینت و AlloyDB Omni را نشان می‌دهد

در Cloud Shell، ماشین مجازی کلاینت را ایجاد کنید:

export ZONE=us-central1-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 است.

با استفاده از 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

با استفاده از psql به AlloyDB Omni متصل شوید (رمز عبور 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=#

مدل را ثبت کنید

مدل را با استفاده از رویه google_ml.create_model در AlloyDB Omni ثبت کنید. برای مسیریابی درخواست‌ها به سرویس کلاستر Kubernetes، آدرس http://tei-service:8080/embed به عنوان model_request_url مشخص کنید:

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 اجرا می‌شود را برمی‌گرداند.

برای بازگشت به اعلان جلسه psql q را فشار دهید.

خروج از جلسه psql:

\q

۷. مدل را با داده‌های نمونه آزمایش کنید

بارگذاری داده‌های نمونه

این آموزش از مجموعه داده خرده فروشی 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 ، با استفاده از فاصله کسینوسی ( <=> )، پنج محصول برتر مطابق با سوال "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=#

این پرس‌وجو ۸۳ میلی‌ثانیه اجرا شد و فهرستی از درختان را از جدول cymbal_products که با درخواست مطابقت داشتند و موجودی آنها در فروشگاه با شماره ۱۵۸۳ موجود بود، بازگرداند.

ساخت شاخص 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

با قطع ارتباط از جلسه ssh مربوط به instance-1 و فشردن کلیدهای CTRL+D یا تایپ عبارت exit به پوسته Google Cloud بازگردید.

۸. استقرار Gemma با vLLM

اضافه کردن گره برای Gemma

ابتدا، بررسی کنید که چه نوع گره‌هایی در منطقه شما موجود است:

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

شما باید لیستی از انواع شتاب‌دهنده‌های موجود از جمله شتاب‌دهنده nvidia-l4 را ببینید. اکنون یک node pool با نوع شتاب‌دهنده nvidia-l4 ایجاد کنید:

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

با استفاده از vLLM، یک مانیفست استقرار برای مدل Google Gemini 4 12B ایجاد کنید:

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 ، فوروارد کردن پورت را در ترمینال اول (اگر هنوز در حال اجرا است) متوقف کنید.

۹. مدل Gemma 4 را در AlloyDB Omni ثبت کنید

مدل Gemma 12B را با استفاده از رویه google_ml.create_model در AlloyDB Omni ثبت کنید. برای مسیریابی درخواست‌ها به سرویس کلاستر Kubernetes، آدرس http://gemma-12b-gpu-vllm-service:8000/v1/chat/completions به عنوان model_request_url مشخص کنید:

IP نقطه پایانی AlloyDB Omni را بازیابی کنید:

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

با استفاده از SSH به نمونه ماشین مجازی متصل شوید:

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

پس از اتصال به متغیر 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';

برای خروج از پنجره نتایج و بازگشت به اعلان psql q را فشار دهید.

ترکیب جستجوی برداری با LLM RAG در AlloyDB Omni

از جستجوی برداری با درخواست LLM برای نمایش RAG (تولید افزوده بازیابی) با 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 به ماشین مجازی:

exit

فراموش نکنید که AlloyDB Omni ویژگی‌ها و آزمایشگاه‌های بیشتری دارد.

۱۰. محیط را تمیز کنید

برای جلوگیری از هزینه‌های مداوم برای حساب Google Cloud خود، منابع ایجاد شده در این codelab را حذف کنید.

خوشه GKE را حذف کنید

در Cloud Shell، کلاستر GKE را حذف کنید:

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

خروجی مورد انتظار:

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

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

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

ماشین مجازی کلاینت را حذف کنید

در Cloud Shell، نمونه Compute Engine را حذف کنید:

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

خروجی مورد انتظار:

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

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

Deleted

اگر برای این آزمایشگاه کد، پروژه جدیدی ایجاد کرده‌اید، می‌توانید به صورت اختیاری کل پروژه را در Google Cloud Resource Manager حذف کنید.

۱۱. تبریک

تبریک می‌گویم که آزمایشگاه کد را تمام کردید!

آنچه را که پوشش دادید

  • نحوه استقرار AlloyDB Omni در یک کلاستر GKE
  • نحوه اتصال به AlloyDB Omni
  • نحوه بارگذاری داده‌ها در AlloyDB Omni
  • نحوه استقرار مدل‌های هوش مصنوعی (جاسازی و LLM) در GKE
  • نحوه ثبت مدل‌های هوش مصنوعی در AlloyDB Omni
  • نحوه تولید جاسازی‌ها برای جستجوی معنایی
  • نحوه اجرای کوئری‌های جستجوی معنایی در AlloyDB Omni
  • نحوه ایجاد و استفاده از شاخص‌های برداری در AlloyDB Omni

می‌توانید اطلاعات بیشتر در مورد کار با هوش مصنوعی در AlloyDB Omni را در مستندات مطالعه کنید.

نظرسنجی

خروجی:

چگونه از این آموزش استفاده خواهید کرد؟

فقط آن را بخوانید آن را بخوانید و تمرین‌ها را انجام دهید