1. Pengantar
Dalam codelab ini, Anda akan mempelajari cara men-deploy AlloyDB Omni di GKE dan menggunakannya dengan model penyematan terbuka yang di-deploy di cluster Kubernetes yang sama. Deployment model di samping instance database di cluster GKE yang sama akan mengurangi latensi dan dependensi pada layanan pihak ketiga. Selain itu, hal ini mungkin diwajibkan oleh persyaratan keamanan jika data tidak boleh keluar dari organisasi dan penggunaan layanan pihak ketiga tidak diizinkan.
Prasyarat
- Pemahaman dasar tentang Google Cloud, konsol
- Keterampilan dasar dalam antarmuka command line dan Cloud Shell
Yang akan Anda pelajari
- Cara men-deploy AlloyDB Omni di cluster Google Kubernetes
- Cara terhubung ke AlloyDB Omni
- Cara memuat data ke AlloyDB Omni
- Cara men-deploy model penyematan terbuka ke GKE
- Cara mendaftarkan model penyematan di AlloyDB Omni
- Cara membuat embedding untuk penelusuran semantik
- Cara menggunakan embedding yang dihasilkan untuk penelusuran semantik di AlloyDB Omni
- Cara membuat dan menggunakan indeks vektor di AlloyDB
Yang Anda butuhkan
- Akun Google Cloud dan Project Google Cloud
- Browser web seperti Chrome yang mendukung Konsol Google Cloud dan Cloud Shell
2. Penyiapan dan Persyaratan
Penyiapan lingkungan mandiri
- Login ke Google Cloud Console dan buat project baru atau gunakan kembali project yang sudah ada. Jika belum memiliki akun Gmail atau Google Workspace, Anda harus membuatnya.
- Project name adalah nama tampilan untuk peserta project ini. String ini adalah string karakter yang tidak digunakan oleh Google API. Anda dapat memperbaruinya kapan saja.
- Project ID bersifat unik di semua project Google Cloud dan tidak dapat diubah (tidak dapat diubah setelah ditetapkan). Cloud Console otomatis membuat string unik; biasanya Anda tidak mementingkan kata-katanya. Di sebagian besar codelab, Anda harus merujuk Project ID-nya (umumnya diidentifikasi sebagai
PROJECT_ID
). Jika tidak suka dengan ID yang dibuat, Anda dapat membuat ID acak lainnya. Atau, Anda dapat mencobanya sendiri, dan lihat apakah ID tersebut tersedia. ID tidak dapat diubah setelah langkah ini dan tersedia selama durasi project. - Sebagai informasi, ada nilai ketiga, Project Number, yang digunakan oleh beberapa API. Pelajari lebih lanjut ketiga nilai ini di dokumentasi.
- Selanjutnya, Anda harus mengaktifkan penagihan di Konsol Cloud untuk menggunakan resource/API Cloud. Menjalankan operasi dalam codelab ini tidak akan memakan banyak biaya, bahkan mungkin tidak sama sekali. Guna mematikan resource agar tidak menimbulkan penagihan di luar tutorial ini, Anda dapat menghapus resource yang dibuat atau menghapus project-nya. Pengguna baru Google Cloud memenuhi syarat untuk mengikuti program Uji Coba Gratis senilai $300 USD.
Mulai Cloud Shell
Meskipun Google Cloud dapat dioperasikan dari jarak jauh menggunakan laptop Anda, dalam codelab ini, Anda akan menggunakan Google Cloud Shell, lingkungan command line yang berjalan di Cloud.
Dari Google Cloud Console, klik ikon Cloud Shell di toolbar kanan atas:
Hanya perlu waktu beberapa saat untuk penyediaan dan terhubung ke lingkungan. Jika sudah selesai, Anda akan melihat tampilan seperti ini:
Mesin virtual ini berisi semua alat pengembangan yang Anda perlukan. Layanan ini menawarkan direktori beranda tetap sebesar 5 GB dan beroperasi di Google Cloud, sehingga sangat meningkatkan performa dan autentikasi jaringan. Semua pekerjaan Anda dalam codelab ini dapat dilakukan di browser. Anda tidak perlu menginstal apa pun.
3. Sebelum memulai
Aktifkan API
Output:
Di dalam Cloud Shell, pastikan project ID Anda sudah disiapkan:
PROJECT_ID=$(gcloud config get-value project)
echo $PROJECT_ID
Jika tidak ditentukan dalam konfigurasi cloud shell, siapkan menggunakan perintah berikut
export PROJECT_ID=<your project>
gcloud config set project $PROJECT_ID
Aktifkan semua layanan yang diperlukan:
gcloud services enable compute.googleapis.com
gcloud services enable container.googleapis.com
Output yang diharapkan
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. Men-deploy AlloyDB Omni di GKE
Untuk men-deploy AlloyDB Omni di GKE, kita perlu menyiapkan cluster Kubernetes dengan mengikuti persyaratan yang tercantum dalam persyaratan operator AlloyDB Omni.
Membuat Cluster GKE
Kita perlu men-deploy cluster GKE standar dengan konfigurasi kumpulan yang memadai untuk men-deploy pod dengan instance AlloyDB Omni. Kita memerlukan minimal 2 CPU dan RAM 8 GB untuk Omni dengan beberapa ruang untuk layanan operator dan pemantauan.
Siapkan variabel lingkungan untuk deployment Anda.
export PROJECT_ID=$(gcloud config get project)
export LOCATION=us-central1
export CLUSTER_NAME=alloydb-ai-gke
export MACHINE_TYPE=e2-standard-4
Kemudian, kita menggunakan gcloud untuk membuat cluster standar 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
Output konsol yang diharapkan:
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)$
Menyiapkan Cluster
Kita perlu menginstal komponen yang diperlukan seperti layanan cert-manager. Kita dapat mengikuti langkah-langkah dalam dokumentasi untuk penginstalan cert-manager
Kita menggunakan alat command line Kubernetes, kubectl, yang sudah diinstal di Cloud Shell. Sebelum menggunakan utilitas, kita perlu mendapatkan kredensial untuk cluster.
gcloud container clusters get-credentials ${CLUSTER_NAME} --region=${LOCATION}
Sekarang kita dapat menggunakan kubectl untuk menginstal cert-manager:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.2/cert-manager.yaml
Output konsol yang diharapkan (disamarkan):
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
Menginstal AlloyDB Omni
Operator AlloyDB Omni dapat diinstal menggunakan utilitas helm.
Jalankan perintah berikut untuk menginstal operator 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
Output konsol yang diharapkan (disamarkan):
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:~$
Setelah operator AlloyDB Omni diinstal, kita dapat menindaklanjuti dengan deployment cluster database.
Berikut adalah contoh manifes deployment dengan parameter googleMLExtension yang diaktifkan dan load balancer internal (pribadi).:
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
Nilai secret untuk sandi adalah representasi Base64 dari kata sandi "VeryStrongPassword". Cara yang lebih andal adalah menggunakan pengelola secret Google untuk menyimpan nilai sandi. Anda dapat membacanya lebih lanjut di dokumentasi.
Simpan manifes sebagai my-omni.yaml untuk diterapkan di langkah berikutnya. Jika berada di Cloud Shell, Anda dapat melakukannya menggunakan editor dengan menekan tombol "Open Editor" di kanan atas terminal.
Setelah menyimpan file dengan nama my-omni.yaml, kembali ke terminal dengan menekan tombol "Open Terminal".
Terapkan manifes my-omni.yaml ke cluster menggunakan utilitas kubectl:
kubectl apply -f my-omni.yaml
Output konsol yang diharapkan:
secret/db-pw-my-omni created dbcluster.alloydbomni.dbadmin.goog/my-omni created
Periksa status cluster my-omni menggunakan utilitas kubectl:
kubectl get dbclusters.alloydbomni.dbadmin.goog my-omni -n default
Selama deployment, cluster akan melalui berbagai fase dan pada akhirnya akan berakhir dengan status DBClusterReady.
Output konsol yang diharapkan:
$ kubectl get dbclusters.alloydbomni.dbadmin.goog my-omni -n default NAME PRIMARYENDPOINT PRIMARYPHASE DBCLUSTERPHASE HAREADYSTATUS HAREADYREASON my-omni 10.131.0.33 Ready DBClusterReady
Menghubungkan ke AlloyDB Omni
Menghubungkan Menggunakan Pod Kubernetes
Setelah cluster siap, kita dapat menggunakan biner klien PostgreSQL di pod instance AlloyDB Omni. Kita menemukan ID pod, lalu menggunakan kubectl untuk terhubung langsung ke pod dan menjalankan software klien. Sandinya adalah VeryStrongPassword seperti yang ditetapkan melalui hash di 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
Contoh output konsol:
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. Men-deploy Model AI di GKE
Untuk menguji integrasi AlloyDB Omni AI dengan model lokal, kita perlu men-deploy model ke cluster.
Membuat Node Pool untuk Model
Untuk menjalankan model, kita perlu menyiapkan node pool untuk menjalankan inferensi. Pendekatan terbaik dari sudut pandang performa adalah kumpulan dengan akselerator grafis yang menggunakan konfigurasi node seperti g2-standard-8 dengan akselerator Nvidia L4.
Buat node pool dengan akselerator 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
Output yang diharapkan
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
Menyiapkan Manifes Deployment
Untuk men-deploy model, kita perlu menyiapkan manifes deployment.
Kami menggunakan model penyematan BGE Base v1.5 dari Hugging Face. Anda dapat membaca kartu model di sini. Untuk men-deploy model, kita dapat menggunakan petunjuk yang sudah disiapkan dari Hugging Face dan paket deployment dari GitHub.
Meng-clone paket
git clone https://github.com/huggingface/Google-Cloud-Containers
Edit manifes dengan mengganti nilai cloud.google.com/gke-accelerator dengan nvidia-l4 dan menambahkan batas ke resource.
vi Google-Cloud-Containers/examples/gke/tei-deployment/gpu-config/deployment.yaml
Berikut adalah manifes yang telah diperbaiki.
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
Men-deploy Model
Kita perlu menyiapkan akun layanan dan namespace untuk deployment.
Buat namespace kubernetes hf-gke-namespace.
export NAMESPACE=hf-gke-namespace
kubectl create namespace $NAMESPACE
Membuat akun layanan kubernetes
export SERVICE_ACCOUNT=hf-gke-service-account
kubectl create serviceaccount $SERVICE_ACCOUNT --namespace $NAMESPACE
Men-deploy model
kubectl apply -f Google-Cloud-Containers/examples/gke/tei-deployment/gpu-config
Memverifikasi deployment
kubectl get pods
Memverifikasi layanan model
kubectl get service tei-service
Ini seharusnya menampilkan jenis layanan yang sedang berjalan ClusterIP
Contoh output:
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 untuk layanan adalah yang akan kita gunakan sebagai alamat endpoint. Penyematan model dapat merespons dengan URI http://34.118.233.48:8080/embed. Nama ini akan digunakan nanti saat Anda mendaftarkan model di AlloyDB Omni.
Kita dapat mengujinya dengan mengeksposnya menggunakan perintah kubectl port-forward.
kubectl port-forward service/tei-service 8080:8080
Penerusan port akan berjalan di satu sesi Cloud Shell dan kita memerlukan sesi lain untuk mengujinya.
Buka tab Cloud Shell lain menggunakan tanda "+" di bagian atas.
Lalu, jalankan perintah curl di sesi shell baru.
curl http://localhost:8080/embed \
-X POST \
-d '{"inputs":"Test"}' \
-H 'Content-Type: application/json'
Fungsi ini akan menampilkan array vektor seperti dalam contoh output berikut (disamarkan):
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. Mendaftarkan Model di AlloyDB Omni
Untuk menguji cara kerja AlloyDB Omni dengan model yang di-deploy, kita perlu membuat database dan mendaftarkan model.
Buat Database
Buat VM GCE sebagai jump box, hubungkan ke AlloyDB Omni dari VM klien Anda, lalu buat database.
Kita memerlukan jump box karena load balancer eksternal GKE untuk Omni memberi Anda akses dari VPC menggunakan alamat IP pribadi, tetapi tidak mengizinkan Anda terhubung dari luar VPC. Secara umum, cara ini lebih aman dan tidak mengekspos instance database Anda ke internet. Periksa diagram untuk mengetahui kejelasannya.
Untuk membuat VM dalam sesi Cloud Shell, jalankan:
export ZONE=us-central1-a
gcloud compute instances create instance-1 \
--zone=$ZONE
Temukan IP endpoint AlloyDB Omni menggunakan kubectl di Cloud Shell:
kubectl get dbclusters.alloydbomni.dbadmin.goog my-omni -n default
Catat PRIMARYENDPOINT. Ini contohnya.
output:
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 adalah IP yang akan kita gunakan dalam contoh untuk terhubung ke instance AlloyDB Omni.
Hubungkan ke VM menggunakan gcloud:
gcloud compute ssh instance-1 --zone=$ZONE
Jika diminta untuk membuat kunci SSH, ikuti petunjuknya. Baca selengkapnya tentang koneksi ssh di dokumentasi.
Dalam sesi ssh ke VM, instal klien PostgreSQL:
sudo apt-get update
sudo apt-get install --yes postgresql-client
Ekspor IP load balancer AlloyDB Omni seperti dalam contoh berikut (ganti IP dengan IP load balancer Anda):
export INSTANCE_IP=10.131.0.33
Hubungkan ke AlloyDB Omni, sandinya adalah VeryStrongPassword seperti yang ditetapkan melalui hash di my-omni.yaml:
psql "host=$INSTANCE_IP user=postgres sslmode=require"
Dalam sesi psql yang dibuat, jalankan:
create database demo;
Keluar dari sesi dan terhubung ke demo database (atau Anda cukup menjalankan "\c demo" dalam sesi yang sama)
psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"
Membuat fungsi transformasi
Untuk model penyematan pihak ketiga, kita perlu membuat fungsi transformasi yang memformat input dan output ke format yang diharapkan oleh model dan fungsi internal kita.
Berikut adalah fungsi transformasi yang menangani input:
-- 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;
$$;
Jalankan kode yang diberikan saat terhubung ke database demo seperti yang ditunjukkan dalam contoh output:
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=#
Berikut adalah fungsi output yang mengubah respons dari model menjadi array bilangan riil:
-- 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;
$$;
Jalankan dalam sesi yang sama:
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=#
Mendaftarkan model
Sekarang kita dapat mendaftarkan model di database.
Berikut adalah panggilan prosedur untuk mendaftarkan model dengan nama bge-base-1.5, rganti IP 34.118.233.48 dengan alamat IP layanan model Anda (output dari 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');
Jalankan kode yang diberikan saat terhubung ke database demo:
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=#
Kita dapat menguji model pendaftaran menggunakan kueri pengujian berikut yang akan menampilkan array bilangan riil.
select google_ml.embedding('bge-base-1.5','What is AlloyDB Omni?');
7. Menguji Model di AlloyDB Omni
Memuat Data
Untuk menguji cara kerja AlloyDB Omni dengan model yang di-deploy, kita perlu memuat beberapa data. Saya menggunakan data yang sama seperti di salah satu codelab lainnya untuk penelusuran vektor di AlloyDB.
Salah satu cara untuk memuat data adalah menggunakan Google Cloud SDK dan software klien PostgreSQL. Kita dapat menggunakan VM klien yang sama dengan yang digunakan untuk membuat database demo. Google Cloud SDK seharusnya sudah diinstal di sana jika Anda telah menggunakan setelan default untuk image VM. Namun, jika telah menggunakan image kustom tanpa Google SDK, Anda dapat menambahkannya dengan mengikuti dokumentasi.
Ekspor IP load balancer AlloyDB Omni seperti dalam contoh berikut (ganti IP dengan IP load balancer Anda):
export INSTANCE_IP=10.131.0.33
Hubungkan ke database dan aktifkan ekstensi pgvector.
psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"
Dalam sesi psql:
CREATE EXTENSION IF NOT EXISTS vector;
Keluar dari sesi psql dan dalam sesi command line, jalankan perintah untuk memuat data ke database demo.
Buat tabel:
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=demo"
Output konsol yang diharapkan:
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:~$
Berikut adalah daftar tabel yang dibuat:
psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\dt+"
Output:
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:~$
Muat data ke tabel 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"
Output konsol yang diharapkan:
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:~$
Berikut adalah contoh beberapa baris dari tabel 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"
Output:
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:~$
Muat data ke tabel 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"
Output konsol yang diharapkan:
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:~$
Berikut adalah contoh beberapa baris dari tabel cymbal_inventory.
psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT * FROM cymbal_inventory LIMIT 3"
Output:
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:~$
Muat data ke tabel 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"
Output konsol yang diharapkan:
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:~$
Berikut adalah contoh beberapa baris dari tabel cymbal_stores.
psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT store_id, name, zip_code FROM cymbal_stores limit 3"
Output:
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:~$
Membuat Penyematan
Hubungkan ke database demo menggunakan psql dan buat penyematan untuk produk yang dijelaskan dalam tabel cymbal_products berdasarkan nama dan deskripsi produk.
Hubungkan ke database demo:
psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"
Kita menggunakan tabel cymbal_embedding dengan penyematan kolom untuk menyimpan penyematan dan menggunakan deskripsi produk sebagai input teks ke fungsi.
Aktifkan pengaturan waktu untuk kueri Anda agar dapat dibandingkan nanti dengan model jarak jauh.:
\timing
Jalankan kueri untuk membuat penyematan:
INSERT INTO cymbal_embedding(uniq_id,embedding) SELECT uniq_id, google_ml.embedding('bge-base-1.5',product_description)::vector FROM cymbal_products;
Output konsol yang diharapkan:
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=#
Dalam contoh ini, pembuatan penyematan untuk 941 data memerlukan waktu sekitar 11 detik.
Menjalankan Kueri Pengujian
Hubungkan ke database demo menggunakan psql dan aktifkan pengaturan waktu untuk mengukur waktu eksekusi kueri seperti yang kita lakukan untuk membuat penyematan.
Mari kita temukan 5 produk teratas yang cocok dengan permintaan seperti "Jenis pohon buah apa yang tumbuh subur di sini?" menggunakan jarak kosinus sebagai algoritma untuk penelusuran vektor.
Dalam sesi psql, jalankan:
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;
Output konsol yang diharapkan:
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=#
Kueri berjalan selama 28 md dan menampilkan daftar hierarki dari tabel cymbal_products yang cocok dengan permintaan dan dengan inventaris yang tersedia di toko dengan nomor 1583.
Mem-build Indeks ANN
Jika kita hanya memiliki set data kecil, penelusuran persis yang memindai semua penyematan akan mudah digunakan, tetapi saat data bertambah, waktu pemuatan dan respons juga akan meningkat. Untuk meningkatkan performa, Anda dapat membuat indeks pada data penyematan. Berikut adalah contoh cara melakukannya menggunakan indeks Google ScaNN untuk data vektor.
Hubungkan kembali ke database demo jika koneksi terputus:
psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"
Aktifkan ekstensi alloydb_scann:
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
Buat indeks:
CREATE INDEX cymbal_embedding_scann ON cymbal_embedding USING scann (embedding cosine);
Coba kueri yang sama seperti sebelumnya dan bandingkan hasilnya:
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=#
Waktu eksekusi kueri sedikit berkurang dan peningkatan tersebut akan lebih terlihat dengan set data yang lebih besar. Hasilnya cukup mirip dan hanya Cherry yang diganti dengan Fremont Cottonwood.
Coba kueri lain dan baca selengkapnya tentang cara memilih indeks vektor di dokumentasi.
Jangan lupa bahwa AlloyDB Omni memiliki lebih banyak fitur dan lab.
8. Membersihkan lingkungan
Sekarang kita dapat menghapus cluster GKE dengan AlloyDB Omni dan model AI
Menghapus Cluster GKE
Di Cloud Shell, jalankan:
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}
Output konsol yang diharapkan:
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
Menghapus VM
Di Cloud Shell, jalankan:
export PROJECT_ID=$(gcloud config get project)
export ZONE=us-central1-a
gcloud compute instances delete instance-1 \
--project=${PROJECT_ID} \
--zone=${ZONE}
Output konsol yang diharapkan:
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
Jika Anda membuat project baru untuk codelab ini, Anda dapat menghapus project lengkap: https://console.cloud.google.com/cloud-resource-manager
9. Selamat
Selamat, Anda telah menyelesaikan codelab.
Yang telah kita bahas
- Cara men-deploy AlloyDB Omni di cluster Google Kubernetes
- Cara terhubung ke AlloyDB Omni
- Cara memuat data ke AlloyDB Omni
- Cara men-deploy model penyematan terbuka ke GKE
- Cara mendaftarkan model penyematan di AlloyDB Omni
- Cara membuat embedding untuk penelusuran semantik
- Cara menggunakan embedding yang dihasilkan untuk penelusuran semantik di AlloyDB Omni
- Cara membuat dan menggunakan indeks vektor di AlloyDB
Anda dapat membaca selengkapnya tentang cara menggunakan AI di AlloyDB Omni di dokumentasi.
10. Survei
Output: