เริ่มต้นใช้งานการค้นหาเวกเตอร์ของ Spanner

เริ่มต้นใช้งานการค้นหาเวกเตอร์ของ Spanner

เกี่ยวกับ Codelab นี้

subjectอัปเดตล่าสุดเมื่อ มิ.ย. 5, 2025
account_circleเขียนโดย Derek Downey, Rose Liu, Chow Lin

1 บทนำ

Spanner เป็นบริการฐานข้อมูลที่รองรับการปรับขนาดในแนวนอนและมีการจัดการครบวงจรซึ่งจัดจำหน่ายทั่วโลก เหมาะสำหรับทั้งภาระงานเชิงสัมพันธ์และไม่ใช่เชิงสัมพันธ์

Spanner รองรับการค้นหาเวกเตอร์ในตัว ซึ่งช่วยให้คุณทำการค้นหาแบบคล้ายกันหรือแบบเชิงความหมาย และใช้การสร้างแบบเพิ่มประสิทธิภาพการดึงข้อมูล (RAG) ในแอปพลิเคชัน GenAI ได้ในวงกว้าง โดยใช้ฟีเจอร์ K-Nearest Neighbor ที่ตรงกันทั้งหมด (KNN) หรือ Nearest Neighbor แบบใกล้เคียง (ANN)

การค้นหาเวกเตอร์ของ Spanner จะแสดงข้อมูลแบบเรียลไทม์ที่อัปเดตใหม่ทันทีที่ธุรกรรมได้รับการยืนยัน เช่นเดียวกับการค้นหาอื่นๆ ในข้อมูลการดำเนินการ

ในโปรแกรม Lab นี้ คุณจะได้ดูการตั้งค่าฟีเจอร์พื้นฐานที่จําเป็นต่อการใช้ Spanner เพื่อทําการค้นหาเวกเตอร์ รวมถึงเข้าถึงการฝังและโมเดล LLM จากสวนโมเดลของ VertexAI โดยใช้ SQL

สถาปัตยกรรมจะมีลักษณะดังนี้

d179a760add7adc0.png

เมื่อทราบพื้นฐานแล้ว คุณจะได้เรียนรู้วิธีสร้างดัชนีเวกเตอร์ที่รองรับโดยอัลกอริทึม SCANN และใช้ฟังก์ชันระยะทาง APPROX เมื่อต้องปรับขนาดเวิร์กโหลดเชิงความหมาย

สิ่งที่คุณจะสร้าง

ในส่วนนี้ คุณจะได้ทําสิ่งต่อไปนี้

  • สร้างอินสแตนซ์ Spanner
  • ตั้งค่าสคีมาฐานข้อมูลของ Spanner เพื่อผสานรวมกับโมเดลการฝังและ LLM ใน VertexAI
  • โหลดชุดข้อมูลค้าปลีก
  • ออกคําค้นหาที่คล้ายกันกับชุดข้อมูล
  • ระบุบริบทให้กับโมเดล LLM เพื่อสร้างคําแนะนําเฉพาะผลิตภัณฑ์
  • แก้ไขสคีมาและสร้างดัชนีเวกเตอร์
  • เปลี่ยนการค้นหาเพื่อใช้ประโยชน์จากดัชนีเวกเตอร์ที่สร้างขึ้นใหม่

สิ่งที่คุณจะได้เรียนรู้

  • วิธีตั้งค่าอินสแตนซ์ Spanner
  • วิธีผสานรวมกับ VertexAI
  • วิธีใช้ Spanner เพื่อทำการค้นหาเวกเตอร์เพื่อค้นหารายการที่คล้ายกันในชุดข้อมูลค้าปลีก
  • วิธีเตรียมฐานข้อมูลเพื่อปรับขนาดปริมาณงานการค้นหาเวกเตอร์โดยใช้การค้นหา ANN

สิ่งที่คุณต้องมี

  • โปรเจ็กต์ Google Cloud ที่เชื่อมต่อกับบัญชีสำหรับการเรียกเก็บเงิน
  • เว็บเบราว์เซอร์ เช่น Chrome หรือ Firefox

2 การตั้งค่าและข้อกำหนด

สร้างโปรเจ็กต์

หากยังไม่มีบัญชี Google (Gmail หรือ Google Apps) คุณต้องสร้างบัญชี ลงชื่อเข้าใช้คอนโซล Google Cloud Platform ( console.cloud.google.com) และสร้างโปรเจ็กต์ใหม่

หากคุณมีโปรเจ็กต์อยู่แล้ว ให้คลิกเมนูแบบเลื่อนลงเพื่อเลือกโปรเจ็กต์ที่ด้านซ้ายบนของคอนโซล

6c9406d9b014760.png

และคลิกปุ่ม "โปรเจ็กต์ใหม่" ในกล่องโต้ตอบที่ปรากฏขึ้นเพื่อสร้างโปรเจ็กต์ใหม่

949d83c8a4ee17d9.png

หากยังไม่มีโปรเจ็กต์ คุณควรเห็นกล่องโต้ตอบเช่นนี้เพื่อสร้างโปรเจ็กต์แรก

870a3cbd6541ee86.png

กล่องโต้ตอบการสร้างโปรเจ็กต์ที่ตามมาจะช่วยให้คุณป้อนรายละเอียดของโปรเจ็กต์ใหม่ได้ ดังนี้

6a92c57d3250a4b3.png

โปรดจดจำรหัสโปรเจ็กต์ ซึ่งเป็นชื่อที่ไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมด (ชื่อด้านบนมีผู้ใช้แล้วและจะใช้ไม่ได้ ขออภัย) ซึ่งจะเรียกในภายหลังในโค้ดแล็บนี้ว่า PROJECT_ID

ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินในคอนโซลนักพัฒนาซอฟต์แวร์เพื่อใช้ทรัพยากร Google Cloud และเปิดใช้ Spanner API หากยังไม่ได้ดำเนินการ

15d0ef27a8fbab27.png

ค่าใช้จ่ายในการเรียกใช้ Codelab นี้ไม่ควรเกิน 200 บาท แต่อาจมากกว่านั้นหากคุณตัดสินใจใช้ทรัพยากรเพิ่มเติมหรือปล่อยไว้ให้ทำงาน (ดูส่วน "ล้างข้อมูล" ที่ท้ายเอกสารนี้) ดูข้อมูลราคาของ Google Cloud Spanner ได้ที่นี่

ผู้ใช้ใหม่ของ Google Cloud Platform มีสิทธิ์ทดลองใช้ฟรีมูลค่า$300 ซึ่งจะทำให้โค้ดแล็บนี้ไม่มีค่าใช้จ่ายใดๆ ทั้งสิ้น

การตั้งค่า Google Cloud Shell

แม้ว่า Google Cloud และ Spanner จะทำงานจากระยะไกลจากแล็ปท็อปได้ แต่ในโค้ดแล็บนี้ เราจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์

เครื่องเสมือนที่ใช้ Debian นี้โหลดเครื่องมือการพัฒนาทั้งหมดที่คุณต้องการแล้ว ซึ่งจะมีไดเรกทอรีหลักขนาด 5 GB ถาวรและทำงานใน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพเครือข่ายและการรับรองได้อย่างมีประสิทธิภาพ ซึ่งหมายความว่าสิ่งที่คุณต้องใช้สำหรับโค้ดแล็บนี้ก็มีแค่เบราว์เซอร์ (ใช่ โค้ดแล็บนี้ใช้ได้ใน Chromebook)

  1. หากต้องการเปิดใช้งาน Cloud Shell จาก Cloud Console เพียงคลิกเปิดใช้งาน Cloud Shell gcLMt5IuEcJJNnMId-Bcz3sxCd0rZn7IzT_r95C8UZeqML68Y1efBG_B0VRp7hc7qiZTLAF-TXD7SsOadxn8uadgHhaLeASnVS3ZHK39eOlKJOgj9SJua_oeGhMxRrbOg3qigddS2A (ระบบจะใช้เวลาเพียงไม่กี่นาทีในการเตรียมการและเชื่อมต่อกับสภาพแวดล้อม)

JjEuRXGg0AYYIY6QZ8d-66gx_Mtc-_jDE9ijmbXLJSAXFvJt-qUpNtsBsYjNpv2W6BQSrDc1D-ARINNQ-1EkwUhz-iUK-FUCZhJ-NtjvIEx9pIkE-246DomWuCfiGHK78DgoeWkHRw

Screen Shot 2017-06-14 at 10.13.43 PM.png

เมื่อเชื่อมต่อกับ Cloud Shell แล้ว คุณควรจะเห็นการรับรองความถูกต้องและโปรเจ็กต์ตั้งค่าเป็น PROJECT_ID ของคุณแล้ว

gcloud auth list

เอาต์พุตจากคำสั่ง

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

เอาต์พุตจากคำสั่ง

[core]
project = <PROJECT_ID>

หากไม่ได้ตั้งค่าโปรเจ็กต์ไว้ด้วยเหตุผลใดก็ตาม ให้ใช้คําสั่งต่อไปนี้

gcloud config set project <PROJECT_ID>

หากกำลังมองหา PROJECT_ID ตรวจสอบรหัสที่คุณใช้ในขั้นตอนการตั้งค่าหรือค้นหาในแดชบอร์ดของ Cloud Console

158fNPfwSxsFqz9YbtJVZes8viTS3d1bV4CVhij3XPxuzVFOtTObnwsphlm6lYGmgdMFwBJtc-FaLrZU7XHAg_ZYoCrgombMRR3h-eolLPcvO351c5iBv506B3ZwghZoiRg6cz23Qw

นอกจากนี้ Cloud Shell ยังตั้งค่าตัวแปรสภาพแวดล้อมบางอย่างโดยค่าเริ่มต้น ซึ่งอาจมีประโยชน์เมื่อคุณเรียกใช้คําสั่งในอนาคต

echo $GOOGLE_CLOUD_PROJECT

เอาต์พุตจากคำสั่ง

<PROJECT_ID>

เปิดใช้ Spanner API และ VertexAI API

gcloud services enable spanner.googleapis.com
gcloud services enable aiplatform
.googleapis.com

ตรวจสอบนโยบาย IAM

สิ่งเดียวที่จำเป็นในนโยบาย IAM เพื่อให้การค้นหาเวกเตอร์ทำงานในอินสแตนซ์ Spanner คือการมอบสิทธิ์ service-<PROJECT_NUMBER>@gcp-sa-spanner.iam.gserviceaccount.com เป็นตัวแทนบริการ Cloud Spanner API คลิกไอคอนแถบ 3 แถบที่มุมซ้ายบนดังภาพด้านล่าง

4ee603eabf02695d.png

คุณจะเห็นนโยบาย IAM ในส่วนนี้

9ffe38da6fcd7a72.png

คุณตรวจสอบการตั้งค่า IAM ในส่วนสิทธิ์ได้ดังด้านล่าง

17c283eb06a6bd58.png

และหากไม่มี Cloud Spanner API Service Agent ให้ใช้คำสั่งด้านล่างเพื่อมอบสิทธิ์ ดูวิธีการเพิ่มเติมได้ที่นี่

$ gcloud beta services identity create --service=spanner.googleapis.com --project=<PROJECT_ID>
$
gcloud projects add-iam-policy-binding <PROJECT_NUMBER>  --member=serviceAccount:service-<PROJECT_NUMBER>@gcp-sa-spanner.iam.gserviceaccount.com  --role=roles/spanner.serviceAgent --condition=None

สรุป

ในขั้นตอนนี้ คุณได้ตั้งค่าโปรเจ็กต์ (หากยังไม่มี) เปิดใช้งาน Cloud Shell และเปิดใช้ API ที่จำเป็นแล้ว

ถัดไป

ถัดไป คุณจะต้องตั้งค่าอินสแตนซ์และฐานข้อมูล Spanner

3 สร้างอินสแตนซ์และฐานข้อมูล Spanner

สร้างอินสแตนซ์ Spanner

ในขั้นตอนนี้ เราจะตั้งค่าอินสแตนซ์ Spanner สําหรับ Codelab โดยเปิด Cloud Shell แล้วเรียกใช้คำสั่งนี้

export SPANNER_INSTANCE_ID=retail-demo
gcloud spanner instances create $SPANNER_INSTANCE_ID \
--edition=ENTERPRISE \
--config=regional-us-central1 \
--description="spanner AI retail demo" \
--nodes=1

ฉบับต่ำสุดควรเป็น ENTERPRISE รุ่น STANDARD ไม่มีความสามารถในการค้นหาเวกเตอร์

เอาต์พุตจากคำสั่ง:

$ Creating instance...done.  

สร้างฐานข้อมูล

เมื่ออินสแตนซ์ทํางานแล้ว คุณก็สร้างฐานข้อมูลได้ Spanner รองรับฐานข้อมูลหลายรายการในอินสแตนซ์เดียว

ฐานข้อมูลคือที่ที่คุณกําหนดสคีมา นอกจากนี้ คุณยังควบคุมผู้ที่มีสิทธิ์เข้าถึงฐานข้อมูล ตั้งค่าการเข้ารหัสที่กำหนดเอง กำหนดค่าเครื่องมือเพิ่มประสิทธิภาพ และกำหนดระยะเวลาการเก็บรักษาได้ด้วย

หากต้องการสร้างฐานข้อมูล ให้ใช้เครื่องมือบรรทัดคำสั่ง gcloud อีกครั้งโดยทำดังนี้

export SPANNER_DATABASE=cymbal-bikes
gcloud spanner databases create $SPANNER_DATABASE \
 --instance=$SPANNER_INSTANCE_ID

เอาต์พุตจากคำสั่ง:

$ Creating database...done.

สรุป

ในขั้นตอนนี้ คุณได้สร้างอินสแตนซ์และฐานข้อมูล Spanner แล้ว

ถัดไป

ต่อไป คุณจะต้องตั้งค่าสคีมาและข้อมูล Spanner

4 โหลดสคีมาและข้อมูล Cymbal

สร้างสคีมา Cymbal

หากต้องการตั้งค่าสคีมา ให้ไปที่ Spanner Studio โดยทำดังนี้

3e1a0fed928b33cf.png

สคีมาแบ่งออกเป็น 2 ส่วน ก่อนอื่นให้เพิ่มตาราง products คัดลอกและวางคำสั่งนี้ในแท็บว่าง

สําหรับสคีมา ให้คัดลอกและวาง DDL นี้ลงในช่อง

CREATE TABLE products(
  categoryId INT64 NOT NULL,
  productId INT64 NOT NULL,
  productName STRING(MAX) NOT NULL,
  productDescription STRING(MAX) NOT NULL,
  productDescriptionEmbedding ARRAY<FLOAT32>,
  createTime TIMESTAMP NOT NULL
  OPTIONS (
    allow_commit_timestamp = TRUE),
  inventoryCount INT64 NOT NULL,
  priceInCents INT64,)
  PRIMARY KEY(categoryId, productId);

จากนั้นคลิกปุ่ม run และรอ 2-3 วินาทีเพื่อให้ระบบสร้างสคีมา

ถัดไป คุณจะต้องสร้างโมเดล 2 รายการและกำหนดค่าให้กับปลายทางโมเดล VertexAI

โมเดลแรกคือโมเดลการฝังที่ใช้สร้างการฝังจากข้อความ และโมเดลที่ 2 คือโมเดล LLM ที่ใช้สร้างคำตอบตามข้อมูลใน Spanner

วางสคีมาต่อไปนี้ลงในแท็บใหม่ใน Spanner Studio

CREATE OR REPLACE MODEL EmbeddingsModel
  INPUT(content STRING(MAX)) OUTPUT(embeddings STRUCT<values ARRAY<FLOAT32>>) REMOTE
  OPTIONS (
    endpoint = '//aiplatform.googleapis.com/projects/<PROJECT_ID>/locations/us-central1/publishers/google/models/text-embedding-004');


CREATE OR REPLACE MODEL LLMModel
  INPUT(prompt STRING(MAX)) OUTPUT(content STRING(MAX)) REMOTE
  OPTIONS (
    endpoint = '//aiplatform.googleapis.com/projects/<PROJECT_ID>/locations/us-central1/publishers/google/models/gemini-2.0-flash-001',
    default_batch_size = 1);

จากนั้นคลิกปุ่ม run แล้วรอ 2-3 วินาทีเพื่อให้ระบบสร้างรูปแบบ

ในแผงด้านซ้ายของ Spanner Studio คุณควรเห็นตารางและโมเดลต่อไปนี้

62455aa4b0e839d9.png

โหลดข้อมูล

ตอนนี้คุณจะต้องแทรกผลิตภัณฑ์บางรายการลงในฐานข้อมูล เปิดแท็บใหม่ใน Spanner Studio แล้วคัดลอกและวางคำสั่งแทรกต่อไปนี้

INSERT INTO products (categoryId, productId, productName, productDescription, createTime, inventoryCount, priceInCents)
VALUES (1, 1, "Cymbal Helios Helmet", "Safety meets style with the Cymbal children's bike helmet. Its lightweight design, superior ventilation, and adjustable fit ensure comfort and protection on every ride. Stay bright and keep your child safe under the sun with Cymbal Helios!", PENDING_COMMIT_TIMESTAMP(), 100, 10999),
(1, 2, "Cymbal Sprout", "Let their cycling journey begin with the Cymbal Sprout, the ideal balance bike for beginning riders ages 2-4 years. Its lightweight frame, low seat height, and puncture-proof tires promote stability and confidence as little ones learn to balance and steer. Watch them sprout into cycling enthusiasts with Cymbal Sprout!", PENDING_COMMIT_TIMESTAMP(), 10, 13999),
(1, 3, "Cymbal Spark Jr.", "Light, vibrant, and ready for adventure, the Spark Jr. is the perfect first bike for young riders (ages 5-8). Its sturdy frame, easy-to-use brakes, and puncture-resistant tires inspire confidence and endless playtime. Let the spark of cycling ignite with Cymbal!", PENDING_COMMIT_TIMESTAMP(), 34, 13900),
(1, 4, "Cymbal Summit", "Conquering trails is a breeze with the Summit mountain bike. Its lightweight aluminum frame, responsive suspension, and powerful disc brakes provide exceptional control and comfort for experienced bikers navigating rocky climbs or shredding downhill. Reach new heights with Cymbal Summit!", PENDING_COMMIT_TIMESTAMP(), 0, 79999),
(1, 5, "Cymbal Breeze", "Cruise in style and embrace effortless pedaling with the Breeze electric bike. Its whisper-quiet motor and long-lasting battery let you conquer hills and distances with ease. Enjoy scenic rides, commutes, or errands with a boost of confidence from Cymbal Breeze!", PENDING_COMMIT_TIMESTAMP(), 72, 129999),
(1, 6, "Cymbal Trailblazer Backpack", "Carry all your essentials in style with the Trailblazer backpack. Its water-resistant material, multiple compartments, and comfortable straps keep your gear organized and accessible, allowing you to focus on the adventure. Blaze new trails with Cymbal Trailblazer!", PENDING_COMMIT_TIMESTAMP(), 24, 7999),
(1, 7, "Cymbal Phoenix Lights", "See and be seen with the Phoenix bike lights. Powerful LEDs and multiple light modes ensure superior visibility, enhancing your safety and enjoyment during day or night rides. Light up your journey with Cymbal Phoenix!", PENDING_COMMIT_TIMESTAMP(), 87, 3999),
(1, 8, "Cymbal Windstar Pump", "Flat tires are no match for the Windstar pump. Its compact design, lightweight construction, and high-pressure capacity make inflating tires quick and effortless. Get back on the road in no time with Cymbal Windstar!", PENDING_COMMIT_TIMESTAMP(), 36, 24999),
(1, 9,"Cymbal Odyssey Multi-Tool","Be prepared for anything with the Odyssey multi-tool. This handy gadget features essential tools like screwdrivers, hex wrenches, and tire levers, keeping you ready for minor repairs and adjustments on the go. Conquer your journey with Cymbal Odyssey!", PENDING_COMMIT_TIMESTAMP(), 52, 999),
(1, 10,"Cymbal Nomad Water Bottle","Stay hydrated on every ride with the Nomad water bottle. Its sleek design, BPA-free construction, and secure lock lid make it the perfect companion for staying refreshed and motivated throughout your adventures. Hydrate and explore with Cymbal Nomad!", PENDING_COMMIT_TIMESTAMP(), 42, 1299);

คลิกปุ่ม run เพื่อแทรกข้อมูล

สรุป

ในขั้นตอนนี้ คุณได้สร้างสคีมาและโหลดข้อมูลพื้นฐานบางอย่างลงในฐานข้อมูล cymbal-bikes

ถัดไป

ถัดไป คุณจะต้องผสานรวมกับโมเดลการฝังเพื่อสร้างการฝังสําหรับคําอธิบายผลิตภัณฑ์ รวมถึงแปลงคําขอค้นหาที่เป็นข้อความเป็นการฝังเพื่อค้นหาผลิตภัณฑ์ที่เกี่ยวข้อง

5 ทำงานกับการฝัง

สร้างการฝังเวกเตอร์สําหรับรายละเอียดผลิตภัณฑ์

หากต้องการให้การค้นหาที่คล้ายกันทำงานกับผลิตภัณฑ์ คุณต้องสร้างการฝังสำหรับคำอธิบายผลิตภัณฑ์

เมื่อสร้าง EmbeddingsModel ในสคีมาแล้ว คำสั่งนี้เป็นคำสั่ง DML UPDATE ง่ายๆ

UPDATE products p1
SET
  productDescriptionEmbedding
= (
    SELECT embeddings
.values
    FROM
      ML
.PREDICT(
        MODEL
EmbeddingsModel,
       
(SELECT productDescription AS content))
 
)
WHERE categoryId
= 1;

คลิกปุ่ม run เพื่ออัปเดตรายละเอียดผลิตภัณฑ์

หากพบข้อผิดพลาด ให้ลองเรียกใช้คำสั่ง sql ในเทอร์มินัลโดยใช้คำสั่ง gcloud เพื่อดูข้อความแสดงข้อผิดพลาดโดยละเอียด เช่น

gcloud spanner databases execute-sql <YOUR_DATA_BASE> --instance=<YOUR_INSTANCE> --sql 'UPDATE products p1
SET
  productDescriptionEmbedding = (
    SELECT embeddings.values
    FROM
      ML.PREDICT(
        MODEL EmbeddingsModel,
        (SELECT productDescription AS content FROM products p2 WHERE p2.productId = p1.productId))
  )
WHERE categoryId = 1;'

ในตัวอย่างนี้ คุณจะให้คําขอค้นหาด้วยภาษาที่เป็นธรรมชาติผ่านคําค้นหา SQL คําค้นหานี้จะเปลี่ยนคําขอค้นหาเป็นการฝัง จากนั้นจะค้นหาผลลัพธ์ที่คล้ายกันโดยอิงตามการฝังคําอธิบายผลิตภัณฑ์ที่เก็บไว้ซึ่งสร้างขึ้นในขั้นตอนก่อนหน้า

-- Use Spanner's vector search, and integration with embedding and LLM models to
-- return items that are semantically relevant and available in inventory based on
-- real-time data.

SELECT
  productName,
  productDescription,
  inventoryCount,
  COSINE_DISTANCE(
    productDescriptionEmbedding,
    (
      SELECT embeddings.values
      FROM
        ML.PREDICT(
          MODEL EmbeddingsModel,
          (SELECT "I'd like to buy a starter bike for my 3 year old child" AS content))
    )) AS distance
FROM products
WHERE inventoryCount > 0
ORDER BY distance
LIMIT 5;

คลิกปุ่ม run เพื่อค้นหาผลิตภัณฑ์ที่คล้ายกัน ผลลัพธ์ควรมีลักษณะดังนี้

672e111753077fcf.png

โปรดทราบว่ามีการใช้ตัวกรองเพิ่มเติมในข้อความค้นหา เช่น สนใจเฉพาะผลิตภัณฑ์ที่มีสินค้าพร้อมจำหน่าย (inventoryCount > 0)

สรุป

ในขั้นตอนนี้ คุณได้สร้างการฝังคําอธิบายผลิตภัณฑ์และการฝังคําขอค้นหาโดยใช้ SQL โดยใช้ประโยชน์จากการผสานรวมของ Spanner กับโมเดลใน VertexAI นอกจากนี้ คุณยังทำการค้นหาเวกเตอร์เพื่อค้นหาผลิตภัณฑ์ที่คล้ายกันซึ่งตรงกับคำขอค้นหาด้วย

ขั้นตอนถัดไป

ต่อไป เราจะใช้ผลการค้นหาเพื่อป้อนข้อมูลไปยัง LLM เพื่อสร้างคำตอบที่กำหนดเองสำหรับผลิตภัณฑ์แต่ละรายการ

6 ทำงานร่วมกับ LLM

Spanner ช่วยให้ผสานรวมกับโมเดล LLM ที่แสดงจาก VertexAI ได้ง่าย ซึ่งช่วยให้นักพัฒนาซอฟต์แวร์ใช้ SQL เพื่อเชื่อมต่อกับ LLM ได้โดยตรง แทนที่จะกำหนดให้แอปพลิเคชันต้องดำเนินการตามตรรกะ

ตัวอย่างเช่น เรามีผลการค้นหา SQL ก่อนหน้าจากผู้ใช้ "I'd like to buy a starter bike for my 3 year old child".

นักพัฒนาแอปต้องการตอบกลับสำหรับผลการค้นหาแต่ละรายการว่าผลิตภัณฑ์เหมาะกับผู้ใช้หรือไม่ โดยใช้พรอมต์ต่อไปนี้

"Answer with ‘Yes' or ‘No' and explain why: Is this a good fit for me? I'd like to buy a starter bike for my 3 year old child"

คําค้นหาที่คุณใช้ได้มีดังนี้

-- Use an LLM to analyze this list and provide a recommendation on whether each
-- product is a good fit for the user. We use the vector search and real time
-- inventory data to first filter the products to reduce the size of the prompt to
-- the LLM.
SELECT productName, productDescription, inventoryCount, content AS LLMResponse
FROM
  ML.PREDICT(
    MODEL LLMModel,
    (
      SELECT
        FORMAT(
          """Answer with Yes or No and explain why: Is this a good fit for me?
          I would like to buy a starter bike for my 3 year old child \n Product Name: %s\nProduct Description: %s""", productName,productDescription) AS prompt,
        -- Pass through columns.
        inventoryCount,
        productName,
        productDescription,
      FROM products
      WHERE inventoryCount > 0
      ORDER BY
        COSINE_DISTANCE(
          productDescriptionEmbedding,
          (
            SELECT embeddings.values
            FROM
              ML.PREDICT(
                MODEL EmbeddingsModel,
                (SELECT "I'd like to buy a starter bike for my 3 year old child" AS content))
          ))
      LIMIT 5
    ));

คลิกปุ่ม run เพื่อส่งการค้นหา ผลลัพธ์ควรมีลักษณะดังนี้

35878cd0f88f1470.png

ผลิตภัณฑ์แรกเหมาะสำหรับเด็กอายุ 3 ปีเนื่องจากช่วงอายุในคำอธิบายผลิตภัณฑ์ (2-4 ปี) ผลิตภัณฑ์อื่นๆ นั้นไม่เหมาะเท่าไหร่

สรุป

ในขั้นตอนนี้ คุณทํางานกับ LLM เพื่อสร้างคําตอบพื้นฐานสําหรับพรอมต์จากผู้ใช้

ขั้นตอนถัดไป

ถัดไป เราจะมาดูวิธีใช้ ANN เพื่อปรับขนาดการค้นหาเวกเตอร์กัน

7 การปรับขนาดการค้นหาเวกเตอร์

ตัวอย่างการค้นหาเวกเตอร์ก่อนหน้านี้ใช้ประโยชน์จากการค้นหาเวกเตอร์ KNN ที่ตรงกันทั้งหมด ซึ่งจะมีประโยชน์อย่างยิ่งเมื่อคุณค้นหาชุดย่อยที่เฉพาะเจาะจงมากของข้อมูล Spanner ได้ คำค้นหาประเภทดังกล่าวเรียกว่าแบ่งพาร์ติชันได้สูง

หากมีปริมาณงานที่มีการแบ่งพาร์ติชันได้ยากและมีข้อมูลจํานวนมาก คุณควรใช้การค้นหาเวกเตอร์ ANN โดยใช้ประโยชน์จากอัลกอริทึม SCANN เพื่อเพิ่มประสิทธิภาพการค้นหา

หากต้องการดำเนินการดังกล่าวใน Spanner คุณจะต้องทํา 2 อย่างต่อไปนี้

  • สร้างดัชนีเวกเตอร์
  • แก้ไขการค้นหาเพื่อใช้ประโยชน์จากฟังก์ชันระยะทาง APPROX

สร้างดัชนีเวกเตอร์

หากต้องการสร้างดัชนีเวกเตอร์ในชุดข้อมูลนี้ ก่อนอื่นเราต้องแก้ไขคอลัมน์ productDescriptionEmbeddings เพื่อกำหนดความยาวของเวกเตอร์แต่ละรายการ หากต้องการเพิ่มความยาวเวกเตอร์ลงในคอลัมน์ คุณต้องวางคอลัมน์เดิมและสร้างใหม่

ALTER TABLE products DROP COLUMN productDescriptionEmbedding;

ALTER TABLE products
ADD COLUMN productDescriptionEmbedding ARRAY
<FLOAT32>(vector_length => 768);

จากนั้นสร้างการฝังอีกครั้งจากขั้นตอน Generate Vector embedding ที่คุณเคยเรียกใช้

UPDATE products p1
SET
  productDescriptionEmbedding
= (
    SELECT embeddings
.values
    FROM
      ML
.PREDICT(
        MODEL
EmbeddingsModel,
       
(SELECT productDescription AS content FROM products p2 WHERE p2.productId = p1.productId))
 
)
WHERE categoryId
= 1;

หลังจากสร้างคอลัมน์แล้ว ให้สร้างดัชนีโดยทำดังนี้

CREATE VECTOR INDEX ProductDescriptionEmbeddingIndex
    ON products(productDescriptionEmbedding)
    WHERE productDescriptionEmbedding IS NOT NULL
OPTIONS (
 distance_type = 'COSINE'
);

ดู PDML ได้ที่ https://cloud.google.com/spanner/docs/backfill-embeddings หากสนใจ คำสั่ง DML รายการเดียวคือธุรกรรมที่มีขีดจำกัดการเปลี่ยนแปลงสูงสุด 80,000 รายการ คุณจึงอัปเดตแถวหลายแถวพร้อมกันไม่ได้ PDML จะจัดการการแบ่งออกเป็นกลุ่มเล็กๆ ได้อย่างมีประสิทธิภาพ

ใช้ดัชนีใหม่

หากต้องการใช้ดัชนีเวกเตอร์ใหม่ คุณจะต้องแก้ไขการค้นหาการฝังก่อนหน้าเล็กน้อย

คําค้นหาเดิมมีดังนี้

SELECT
  productName,
  productDescription,
  inventoryCount,
  COSINE_DISTANCE(
    productDescriptionEmbedding,
    (
      SELECT embeddings.values
      FROM
        ML.PREDICT(
          MODEL EmbeddingsModel,
          (SELECT "I'd like to buy a starter bike for my 3 year old child" AS content))
    )) AS distance
FROM products
WHERE inventoryCount > 0
ORDER BY distance
LIMIT 5;

คุณจะต้องทําการเปลี่ยนแปลงต่อไปนี้

  • ใช้คำแนะนำดัชนีสำหรับดัชนีเวกเตอร์ใหม่ @{force_index=ProductDescriptionEmbeddingIndex}
  • เปลี่ยนการเรียกใช้ฟังก์ชัน COSINE_DISTANCE เป็น APPROX_COSINE_DISTANCE โปรดทราบว่าต้องระบุตัวเลือก JSON ในข้อความค้นหาสุดท้ายด้านล่างด้วย
  • สร้างการฝังจากฟังก์ชัน ML.PREDICT แยกกัน
  • คัดลอกผลลัพธ์ของการฝังลงในข้อความค้นหาสุดท้าย

สร้างและใช้การฝัง

-- Generate the prompt embeddings
SELECT embeddings
.values
FROM ML
.PREDICT(
  MODEL
EmbeddingsModel,
   
(SELECT "I'd like to buy a starter bike for my 3 year old child" as content)
 
);

ไฮไลต์ผลลัพธ์จากการค้นหา แล้วคัดลอก

1b43c5ae4ef9ab68.png

จากนั้นแทนที่ <VECTOR> ในข้อความค้นหาต่อไปนี้ด้วยการวางการฝังที่คุณคัดลอกไว้

-- Generate the embeddings and query them using the vector index
SELECT
  productName,
  productDescription,
  inventoryCount,
  APPROX_COSINE_DISTANCE(
    productDescriptionEmbedding,
    array<float32>[@VECTOR],
    options => JSON '{\"num_leaves_to_search\": 10}') AS distance
FROM products @{force_index = ProductDescriptionEmbeddingIndex}
WHERE productDescriptionEmbedding IS NOT NULL AND inventoryCount > 0
ORDER BY distance
LIMIT 5;

ซึ่งควรมีหน้าตาเช่นนี้

12397107ec49c491.png

สรุป

ในขั้นตอนนี้ คุณได้แปลงสคีมาเพื่อสร้างดัชนีเวกเตอร์ จากนั้นคุณเขียนคําค้นหาแบบฝังใหม่เพื่อทำการค้นหา ANN โดยใช้ดัชนีเวกเตอร์ ขั้นตอนนี้เป็นขั้นตอนสําคัญเมื่อข้อมูลมีขนาดใหญ่ขึ้นเพื่อปรับขนาดเวิร์กโหลดการค้นหาเวกเตอร์

ขั้นตอนถัดไป

ต่อไปก็ถึงเวลาทำความสะอาด

8 การเก็บกวาด (ไม่บังคับ)

หากต้องการล้างข้อมูล ให้ลบอินสแตนซ์ 'retail-demo' ที่เราสร้างใน Codelab

41cbc1a84b3588d5.png

9 ยินดีด้วย

ยินดีด้วย คุณได้ทำการค้นหาความคล้ายคลึงโดยใช้การค้นหาเวกเตอร์ในตัวของ Spanner เรียบร้อยแล้ว นอกจากนี้ คุณยังได้เห็นว่าการทํางานกับโมเดลการฝังและ LLM เพื่อมอบฟังก์ชัน Generative AI โดยตรงโดยใช้ SQL นั้นง่ายเพียงใด

สุดท้าย คุณก็ได้ทราบกระบวนการค้นหา ANN ที่รองรับโดยอัลกอริทึม SCANN สําหรับการปรับขนาดเวิร์กโหลดการค้นหาเวกเตอร์

ขั้นตอนถัดไปคือ

ดูข้อมูลเพิ่มเติมเกี่ยวกับฟีเจอร์เพื่อนบ้านที่ใกล้ที่สุดแบบตรงทั้งหมด (การค้นหาเวกเตอร์ KNN) ของ Spanner ได้ที่ https://cloud.google.com/spanner/docs/find-k-nearest-neighbors

ดูข้อมูลเพิ่มเติมเกี่ยวกับฟีเจอร์เพื่อนบ้านใกล้เคียงโดยประมาณ (การค้นหาเวกเตอร์ ANN) ของ Spanner ได้ที่ https://cloud.google.com/spanner/docs/find-approximate-nearest-neighbors

นอกจากนี้ คุณยังอ่านข้อมูลเพิ่มเติมเกี่ยวกับวิธีทําการคาดการณ์ออนไลน์ด้วย SQL โดยใช้การผสานรวม VertexAI ของ Spanner ได้ที่นี่ https://cloud.google.com/spanner/docs/ml