1. مقدمة
في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية نشر AlloyDB Omni على GKE واستخدامه مع نموذج تضمين مفتوح يتم نشره في مجموعة Kubernetes نفسها. يؤدي نشر نموذج بجانب مثيل قاعدة البيانات في مجموعة GKE نفسها إلى تقليل وقت الاستجابة والتبعيات على الخدمات التابعة لجهات خارجية. بالإضافة إلى ذلك، قد تفرض متطلبات الأمان استخدام هذا الإجراء عندما لا يُسمح بخروج البيانات من المؤسسة ولا يُسمح باستخدام خدمات تابعة لجهات خارجية.
المتطلبات الأساسية
- فهم أساسي لوحدة تحكّم Google Cloud
- المهارات الأساسية في واجهة سطر الأوامر وCloud Shell
ما ستتعرّف عليه
- كيفية نشر AlloyDB Omni على مجموعة Google Kubernetes
- كيفية الاتصال بخدمة AlloyDB Omni
- كيفية تحميل البيانات إلى AlloyDB Omni
- كيفية نشر نموذج تضمين مفتوح في GKE
- كيفية تسجيل نموذج التضمين في AlloyDB Omni
- كيفية إنشاء عمليات إدراج للبحث الدلالي
- كيفية استخدام النماذج المُنشأة للبحث الدلالي في AlloyDB Omni
- كيفية إنشاء فهارس متّجهات واستخدامها في AlloyDB
المتطلبات
- حساب Google Cloud ومشروع Google Cloud
- متصفّح ويب، مثل Chrome، متوافق مع وحدة تحكّم Google Cloud وCloud Shell
2. الإعداد والمتطلبات
إعداد البيئة حسب السرعة التي تناسبك
- سجِّل الدخول إلى Google Cloud Console وأنشئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.
- اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها واجهات برمجة تطبيقات Google. ويمكنك تعديلها في أي وقت.
- يكون معرّف المشروع فريدًا في جميع مشاريع Google Cloud وغير قابل للتغيير (لا يمكن تغييره بعد ضبطه). تنشئ وحدة تحكّم Cloud Console سلسلة فريدة تلقائيًا، ولا يهمّك عادةً معرفة محتواها. في معظم مختبرات رموز البرامج، عليك الإشارة إلى معرّف المشروع (يُعرَف عادةً باسم
PROJECT_ID
). إذا لم يعجبك المعرّف الذي تم إنشاؤه، يمكنك إنشاء معرّف آخر عشوائي. يمكنك بدلاً من ذلك تجربة عنوانك الخاص لمعرفة ما إذا كان متاحًا. ولا يمكن تغييره بعد هذه الخطوة ويبقى ساريًا طوال مدة المشروع. - يُرجى العِلم أنّ هناك قيمة ثالثة، وهي رقم المشروع، تستخدمها بعض واجهات برمجة التطبيقات. اطّلِع على مزيد من المعلومات عن كلّ من هذه القيم الثلاث في المستندات.
- بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد/واجهات برمجة تطبيقات Cloud. لن تُكلّفك هذه الدورة التدريبية على إنشاء الرموز البرمجية الكثير من المال، إن لم تكن تكلفتك أيّ أموال على الإطلاق. لإيقاف الموارد لتجنُّب تحصيل رسوم بعد انتهاء هذا الدليل التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع. يكون مستخدمو Google Cloud الجدد مؤهّلين للاستفادة من برنامج الفترة التجريبية المجانية التي تبلغ قيمتها 300 دولار أمريكي.
بدء Cloud Shell
على الرغم من أنّه يمكن تشغيل Google Cloud عن بُعد من الكمبيوتر المحمول، ستستخدم في هذا الدليل التعليمي Google Cloud Shell، وهي بيئة سطر أوامر تعمل في السحابة الإلكترونية.
من Google Cloud Console، انقر على رمز Cloud Shell في شريط الأدوات أعلى يسار الصفحة:
من المفترض ألا تستغرق عملية توفير البيئة والاتصال بها سوى بضع لحظات. عند الانتهاء، من المفترض أن يظهر لك ما يلي:
يتم تحميل هذه الآلة الافتراضية مزوّدة بكل أدوات التطوير التي ستحتاج إليها. ويقدّم هذا الدليل دليلاً منزليًا دائمًا بسعة 5 غيغابايت، ويتم تشغيله على Google Cloud، ما يُحسِّن بشكل كبير أداء الشبكة والمصادقة. يمكنك تنفيذ جميع أعمالك في هذا الدليل التعليمي للترميز داخل متصفّح. لست بحاجة إلى تثبيت أي تطبيق.
3- قبل البدء
تفعيل واجهة برمجة التطبيقات
إخراج:
في Cloud Shell، تأكَّد من إعداد رقم تعريف مشروعك:
PROJECT_ID=$(gcloud config get-value project)
echo $PROJECT_ID
إذا لم يكن محدّدًا في إعدادات Cloud Shell، يمكنك إعداده باستخدام الأوامر التالية:
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 عادية مع إعداد مجموعة كافٍ لنشر مجموعة مع مثيل AlloyDB Omni. نحتاج إلى وحدتَي معالجة مركزية على الأقل وذاكرة وصول عشوائي بسعة 8 غيغابايت لنظام 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)$
إعداد المجموعة
نحتاج إلى تثبيت المكوّنات المطلوبة، مثل خدمة cert-manager. يمكننا اتّباع الخطوات الواردة في المستندات الخاصة بتثبيت cert-manager.
نستخدم أداة سطر أوامر 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 باستخدام أداة helm.
شغِّل الأمر التالي لتثبيت مشغّل 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 لتخزين قيمة كلمة المرور. يمكنك الاطّلاع على مزيد من المعلومات حول هذا الموضوع في المستندات.
احفظ البيان باسم my-omni.yaml ليتم تطبيقه في الخطوة التالية. إذا كنت تستخدم Cloud Shell، يمكنك إجراء ذلك باستخدام المحرِّر من خلال الضغط على الزر "فتح المحرِّر" في أعلى يسار المحطة الطرفية.
بعد حفظ الملف باسم my-omni.yaml، ارجع إلى الوحدة الطرفية من خلال الضغط على الزر "فتح الوحدة الطرفية".
طبِّق بيان 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
عندما تكون المجموعة جاهزة، يمكننا استخدام ملفات ثنائية عميل PostgreSQL في مجموعة مثيلات AlloyDB Omni. نبحث عن معرّف الحزمة ثم نستخدم kubectl للاتصال مباشرةً بالحزمة وتشغيل برنامج العميل. كلمة المرور هي 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- نشر نموذج الذكاء الاصطناعي على GKE
لاختبار دمج AlloyDB Omni AI مع النماذج المحلية، يجب نشر نموذج في المجموعة.
إنشاء مجموعة عقد للنموذج
لتشغيل النموذج، نحتاج إلى إعداد مجموعة عقد لتشغيل الاستنتاج. من وجهة نظر الأداء، فإنّ أفضل طريقة هي استخدام مجموعة تتضمّن مسرّعات الرسومات باستخدام إعدادات عقدة مثل 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 1.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 للخدمة هو ما سنستخدمه كعنوان نقطة النهاية. يمكن أن يستجيب إدراج النموذج من خلال عنوان URL http://34.118.233.48:8080/embed. وسيتم استخدامه لاحقًا عند تسجيل النموذج في AlloyDB Omni.
يمكننا اختباره من خلال عرضه باستخدام الأمر kubectl port-forward.
kubectl port-forward service/tei-service 8080:8080
سيتم تشغيل إعادة توجيه المنفذ في جلسة واحدة من Cloud Shell، وسنحتاج إلى جلسة أخرى لاختبارها.
افتح علامة تبويب أخرى في Cloud Shell باستخدام الرمز "+" في أعلى الصفحة.
ونفِّذ الأمر curl في جلسة shell الجديدة.
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 افتراضيًا كنقطة اتصال، واتصل بـ AlloyDB Omni من جهازك الافتراضي للعملاء وأنشئ قاعدة بيانات.
نحتاج إلى وحدة التحكّم في الجلسة لأنّ أداة موازنة التحميل الخارجية في GKE لـ Omni تمنحك إمكانية الوصول من شبكة VPC باستخدام عناوين IP الخاصة، ولكنها لا تسمح لك بالاتصال من خارج شبكة VPC. وهو أكثر أمانًا بشكل عام ولا يعرِض مثيل قاعدة البيانات على الإنترنت. يُرجى الاطّلاع على الرسم البياني للمزيد من الوضوح.
لإنشاء جهاز افتراضي في جلسة Cloud Shell، نفِّذ ما يلي:
export ZONE=us-central1-a
gcloud compute instances create instance-1 \
--zone=$ZONE
ابحث عن عنوان IP لنقطة نهاية AlloyDB Omni باستخدام kubectl في Cloud Shell:
kubectl get dbclusters.alloydbomni.dbadmin.goog my-omni -n default
دوِّن PRIMARYENDPOINT. في ما يلي مثال:
النتيجة:
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:
gcloud compute ssh instance-1 --zone=$ZONE
اتّبِع التعليمات إذا طُلب منك إنشاء مفتاح ssh. يمكنك الاطّلاع على مزيد من المعلومات حول الاتصال عبر بروتوكول ssh في المستندات.
في جلسة ssh للوصول إلى الجهاز الظاهري، ثبِّت عميل 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.
من الطرق لتحميل البيانات استخدام حِزمة تطوير البرامج (SDK) من Google Cloud وبرنامج عميل PostgreSQL. يمكننا استخدام جهاز الكمبيوتر الظاهري للعميل نفسه المستخدَم لإنشاء قاعدة بيانات الإصدار التجريبي. من المفترض أن تكون حزمة تطوير البرامج (SDK) من Google Cloud مثبّتة على الجهاز الافتراضي إذا كنت قد استخدمت الإعدادات التلقائية لصورة الجهاز الافتراضي. ولكن إذا استخدمت صورة مخصّصة بدون حزمة تطوير البرامج (SDK) من Google، يمكنك إضافتها باتّباع المستندات.
تصدير عنوان 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:~$
إنشاء عمليات التضمين
اربط بقاعدة البيانات التجريبية باستخدام 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=#
انخفض وقت تنفيذ طلب البحث قليلاً، وسيكون هذا الإنجاز أكثر وضوحًا مع مجموعات البيانات الأكبر حجمًا. النتائج متشابهة جدًا، وتم استبدال شجرة الكرز فقط بشجرة Fremont Cottonwood.
جرِّب طلبات بحث أخرى واطّلِع على مزيد من المعلومات عن اختيار فهرس المتجهات في المستندات.
ولا تنسَ أنّ AlloyDB Omni تتضمّن المزيد من الميزات والمختبرات.
8. تنظيف البيئة
يمكننا الآن حذف مجموعة GKE باستخدام AlloyDB Omni ونموذج الذكاء الاصطناعي.
حذف مجموعة GKE
في 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
حذف جهاز افتراضي
في 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. استطلاع
إخراج: