1. مقدمة
يقدّم هذا الدرس التطبيقي حول الترميز دليلاً حول نشر AlloyDB والاستفادة من دمج الذكاء الاصطناعي في البحث الدلالي باستخدام التضمينات المتعددة الوسائط. يشكّل هذا المختبر جزءًا من مجموعة مختبرات مخصّصة لميزات AlloyDB AI. يمكنك الاطّلاع على مزيد من المعلومات في صفحة AlloyDB AI ضمن المستندات.
المتطلبات الأساسية
- فهم أساسي لـ Google Cloud وGoogle Cloud Console
- مهارات أساسية في واجهة سطر الأوامر وCloud Shell
ما ستتعلمه
- كيفية نشر AlloyDB for Postgres
- كيفية استخدام البحث المتعدّد الوسائط المستند إلى المتجهات
- كيفية تفعيل مشغّلي AlloyDB AI
- كيفية استخدام عوامل تشغيل مختلفة في AlloyDB AI للبحث المتعدّد الوسائط
- كيفية استخدام AlloyDB AI لدمج نتائج البحث النصية والمرئية
المتطلبات
- حساب Google Cloud ومشروع Google Cloud
- متصفّح ويب، مثل Chrome، متوافق مع "وحدة تحكّم Google Cloud" وCloud Shell
2. الإعداد والمتطلبات
إعداد البيئة بالسرعة التي تناسبك
- سجِّل الدخول إلى Google Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.
- اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديلها في أي وقت.
- معرّف المشروع هو معرّف فريد في جميع مشاريع 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، تأكَّد من إعداد رقم تعريف مشروعك:
gcloud config set project [YOUR-PROJECT-ID]
اضبط متغيّر البيئة PROJECT_ID:
PROJECT_ID=$(gcloud config get-value project)
فعِّل جميع الخدمات اللازمة:
gcloud services enable alloydb.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
aiplatform.googleapis.com \
discoveryengine.googleapis.com \
secretmanager.googleapis.com
الناتج المتوقّع
student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417 Updated property [core/project]. student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project) Your active configuration is: [cloudshell-14650] student@cloudshell:~ (test-project-001-402417)$ student@cloudshell:~ (test-project-001-402417)$ gcloud services enable alloydb.googleapis.com \ compute.googleapis.com \ cloudresourcemanager.googleapis.com \ servicenetworking.googleapis.com \ aiplatform.googleapis.com Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.
4. نشر AlloyDB
أنشئ مجموعة AlloyDB ومثيلًا أساسيًا. يوضّح الإجراء التالي كيفية إنشاء مجموعة ومثيل AlloyDB باستخدام Google Cloud SDK. إذا كنت تفضّل استخدام وحدة التحكّم، يمكنك اتّباع التعليمات الواردة في المستندات هنا.
قبل إنشاء مجموعة AlloyDB، نحتاج إلى نطاق عناوين IP خاصة متاح في شبكة السحابة الإلكترونية الخاصة الافتراضية (VPC) لاستخدامه في مثيل AlloyDB المستقبلي. إذا لم يكن لدينا، علينا إنشاؤه وتعيينه ليتم استخدامه من قِبل خدمات Google الداخلية، وبعد ذلك سنتمكّن من إنشاء المجموعة والمثيل.
إنشاء نطاق عناوين IP خاص
علينا ضبط إعدادات ميزة "الوصول إلى الخدمات الخاصة" في شبكة VPC الخاصة بنا من أجل AlloyDB. الافتراض هنا هو أنّ لدينا شبكة VPC "تلقائية" في المشروع وسيتم استخدامها في جميع الإجراءات.
أنشئ نطاق عناوين IP الخاصّة:
gcloud compute addresses create psa-range \
--global \
--purpose=VPC_PEERING \
--prefix-length=24 \
--description="VPC private service access" \
--network=default
أنشئ اتصالاً خاصًا باستخدام نطاق عناوين IP المخصّص:
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=psa-range \
--network=default
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-402417)$ gcloud compute addresses create psa-range \ --global \ --purpose=VPC_PEERING \ --prefix-length=24 \ --description="VPC private service access" \ --network=default Created [https://www.googleapis.com/compute/v1/projects/test-project-402417/global/addresses/psa-range]. student@cloudshell:~ (test-project-402417)$ gcloud services vpc-peerings connect \ --service=servicenetworking.googleapis.com \ --ranges=psa-range \ --network=default Operation "operations/pssn.p24-4470404856-595e209f-19b7-4669-8a71-cbd45de8ba66" finished successfully. student@cloudshell:~ (test-project-402417)$
إنشاء مجموعة AlloyDB
في هذا القسم، سننشئ مجموعة AlloyDB في المنطقة us-central1.
حدِّد كلمة مرور لمستخدم postgres. يمكنك تحديد كلمة المرور الخاصة بك أو استخدام دالة عشوائية لإنشاء كلمة مرور
export PGPASSWORD=`openssl rand -hex 12`
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-402417)$ export PGPASSWORD=`openssl rand -hex 12`
دوِّن كلمة مرور PostgreSQL لاستخدامها في المستقبل.
echo $PGPASSWORD
ستحتاج إلى كلمة المرور هذه في المستقبل للاتصال بالجهاز الظاهري بصفتك مستخدم postgres. أنصحك بتدوينه أو نسخه في مكان ما لتتمكّن من استخدامه لاحقًا.
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-402417)$ echo $PGPASSWORD bbefbfde7601985b0dee5723
إنشاء مجموعة من الفترات التجريبية المجانية
إذا لم يسبق لك استخدام AlloyDB، يمكنك إنشاء مجموعة تجريبية مجانية باتّباع الخطوات التالية:
حدِّد المنطقة واسم مجموعة AlloyDB. سنستخدم المنطقة us-central1 وalloydb-aip-01 كاسم مجموعة:
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
نفِّذ الأمر التالي لإنشاء المجموعة:
gcloud alloydb clusters create $ADBCLUSTER \
--password=$PGPASSWORD \
--network=default \
--region=$REGION \
--subscription-type=TRIAL
الناتج المتوقّع في وحدة التحكّم:
export REGION=us-central1 export ADBCLUSTER=alloydb-aip-01 gcloud alloydb clusters create $ADBCLUSTER \ --password=$PGPASSWORD \ --network=default \ --region=$REGION \ --subscription-type=TRIAL Operation ID: operation-1697655441138-6080235852277-9e7f04f5-2012fce4 Creating cluster...done.
أنشئ مثيلاً أساسيًا من AlloyDB لمجموعتك في جلسة Cloud Shell نفسها. في حال انقطاع الاتصال، عليك تحديد متغيرات بيئة اسم المنطقة واسم المجموعة مرة أخرى.
gcloud alloydb instances create $ADBCLUSTER-pr \
--instance-type=PRIMARY \
--cpu-count=8 \
--region=$REGION \
--cluster=$ADBCLUSTER
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-402417)$ gcloud alloydb instances create $ADBCLUSTER-pr \ --instance-type=PRIMARY \ --cpu-count=8 \ --region=$REGION \ --availability-type ZONAL \ --cluster=$ADBCLUSTER Operation ID: operation-1697659203545-6080315c6e8ee-391805db-25852721 Creating instance...done.
إنشاء مجموعة AlloyDB Standard
إذا لم تكن هذه هي مجموعة AlloyDB الأولى في المشروع، يمكنك المتابعة لإنشاء مجموعة عادية.
حدِّد المنطقة واسم مجموعة AlloyDB. سنستخدم المنطقة us-central1 وalloydb-aip-01 كاسم مجموعة:
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
نفِّذ الأمر التالي لإنشاء المجموعة:
gcloud alloydb clusters create $ADBCLUSTER \
--password=$PGPASSWORD \
--network=default \
--region=$REGION
الناتج المتوقّع في وحدة التحكّم:
export REGION=us-central1 export ADBCLUSTER=alloydb-aip-01 gcloud alloydb clusters create $ADBCLUSTER \ --password=$PGPASSWORD \ --network=default \ --region=$REGION Operation ID: operation-1697655441138-6080235852277-9e7f04f5-2012fce4 Creating cluster...done.
أنشئ مثيلاً أساسيًا من AlloyDB لمجموعتك في جلسة Cloud Shell نفسها. في حال انقطاع الاتصال، عليك تحديد متغيرات بيئة اسم المنطقة واسم المجموعة مرة أخرى.
gcloud alloydb instances create $ADBCLUSTER-pr \
--instance-type=PRIMARY \
--cpu-count=2 \
--region=$REGION \
--cluster=$ADBCLUSTER
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-402417)$ gcloud alloydb instances create $ADBCLUSTER-pr \ --instance-type=PRIMARY \ --cpu-count=2 \ --region=$REGION \ --availability-type ZONAL \ --cluster=$ADBCLUSTER Operation ID: operation-1697659203545-6080315c6e8ee-391805db-25852721 Creating instance...done.
5- إعداد قاعدة البيانات
علينا إنشاء قاعدة بيانات وتفعيل تكامل Vertex AI وإنشاء عناصر قاعدة البيانات واستيراد البيانات.
منح الأذونات اللازمة إلى AlloyDB
أضِف أذونات Vertex AI إلى وكيل خدمة AlloyDB.
افتح علامة تبويب أخرى في Cloud Shell باستخدام علامة "+" في أعلى الصفحة.
في علامة تبويب Cloud Shell الجديدة، نفِّذ ما يلي:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project) Your active configuration is: [cloudshell-11039] student@cloudshell:~ (test-project-001-402417)$ gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \ --role="roles/aiplatform.user" Updated IAM policy for project [test-project-001-402417]. bindings: - members: - serviceAccount:service-4470404856@gcp-sa-alloydb.iam.gserviceaccount.com role: roles/aiplatform.user - members: ... etag: BwYIEbe_Z3U= version: 1
أغلِق علامة التبويب من خلال تنفيذ الأمر "exit" في علامة التبويب:
exit
الربط بـ AlloyDB Studio
في الفصول التالية، يمكن تنفيذ جميع أوامر SQL التي تتطلّب الاتصال بقاعدة البيانات بشكل بديل في AlloyDB Studio. لتنفيذ الأمر، عليك فتح واجهة وحدة تحكّم الويب لمجموعة AlloyDB من خلال النقر على المثيل الأساسي.
بعد ذلك، انقر على AlloyDB Studio في يمين الصفحة:
اختَر قاعدة بيانات postgres ومستخدم postgres وأدخِل كلمة المرور التي دوّنتها عند إنشاء المجموعة. بعد ذلك، انقر على الزر "المصادقة".
سيؤدي ذلك إلى فتح واجهة AlloyDB Studio. لتنفيذ الأوامر في قاعدة البيانات، انقر على علامة التبويب "المحرّر 1" على اليسار.
يفتح واجهة يمكنك من خلالها تنفيذ أوامر SQL
إنشاء قاعدة بيانات
إنشاء قاعدة بيانات باستخدام التشغيل السريع
في "محرّر AlloyDB Studio"، نفِّذ الأمر التالي.
إنشاء قاعدة بيانات:
CREATE DATABASE quickstart_db
الناتج المتوقّع:
Statement executed successfully
الاتصال بقاعدة بيانات quickstart_db
أعِد الاتصال بالاستوديو باستخدام الزرّ لتبديل المستخدم أو قاعدة البيانات.
اختَر قاعدة البيانات الجديدة quickstart_db من القائمة المنسدلة واستخدِم اسم المستخدم وكلمة المرور نفسها كما كان من قبل.
سيتم فتح اتصال جديد يمكنك من خلاله العمل مع عناصر من قاعدة بيانات quickstart_db.
6. عيّنات البيانات
الآن، علينا إنشاء عناصر في قاعدة البيانات وتحميل البيانات. سنستخدم متجرًا وهميًا باسم "Cymbal" يتضمّن بيانات وهمية.
قبل استيراد البيانات، علينا تفعيل الإضافات التي تتوافق مع أنواع البيانات والفهارس. نحتاج إلى إضافةَين إحداهما تتيح نوع بيانات المتّجه والأخرى تتيح فهرس AlloyDB ScaNN.
في AlloyDB Studio، نفِّذ عملية الربط بقاعدة بيانات quickstart_db.
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
يتم إعداد مجموعة البيانات ووضعها كملف SQL يمكن تحميله إلى قاعدة البيانات باستخدام واجهة الاستيراد. في Cloud Shell، نفِّذ الأوامر التالية:
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
gcloud alloydb clusters import $ADBCLUSTER --region=$REGION --database=quickstart_db --gcs-uri='gs://sample-data-and-media/ecomm-retail/ecom_generic_vectors.sql' --user=postgres --sql
يستخدم الأمر AlloyDB SDK وينشئ مستخدمًا باسم agentspace_user، ثم يستورد بيانات نموذجية مباشرةً من حزمة GCS إلى قاعدة البيانات، ما يؤدي إلى إنشاء جميع العناصر اللازمة وإدراج البيانات.
بعد الاستيراد، يمكننا التحقّق من الجداول في AlloyDB Studio. تكون الجداول في مخطط ecomm:
وتأكَّد من عدد الصفوف في أحد الجداول.
لقد استوردنا بياناتنا النموذجية بنجاح ويمكننا مواصلة الخطوات التالية.
7. البحث الدلالي باستخدام التضمينات النصية
في هذا الفصل، سنحاول استخدام البحث الدلالي باستخدام تضمينات نصية ومقارنته بالبحث التقليدي عن النص والبحث عن النص الكامل في Postgres.
لنبدأ أولاً بالبحث الكلاسيكي باستخدام لغة SQL القياسية في PostgreSQL مع عامل التشغيل LIKE.
إذا حاولنا البحث عن معطف واقٍ من المطر باستخدام طلب البحث التالي:
SET session.my_search_var='%wet%conditions%jacket%';
SELECT
name,
product_description,
retail_price, replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url
FROM
ecomm.products
WHERE
name ILIKE current_setting('session.my_search_var')
OR product_description ILIKE current_setting('session.my_search_var')
LIMIT
10;
لا يعرض طلب البحث أي صفوف لأنّه يحتاج إلى كلمات مطابقة تمامًا، مثل "ظروف رطبة" و"سترة"، لتكون إما في اسم المنتج أو في وصفه. ولا يمكن اعتبار "سترة الطقس الرطب" هي نفسها "سترة الطقس الممطر".
يمكننا محاولة تضمين جميع الصيغ المحتملة للبحث. لنجرّب تضمين كلمتَين فقط. على سبيل المثال:
SELECT
name,
product_description,
retail_price,
replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url
FROM
ecomm.products
WHERE
name ILIKE '%wet%jacket%'
OR name ILIKE '%jacket%wet%'
OR name ILIKE '%jacket%'
OR name ILIKE '%%wet%'
OR product_description ILIKE '%wet%jacket%'
OR product_description ILIKE '%jacket%wet%'
OR product_description ILIKE '%jacket%'
OR product_description ILIKE '%wet%'
LIMIT
10;
سيؤدي ذلك إلى عرض صفوف متعددة، ولكن لن يتطابق كلّها تمامًا مع طلبنا بشأن السترات، وسيكون من الصعب ترتيبها حسب الصلة بالموضوع. على سبيل المثال، إذا أضفنا المزيد من الشروط، مثل "للرجال" وغيرها، سيزيد ذلك بشكل كبير من تعقيد طلب البحث. يمكننا بدلاً من ذلك تجربة البحث عن النص الكامل، ولكن حتى في هذه الحالة، نواجه قيودًا متعلقة بالكلمات المطابقة أو غير المطابقة ومدى صلة الردّ بطلب البحث.
يمكننا الآن إجراء بحث مشابه باستخدام التضمينات. لقد سبق أن حسبنا التضمينات مسبقًا لمنتجاتنا باستخدام نماذج مختلفة. سنستخدم أحدث نموذج من Google، وهو gemini-embedding-001. لقد خزّنّاها في العمود product_embedding من الجدول ecomm.products. إذا نفّذنا طلب بحث لشرط البحث "سترة مطر للرجال" باستخدام طلب البحث التالي:
SELECT
name,
product_description,
retail_price,
replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
product_embedding <=> embedding ('gemini-embedding-001','wet conditions jacket for men')::vector AS distance
FROM
ecomm.products
ORDER BY distance
LIMIT
10;
لن يعرض هذا الطلب السترات المخصّصة للطقس الرطب فقط، بل سيتم أيضًا ترتيب جميع النتائج بحيث تظهر النتائج الأكثر صلة في الأعلى.
يعرض طلب البحث الذي يتضمّن تضمينات نتائج في غضون 90 إلى 150 ملي ثانية، ويتم استغراق جزء من هذا الوقت للحصول على البيانات من نموذج التضمين المستند إلى السحابة الإلكترونية. إذا نظرنا إلى خطة التنفيذ، سيتم تضمين الطلب المقدَّم إلى النموذج في وقت التخطيط. إنّ جزء طلب البحث الذي يجري البحث نفسه قصير جدًا. يستغرق البحث في 29 ألف سجل باستخدام فهرس ScaNN في AlloyDB أقل من 7 ملي ثانية.
Limit (cost=2709.20..2718.82 rows=10 width=490) (actual time=6.966..7.049 rows=10 loops=1)
-> Index Scan using embedding_scann on products (cost=2709.20..30736.40 rows=29120 width=490) (actual time=6.964..7.046 rows=10 loops=1)
Order By: (product_embedding <=> '[-0.0020264734,-0.016582033,0.027258193
...
-0.0051468653,-0.012440448]'::vector)
Limit: 10
Planning Time: 136.579 ms
Execution Time: 6.791 ms
(6 rows)
كان هذا البحث عن تضمين النص باستخدام نموذج التضمين النصي فقط. ولكن لدينا أيضًا صور لمنتجاتنا ويمكننا استخدامها مع البحث. في الفصل التالي، سنوضّح كيف يستخدم النموذج المتعدّد الوسائط الصور للبحث.
8. استخدام ميزة "البحث المتعدّد الوسائط"
على الرغم من أنّ البحث الدلالي المستند إلى النصوص مفيد، إلا أنّ وصف التفاصيل المعقّدة قد يكون صعبًا. توفّر ميزة البحث المتعدّد الوسائط في AlloyDB ميزة إضافية من خلال إتاحة العثور على المنتجات من خلال إدخال الصور. ويكون ذلك مفيدًا بشكل خاص عندما يوضّح التمثيل المرئي نية البحث بفعالية أكبر من الأوصاف النصية وحدها. على سبيل المثال، "أريد معطفًا مشابهًا لهذا المعطف في الصورة".
لنعد إلى مثال السترة. إذا كانت لديّ صورة لسترة مشابهة لما أريد العثور عليه، يمكنني إرسالها إلى نموذج التضمين المتعدّد الوسائط من Google ومقارنتها بعمليات التضمين لصور منتجاتي. في جدولنا، حسبنا مسبقًا التضمينات لصور منتجاتنا في العمود product_image_embedding، ويمكنك الاطّلاع على النموذج المستخدَم في العمود product_image_embedding_model.
بالنسبة إلى عملية البحث، يمكننا استخدام الدالة image_embedding للحصول على التضمين الخاص بالصورة ومقارنته بعمليات التضمين التي تم احتسابها مسبقًا. لتفعيل هذه الوظيفة، يجب التأكّد من استخدام الإصدار الصحيح من إضافة google_ml_integration.
لنثبت صحة إصدار الإضافة الحالي. في AlloyDB Studio، نفِّذ ما يلي:
SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
إذا كان الإصدار أقل من 1.4.4، عليك تنفيذ الإجراء التالي.
CALL google_ml.upgrade_to_preview_version();
وأعِد التحقّق من إصدار الإضافة. يجب أن يكون 1.4.4.
في ما يلي صورة نموذجية للبحث، ولكن يمكنك استخدام أي صورة مخصّصة. ما عليك سوى تحميله إلى مساحة التخزين في Google أو أي مصدر آخر متاح للجميع ووضع معرّف الموارد المنتظم (URI) في طلب البحث.
ويتم تحميلها إلى gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png
البحث بالصور
أولاً، نحاول البحث باستخدام الصورة فقط:
SELECT
name,
product_description,
retail_price,
replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
product_image_embedding <=> google_ml.image_embedding (model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector AS distance
FROM
ecomm.products
ORDER BY distance
LIMIT
4;
وتمكّنا من العثور على بعض السترات الشتوية في المستودع.
يعرض لنا البحث عن الصور عناصر تشبه الصورة التي قدّمناها للمقارنة. كما ذكرتُ سابقًا، يمكنك محاولة تحميل صورك إلى حزمة متاحة للجميع ومعرفة ما إذا كان بإمكانها العثور على أنواع مختلفة من الملابس.
استخدمنا نموذج "multimodalembedding@001" من Google للبحث عن الصور. ترسل الدالة image_embedding الصورة إلى Vertex AI، وتحوّلها إلى متّجه، ثم تعيدها للمقارنة مع المتّجهات المخزّنة للصور في قاعدة البيانات.
يمكننا أيضًا التحقّق باستخدام "EXPLAIN ANALYZE" من سرعة عملها مع فهرس AlloyDB ScaNN.
Limit (cost=971.70..975.55 rows=4 width=490) (actual time=2.453..2.477 rows=4 loops=1)
-> Index Scan using product_image_embedding_scann on products (cost=971.70..28998.90 rows=29120 width=490) (actual time=2.451..2.475 rows=4 loops=1)
Order By: (product_image_embedding <=> '[0.02119865,0.034206174,0.030682731,
...
,-0.010307034,-0.010053742]'::vector)
Limit: 4
Planning Time: 913.322 ms
Execution Time: 2.517 ms
(6 rows)
وكما هو الحال في المثال السابق، نلاحظ أنّ معظم الوقت تم استخدامه لتحويل الصورة إلى تضمينات باستخدام نقطة النهاية السحابية، وأنّ البحث المتّجه نفسه يستغرق 2.5 ملي ثانية فقط.
البحث بالصور باستخدام النص
باستخدام البحث المتعدد الوسائط، يمكننا أيضًا تمرير وصف نصي للسترة التي نحاول البحث عنها إلى النموذج باستخدام google_ml.text_embedding للنموذج نفسه ومقارنتها بتضمينات الصور لمعرفة الصور التي يعرضها.
SELECT
name,
product_description,
retail_price,
replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
product_image_embedding <=> google_ml.text_embedding (model_id => 'multimodalembedding@001',content => 'puffy jacket for men, grey or dark colour')::vector AS distance
FROM
ecomm.products
ORDER BY distance
LIMIT
4;
وحصلنا على مجموعة من السترات المنتفخة بألوان رمادية أو داكنة.
لقد حصلنا على مجموعة مختلفة قليلاً من السترات، ولكن تم اختيار السترات بشكل صحيح استنادًا إلى الوصف الذي قدّمناه والبحث في تضمينات الصور.
لنجرّب طريقة أخرى للبحث بين الأوصاف باستخدام التضمين الخاص بصورة البحث.
البحث النصي باستخدام الصور
حاولنا البحث عن صور من خلال تمرير التضمين الخاص بصورتنا ومقارنته بتضمينات الصور المحسوبة مسبقًا لمنتجاتنا. جرّبنا أيضًا البحث عن الصور من خلال تمرير التضمين لطلب النص والبحث بين التضمين نفسه عن صور المنتجات. لنحاول الآن استخدام التضمين لصورنا ومقارنته بعمليات تضمين النصوص الخاصة بأوصاف المنتجات. يتم تخزين التضمين في العمود product_description_embedding ويستخدم النموذج نفسه multimodalembedding@001.
إليك طلب البحث:
SELECT
name,
product_description,
retail_price,
replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
product_description_embedding <=> google_ml.image_embedding (model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector AS distance
FROM
ecomm.products
ORDER BY distance
LIMIT
4;
وهنا حصلنا على مجموعة مختلفة قليلاً من السترات ذات الألوان الرمادية أو الداكنة، بعضها مطابق أو قريب جدًا من السترات التي تم اختيارها بطريقة بحث مختلفة.
ويعرض السترات نفسها الواردة أعلاه بترتيب مختلف قليلاً. استنادًا إلى عملية التضمين التي نجريها للصور، يمكن مقارنتها بعمليات التضمين المحسوبة للوصف النصي وعرض المجموعة الصحيحة من المنتجات.
البحث المختلط عن النصوص والصور
يمكنك أيضًا تجربة الجمع بين تضمينات النص والصور معًا باستخدام دمج الترتيب المتبادل مثلاً. في ما يلي مثال على طلب بحث من هذا النوع، حيث جمعنا بين بحثَين مع تحديد درجة لكل ترتيب وترتيب النتائج استنادًا إلى الدرجة المجمَّعة.
WITH image_search AS (
SELECT id,
RANK () OVER (ORDER BY product_image_embedding <=>google_ml.image_embedding(model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector) AS rank
FROM ecomm.products
ORDER BY product_image_embedding <=>google_ml.image_embedding(model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector LIMIT 5
),
text_search AS (
SELECT id,
RANK () OVER (ORDER BY product_description_embedding <=>google_ml.text_embedding(model_id => 'multimodalembedding@001',content => 'puffy jacket for men, grey or dark colour'
)::vector) AS rank
FROM ecomm.products
ORDER BY product_description_embedding <=>google_ml.text_embedding(model_id => 'multimodalembedding@001',content => 'puffy jacket for men, grey or dark colour'
)::vector LIMIT 5
),
rrf_score AS (
SELECT
COALESCE(image_search.id, text_search.id) AS id,
COALESCE(1.0 / (60 + image_search.rank), 0.0) + COALESCE(1.0 / (60 + text_search.rank), 0.0) AS rrf_score
FROM image_search FULL OUTER JOIN text_search ON image_search.id = text_search.id
ORDER BY rrf_score DESC
)
SELECT
ep.name,
ep.product_description,
ep.retail_price,
replace(ep.product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url
FROM ecomm.products ep, rrf_score
WHERE
ep.id=rrf_score.id
ORDER by rrf_score DESC
LIMIT 4;
يمكنك محاولة استخدام معلَمات مختلفة في طلب البحث ومعرفة ما إذا كان ذلك سيحسّن نتائج البحث.
بهذا نكون قد أنهينا المختبر، ويُنصح بحذف الموارد غير المستخدَمة لتجنُّب الرسوم غير المتوقّعة.
بالإضافة إلى ذلك، يمكنك استخدام عوامل تشغيل أخرى للذكاء الاصطناعي لترتيب النتائج كما هو موضّح في المستندات.
9- تنظيف البيئة
تدمير آلات AlloyDB الافتراضية والمجموعة عند الانتهاء من الدرس التطبيقي
حذف مجموعة AlloyDB وجميع مثيلاتها
يتم تدمير المجموعة باستخدام الخيار force الذي يؤدي أيضًا إلى حذف جميع المثيلات التابعة للمجموعة.
في Cloud Shell، حدِّد متغيرات المشروع والبيئة إذا تم قطع الاتصال وفقدت جميع الإعدادات السابقة:
gcloud config set project <your project id>
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
export PROJECT_ID=$(gcloud config get-value project)
احذف المجموعة:
gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-001-402417)$ gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force All of the cluster data will be lost when the cluster is deleted. Do you want to continue (Y/n)? Y Operation ID: operation-1697820178429-6082890a0b570-4a72f7e4-4c5df36f Deleting cluster...done.
حذف نُسخ AlloyDB الاحتياطية
احذف جميع نُسخ AlloyDB الاحتياطية للمجموعة:
for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-001-402417)$ for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done Operation ID: operation-1697826266108-60829fb7b5258-7f99dc0b-99f3c35f Deleting backup...done.
10. تهانينا
تهانينا على إكمال هذا الدرس العملي. لقد تعلّمت كيفية استخدام البحث المتعدّد الوسائط في AlloyDB باستخدام دوال التضمين للنصوص والصور. يمكنك محاولة اختبار البحث المتعدّد الوسائط وتحسينه باستخدام الدالة google_ml.rank من خلال الدرس التطبيقي حول مشغّلي AlloyDB AI.
المواضيع التي تناولناها
- كيفية نشر AlloyDB for Postgres
- كيفية استخدام البحث المتعدّد الوسائط المستند إلى المتجهات
- كيفية تفعيل مشغّلي AlloyDB AI
- كيفية استخدام عوامل تشغيل مختلفة في AlloyDB AI للبحث المتعدّد الوسائط
- كيفية استخدام AlloyDB AI لدمج نتائج البحث النصية والمرئية
11. استطلاع
إخراج: