マルチモーダル エンベディングの生成と検索
このチュートリアルでは、画像とテキストのマルチモーダル エンベディングを作成し、クロスモダリティのテキストから画像への検索を行うエンドツーエンドのプロセスについて説明します。
このチュートリアルでは、次のタスクについて説明します。
- Cloud Storage バケット内の画像データに対して BigQuery オブジェクト テーブルを作成する。
- BigQuery の Colab Enterprise ノートブックを使用して画像データを探索する。
- Vertex AI
multimodalembedding
基盤モデルをターゲットとする BigQuery ML リモートモデルを作成する。 - リモートモデルと
ML.GENERATE_EMBEDDING
関数を使用して、オブジェクト テーブル内の画像からエンベディングを生成する。 - エンベディング生成エラーを修正する。
- 必要に応じて、ベクトル インデックスを作成して、画像エンベディングにインデックスを付ける。
- 指定された検索文字列のテキスト エンベディングを作成する。
VECTOR_SEARCH
関数を使用して、テキスト エンベディングに類似した画像エンベディングを検索する。- ノートブックを使用して結果を可視化する。
このチュートリアルでは、Cloud Storage の公開バケット gcs-public-data--met
にあるメトロポリタン美術館のパブリック ドメインのアート画像を使用します。
必要な権限
このチュートリアルを実行するには、次の Identity and Access Management(IAM)権限が必要です。
接続を作成するには、BigQuery 接続管理者(
roles/bigquery.connectionAdmin
)ロールのメンバーシップが必要です。接続のサービス アカウントに権限を付与するには、
resourcemanager.projects.setIamPolicy
権限が必要です。ノートブックを作成して実行するには、次の IAM 権限が必要です。
resourcemanager.projects.get
resourcemanager.projects.list
bigquery.config.get
bigquery.jobs.create
bigquery.readsessions.create
bigquery.readsessions.getData
bigquery.readsessions.update
resourcemanager.projects.get
resourcemanager.projects.list
dataform.locations.get
dataform.locations.list
dataform.repositories.create
dataform.repositories.list
dataform.collections.create
dataform.collections.list
aiplatform.notebookRuntimeTemplates.apply
aiplatform.notebookRuntimeTemplates.get
aiplatform.notebookRuntimeTemplates.list
aiplatform.notebookRuntimeTemplates.getIamPolicy
aiplatform.notebookRuntimes.assign
aiplatform.notebookRuntimes.get
aiplatform.notebookRuntimes.list
aiplatform.operations.list
これらの権限は、次の IAM ロールから取得できます。
- BigQuery 読み取りセッション ユーザー(
roles/bigquery.readSessionUser
) - BigQuery Studio ユーザー(
roles/bigquery.studioUser
)
このチュートリアルで、残りの BigQuery オペレーションに必要となる IAM 権限は、次の 2 つのロールに含まれています。
- BigQuery データ編集者(
roles/bigquery.dataEditor
)。モデル、テーブル、インデックスを作成するためのロールです。 - BigQuery ユーザー(
roles/bigquery.user
)。BigQuery ジョブを実行するためのロールです。
- BigQuery データ編集者(
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
- BigQuery ML: You incur costs for the data that you process in BigQuery.
- Vertex AI: You incur costs for calls to the Vertex AI service that's represented by the remote model.
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
BigQuery の料金の詳細については、BigQuery ドキュメントの BigQuery の料金をご覧ください。
Vertex AI の料金の詳細については、Vertex AI の料金のページをご覧ください。
始める前に
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the BigQuery, BigQuery Connection, and Vertex AI APIs.
- BigQuery Studio を有効にする
データセットを作成する
ML モデルを格納する BigQuery データセットを作成します。
Google Cloud コンソールで [BigQuery] ページに移動します。
[エクスプローラ] ペインで、プロジェクト名をクリックします。
「アクションを表示」> [データセットを作成] をクリックします。
[データセットを作成する] ページで、次の操作を行います。
[データセット ID] に「
bqml_tutorial
」と入力します。[ロケーション タイプ] で [マルチリージョン] を選択してから、[US (米国の複数のリージョン)] を選択します。
一般公開データセットは
US
マルチリージョンに保存されています。わかりやすくするため、データセットを同じロケーションに保存します。残りのデフォルトの設定は変更せず、[データセットを作成] をクリックします。
接続を作成する
クラウド リソース接続を作成し、接続のサービス アカウントを取得します。前の手順で作成したデータセットと同じロケーションに接続を作成します。
次のオプションのいずれかを選択します。
コンソール
BigQuery ページに移動します。
接続を作成するには、[
追加] をクリックし、続いて [外部データソースへの接続] をクリックします。[接続タイプ] リストで、[Vertex AI リモートモデル、リモート関数、BigLake(Cloud リソース)] を選択します。
[接続 ID] フィールドに接続の名前を入力します。
[接続を作成] をクリックします。
[接続へ移動] をクリックします。
[接続情報] ペインで、後の手順で使用するサービス アカウント ID をコピーします。
bq
コマンドライン環境で接続を作成します。
bq mk --connection --location=REGION --project_id=PROJECT_ID \ --connection_type=CLOUD_RESOURCE CONNECTION_ID
--project_id
パラメータは、デフォルト プロジェクトをオーバーライドします。以下を置き換えます。
REGION
: 接続のリージョンPROJECT_ID
: 実際の Google Cloud プロジェクト IDCONNECTION_ID
: 接続の ID
接続リソースを作成すると、BigQuery は、一意のシステム サービス アカウントを作成し、それを接続に関連付けます。
トラブルシューティング: 次の接続エラーが発生した場合は、Google Cloud SDK を更新します。
Flags parsing error: flag --connection_type=CLOUD_RESOURCE: value should be one of...
後の手順で使用するため、サービス アカウント ID を取得してコピーします。
bq show --connection PROJECT_ID.REGION.CONNECTION_ID
出力は次のようになります。
name properties 1234.REGION.CONNECTION_ID {"serviceAccountId": "connection-1234-9u56h9@gcp-sa-bigquery-condel.iam.gserviceaccount.com"}
Terraform
google_bigquery_connection
リソースを使用します。
BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、クライアント ライブラリの認証を設定するをご覧ください。
次の例では、US
リージョンに my_cloud_resource_connection
という名前の Cloud リソース接続を作成します。
Google Cloud プロジェクトで Terraform 構成を適用するには、次のセクションの手順を完了します。
Cloud Shell を準備する
- Cloud Shell を起動します。
-
Terraform 構成を適用するデフォルトの Google Cloud プロジェクトを設定します。
このコマンドは、プロジェクトごとに 1 回だけ実行する必要があります。これは任意のディレクトリで実行できます。
export GOOGLE_CLOUD_PROJECT=PROJECT_ID
Terraform 構成ファイルに明示的な値を設定すると、環境変数がオーバーライドされます。
ディレクトリを準備する
Terraform 構成ファイルには独自のディレクトリ(ルート モジュールとも呼ばれます)が必要です。
-
Cloud Shell で、ディレクトリを作成し、そのディレクトリ内に新しいファイルを作成します。ファイルの拡張子は
.tf
にする必要があります(例:main.tf
)。このチュートリアルでは、このファイルをmain.tf
とします。mkdir DIRECTORY && cd DIRECTORY && touch main.tf
-
チュートリアルを使用している場合は、各セクションまたはステップのサンプルコードをコピーできます。
新しく作成した
main.tf
にサンプルコードをコピーします。必要に応じて、GitHub からコードをコピーします。Terraform スニペットがエンドツーエンドのソリューションの一部である場合は、この方法をおすすめします。
- 環境に適用するサンプル パラメータを確認し、変更します。
- 変更を保存します。
-
Terraform を初期化します。これは、ディレクトリごとに 1 回だけ行う必要があります。
terraform init
必要に応じて、最新バージョンの Google プロバイダを使用する場合は、
-upgrade
オプションを使用します。terraform init -upgrade
変更を適用する
-
構成を確認して、Terraform が作成または更新するリソースが想定どおりであることを確認します。
terraform plan
必要に応じて構成を修正します。
-
次のコマンドを実行し、プロンプトで「
yes
」と入力して、Terraform 構成を適用します。terraform apply
Terraform に「Apply complete!」のメッセージが表示されるまで待ちます。
- Google Cloud プロジェクトを開いて結果を表示します。Google Cloud コンソールの UI でリソースに移動して、Terraform によって作成または更新されたことを確認します。
接続のサービス アカウントに権限を付与する
Cloud Storage サービスと Vertex AI サービスにアクセスするために、接続のサービス アカウントに適切なロールを付与します。これらのロールは、始める前にで作成または選択したプロジェクトで付与する必要があります。別のプロジェクトでロールを付与すると、bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.iam.gserviceaccount.com does not have the permission to access resource
エラーが発生します。
適切なロールを付与する手順は次のとおりです。
[IAM と管理] ページに移動します。
[
アクセス権を付与] をクリックします。[新しいプリンシパル] フィールドに、前の手順でコピーしたサービス アカウント ID を入力します。
[ロールを選択] フィールドで、[Vertex AI]、[Vertex AI ユーザー] の順に選択します。
[別のロールを追加] をクリックします。
[ロールを選択] フィールドで、[Cloud Storage] を選択し、続いて [Storage オブジェクト閲覧者] を選択します。
[保存] をクリックします。
オブジェクト テーブルを作成する
公開 Cloud Storage gcs-public-data--met
バケットの画像に対してオブジェクト テーブルを作成します。オブジェクト テーブルを使用すると、Cloud Storage から画像を移動せずに分析できます。
Google Cloud コンソールで [BigQuery] ページに移動します。
[クエリエディタ] ペインで、次のクエリを実行します。
CREATE OR REPLACE EXTERNAL TABLE `bqml_tutorial.met_images` WITH CONNECTION `LOCATION.CONNECTION_ID` OPTIONS ( object_metadata = 'SIMPLE', uris = ['gs://gcs-public-data--met/*'] );
次のように置き換えます。
LOCATION
: 接続のロケーション。CONNECTION_ID
: BigQuery 接続の ID。Google Cloud コンソールで接続の詳細を表示する場合、これは [接続 ID] に表示される完全修飾接続 ID の最後のセクションの値です。例:
projects/myproject/locations/connection_location/connections/myconnection
画像データを調べる
BigQuery で Colab Enterprise ノートブックを作成して、画像データを調べます。
Google Cloud コンソールで [BigQuery] ページに移動します。
ノートブックを設定します。
- ノートブックにコードセルを追加します。
次のコードをコピーして、コードセルに貼り付けます。
#@title Set up credentials from google.colab import auth auth.authenticate_user() print('Authenticated') PROJECT_ID='PROJECT_ID' from google.cloud import bigquery client = bigquery.Client(PROJECT_ID)
PROJECT_ID
は、このチュートリアルで使用するプロジェクトの名前に置き換えます。コードセルを実行します。
テーブル表示を有効にします。
- ノートブックにコードセルを追加します。
次のコードをコピーして、コードセルに貼り付けます。
#@title Enable data table display %load_ext google.colab.data_table
コードセルを実行します。
画像を表示する関数を作成します。
- ノートブックにコードセルを追加します。
次のコードをコピーして、コードセルに貼り付けます。
#@title Util function to display images import io from PIL import Image import matplotlib.pyplot as plt import tensorflow as tf def printImages(results): image_results_list = list(results) amt_of_images = len(image_results_list) fig, axes = plt.subplots(nrows=amt_of_images, ncols=2, figsize=(20, 20)) fig.tight_layout() fig.subplots_adjust(hspace=0.5) for i in range(amt_of_images): gcs_uri = image_results_list[i][0] text = image_results_list[i][1] f = tf.io.gfile.GFile(gcs_uri, 'rb') stream = io.BytesIO(f.read()) img = Image.open(stream) axes[i, 0].axis('off') axes[i, 0].imshow(img) axes[i, 1].axis('off') axes[i, 1].text(0, 0, text, fontsize=10) plt.show()
コードセルを実行します。
画像を表示します。
- ノートブックにコードセルを追加します。
次のコードをコピーして、コードセルに貼り付けます。
#@title Display Met images inspect_obj_table_query = """ SELECT uri, content_type FROM bqml_tutorial.met_images WHERE content_type = 'image/jpeg' Order by uri LIMIT 10; """ printImages(client.query(inspect_obj_table_query))
コードセルを実行します。
結果は次のようになります。
ノートブックを
met-image-analysis
として保存します。
リモートモデルを作成する
ホストされる Vertex AI マルチモーダル エンベディング モデルを表すリモートモデルを作成します。
Google Cloud コンソールで [BigQuery] ページに移動します。
[クエリエディタ] ペインで、次のクエリを実行します。
CREATE OR REPLACE MODEL `bqml_tutorial.multimodal_embedding_model` REMOTE WITH CONNECTION `LOCATION.CONNECTION_ID` OPTIONS (ENDPOINT = 'multimodalembedding@001');
次のように置き換えます。
LOCATION
: 接続のロケーション。CONNECTION_ID
: BigQuery 接続の ID。Google Cloud コンソールで接続の詳細を表示する場合、これは [接続 ID] に表示される完全修飾接続 ID の最後のセクションの値です。例:
projects/myproject/locations/connection_location/connections/myconnection
クエリが完了するまでに数秒かかります。完了後、
multimodal_embedding_model
モデルが [エクスプローラ] ペインのbqml_tutorial
データセットに表示されます。クエリはCREATE MODEL
ステートメントを使用してモデルを作成するため、クエリの結果はありません。
画像のエンベディングを生成する
ML.GENERATE_EMBEDDING
関数を使用してオブジェクト テーブル内の画像からエンベディングを生成し、次のステップで使用するためにテーブルに書き込みます。エンベディングの生成は負荷の高い処理であるため、クエリで 601,294 枚の画像を含むデータセット全体を対象にするのではなく、LIMIT
句を含むサブクエリを使用して、10,000 枚の画像に限定してエンベディングを生成します。また、ML.GENERATE_EMBEDDING
関数の上限である 25,000 未満の画像数を維持するためにも役立ちます。このクエリの実行には約 40 分かかります。
Google Cloud コンソールで [BigQuery] ページに移動します。
[クエリエディタ] ペインで、次のクエリを実行します。
CREATE OR REPLACE TABLE `bqml_tutorial.met_image_embeddings` AS SELECT * FROM ML.GENERATE_EMBEDDING( MODEL `bqml_tutorial.multimodal_embedding_model`, (SELECT * FROM `bqml_tutorial.met_images` WHERE content_type = 'image/jpeg' LIMIT 10000))
エンベディング生成エラーを修正する
エンベディング生成エラーがないか確認して修正します。Vertex AI での生成 AI の割り当てまたはサービスの利用不可が原因で、エンベディングの生成が失敗することがあります。
ML.GENERATE_EMBEDDING
関数は、ml_generate_embedding_status
列にエラーの詳細を返します。エンベディングの生成が成功した場合、この列は空になります。エンベディングの生成が失敗した場合は、エラー メッセージが表示されます。
Google Cloud コンソールで [BigQuery] ページに移動します。
クエリエディタで次のクエリを実行して、エンベディング生成の失敗があったかどうかを確認します。
SELECT DISTINCT(ml_generate_embedding_status), COUNT(uri) AS num_rows FROM bqml_tutorial.met_image_embeddings GROUP BY 1;
エラーのある行が返された場合は、エンベディング生成に失敗した行をすべて削除します。
DELETE FROM `bqml_tutorial.met_image_embeddings` WHERE ml_generate_embedding_status = 'A retryable error occurred: RESOURCE_EXHAUSTED error from remote service/endpoint.';
ベクトル インデックスを作成する
必要に応じて、CREATE VECTOR INDEX
ステートメントを使用して、met_images_embeddings
テーブルの ml_generate_embedding_result
列に met_images_index
ベクトル インデックスを作成できます。ベクトル インデックスを使用すると、ベクトル検索をより迅速に実行できますが、再現率が低下するため、より近似的な結果が返されます。
Google Cloud コンソールで [BigQuery] ページに移動します。
[クエリエディタ] ペインで、次のクエリを実行します。
CREATE OR REPLACE VECTOR INDEX `met_images_index` ON bqml_tutorial.met_image_embeddings(ml_generate_embedding_result) OPTIONS ( index_type = 'IVF', distance_type = 'COSINE');
ベクトル インデックスは非同期で作成されます。ベクトル インデックスが作成されているかどうかを確認するには、
INFORMATION_SCHEMA.VECTOR_INDEXES
ビューをクエリして、coverage_percentage
値が0
よりも大きく、last_refresh_time
値がNULL
でないことを確認します。SELECT table_name, index_name, index_status, coverage_percentage, last_refresh_time, disable_reason FROM bqml_tutorial.INFORMATION_SCHEMA.VECTOR_INDEXES WHERE index_name = 'met_images_index';
検索テキストのエンベディングを生成する
指定したテキスト検索文字列に対応する画像を検索するには、まずその文字列のテキスト エンベディングを作成する必要があります。同じリモートモデルを使用して、画像エンベディングの作成に使用したテキスト エンベディングを作成します。次に、テキスト エンベディングをテーブルに書き込んで、次の手順で使用できるようにします。検索文字列は pictures of white or cream colored dress from victorian era
です。
Google Cloud コンソールで [BigQuery] ページに移動します。
[クエリエディタ] ペインで、次のクエリを実行します。
CREATE OR REPLACE TABLE `bqml_tutorial.search_embedding` AS SELECT * FROM ML.GENERATE_EMBEDDING( MODEL `bqml_tutorial.multimodal_embedding_model`, ( SELECT 'pictures of white or cream colored dress from victorian era' AS content ) );
クロスモダリティのテキストから画像への検索を行う
VECTOR_SEARCH
関数を使用して、テキスト エンベディングで表される検索文字列に最も一致する画像を検索し、次のステップで使用するためにテーブルに書き込みます。
Google Cloud コンソールで [BigQuery] ページに移動します。
[クエリエディタ] ペインで、次のクエリを実行します。
CREATE OR REPLACE TABLE `bqml_tutorial.vector_search_results` AS SELECT base.uri AS gcs_uri, distance FROM VECTOR_SEARCH( TABLE `bqml_tutorial.met_image_embeddings`, 'ml_generate_embedding_result', TABLE `bqml_tutorial.search_embedding`, 'ml_generate_embedding_result', top_k => 3);
ベクトル検索結果を可視化する
ノートブックを使用してベクトル検索結果を可視化します。
Google Cloud コンソールで [BigQuery] ページに移動します。
先ほど作成した
met-image-analysis
ノートブックを開きます。ベクトル検索結果を可視化します。
- ノートブックにコードセルを追加します。
次のコードをコピーして、コードセルに貼り付けます。
query = """ SELECT * FROM `bqml_tutorial.vector_search_results` ORDER BY distance; """ printImages(client.query(query))
コードセルを実行します。
結果は次のようになります。
クリーンアップ
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.