マルチモーダル エンベディングの生成と検索
このチュートリアルでは、BigQuery と Vertex AI を使用して画像とテキストのマルチモーダル エンベディングを生成し、これらのエンベディングを使用してテキストから画像へのセマンティック検索を実行する方法について説明します。
このチュートリアルでは、次のタスクについて説明します。
- 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 データセット、接続、モデル、ノートブックを作成して使用する: BigQuery Studio 管理者(
roles/bigquery.studioAdmin)。 - 接続のサービス アカウントに権限を付与する: Project IAM 管理者(
roles/resourcemanager.projectIamAdmin)。
これらの事前定義ロールには、このドキュメントのタスクを実行するために必要な権限が含まれています。必要とされる正確な権限については、「必要な権限」セクションを開いてご確認ください。
必要な権限
- データセットを作成する:
bigquery.datasets.create - 接続を作成、委任、使用する:
bigquery.connections.* - デフォルトの接続を設定する:
bigquery.config.* - サービス アカウントの権限を設定する:
resourcemanager.projects.getIamPolicyとresourcemanager.projects.setIamPolicy - オブジェクト テーブルを作成する:
bigquery.tables.createとbigquery.tables.update - モデルを作成して推論を実行する
bigquery.jobs.createbigquery.models.createbigquery.models.getDatabigquery.models.updateDatabigquery.models.updateMetadata
- ノートブックを作成して使用する:
resourcemanager.projects.getresourcemanager.projects.listbigquery.config.getbigquery.jobs.createbigquery.readsessions.createbigquery.readsessions.getDatabigquery.readsessions.updatedataform.locations.getdataform.locations.listdataform.repositories.create
dataform.repositories.listdataform.collections.createdataform.collections.listaiplatform.notebookRuntimeTemplates.applyaiplatform.notebookRuntimeTemplates.getaiplatform.notebookRuntimeTemplates.listaiplatform.notebookRuntimeTemplates.getIamPolicyaiplatform.notebookRuntimes.assignaiplatform.notebookRuntimes.getaiplatform.notebookRuntimes.listaiplatform.operations.listaiplatform.notebookRuntimeTemplates.apply
カスタムロールや他の事前定義ロールを使用して、これらの権限を取得することもできます。
費用
このドキュメントでは、課金対象である次の 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.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the BigQuery, BigQuery Connection, and Vertex AI APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.
データセットを作成する
ML モデルを保存する BigQuery データセットを作成します。
コンソール
Google Cloud コンソールで、[BigQuery] ページに移動します。
[エクスプローラ] ペインで、プロジェクト名をクリックします。
[アクションを表示] > [データセットを作成] をクリックします。
[データセットを作成する] ページで、次の操作を行います。
[データセット ID] に「
bqml_tutorial」と入力します。[ロケーション タイプ] で [マルチリージョン] を選択してから、[US(米国の複数のリージョン)] を選択します。
残りのデフォルトの設定は変更せず、[データセットを作成] をクリックします。
bq
新しいデータセットを作成するには、--location フラグを指定した bq mk コマンドを使用します。使用可能なパラメータの一覧については、bq mk --dataset コマンドのリファレンスをご覧ください。
データの場所が
USに設定され、BigQuery ML tutorial datasetという説明の付いた、bqml_tutorialという名前のデータセットを作成します。bq --location=US mk -d \ --description "BigQuery ML tutorial dataset." \ bqml_tutorial
このコマンドでは、
--datasetフラグの代わりに-dショートカットを使用しています。-dと--datasetを省略した場合、このコマンドはデフォルトでデータセットを作成します。データセットが作成されたことを確認します。
bq ls
API
定義済みのデータセット リソースを使用して datasets.insert メソッドを呼び出します。
{ "datasetReference": { "datasetId": "bqml_tutorial" } }
BigQuery DataFrames
このサンプルを試す前に、BigQuery DataFrames を使用した BigQuery クイックスタートの手順に沿って BigQuery DataFrames を設定してください。詳細については、BigQuery DataFrames のリファレンス ドキュメントをご覧ください。
BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の ADC の設定をご覧ください。
オブジェクト テーブルを作成する
公開 Cloud Storage gcs-public-data--met バケットの画像に対してオブジェクト テーブルを作成します。オブジェクト テーブルを使用すると、Cloud Storage から画像を移動せずに分析できます。
Google Cloud コンソールで、[BigQuery] ページに移動します。
[クエリエディタ] ペインで、次のクエリを実行します。
CREATE OR REPLACE EXTERNAL TABLE `bqml_tutorial.met_images` WITH CONNECTION DEFAULT OPTIONS ( object_metadata = 'SIMPLE', uris = ['gs://gcs-public-data--met/*'] );
画像データを調べる
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 DEFAULT OPTIONS (ENDPOINT = 'multimodalembedding@001');
クエリが完了するまでに数秒かかります。完了後、
bqml_tutorialデータセットに表示されるmultimodal_embedding_modelモデルにアクセスできます。クエリは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.