AlloyDB Omni و مدل AI محلی در Kubernetes.

1. مقدمه

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

391e4244b25a7db0.png

پیش نیازها

  • درک اولیه از Google Cloud، کنسول
  • مهارت های اولیه در رابط خط فرمان و Cloud Shell

چیزی که یاد خواهید گرفت

  • نحوه استقرار AlloyDB Omni در خوشه Google Kubernetes
  • نحوه اتصال به AlloyDB Omni
  • نحوه بارگیری داده ها در AlloyDB Omni
  • نحوه استقرار یک مدل تعبیه باز در GKE
  • نحوه ثبت مدل تعبیه در AlloyDB Omni
  • نحوه ایجاد جاسازی برای جستجوی معنایی
  • نحوه استفاده از جاسازی های تولید شده برای جستجوی معنایی در AlloyDB Omni
  • نحوه ایجاد و استفاده از نمایه های برداری در AlloyDB

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

  • یک حساب Google Cloud و پروژه Google Cloud
  • یک مرورگر وب مانند کروم که از کنسول Google Cloud و Cloud Shell پشتیبانی می کند

2. راه اندازی و الزامات

تنظیم محیط خود به خود

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

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • نام پروژه نام نمایشی برای شرکت کنندگان این پروژه است. این یک رشته کاراکتری است که توسط API های Google استفاده نمی شود. همیشه می توانید آن را به روز کنید.
  • شناسه پروژه در تمام پروژه‌های Google Cloud منحصربه‌فرد است و تغییرناپذیر است (پس از تنظیم نمی‌توان آن را تغییر داد). Cloud Console به طور خودکار یک رشته منحصر به فرد تولید می کند. معمولاً برای شما مهم نیست که چیست. در اکثر کدها، باید شناسه پروژه خود را ارجاع دهید (معمولاً با نام PROJECT_ID شناخته می شود). اگر شناسه تولید شده را دوست ندارید، ممکن است یک شناسه تصادفی دیگر ایجاد کنید. از طرف دیگر، می‌توانید خودتان را امتحان کنید، و ببینید آیا در دسترس است یا خیر. پس از این مرحله نمی توان آن را تغییر داد و در طول مدت پروژه باقی می ماند.
  • برای اطلاع شما، یک مقدار سوم وجود دارد، یک شماره پروژه ، که برخی از API ها از آن استفاده می کنند. در مورد هر سه این مقادیر در مستندات بیشتر بیاموزید.
  1. در مرحله بعد، برای استفاده از منابع Cloud/APIها باید صورتحساب را در کنسول Cloud فعال کنید . اجرا کردن از طریق این کد لبه هزینه زیادی نخواهد داشت. برای خاموش کردن منابع برای جلوگیری از تحمیل صورت‌حساب فراتر از این آموزش، می‌توانید منابعی را که ایجاد کرده‌اید حذف کنید یا پروژه را حذف کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان 300 دلاری هستند.

Cloud Shell را راه اندازی کنید

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

از Google Cloud Console ، روی نماد Cloud Shell در نوار ابزار بالا سمت راست کلیک کنید:

55efc1aaa7a4d3ad.png

تهیه و اتصال به محیط فقط چند لحظه طول می کشد. وقتی تمام شد، باید چیزی شبیه به این را ببینید:

7ffe5cbb04455448.png

این ماشین مجازی با تمام ابزارهای توسعه که شما نیاز دارید بارگذاری شده است. این یک فهرست اصلی 5 گیگابایتی دائمی را ارائه می دهد و در Google Cloud اجرا می شود و عملکرد و احراز هویت شبکه را تا حد زیادی افزایش می دهد. تمام کارهای شما در این کد لبه را می توان در یک مرورگر انجام داد. شما نیازی به نصب چیزی ندارید.

3. قبل از شروع

فعال کردن API

خروجی:

در داخل Cloud Shell، مطمئن شوید که ID پروژه شما تنظیم شده است:

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

اگر در پیکربندی پوسته ابری تعریف نشده باشد، آن را با استفاده از دستورات زیر تنظیم کنید

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

فعال کردن تمام خدمات لازم:

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.

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

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

یک خوشه GKE ایجاد کنید

ما باید یک کلاستر استاندارد GKE با یک پیکربندی استخری برای استقرار یک pod با نمونه AlloyDB Omni کافی استقرار دهیم. حداقل 2 CPU و 8 GB RAM برای Omni با مقداری اتاق برای خدمات اپراتور و نظارت نیاز داریم.

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

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

سپس از gcloud برای ایجاد کلاستر استاندارد 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:~ (gleb-test-short-001-415614)$ export PROJECT_ID=$(gcloud config get project)
export LOCATION=us-central1
export CLUSTER_NAME=alloydb-ai-gke
export MACHINE_TYPE=n2-highmem-2
Your active configuration is: [gleb-test-short-001-415614]
student@cloudshell:~ (gleb-test-short-001-415614)$ 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: The Kubelet readonly port (10255) is now deprecated. Please update your workloads to use the recommended alternatives. See https://cloud.google.com/kubernetes-engine/docs/how-to/disable-kubelet-readonly-port for ways to check usage and for migration instructions.
Note: Your Pod address range (`--cluster-ipv4-cidr`) can accommodate at most 1008 node(s).
Creating cluster alloydb-ai-gke in us-central1..


NAME: omni01
ZONE: us-central1-a
MACHINE_TYPE: e2-standard-4
PREEMPTIBLE: 
INTERNAL_IP: 10.128.0.3
EXTERNAL_IP: 35.232.157.123
STATUS: RUNNING
student@cloudshell:~ (gleb-test-short-001-415614)$ 

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

ما باید اجزای مورد نیاز مانند سرویس مدیر گواهی را نصب کنیم. برای نصب مدیر گواهی می توانیم مراحل موجود در مستندات را دنبال کنیم

ما از ابزار خط فرمان Kubernetes به نام kubectl استفاده می کنیم که قبلاً در Cloud Shell نصب شده است. قبل از استفاده از ابزار، باید اعتبارنامه خوشه خود را دریافت کنیم.

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

اکنون می توانیم از kubectl برای نصب cert-manager استفاده کنیم:

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

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

student@cloudshell:~$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.2/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 را می توان با استفاده از ابزار فرمان نصب کرد.

برای نصب اپراتور AlloyDB Omni دستور زیر را اجرا کنید:

export GCS_BUCKET=alloydb-omni-operator
export HELM_PATH=$(gcloud storage cat gs://$GCS_BUCKET/latest)
export OPERATOR_VERSION="${HELM_PATH%%/*}"
gcloud storage cp gs://$GCS_BUCKET/$HELM_PATH ./ --recursive
helm install alloydbomni-operator alloydbomni-operator-${OPERATOR_VERSION}.tgz \
--create-namespace \
--namespace alloydb-omni-system \
--atomic \
--timeout 5m

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

student@cloudshell:~$ gcloud storage cp gs://$GCS_BUCKET/$HELM_PATH ./ --recursive
Copying gs://alloydb-omni-operator/1.2.0/alloydbomni-operator-1.2.0.tgz to file://./alloydbomni-operator-1.2.0.tgz
  Completed files 1/1 | 126.5kiB/126.5kiB
student@cloudshell:~$ helm install alloydbomni-operator alloydbomni-operator-${OPERATOR_VERSION}.tgz \
> --create-namespace \
> --namespace alloydb-omni-system \
> --atomic \
> --timeout 5m
NAME: alloydbomni-operator
LAST DEPLOYED: Mon Jan 20 13:13:20 2025
NAMESPACE: alloydb-omni-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
student@cloudshell:~$

هنگامی که اپراتور AlloyDB Omni نصب می شود، می توانیم استقرار کلاستر پایگاه داده خود را پیگیری کنیم.

در اینجا نمونه ای از مانیفست استقرار با پارامتر googleMLExtension فعال و متعادل کننده بار داخلی (خصوصی) است.:

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: "15.7.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

مقدار مخفی رمز عبور، نمایش Base64 کلمه رمز عبور "VeryStrongPassword" است. راه قابل اعتمادتر استفاده از Google Secret Manager برای ذخیره مقدار رمز عبور است. شما می توانید در مورد آن در مستندات بیشتر بخوانید.

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

47ab85dad9afdff7.png

پس از ذخیره فایل با نام my-omni.yaml با فشار دادن دکمه "باز کردن ترمینال" به ترمینال برگردید.

b9b7747b39dbe8c7.png

مانیفست my-omni.yaml را با استفاده از ابزار kubectl روی خوشه اعمال کنید:

kubectl apply -f my-omni.yaml

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

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

وضعیت وضعیت خوشه my-omni خود را با استفاده از ابزار kubectl بررسی کنید:

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

به AlloyDB Omni متصل شوید

با استفاده از Kubernetes Pod متصل شوید

وقتی خوشه آماده شد، می‌توانیم از باینری‌های مشتری PostgreSQL در پاد نمونه AlloyDB Omni استفاده کنیم. شناسه pod را پیدا می کنیم و سپس از kubectl برای اتصال مستقیم به pod و اجرای نرم افزار مشتری استفاده می کنیم. رمز عبور 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 (15.7)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_128_GCM_SHA256, compression: off)
Type "help" for help.

postgres=#

5. مدل AI را در GKE مستقر کنید

برای آزمایش ادغام AlloyDB Omni AI با مدل های محلی، باید یک مدل را در خوشه مستقر کنیم.

یک Node Pool برای مدل ایجاد کنید

برای اجرای مدل باید یک Node Pool برای اجرای استنتاج آماده کنیم. بهترین رویکرد از نقطه نظر عملکرد، یک استخر با شتاب دهنده های گرافیکی با استفاده از یک پیکربندی گره مانند g2-standard-8 با شتاب دهنده L4 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

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

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 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
Note: Machines with GPUs have certain limitations which may affect your workflow. Learn more at https://cloud.google.com/kubernetes-engine/docs/how-to/gpus
Note: Starting in GKE 1.30.1-gke.115600, if you don't specify a driver version, GKE installs the default GPU driver for your node's GKE version.
Creating node pool gpupool...done.
Created [https://container.googleapis.com/v1/projects/student-test-001/zones/us-central1/clusters/alloydb-ai-gke/nodePools/gpupool].
NAME     MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
gpupool  g2-standard-8  100           1.31.4-gke.1183000

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

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

ما از مدل تعبیه شده BGE Base v1.5 از Hugging Face استفاده می کنیم. می توانید مدل کارت را اینجا بخوانید. برای استقرار مدل می‌توانیم از دستورالعمل‌های آماده شده از Hugging Face و بسته استقرار GitHub استفاده کنیم.

بسته را شبیه سازی کنید

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

مانیفست را با جایگزین کردن مقدار cloud.google.com/gke-accelerator توسط nvidia-l4 ما و افزودن محدودیت‌هایی به منابع ویرایش کنید.

vi Google-Cloud-Containers/examples/gke/tei-deployment/gpu-config/deployment.yaml

در اینجا یک مانیفست تصحیح شده است.

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: Snowflake--snowflake-arctic-embed-m
        hf.co/task: text-embeddings
    spec:
      containers:
        - name: tei-container
          image: us-docker.pkg.dev/deeplearning-platform-release/gcr.io/huggingface-text-embeddings-inference-cu122.1-4.ubuntu2204:latest
          resources:
            requests:
              nvidia.com/gpu: 1
            limits:
              nvidia.com/gpu: 1
          env:
            - name: MODEL_ID
              value: Snowflake/snowflake-arctic-embed-m
            - name: NUM_SHARD
              value: "1"
            - name: PORT
              value: "8080"
          volumeMounts:
            - mountPath: /dev/shm
              name: dshm
            - mountPath: /data
              name: data
      volumes:
        - name: dshm
          emptyDir:
            medium: Memory
            sizeLimit: 1Gi
        - name: data
          emptyDir: {}
      nodeSelector:
        cloud.google.com/gke-accelerator: nvidia-l4

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

ما باید یک حساب سرویس و یک فضای نام برای استقرار آماده کنیم.

یک فضای نام kubernetes hf-gke-namespace ایجاد کنید.

export NAMESPACE=hf-gke-namespace
kubectl create namespace $NAMESPACE

یک حساب سرویس kubernetes ایجاد کنید

export SERVICE_ACCOUNT=hf-gke-service-account
kubectl create serviceaccount $SERVICE_ACCOUNT --namespace $NAMESPACE

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

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

استقرارها را تأیید کنید

kubectl get pods

سرویس مدل را تأیید کنید

kubectl get service tei-service

قرار است نوع سرویس در حال اجرا ClusterIP را نشان دهد

خروجی نمونه:

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 برای سرویس همان چیزی است که ما می خواهیم به عنوان آدرس نقطه پایانی خود استفاده کنیم. تعبیه مدل می تواند توسط URI http://34.118.233.48:8080/embed پاسخ دهد. بعداً هنگام ثبت مدل در AlloyDB Omni از آن استفاده خواهد شد.

می‌توانیم آن را با استفاده از دستور port-forward kubectl آزمایش کنیم.

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

ارسال پورت در یک جلسه Cloud Shell اجرا می شود و برای آزمایش آن به جلسه دیگری نیاز داریم.

یک برگه دیگر Cloud Shell را با استفاده از علامت "+" در بالا باز کنید.

4ca978f5142bb6ce.png

و دستور 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]]

6. مدل را در AlloyDB Omni ثبت کنید

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

ایجاد پایگاه داده

یک GCE VM به عنوان یک جعبه پرش ایجاد کنید، از VM مشتری خود به AlloyDB Omni متصل شوید و یک پایگاه داده ایجاد کنید.

ما به جعبه پرش نیاز داریم زیرا متعادل کننده بار خارجی GKE برای Omni به شما امکان دسترسی از VPC را با استفاده از آدرس دهی IP خصوصی می دهد اما به شما اجازه نمی دهد از خارج از VPC متصل شوید. به طور کلی امن تر است و نمونه پایگاه داده شما را در معرض اینترنت قرار نمی دهد. لطفا نمودار را برای وضوح بررسی کنید.

391e4244b25a7db0.png

برای ایجاد یک ماشین مجازی در جلسه Cloud Shell این موارد را اجرا کنید:

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

IP Endpoint AlloyDB Omni را با استفاده از kubectl در Cloud Shell پیدا کنید:

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

نقطه اولیه را یادداشت کنید. در اینجا یک مثال است.

خروجی:

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

10.131.0.33 IP است که ما در مثال های خود برای اتصال به نمونه AlloyDB Omni استفاده خواهیم کرد.

با استفاده از gcloud به VM متصل شوید:

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

اگر برای طبقه تولید کلید ssh خواسته شد دستورالعمل ها. درباره اتصال ssh در مستندات بیشتر بخوانید.

در جلسه ssh به VM، سرویس گیرنده PostgreSQL را نصب کنید:

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

IP متعادل کننده بار AlloyDB Omni را مانند مثال زیر صادر کنید (IP را با IP متعادل کننده بار جایگزین کنید):

export INSTANCE_IP=10.131.0.33

به AlloyDB Omni متصل شوید، رمز عبور VeryStrongPassword است که از طریق هش در my-omni.yaml تنظیم شده است:

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

در جلسه psql ایجاد شده اجرا کنید:

create database demo;

از جلسه خارج شوید و به نسخه نمایشی پایگاه داده متصل شوید (یا می توانید به سادگی "\c demo" را در همان جلسه اجرا کنید)

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

ایجاد توابع تبدیل

برای مدل‌های تعبیه‌شده شخص ثالث، باید توابع تبدیل ایجاد کنیم که ورودی و خروجی را به فرمت مورد انتظار مدل و عملکردهای داخلی ما قالب‌بندی کند.

در اینجا تابع تبدیل است که ورودی را کنترل می کند:

-- Input Transform Function corresponding to the custom model endpoint
CREATE OR REPLACE FUNCTION tei_text_input_transform(model_id VARCHAR(100), input_text TEXT)
RETURNS JSON
LANGUAGE plpgsql
AS $$
DECLARE
  transformed_input JSON;
  model_qualified_name TEXT;
BEGIN
  SELECT json_build_object('inputs', input_text, 'truncate', true)::JSON INTO transformed_input;
  RETURN transformed_input;
END;
$$;

همانطور که در خروجی نمونه نشان داده شده است، کد ارائه شده را هنگام اتصال به پایگاه داده آزمایشی اجرا کنید:

demo=# -- Input Transform Function corresponding to the custom model endpoint
CREATE OR REPLACE FUNCTION tei_text_input_transform(model_id VARCHAR(100), input_text TEXT)
RETURNS JSON
LANGUAGE plpgsql
AS $$
DECLARE
  transformed_input JSON;
  model_qualified_name TEXT;
BEGIN
  SELECT json_build_object('inputs', input_text, 'truncate', true)::JSON INTO transformed_input;
  RETURN transformed_input;
END;
$$;
CREATE FUNCTION
demo=#

و در اینجا تابع خروجی است که پاسخ را از مدل به آرایه اعداد واقعی تبدیل می کند:

-- Output Transform Function corresponding to the custom model endpoint
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=# -- Output Transform Function corresponding to the custom model endpoint
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=#

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

اکنون می توانیم مدل را در پایگاه داده ثبت کنیم.

در اینجا فراخوانی برای ثبت مدل با نام bge-base-1.5، جایگزینی IP 34.118.233.48 با آدرس IP سرویس مدل شما (خروجی از kubectl get service tei-service ) است:

CALL
  google_ml.create_model(
    model_id => 'bge-base-1.5',
    model_request_url => 'http://34.118.233.48: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 => 'bge-base-1.5',
    model_request_url => 'http://34.118.233.48: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=#

ما می توانیم مدل ثبات را با استفاده از پرس و جو آزمایشی زیر آزمایش کنیم که باید یک آرایه اعداد واقعی را برگرداند.

select google_ml.embedding('bge-base-1.5','What is AlloyDB Omni?');

7. مدل را در AlloyDB Omni تست کنید

بارگذاری داده ها

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

یکی از راه های بارگیری داده ها استفاده از Google Cloud SDK و نرم افزار مشتری PostgreSQL است. ما می‌توانیم از همان VM کلاینت برای ایجاد پایگاه داده آزمایشی استفاده کنیم. اگر از پیش‌فرض‌های تصویر VM استفاده کرده‌اید، Google Cloud SDK باید قبلاً در آنجا نصب شده باشد. اما اگر از یک تصویر سفارشی بدون Google SDK استفاده کرده‌اید، می‌توانید آن را به دنبال مستندات اضافه کنید.

IP متعادل کننده بار AlloyDB Omni را مانند مثال زیر صادر کنید (IP را با IP متعادل کننده بار جایگزین کنید):

export INSTANCE_IP=10.131.0.33

به پایگاه داده متصل شده و پسوند pgvector را فعال کنید.

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

در جلسه psql:

CREATE EXTENSION IF NOT EXISTS vector;

از جلسه psql خارج شوید و در جلسه خط فرمان دستورات را برای بارگذاری داده ها در پایگاه داده دمو اجرا کنید.

جداول را ایجاد کنید:

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)
student@cloudshell:~$ 

بارگذاری داده ها در جدول 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:~$ 

ساخت Embeddings

با استفاده از psql به پایگاه داده آزمایشی متصل شوید و برای محصولاتی که در جدول cymbal_products توضیح داده شده اند، بر اساس نام و توضیحات محصولات، جاسازی ایجاد کنید.

اتصال به پایگاه داده آزمایشی:

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

ما از یک جدول cymbal_embedding با جاسازی ستون برای ذخیره سازی جاسازی های خود استفاده می کنیم و از توضیحات محصول به عنوان ورودی متنی تابع استفاده می کنیم.

زمان بندی درخواست های خود را فعال کنید تا بعداً با مدل های راه دور مقایسه شوند.:

\timing

برای ساخت جاسازی ها کوئری را اجرا کنید:

INSERT INTO cymbal_embedding(uniq_id,embedding)  SELECT uniq_id, google_ml.embedding('bge-base-1.5',product_description)::vector FROM cymbal_products;

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

demo=#  INSERT INTO cymbal_embedding(uniq_id,embedding)  SELECT uniq_id, google_ml.embedding('bge-base-1.5',product_description)::vector FROM cymbal_products;
INSERT 0 941
Time: 11069.762 ms (00:11.070)
demo=#

در این مثال، ساخت جاسازی برای 941 رکورد حدود 11 ثانیه طول کشید.

کوئری های تست را اجرا کنید

با استفاده از psql به پایگاه داده آزمایشی متصل شوید و زمان بندی را فعال کنید تا زمان اجرا را برای پرس و جوهایمان اندازه گیری کنیم، همانطور که برای ساختن جاسازی ها انجام دادیم.

بیایید 5 محصول برتر مطابق با درخواستی مانند "در اینجا چه نوع درختان میوه ای خوب رشد می کنند؟" با استفاده از فاصله کسینوس به عنوان الگوریتم جستجوی برداری.

در جلسه psql اجرا کنید:

SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        (ce.embedding <=> google_ml.embedding('bge-base-1.5','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
        AND 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('bge-base-1.5','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
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        distance ASC
LIMIT 5;
     product_name      |                                   description                                    | sale_price | zip_code |      distance
-----------------------+----------------------------------------------------------------------------------+------------+----------+---------------------
 California Sycamore   | This is a beautiful sycamore tree that can grow to be over 100 feet tall. It is  |     300.00 |    93230 | 0.22753925487632942
 Toyon                 | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e |      10.00 |    93230 | 0.23497374266229387
 California Peppertree | This is a beautiful peppertree that can grow to be over 30 feet tall. It is an e |      25.00 |    93230 | 0.24215884459965364
 California Redwood    | This is a beautiful redwood tree that can grow to be over 300 feet tall. It is a |    1000.00 |    93230 | 0.24564130578287147
 Cherry Tree           | This is a beautiful cherry tree that will produce delicious cherries. It is an d |      75.00 |    93230 | 0.24846117929767153
(5 rows)

Time: 28.724 ms
demo=#

پرس و جو 28 میلی ثانیه اجرا شد و لیستی از درختان را از جدول 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;

نمایه را بسازید:

CREATE INDEX cymbal_embedding_scann ON cymbal_embedding USING scann (embedding cosine);

همان عبارت قبلی را امتحان کنید و نتایج را با هم مقایسه کنید:

demo=# SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        (ce.embedding <=> google_ml.embedding('bge-base-1.5','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
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        distance ASC
LIMIT 5;
     product_name      |                                   description                                    | sale_price | zip_code |      distance
-----------------------+----------------------------------------------------------------------------------+------------+----------+---------------------
 California Sycamore   | This is a beautiful sycamore tree that can grow to be over 100 feet tall. It is  |     300.00 |    93230 | 0.22753925487632942
 Toyon                 | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e |      10.00 |    93230 | 0.23497374266229387
 California Peppertree | This is a beautiful peppertree that can grow to be over 30 feet tall. It is an e |      25.00 |    93230 | 0.24215884459965364
 California Redwood    | This is a beautiful redwood tree that can grow to be over 300 feet tall. It is a |    1000.00 |    93230 | 0.24564130578287147
 Fremont Cottonwood    | This is a beautiful cottonwood tree that can grow to be over 100 feet tall. It i |     200.00 |    93230 |  0.2533482837690365
(5 rows)

Time: 14.665 ms
demo=#

زمان اجرای پرس و جو کمی کاهش یافته است و این افزایش با مجموعه داده های بزرگتر قابل توجه تر خواهد بود. نتایج کاملا مشابه هستند و فقط Cherry با Fremont Cottonwood جایگزین شد.

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

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

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

اکنون می‌توانیم خوشه GKE خود را با AlloyDB Omni و یک مدل هوش مصنوعی حذف کنیم

GKE Cluster را حذف کنید

در Cloud Shell اجرا کنید:

export PROJECT_ID=$(gcloud config get 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

VM را حذف کنید

در Cloud Shell اجرا کنید:

export PROJECT_ID=$(gcloud config get 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

اگر پروژه جدیدی برای این کد لبه ایجاد کرده‌اید، می‌توانید در عوض پروژه کامل را حذف کنید: https://console.cloud.google.com/cloud-resource-manager

9. تبریک می گویم

برای تکمیل کد لبه تبریک می گویم.

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

  • نحوه استقرار AlloyDB Omni در خوشه Google Kubernetes
  • نحوه اتصال به AlloyDB Omni
  • نحوه بارگیری داده ها در AlloyDB Omni
  • نحوه استقرار یک مدل تعبیه باز در GKE
  • نحوه ثبت مدل تعبیه در AlloyDB Omni
  • نحوه ایجاد جاسازی برای جستجوی معنایی
  • نحوه استفاده از جاسازی های تولید شده برای جستجوی معنایی در AlloyDB Omni
  • نحوه ایجاد و استفاده از نمایه های برداری در AlloyDB

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

10. نظرسنجی

خروجی:

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

فقط آن را بخوانید آن را بخوانید و تمرینات را کامل کنید