1. はじめに
この Codelab では、AlloyDB Omni を GKE にデプロイし、同じ Kubernetes クラスタにデプロイされたオープン エンベディング モデルで使用する方法について説明します。同じ GKE クラスタ内のデータベース インスタンスの横にモデルをデプロイすると、レイテンシとサードパーティ サービスへの依存関係が軽減されます。また、データが組織外に漏洩してはならず、サードパーティ サービスの使用が許可されていない場合、セキュリティ要件によって求められることもあります。
前提条件
- Google Cloud コンソールの基本的な知識
- コマンドライン インターフェースと Cloud Shell の基本的なスキル
学習内容
- Google Kubernetes クラスタに AlloyDB Omni をデプロイする方法
- AlloyDB Omni に接続する方法
- AlloyDB Omni にデータを読み込む方法
- オープン エンベディング モデルを GKE にデプロイする方法
- AlloyDB Omni でエンベディング モデルを登録する方法
- セマンティック検索用のエンベディングを生成する方法
- AlloyDB Omni で生成されたエンベディングをセマンティック検索に使用する方法
- AlloyDB でベクトル インデックスを作成して使用する方法
必要なもの
- Google Cloud アカウントと Google Cloud プロジェクト
- Google Cloud コンソールと Cloud Shell をサポートするウェブブラウザ(Chrome など)
2. 設定と要件
セルフペース型の環境設定
- Google Cloud Console にログインして、プロジェクトを新規作成するか、既存のプロジェクトを再利用します。Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください。
- プロジェクト名は、このプロジェクトの参加者に表示される名称です。Google API では使用されない文字列です。いつでも更新できます。
- プロジェクト ID は、すべての Google Cloud プロジェクトにおいて一意でなければならず、不変です(設定後は変更できません)。Cloud コンソールでは一意の文字列が自動生成されます。通常は、この内容を意識する必要はありません。ほとんどの Codelab では、プロジェクト ID(通常は
PROJECT_ID
と識別されます)を参照する必要があります。生成された ID が好みではない場合は、ランダムに別の ID を生成できます。または、ご自身で試して、利用可能かどうかを確認することもできます。このステップ以降は変更できず、プロジェクトを通して同じ ID になります。 - なお、3 つ目の値として、一部の API が使用するプロジェクト番号があります。これら 3 つの値について詳しくは、こちらのドキュメントをご覧ください。
- 次に、Cloud のリソースや API を使用するために、Cloud コンソールで課金を有効にする必要があります。この Codelab の操作をすべて行って、費用が生じたとしても、少額です。このチュートリアルの終了後に請求が発生しないようにリソースをシャットダウンするには、作成したリソースを削除するか、プロジェクトを削除します。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。
Cloud Shell を起動する
Google Cloud はノートパソコンからリモートで操作できますが、この Codelab では、Google Cloud Shell(Cloud 上で動作するコマンドライン環境)を使用します。
Google Cloud Console で、右上のツールバーにある Cloud Shell アイコンをクリックします。
プロビジョニングと環境への接続にはそれほど時間はかかりません。完了すると、次のように表示されます。
この仮想マシンには、必要な開発ツールがすべて用意されています。永続的なホーム ディレクトリが 5 GB 用意されており、Google Cloud で稼働します。そのため、ネットワークのパフォーマンスと認証機能が大幅に向上しています。この Codelab での作業はすべて、ブラウザ内から実行できます。インストールは不要です。
3. はじめに
API を有効にする
出力:
Cloud Shell で、プロジェクト ID が設定されていることを確認します。
PROJECT_ID=$(gcloud config get-value project)
echo $PROJECT_ID
Cloud Shell 構成で定義されていない場合は、次のコマンドを使用して設定します。
export PROJECT_ID=<your project>
gcloud config set project $PROJECT_ID
必要なサービスをすべて有効にします。
gcloud services enable compute.googleapis.com
gcloud services enable container.googleapis.com
想定される出力
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=test-project-001-402417 student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417 Updated property [core/project]. student@cloudshell:~ (test-project-001-402417)$ gcloud services enable compute.googleapis.com gcloud services enable container.googleapis.com Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.
4. GKE に AlloyDB Omni をデプロイする
GKE に AlloyDB Omni をデプロイするには、AlloyDB Omni オペレーターの要件に記載されている要件に沿って Kubernetes クラスタを準備する必要があります。
GKE クラスタを作成する
AlloyDB Omni インスタンスを含む Pod をデプロイするのに十分なプール構成を持つ標準の GKE クラスタをデプロイする必要があります。Omni には、オペレーター サービスとモニタリング サービス用のスペースを残して、少なくとも 2 つの CPU と 8 GB の RAM が必要です。
デプロイの環境変数を設定します。
export PROJECT_ID=$(gcloud config get project)
export LOCATION=us-central1
export CLUSTER_NAME=alloydb-ai-gke
export MACHINE_TYPE=e2-standard-4
次に、gcloud を使用して GKE Standard クラスタを作成します。
gcloud container clusters create ${CLUSTER_NAME} \
--project=${PROJECT_ID} \
--region=${LOCATION} \
--workload-pool=${PROJECT_ID}.svc.id.goog \
--release-channel=rapid \
--machine-type=${MACHINE_TYPE} \
--num-nodes=1
想定されるコンソール出力:
student@cloudshell:~ (gleb-test-short-001-415614)$ export PROJECT_ID=$(gcloud config get project) export LOCATION=us-central1 export CLUSTER_NAME=alloydb-ai-gke export MACHINE_TYPE=n2-highmem-2 Your active configuration is: [gleb-test-short-001-415614] student@cloudshell:~ (gleb-test-short-001-415614)$ gcloud container clusters create ${CLUSTER_NAME} \ --project=${PROJECT_ID} \ --region=${LOCATION} \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --release-channel=rapid \ --machine-type=${MACHINE_TYPE} \ --num-nodes=1 Note: The Kubelet readonly port (10255) is now deprecated. Please update your workloads to use the recommended alternatives. See https://cloud.google.com/kubernetes-engine/docs/how-to/disable-kubelet-readonly-port for ways to check usage and for migration instructions. Note: Your Pod address range (`--cluster-ipv4-cidr`) can accommodate at most 1008 node(s). Creating cluster alloydb-ai-gke in us-central1.. NAME: omni01 ZONE: us-central1-a MACHINE_TYPE: e2-standard-4 PREEMPTIBLE: INTERNAL_IP: 10.128.0.3 EXTERNAL_IP: 35.232.157.123 STATUS: RUNNING student@cloudshell:~ (gleb-test-short-001-415614)$
クラスタを準備する
cert-manager サービスなどの必要なコンポーネントをインストールする必要があります。cert-manager のインストールに関するドキュメントの手順に沿って操作します。
Kubernetes コマンドライン ツール kubectl を使用します。このツールは Cloud Shell にすでにインストールされています。このユーティリティを使用する前に、クラスタの認証情報を取得する必要があります。
gcloud container clusters get-credentials ${CLUSTER_NAME} --region=${LOCATION}
これで、kubectl を使用して cert-manager をインストールできます。
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.2/cert-manager.yaml
想定されるコンソール出力(秘匿化済み):
student@cloudshell:~$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.2/cert-manager.yaml namespace/cert-manager created customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created ... validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
AlloyDB Omni をインストールする
AlloyDB Omni オペレーターは、helm ユーティリティを使用してインストールできます。
次のコマンドを実行して AlloyDB Omni オペレータをインストールします。
export GCS_BUCKET=alloydb-omni-operator
export HELM_PATH=$(gcloud storage cat gs://$GCS_BUCKET/latest)
export OPERATOR_VERSION="${HELM_PATH%%/*}"
gcloud storage cp gs://$GCS_BUCKET/$HELM_PATH ./ --recursive
helm install alloydbomni-operator alloydbomni-operator-${OPERATOR_VERSION}.tgz \
--create-namespace \
--namespace alloydb-omni-system \
--atomic \
--timeout 5m
想定されるコンソール出力(秘匿化済み):
student@cloudshell:~$ gcloud storage cp gs://$GCS_BUCKET/$HELM_PATH ./ --recursive Copying gs://alloydb-omni-operator/1.2.0/alloydbomni-operator-1.2.0.tgz to file://./alloydbomni-operator-1.2.0.tgz Completed files 1/1 | 126.5kiB/126.5kiB student@cloudshell:~$ helm install alloydbomni-operator alloydbomni-operator-${OPERATOR_VERSION}.tgz \ > --create-namespace \ > --namespace alloydb-omni-system \ > --atomic \ > --timeout 5m NAME: alloydbomni-operator LAST DEPLOYED: Mon Jan 20 13:13:20 2025 NAMESPACE: alloydb-omni-system STATUS: deployed REVISION: 1 TEST SUITE: None student@cloudshell:~$
AlloyDB Omni オペレーターがインストールされたら、データベース クラスタのデプロイを続行できます。
以下は、googleMLExtension パラメータと内部(プライベート)ロードバランサが有効になっているデプロイ マニフェストの例です。
apiVersion: v1
kind: Secret
metadata:
name: db-pw-my-omni
type: Opaque
data:
my-omni: "VmVyeVN0cm9uZ1Bhc3N3b3Jk"
---
apiVersion: alloydbomni.dbadmin.goog/v1
kind: DBCluster
metadata:
name: my-omni
spec:
databaseVersion: "15.7.0"
primarySpec:
adminUser:
passwordRef:
name: db-pw-my-omni
features:
googleMLExtension:
enabled: true
resources:
cpu: 1
memory: 8Gi
disks:
- name: DataDisk
size: 20Gi
storageClass: standard
dbLoadBalancerOptions:
annotations:
networking.gke.io/load-balancer-type: "internal"
allowExternalIncomingTraffic: true
パスワードのシークレット値は、パスワード ワード「VeryStrongPassword」の Base64 表現です。より信頼性の高い方法は、Google Secret Manager を使用してパスワード値を保存することです。詳しくは、ドキュメントをご覧ください。
マニフェストを my-omni.yaml として保存し、次のステップで適用します。Cloud Shell を使用している場合は、ターミナルの右上にある [エディタを開く] ボタンをクリックしてエディタを使用して実行できます。
ファイルを my-omni.yaml という名前で保存したら、[ターミナルを開く] ボタンを押してターミナルに戻ります。
kubectl ユーティリティを使用して、my-omni.yaml マニフェストをクラスタに適用します。
kubectl apply -f my-omni.yaml
想定されるコンソール出力:
secret/db-pw-my-omni created dbcluster.alloydbomni.dbadmin.goog/my-omni created
kubectl ユーティリティを使用して my-omni クラスタのステータスを確認します。
kubectl get dbclusters.alloydbomni.dbadmin.goog my-omni -n default
デプロイ中に、クラスタはさまざまなフェーズを経て、最終的に DBClusterReady 状態になります。
想定されるコンソール出力:
$ kubectl get dbclusters.alloydbomni.dbadmin.goog my-omni -n default NAME PRIMARYENDPOINT PRIMARYPHASE DBCLUSTERPHASE HAREADYSTATUS HAREADYREASON my-omni 10.131.0.33 Ready DBClusterReady
AlloyDB Omni に接続する
Kubernetes Pod を使用して接続する
クラスタの準備ができたら、AlloyDB Omni インスタンス Pod で PostgreSQL クライアント バイナリを使用できます。Pod ID を見つけて、kubectl を使用して Pod に直接接続し、クライアント ソフトウェアを実行します。パスワードは、my-omni.yaml のハッシュで設定された VeryStrongPassword です。
DB_CLUSTER_NAME=my-omni
DB_CLUSTER_NAMESPACE=default
DBPOD=`kubectl get pod --selector=alloydbomni.internal.dbadmin.goog/dbcluster=$DB_CLUSTER_NAME,alloydbomni.internal.dbadmin.goog/task-type=database -n $DB_CLUSTER_NAMESPACE -o jsonpath='{.items[0].metadata.name}'`
kubectl exec -ti $DBPOD -n $DB_CLUSTER_NAMESPACE -c database -- psql -h localhost -U postgres
コンソール出力の例:
DB_CLUSTER_NAME=my-omni DB_CLUSTER_NAMESPACE=default DBPOD=`kubectl get pod --selector=alloydbomni.internal.dbadmin.goog/dbcluster=$DB_CLUSTER_NAME,alloydbomni.internal.dbadmin.goog/task-type=database -n $DB_CLUSTER_NAMESPACE -o jsonpath='{.items[0].metadata.name}'` kubectl exec -ti $DBPOD -n $DB_CLUSTER_NAMESPACE -c database -- psql -h localhost -U postgres Password for user postgres: psql (15.7) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_128_GCM_SHA256, compression: off) Type "help" for help. postgres=#
5. GKE に AI モデルをデプロイする
AlloyDB Omni AI とローカルモデルの統合をテストするには、モデルをクラスタにデプロイする必要があります。
モデルのノードプールを作成する
モデルを実行するには、推論を実行するノードプールを準備する必要があります。パフォーマンスの観点から最適なアプローチは、L4 Nvidia アクセラレータを使用する g2-standard-8 などのノード構成を使用するグラフィック アクセラレータを含むプールです。
L4 アクセラレータを使用してノードプールを作成します。
export PROJECT_ID=$(gcloud config get project)
export LOCATION=us-central1
export CLUSTER_NAME=alloydb-ai-gke
gcloud container node-pools create gpupool \
--accelerator type=nvidia-l4,count=1,gpu-driver-version=latest \
--project=${PROJECT_ID} \
--location=${LOCATION} \
--node-locations=${LOCATION}-a \
--cluster=${CLUSTER_NAME} \
--machine-type=g2-standard-8 \
--num-nodes=1
想定される出力
student@cloudshell$ export PROJECT_ID=$(gcloud config get project) Your active configuration is: [pant] export LOCATION=us-central1 export CLUSTER_NAME=alloydb-ai-gke student@cloudshell$ gcloud container node-pools create gpupool \ > --accelerator type=nvidia-l4,count=1,gpu-driver-version=latest \ > --project=${PROJECT_ID} \ > --location=${LOCATION} \ > --node-locations=${LOCATION}-a \ > --cluster=${CLUSTER_NAME} \ > --machine-type=g2-standard-8 \ > --num-nodes=1 Note: Machines with GPUs have certain limitations which may affect your workflow. Learn more at https://cloud.google.com/kubernetes-engine/docs/how-to/gpus Note: Starting in GKE 1.30.1-gke.115600, if you don't specify a driver version, GKE installs the default GPU driver for your node's GKE version. Creating node pool gpupool...done. Created [https://container.googleapis.com/v1/projects/student-test-001/zones/us-central1/clusters/alloydb-ai-gke/nodePools/gpupool]. NAME MACHINE_TYPE DISK_SIZE_GB NODE_VERSION gpupool g2-standard-8 100 1.31.4-gke.1183000
Deployment マニフェストを準備する
モデルをデプロイするには、デプロイ マニフェストを準備する必要があります。
Google では、Hugging Face の BGE Base v1.5 エンベディング モデルを使用しています。モデルカードはこちらでご覧いただけます。モデルをデプロイするには、Hugging Face から事前に準備された手順と GitHub のデプロイ パッケージを使用します。
パッケージのクローンを作成する
git clone https://github.com/huggingface/Google-Cloud-Containers
cloud.google.com/gke-accelerator の値を nvidia-l4 に置き換え、リソースに上限を追加して、マニフェストを編集します。
vi Google-Cloud-Containers/examples/gke/tei-deployment/gpu-config/deployment.yaml
修正済みマニフェストは次のとおりです。
apiVersion: apps/v1
kind: Deployment
metadata:
name: tei-deployment
spec:
replicas: 1
selector:
matchLabels:
app: tei-server
template:
metadata:
labels:
app: tei-server
hf.co/model: Snowflake--snowflake-arctic-embed-m
hf.co/task: text-embeddings
spec:
containers:
- name: tei-container
image: us-docker.pkg.dev/deeplearning-platform-release/gcr.io/huggingface-text-embeddings-inference-cu122.1-4.ubuntu2204:latest
resources:
requests:
nvidia.com/gpu: 1
limits:
nvidia.com/gpu: 1
env:
- name: MODEL_ID
value: Snowflake/snowflake-arctic-embed-m
- name: NUM_SHARD
value: "1"
- name: PORT
value: "8080"
volumeMounts:
- mountPath: /dev/shm
name: dshm
- mountPath: /data
name: data
volumes:
- name: dshm
emptyDir:
medium: Memory
sizeLimit: 1Gi
- name: data
emptyDir: {}
nodeSelector:
cloud.google.com/gke-accelerator: nvidia-l4
モデルをデプロイする
デプロイ用のサービス アカウントと Namespace を準備する必要があります。
Kubernetes Namespace hf-gke-namespace を作成します。
export NAMESPACE=hf-gke-namespace
kubectl create namespace $NAMESPACE
Kubernetes サービス アカウントを作成する
export SERVICE_ACCOUNT=hf-gke-service-account
kubectl create serviceaccount $SERVICE_ACCOUNT --namespace $NAMESPACE
モデルをデプロイする
kubectl apply -f Google-Cloud-Containers/examples/gke/tei-deployment/gpu-config
デプロイを確認する
kubectl get pods
モデルサービスを確認する
kubectl get service tei-service
実行中の Service タイプ ClusterIP が表示されるはずです。
出力例:
student@cloudshell$ kubectl get service tei-service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE tei-service ClusterIP 34.118.233.48 <none> 8080/TCP 10m
サービスの CLUSTER-IP をエンドポイント アドレスとして使用します。モデルのエンベディングは、URI http://34.118.233.48:8080/embed で応答できます。これは、後で AlloyDB Omni にモデルを登録するときに使用します。
これをテストするには、kubectl port-forward コマンドを使用して公開します。
kubectl port-forward service/tei-service 8080:8080
ポート転送は 1 つの Cloud Shell セッションで実行されるため、テストするには別のセッションが必要です。
上部の「+」記号を選択して、別の Cloud Shell タブを開きます。
新しいシェル セッションで curl コマンドを実行します。
curl http://localhost:8080/embed \
-X POST \
-d '{"inputs":"Test"}' \
-H 'Content-Type: application/json'
次のようなサンプル出力(編集済み)のようなベクトル配列が返されます。
curl http://localhost:8080/embed \ > -X POST \ > -d '{"inputs":"Test"}' \ > -H 'Content-Type: application/json' [[-0.018975832,0.0071419072,0.06347208,0.022992613,0.014205903 ... -0.03677433,0.01636146,0.06731572]]
6. AlloyDB Omni にモデルを登録します。
デプロイされたモデルで AlloyDB Omni がどのように機能するかをテストするには、データベースを作成してモデルを登録する必要があります。
データベースを作成する
ジャンプボックスとして GCE VM を作成し、クライアント VM から AlloyDB Omni に接続してデータベースを作成します。
Omni 用の GKE 外部ロードバランサは、限定公開 IP アドレスを使用して VPC からアクセスできますが、VPC の外部から接続することはできません。そのため、ジャンプボックスが必要です。一般に安全性が高く、データベース インスタンスがインターネットに公開されることはありません。わかりやすくするため、図を参照してください。
Cloud Shell セッションで VM を作成するには、次のコマンドを実行します。
export ZONE=us-central1-a
gcloud compute instances create instance-1 \
--zone=$ZONE
Cloud Shell で kubectl を使用して AlloyDB Omni エンドポイントの IP を確認します。
kubectl get dbclusters.alloydbomni.dbadmin.goog my-omni -n default
PRIMARYENDPOINT をメモします。たとえば、
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 は、AlloyDB Omni インスタンスへの接続に使用する IP です。
gcloud を使用して VM に接続します。
gcloud compute ssh instance-1 --zone=$ZONE
SSH 認証鍵の生成を求めるメッセージが表示されたら、手順に沿って操作します。SSH 接続の詳細については、ドキュメントをご覧ください。
VM への SSH セッションで PostgreSQL クライアントをインストールします。
sudo apt-get update
sudo apt-get install --yes postgresql-client
次の例のように AlloyDB Omni ロードバランサの IP をエクスポートします(IP はロードバランサの IP に置き換えます)。
export INSTANCE_IP=10.131.0.33
AlloyDB Omni に接続します。パスワードは、my-omni.yaml のハッシュで設定した VeryStrongPassword です。
psql "host=$INSTANCE_IP user=postgres sslmode=require"
確立された psql セッションで、次のコマンドを実行します。
create database demo;
セッションを終了してデータベース デモに接続します(または、同じセッションで「\c demo」を実行することもできます)。
psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"
変換関数を作成する
サードパーティのエンベディング モデルの場合は、モデルと内部関数で想定される形式に入力と出力をフォーマットする変換関数を作成する必要があります。
入力を処理する変換関数は次のとおりです。
-- Input Transform Function corresponding to the custom model endpoint
CREATE OR REPLACE FUNCTION tei_text_input_transform(model_id VARCHAR(100), input_text TEXT)
RETURNS JSON
LANGUAGE plpgsql
AS $$
DECLARE
transformed_input JSON;
model_qualified_name TEXT;
BEGIN
SELECT json_build_object('inputs', input_text, 'truncate', true)::JSON INTO transformed_input;
RETURN transformed_input;
END;
$$;
サンプル出力に示すように、デモデータベースに接続した状態で、提供されたコードを実行します。
demo=# -- Input Transform Function corresponding to the custom model endpoint CREATE OR REPLACE FUNCTION tei_text_input_transform(model_id VARCHAR(100), input_text TEXT) RETURNS JSON LANGUAGE plpgsql AS $$ DECLARE transformed_input JSON; model_qualified_name TEXT; BEGIN SELECT json_build_object('inputs', input_text, 'truncate', true)::JSON INTO transformed_input; RETURN transformed_input; END; $$; CREATE FUNCTION demo=#
以下は、モデルからのレスポンスを実数配列に変換する出力関数です。
-- Output Transform Function corresponding to the custom model endpoint
CREATE OR REPLACE FUNCTION tei_text_output_transform(model_id VARCHAR(100), response_json JSON)
RETURNS REAL[]
LANGUAGE plpgsql
AS $$
DECLARE
transformed_output REAL[];
BEGIN
SELECT ARRAY(SELECT json_array_elements_text(response_json->0)) INTO transformed_output;
RETURN transformed_output;
END;
$$;
同じセッションで実行します。
demo=# -- Output Transform Function corresponding to the custom model endpoint CREATE OR REPLACE FUNCTION tei_text_output_transform(model_id VARCHAR(100), response_json JSON) RETURNS REAL[] LANGUAGE plpgsql AS $$ DECLARE transformed_output REAL[]; BEGIN SELECT ARRAY(SELECT json_array_elements_text(response_json->0)) INTO transformed_output; RETURN transformed_output; END; $$; CREATE FUNCTION demo=#
モデルを登録する
これで、モデルをデータベースに登録できます。
次は、bge-base-1.5 という名前でモデルを登録するプロシージャ呼び出しです。IP 34.118.233.48 は、モデルサービス IP アドレス(kubectl get service tei-service の出力)に置き換えてください。
CALL
google_ml.create_model(
model_id => 'bge-base-1.5',
model_request_url => 'http://34.118.233.48:8080/embed',
model_provider => 'custom',
model_type => 'text_embedding',
model_in_transform_fn => 'tei_text_input_transform',
model_out_transform_fn => 'tei_text_output_transform');
デモデータベースに接続した状態で、提供されたコードを実行します。
demo=# CALL google_ml.create_model( model_id => 'bge-base-1.5', model_request_url => 'http://34.118.233.48:8080/embed', model_provider => 'custom', model_type => 'text_embedding', model_in_transform_fn => 'tei_text_input_transform', model_out_transform_fn => 'tei_text_output_transform'); CALL demo=#
次のテストクエリを使用してレジスタモデルをテストできます。このクエリは実数配列を返します。
select google_ml.embedding('bge-base-1.5','What is AlloyDB Omni?');
7. AlloyDB Omni でモデルをテストする
データの読み込み
デプロイされたモデルで AlloyDB Omni がどのように機能するかをテストするには、データを読み込む必要があります。AlloyDB のベクトル検索では、他の Codelab のいずれかで使用したものと同じデータを使用しました。
データを読み込む方法の 1 つは、Google Cloud SDK と PostgreSQL クライアント ソフトウェアを使用する方法です。デモ データベースの作成に使用したクライアント VM を使用できます。VM イメージのデフォルトを使用した場合、Google Cloud SDK はすでにインストールされています。ただし、Google SDK を使用せずにカスタム イメージを使用している場合は、ドキュメントに沿って追加できます。
次の例のように AlloyDB Omni ロードバランサの IP をエクスポートします(IP はロードバランサの IP に置き換えます)。
export INSTANCE_IP=10.131.0.33
データベースに接続し、pgvector 拡張機能を有効にします。
psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"
psql セッションで次のコマンドを実行します。
CREATE EXTENSION IF NOT EXISTS vector;
psql セッションを終了し、コマンドライン セッションでコマンドを実行して、データをデモデータベースに読み込みます。
テーブルを作成します。
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=demo"
想定されるコンソール出力:
student@cloudshell:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=demo" Password for user postgres: SET SET SET SET SET set_config ------------ (1 row) SET SET SET SET SET SET CREATE TABLE ALTER TABLE CREATE TABLE ALTER TABLE CREATE TABLE ALTER TABLE CREATE TABLE ALTER TABLE CREATE SEQUENCE ALTER TABLE ALTER SEQUENCE ALTER TABLE ALTER TABLE ALTER TABLE student@cloudshell:~$
作成されたテーブルのリストは次のとおりです。
psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\dt+"
出力:
student@cloudshell:~$ psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\dt+" Password for user postgres: List of relations Schema | Name | Type | Owner | Persistence | Access method | Size | Description --------+------------------+-------+----------+-------------+---------------+------------+------------- public | cymbal_embedding | table | postgres | permanent | heap | 8192 bytes | public | cymbal_inventory | table | postgres | permanent | heap | 8192 bytes | public | cymbal_products | table | postgres | permanent | heap | 8192 bytes | public | cymbal_stores | table | postgres | permanent | heap | 8192 bytes | (4 rows) student@cloudshell:~$
cymbal_products テーブルにデータを読み込みます。
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_products from stdin csv header"
想定されるコンソール出力:
student@cloudshell:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_products from stdin csv header" COPY 941 student@cloudshell:~$
cymbal_products テーブルのいくつかの行の例を次に示します。
psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT uniq_id,left(product_name,30),left(product_description,50),sale_price FROM cymbal_products limit 3"
出力:
student@cloudshell:~$ psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT uniq_id,left(product_name,30),left(product_description,50),sale_price FROM cymbal_products limit 3" Password for user postgres: uniq_id | left | left | sale_price ----------------------------------+--------------------------------+----------------------------------------------------+------------ a73d5f754f225ecb9fdc64232a57bc37 | Laundry Tub Strainer Cup | Laundry tub strainer cup Chrome For 1-.50, drain | 11.74 41b8993891aa7d39352f092ace8f3a86 | LED Starry Star Night Light La | LED Starry Star Night Light Laser Projector 3D Oc | 46.97 ed4a5c1b02990a1bebec908d416fe801 | Surya Horizon HRZ-1060 Area Ru | The 100% polypropylene construction of the Surya | 77.4 (3 rows) student@cloudshell:~$
cymbal_inventory テーブルにデータを読み込みます。
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_inventory from stdin csv header"
想定されるコンソール出力:
student@cloudshell:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_inventory from stdin csv header" Password for user postgres: COPY 263861 student@cloudshell:~$
cymbal_inventory テーブルのいくつかの行の例を次に示します。
psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT * FROM cymbal_inventory LIMIT 3"
出力:
student@cloudshell:~$ psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT * FROM cymbal_inventory LIMIT 3" Password for user postgres: store_id | uniq_id | inventory ----------+----------------------------------+----------- 1583 | adc4964a6138d1148b1d98c557546695 | 5 1490 | adc4964a6138d1148b1d98c557546695 | 4 1492 | adc4964a6138d1148b1d98c557546695 | 3 (3 rows) student@cloudshell:~$
cymbal_stores テーブルにデータを読み込みます。
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_stores from stdin csv header"
想定されるコンソール出力:
student@cloudshell:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "\copy cymbal_stores from stdin csv header" Password for user postgres: COPY 4654 student@cloudshell:~$
cymbal_stores テーブルのいくつかの行の例を次に示します。
psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT store_id, name, zip_code FROM cymbal_stores limit 3"
出力:
student@cloudshell:~$ psql "host=$INSTANCE_IP user=postgres dbname=demo" -c "SELECT store_id, name, zip_code FROM cymbal_stores limit 3" Password for user postgres: store_id | name | zip_code ----------+-------------------+---------- 1990 | Mayaguez Store | 680 2267 | Ware Supercenter | 1082 4359 | Ponce Supercenter | 780 (3 rows) student@cloudshell:~$
エンベディングを構築する
psql を使用してデモデータベースに接続し、商品名と説明に基づいて cymbal_products テーブルに記述されている商品のエンベディングを構築します。
デモデータベースに接続します。
psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"
エンベディングを保存するために、列エンベディングを含む cymbal_embedding テーブルを使用しています。関数へのテキスト入力として商品説明を使用しています。
クエリのタイミングを有効にして、後でリモートモデルと比較します。
\timing
クエリを実行してエンベディングを作成します。
INSERT INTO cymbal_embedding(uniq_id,embedding) SELECT uniq_id, google_ml.embedding('bge-base-1.5',product_description)::vector FROM cymbal_products;
想定されるコンソール出力:
demo=# INSERT INTO cymbal_embedding(uniq_id,embedding) SELECT uniq_id, google_ml.embedding('bge-base-1.5',product_description)::vector FROM cymbal_products; INSERT 0 941 Time: 11069.762 ms (00:11.070) demo=#
この例では、941 件のレコードのエンベディングの作成に約 11 秒かかりました。
テストクエリを実行する
psql を使用してデモデータベースに接続し、エンベディングの構築と同様に、タイミングを有効にしてクエリの実行時間を測定します。
ベクトル検索のアルゴリズムとしてコサイン距離を使用して、「この地域でよく育つ果樹は何ですか?」などのリクエストに一致する上位 5 件の商品を見つけてみましょう。
psql セッションで、次のコマンドを実行します。
SELECT
cp.product_name,
left(cp.product_description,80) as description,
cp.sale_price,
cs.zip_code,
(ce.embedding <=> google_ml.embedding('bge-base-1.5','What kind of fruit trees grow well here?')::vector) as distance
FROM
cymbal_products cp
JOIN cymbal_embedding ce on
ce.uniq_id=cp.uniq_id
JOIN cymbal_inventory ci on
ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
cs.store_id=ci.store_id
AND ci.inventory>0
AND cs.store_id = 1583
ORDER BY
distance ASC
LIMIT 5;
想定されるコンソール出力:
demo=# SELECT cp.product_name, left(cp.product_description,80) as description, cp.sale_price, cs.zip_code, (ce.embedding <=> google_ml.embedding('bge-base-1.5','What kind of fruit trees grow well here?')::vector) as distance FROM cymbal_products cp JOIN cymbal_embedding ce on ce.uniq_id=cp.uniq_id JOIN cymbal_inventory ci on ci.uniq_id=cp.uniq_id JOIN cymbal_stores cs on cs.store_id=ci.store_id AND ci.inventory>0 AND cs.store_id = 1583 ORDER BY distance ASC LIMIT 5; product_name | description | sale_price | zip_code | distance -----------------------+----------------------------------------------------------------------------------+------------+----------+--------------------- California Sycamore | This is a beautiful sycamore tree that can grow to be over 100 feet tall. It is | 300.00 | 93230 | 0.22753925487632942 Toyon | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e | 10.00 | 93230 | 0.23497374266229387 California Peppertree | This is a beautiful peppertree that can grow to be over 30 feet tall. It is an e | 25.00 | 93230 | 0.24215884459965364 California Redwood | This is a beautiful redwood tree that can grow to be over 300 feet tall. It is a | 1000.00 | 93230 | 0.24564130578287147 Cherry Tree | This is a beautiful cherry tree that will produce delicious cherries. It is an d | 75.00 | 93230 | 0.24846117929767153 (5 rows) Time: 28.724 ms demo=#
クエリの実行時間は 28 ミリ秒で、リクエストに一致し、ストアで在庫がある番号 1583 のシンバル プロダクト テーブルから木のリストが返されました。
ANN インデックスを作成する
データセットが小さい場合は、すべてのエンベディングをスキャンする完全一致検索が簡単ですが、データが増えると、読み込み時間とレスポンス時間も増加します。パフォーマンスを向上させるには、エンベディング データにインデックスを作成します。ベクトルデータに Google ScaNN インデックスを使用する方法の例を次に示します。
接続が切断された場合は、デモデータベースに再接続します。
psql "host=$INSTANCE_IP user=postgres sslmode=require dbname=demo"
alloydb_scann 拡張機能を有効にします。
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
インデックスをビルドします。
CREATE INDEX cymbal_embedding_scann ON cymbal_embedding USING scann (embedding cosine);
前と同じクエリを試して、結果を比較します。
demo=# SELECT cp.product_name, left(cp.product_description,80) as description, cp.sale_price, cs.zip_code, (ce.embedding <=> google_ml.embedding('bge-base-1.5','What kind of fruit trees grow well here?')::vector) as distance FROM cymbal_products cp JOIN cymbal_embedding ce on ce.uniq_id=cp.uniq_id JOIN cymbal_inventory ci on ci.uniq_id=cp.uniq_id JOIN cymbal_stores cs on cs.store_id=ci.store_id AND ci.inventory>0 AND cs.store_id = 1583 ORDER BY distance ASC LIMIT 5; product_name | description | sale_price | zip_code | distance -----------------------+----------------------------------------------------------------------------------+------------+----------+--------------------- California Sycamore | This is a beautiful sycamore tree that can grow to be over 100 feet tall. It is | 300.00 | 93230 | 0.22753925487632942 Toyon | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e | 10.00 | 93230 | 0.23497374266229387 California Peppertree | This is a beautiful peppertree that can grow to be over 30 feet tall. It is an e | 25.00 | 93230 | 0.24215884459965364 California Redwood | This is a beautiful redwood tree that can grow to be over 300 feet tall. It is a | 1000.00 | 93230 | 0.24564130578287147 Fremont Cottonwood | This is a beautiful cottonwood tree that can grow to be over 100 feet tall. It i | 200.00 | 93230 | 0.2533482837690365 (5 rows) Time: 14.665 ms demo=#
クエリの実行時間がわずかに短縮されました。この時間短縮は、データセットが大きいほど顕著になります。結果は非常に類似しており、Cherry のみが Fremont Cottonwood に置き換えられています。
他のクエリを試し、ベクトル インデックスの選択について詳しくは、ドキュメントをご覧ください。
AlloyDB Omni には、他にも多くの機能とラボがあります。
8. 環境をクリーンアップする
これで、AlloyDB Omni と AI モデルを使用して GKE クラスタを削除できます。
GKE クラスタを削除する
Cloud Shell で、次のコマンドを実行します。
export PROJECT_ID=$(gcloud config get project)
export LOCATION=us-central1
export CLUSTER_NAME=alloydb-ai-gke
gcloud container clusters delete ${CLUSTER_NAME} \
--project=${PROJECT_ID} \
--region=${LOCATION}
想定されるコンソール出力:
student@cloudshell:~$ gcloud container clusters delete ${CLUSTER_NAME} \ > --project=${PROJECT_ID} \ > --region=${LOCATION} The following clusters will be deleted. - [alloydb-ai-gke] in [us-central1] Do you want to continue (Y/n)? Y Deleting cluster alloydb-ai-gke...done. Deleted
VM の削除
Cloud Shell で、次のコマンドを実行します。
export PROJECT_ID=$(gcloud config get project)
export ZONE=us-central1-a
gcloud compute instances delete instance-1 \
--project=${PROJECT_ID} \
--zone=${ZONE}
想定されるコンソール出力:
student@cloudshell:~$ export PROJECT_ID=$(gcloud config get project) export ZONE=us-central1-a gcloud compute instances delete instance-1 \ --project=${PROJECT_ID} \ --zone=${ZONE} Your active configuration is: [cloudshell-5399] The following instances will be deleted. Any attached disks configured to be auto-deleted will be deleted unless they are attached to any other instances or the `--keep-disks` flag is given and specifies them for keeping. Deleting a disk is irreversible and any data on the disk will be lost. - [instance-1] in [us-central1-a] Do you want to continue (Y/n)? Y Deleted
この Codelab 用に新しいプロジェクトを作成した場合は、代わりにプロジェクト全体を削除できます。https://console.cloud.google.com/cloud-resource-manager
9. 完了
以上で、この Codelab は完了です。
学習した内容
- Google Kubernetes クラスタに AlloyDB Omni をデプロイする方法
- AlloyDB Omni に接続する方法
- AlloyDB Omni にデータを読み込む方法
- オープン エンベディング モデルを GKE にデプロイする方法
- AlloyDB Omni でエンベディング モデルを登録する方法
- セマンティック検索用のエンベディングを生成する方法
- AlloyDB Omni で生成されたエンベディングをセマンティック検索に使用する方法
- AlloyDB でベクトル インデックスを作成して使用する方法
AlloyDB Omni で AI を操作する方法について詳しくは、ドキュメントをご覧ください。
10. アンケート
出力: