1. บทนำ
Codelab นี้มีคำแนะนำในการติดตั้งใช้งาน AlloyDB และใช้ประโยชน์จากการผสานรวม AI สำหรับการค้นหาเชิงความหมายโดยใช้การฝังแบบหลายมิติ ห้องทดลองนี้เป็นส่วนหนึ่งของคอลเล็กชันห้องทดลองที่มุ่งเน้นฟีเจอร์ AlloyDB AI ดูข้อมูลเพิ่มเติมได้ที่หน้า AlloyDB AI ในเอกสารประกอบ
ข้อกำหนดเบื้องต้น
- ความเข้าใจพื้นฐานเกี่ยวกับ Google Cloud และคอนโซล
- ทักษะพื้นฐานในอินเทอร์เฟซบรรทัดคำสั่งและ Cloud Shell
สิ่งที่คุณจะได้เรียนรู้
- วิธีติดตั้งใช้งาน AlloyDB for Postgres
- วิธีใช้การค้นหาเวกเตอร์แบบหลายมิติ
- วิธีเปิดใช้ตัวดำเนินการ AlloyDB AI
- วิธีใช้โอเปอเรเตอร์ AlloyDB AI ที่แตกต่างกันสำหรับการค้นหาแบบมัลติโมดัล
- วิธีใช้ AlloyDB AI เพื่อรวมผลการค้นหาข้อความและรูปภาพ
สิ่งที่คุณต้องมี
- บัญชี Google Cloud และโปรเจ็กต์ Google Cloud
- เว็บเบราว์เซอร์ เช่น Chrome ที่รองรับ Google Cloud Console และ Cloud Shell
2. การตั้งค่าและข้อกำหนด
การตั้งค่าสภาพแวดล้อมแบบเรียนรู้ด้วยตนเอง
- ลงชื่อเข้าใช้ Google Cloud Console แล้วสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี
- ชื่อโปรเจ็กต์คือชื่อที่แสดงสำหรับผู้เข้าร่วมโปรเจ็กต์นี้ ซึ่งเป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ คุณอัปเดตได้ทุกเมื่อ
- รหัสโปรเจ็กต์จะไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมดและเปลี่ยนแปลงไม่ได้ (เปลี่ยนไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ซึ่งโดยปกติแล้วคุณไม่จำเป็นต้องสนใจว่าสตริงนั้นคืออะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยปกติจะระบุเป็น
PROJECT_ID
) หากไม่ชอบรหัสที่สร้างขึ้น คุณอาจสร้างรหัสแบบสุ่มอีกรหัสหนึ่งได้ หรือคุณอาจลองใช้ชื่อของคุณเองและดูว่ามีชื่อนั้นหรือไม่ คุณจะเปลี่ยนแปลงรหัสนี้หลังจากขั้นตอนนี้ไม่ได้ และรหัสจะคงอยู่ตลอดระยะเวลาของโปรเจ็กต์ - โปรดทราบว่ายังมีค่าที่ 3 ซึ่งคือหมายเลขโปรเจ็กต์ที่ API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 นี้ได้ในเอกสารประกอบ
- จากนั้นคุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของ Cloud การทำตาม Codelab นี้จะไม่เสียค่าใช้จ่ายมากนัก หรืออาจไม่เสียเลย หากต้องการปิดทรัพยากรเพื่อหลีกเลี่ยงการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่สร้างขึ้นหรือลบโปรเจ็กต์ได้ ผู้ใช้ Google Cloud รายใหม่มีสิทธิ์เข้าร่วมโปรแกรมช่วงทดลองใช้ฟรีมูลค่า$300 USD
เริ่มต้น Cloud Shell
แม้ว่าคุณจะใช้งาน Google Cloud จากระยะไกลจากแล็ปท็อปได้ แต่ใน Codelab นี้คุณจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์
จาก Google Cloud Console ให้คลิกไอคอน Cloud Shell ในแถบเครื่องมือด้านขวาบน
การจัดสรรและเชื่อมต่อกับสภาพแวดล้อมจะใช้เวลาเพียงไม่กี่นาที เมื่อเสร็จแล้ว คุณควรเห็นข้อความคล้ายกับตัวอย่างนี้
เครื่องเสมือนนี้มาพร้อมเครื่องมือพัฒนาทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักแบบถาวรขนาด 5 GB และทำงานบน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก คุณสามารถทำงานทั้งหมดในโค้ดแล็บนี้ได้ภายในเบราว์เซอร์ คุณไม่จำเป็นต้องติดตั้งอะไร
3. ก่อนเริ่มต้น
เปิดใช้ API
ใน 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
หากไม่ใช่คลัสเตอร์ 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 ให้กับ Agent บริการ 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 หากต้องการเรียกใช้คำสั่งในฐานข้อมูล ให้คลิกแท็บ "Editor 1" ทางด้านขวา
ซึ่งจะเปิดอินเทอร์เฟซที่คุณสามารถเรียกใช้คำสั่ง SQL ได้
สร้างฐานข้อมูล
เริ่มต้นใช้งานด่วนในการสร้างฐานข้อมูล
เรียกใช้คำสั่งต่อไปนี้ในโปรแกรมแก้ไข AlloyDB Studio
สร้างฐานข้อมูล
CREATE DATABASE quickstart_db
ผลลัพธ์ที่คาดหวัง
Statement executed successfully
เชื่อมต่อกับ quickstart_db
เชื่อมต่อกับสตูดิโออีกครั้งโดยใช้ปุ่มเพื่อเปลี่ยนผู้ใช้/ฐานข้อมูล
เลือกฐานข้อมูล quickstart_db ใหม่จากรายการแบบเลื่อนลง แล้วใช้ผู้ใช้และรหัสผ่านเดิม
ซึ่งจะเปิดการเชื่อมต่อใหม่ที่คุณสามารถทำงานกับออบเจ็กต์จากฐานข้อมูล quickstart_db ได้
6. ข้อมูลตัวอย่าง
ตอนนี้เราต้องสร้างออบเจ็กต์ในฐานข้อมูลและโหลดข้อมูล เราจะใช้ร้านค้า "Cymbal" สมมติที่มีข้อมูลสมมติ
ก่อนนำเข้าข้อมูล เราต้องเปิดใช้ส่วนขยายที่รองรับประเภทข้อมูลและดัชนี เราต้องการส่วนขยาย 2 รายการ โดยรายการหนึ่งรองรับประเภทข้อมูลเวกเตอร์ และอีกรายการรองรับดัชนี 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;
คำค้นหาจะไม่แสดงแถวใดๆ เนื่องจากต้องมีคำที่ตรงกันทุกประการ เช่น สภาพอากาศเปียกและเสื้อแจ็กเก็ตอยู่ในชื่อผลิตภัณฑ์หรือคำอธิบาย และ "เสื้อแจ็กเก็ตสำหรับสภาพอากาศเปียก" ไม่เหมือนกับ "เสื้อแจ็กเก็ตสำหรับสภาพอากาศฝนตก"
เราจะพยายามรวมรูปแบบที่เป็นไปได้ทั้งหมดในการค้นหา ลองใส่คำเพียง 2 คำ เช่น
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;
ซึ่งจะแสดงผลหลายแถว แต่ไม่ใช่ทั้งหมดที่ตรงกับคำขอเสื้อแจ็กเก็ตของเราอย่างสมบูรณ์ และจัดเรียงตามความเกี่ยวข้องได้ยาก และหากเราเพิ่มเงื่อนไขอื่นๆ เช่น "สำหรับผู้ชาย" และอื่นๆ ความซับซ้อนของคําค้นหาจะเพิ่มขึ้นอย่างมาก หรือเราอาจลองค้นหาข้อความแบบเต็ม แต่ก็ยังคงมีข้อจำกัดที่เกี่ยวข้องกับคำที่ตรงกันมากหรือน้อยและความเกี่ยวข้องของการตอบกลับ
ตอนนี้เราสามารถทำการค้นหาที่คล้ายกันโดยใช้การฝังได้แล้ว เราได้คำนวณการฝังล่วงหน้าสำหรับผลิตภัณฑ์ของเราโดยใช้โมเดลต่างๆ แล้ว เราจะใช้โมเดล gemini-embedding-001 ล่าสุดของ Google เราได้จัดเก็บไว้ในคอลัมน์ "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 มิลลิวินาที โดยใช้เวลาส่วนหนึ่งในการรับข้อมูลจากโมเดลการฝังในระบบคลาวด์ หากเราดูที่แผนการดำเนินการ คำขอไปยังโมเดลจะรวมอยู่ในเวลาการวางแผน ส่วนของคำค้นหาที่ทำการค้นหาเองนั้นค่อนข้างสั้น ใช้เวลาไม่ถึง 7 มิลลิวินาทีในการค้นหาในระเบียน 29,000 รายการโดยใช้ดัชนี ScaNN ของ AlloyDB
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" ว่าดัชนี ScaNN ของ AlloyDB ทำงานได้เร็วเพียงใด
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)
และอีกครั้งเช่นเดียวกับในตัวอย่างก่อนหน้า เราจะเห็นว่าเวลาส่วนใหญ่ใช้ในการแปลงรูปภาพเป็น Embedding โดยใช้ปลายทางระบบคลาวด์ และการค้นหาเวกเตอร์เองใช้เวลาเพียง 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;
และที่นี่เราได้ชุดเสื้อแจ็กเก็ตที่แตกต่างกันเล็กน้อยซึ่งมีสีเทาหรือสีเข้ม โดยบางตัวเหมือนกันหรือใกล้เคียงกับตัวที่เลือกไว้จากการค้นหาด้วยวิธีต่างๆ
และจะแสดงผลเสื้อแจ็กเก็ตแบบเดียวกับด้านบนแต่เรียงลำดับต่างกันเล็กน้อย การฝังรูปภาพช่วยให้ระบบเปรียบเทียบกับการฝังที่คำนวณแล้วสำหรับคำอธิบายข้อความและแสดงชุดผลิตภัณฑ์ที่ถูกต้องได้
การค้นหาแบบผสมระหว่างข้อความและรูปภาพ
นอกจากนี้ คุณยังทดลองรวมการฝังข้อความและรูปภาพเข้าด้วยกันได้ด้วย เช่น การใช้การผสานอันดับซึ่งกันและกัน ต่อไปนี้คือตัวอย่างคำค้นหาดังกล่าว ซึ่งเราได้รวมการค้นหา 2 รายการเข้าด้วยกันโดยกำหนดคะแนนให้กับแต่ละอันดับและจัดเรียงผลลัพธ์ตามคะแนนรวม
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;
คุณลองเล่นกับพารามิเตอร์ต่างๆ ในคำค้นหาและดูว่าช่วยปรับปรุงผลการค้นหาได้หรือไม่
ซึ่งจะเป็นการสิ้นสุดแล็บ และขอแนะนำให้ลบทรัพยากรที่ไม่ได้ใช้เพื่อป้องกันการเรียกเก็บเงินที่ไม่คาดคิด
นอกจากนี้ คุณยังใช้ตัวดำเนินการ AI อื่นๆ เพื่อจัดอันดับผลลัพธ์ได้ตามที่อธิบายไว้ในเอกสารประกอบ
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. ขอแสดงความยินดี
ขอแสดงความยินดีที่ทำ Codelab นี้เสร็จสมบูรณ์ คุณได้เรียนรู้วิธีใช้การค้นหาแบบมัลติโมดอลใน AlloyDB โดยใช้ฟังก์ชันการฝังสำหรับข้อความและรูปภาพแล้ว คุณสามารถลองทดสอบการค้นหาแบบมัลติโมดัลและปรับปรุงด้วยฟังก์ชัน google_ml.rank โดยใช้ Codelab สำหรับตัวดำเนินการ AlloyDB AI
สิ่งที่เราได้พูดถึง
- วิธีติดตั้งใช้งาน AlloyDB for Postgres
- วิธีใช้การค้นหาเวกเตอร์แบบหลายมิติ
- วิธีเปิดใช้ตัวดำเนินการ AlloyDB AI
- วิธีใช้โอเปอเรเตอร์ AlloyDB AI ที่แตกต่างกันสำหรับการค้นหาแบบมัลติโมดัล
- วิธีใช้ AlloyDB AI เพื่อรวมผลการค้นหาข้อความและรูปภาพ
11. แบบสำรวจ
เอาต์พุต: