ML.GENERATE_EMBEDDING 関数を使用してテキスト エンベディングを生成する

このドキュメントでは、Vertex AI エンベディング モデルを参照する、BigQuery ML のリモートモデルを作成する方法について説明します。次に、そのモデルを ML.GENERATE_EMBEDDING 関数で使用し、BigQuery の標準テーブルのデータを使用してテキスト エンベディングを作成します。

必要なロール

  • 接続を作成するには、次の Identity and Access Management(IAM)ロールのメンバーシップが必要です。

    • roles/bigquery.connectionAdmin
  • 接続のサービス アカウントに権限を付与するには、次の権限が必要です。

    • resourcemanager.projects.setIamPolicy
  • BigQuery ML を使用してモデルを作成するには、次の IAM 権限が必要です。

    • bigquery.jobs.create
    • bigquery.models.create
    • bigquery.models.getData
    • bigquery.models.updateData
    • bigquery.models.updateMetadata
  • 推論を実行するには、次の権限が必要です。

    • テーブルに対する bigquery.tables.getData
    • モデルに対する bigquery.models.getData
    • bigquery.jobs.create

準備

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the BigQuery, BigQuery Connection, and Vertex AI APIs.

    Enable the APIs

データセットの作成

ML モデルを格納する BigQuery データセットを作成します。

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    [BigQuery] ページに移動

  2. [エクスプローラ] ペインで、プロジェクト名をクリックします。

  3. 「アクションを表示」> [データセットを作成] をクリックします。

    データセットを作成する。

  4. [データセットを作成する] ページで、次の操作を行います。

    • [データセット ID] に「bqml_tutorial」と入力します。

    • [ロケーション タイプ] で [マルチリージョン] を選択してから、[US (米国の複数のリージョン)] を選択します。

      一般公開データセットは US マルチリージョンに保存されています。わかりやすくするため、データセットを同じロケーションに保存します。

    • 残りのデフォルトの設定は変更せず、[データセットを作成] をクリックします。

      データセットの作成ページ

接続を作成する

クラウド リソース接続を作成し、接続のサービス アカウントを取得します。前の手順で作成したデータセットと同じロケーションに接続を作成します。

次のオプションのいずれかを選択します。

コンソール

  1. BigQuery ページに移動します。

    [BigQuery] に移動

  2. 接続を作成するには、[追加] をクリックし、続いて [外部データソースへの接続] をクリックします。

  3. [接続タイプ] リストで、[Vertex AI リモートモデル、リモート関数、BigLake(Cloud リソース)] を選択します。

  4. [接続 ID] フィールドに接続の名前を入力します。

  5. [接続を作成] をクリックします。

  6. [接続へ移動] をクリックします。

  7. [接続情報] ペインで、後の手順で使用するサービス アカウント ID をコピーします。

bq

  1. コマンドライン環境で接続を作成します。

    bq mk --connection --location=REGION --project_id=PROJECT_ID \
        --connection_type=CLOUD_RESOURCE CONNECTION_ID

    --project_id パラメータは、デフォルト プロジェクトをオーバーライドします。

    以下を置き換えます。

    接続リソースを作成すると、BigQuery は、一意のシステム サービス アカウントを作成し、それを接続に関連付けます。

    トラブルシューティング: 次の接続エラーが発生した場合は、Google Cloud SDK を更新します。

    Flags parsing error: flag --connection_type=CLOUD_RESOURCE: value should be one of...
    
  2. 後の手順で使用するため、サービス アカウント 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 リソース接続を作成します。


# This queries the provider for project information.
data "google_project" "default" {}

# This creates a cloud resource connection in the US region named my_cloud_resource_connection.
# Note: The cloud resource nested object has only one output field - serviceAccountId.
resource "google_bigquery_connection" "default" {
  connection_id = "my_cloud_resource_connection"
  project       = data.google_project.default.project_id
  location      = "US"
  cloud_resource {}
}

Google Cloud プロジェクトで Terraform 構成を適用するには、次のセクションの手順を完了します。

Cloud Shell を準備する

  1. Cloud Shell を起動します。
  2. Terraform 構成を適用するデフォルトの Google Cloud プロジェクトを設定します。

    このコマンドは、プロジェクトごとに 1 回だけ実行する必要があります。これは任意のディレクトリで実行できます。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    Terraform 構成ファイルに明示的な値を設定すると、環境変数がオーバーライドされます。

ディレクトリを準備する

Terraform 構成ファイルには独自のディレクトリ(ルート モジュールとも呼ばれます)が必要です。

  1. Cloud Shell で、ディレクトリを作成し、そのディレクトリ内に新しいファイルを作成します。ファイルの拡張子は .tf にする必要があります(例: main.tf)。このチュートリアルでは、このファイルを main.tf とします。
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. チュートリアルを使用している場合は、各セクションまたはステップのサンプルコードをコピーできます。

    新しく作成した main.tf にサンプルコードをコピーします。

    必要に応じて、GitHub からコードをコピーします。Terraform スニペットがエンドツーエンドのソリューションの一部である場合は、この方法をおすすめします。

  3. 環境に適用するサンプル パラメータを確認し、変更します。
  4. 変更を保存します。
  5. Terraform を初期化します。これは、ディレクトリごとに 1 回だけ行う必要があります。
    terraform init

    必要に応じて、最新バージョンの Google プロバイダを使用する場合は、-upgrade オプションを使用します。

    terraform init -upgrade

変更を適用する

  1. 構成を確認して、Terraform が作成または更新するリソースが想定どおりであることを確認します。
    terraform plan

    必要に応じて構成を修正します。

  2. 次のコマンドを実行し、プロンプトで「yes」と入力して、Terraform 構成を適用します。
    terraform apply

    Terraform に「Apply complete!」のメッセージが表示されるまで待ちます。

  3. Google Cloud プロジェクトを開いて結果を表示します。Google Cloud コンソールの UI でリソースに移動して、Terraform によって作成または更新されたことを確認します。

サービス アカウントにアクセス権を付与する

接続のサービス アカウントに Vertex AI ユーザーロールを付与します。

リモートモデルの作成時にエンドポイントを URL(endpoint = 'https://us-central1-aiplatform.googleapis.com/v1/projects/myproject/locations/us-central1/publishers/google/models/text-embedding-004' など)として指定する場合は、URL に指定するプロジェクト内でこのロールを付与してください。

リモートモデルの作成時にモデル名(endpoint = 'text-embedding-004' など)を使用してエンドポイントを指定する場合は、リモートモデルを作成するプロジェクト内でこのロールを付与してください。

別のプロジェクト内でロールを付与すると、エラー bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.iam.gserviceaccount.com does not have the permission to access resource が発生します。

ロールを付与する手順は次のとおりです。

コンソール

  1. [IAM と管理] ページに移動

    [IAM と管理] に移動

  2. [アクセスを許可] をクリックします。

    [プリンシパルを追加] ダイアログが開きます。

  3. [新しいプリンシパル] フィールドに、前の手順でコピーしたサービス アカウント ID を入力します。

  4. [ロールを選択] フィールドで、[Vertex AI] を選択し、[Vertex AI ユーザー] を選択します。

  5. [保存] をクリックします。

gcloud

gcloud projects add-iam-policy-binding コマンドを実行します。

gcloud projects add-iam-policy-binding 'PROJECT_NUMBER' --member='serviceAccount:MEMBER' --role='roles/aiplatform.user' --condition=None

次のように置き換えます。

  • PROJECT_NUMBER: プロジェクトの番号
  • MEMBER: 先ほどコピーしたサービス アカウント ID

モデルを作成

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. SQL エディタを使用してリモートモデルを作成します。

    CREATE OR REPLACE MODEL `PROJECT_ID.DATASET_ID.MODEL_NAME`
    REMOTE WITH CONNECTION `CONNECTION_ID`
    OPTIONS (ENDPOINT = 'ENDPOINT');

    次のように置き換えます。

    • PROJECT_ID: プロジェクト ID
    • DATASET_ID: モデルを格納するデータセットの ID
    • MODEL_NAME: モデルの名前
    • CONNECTION_ID: BigQuery 接続の ID

      Google Cloud コンソールで接続の詳細を表示する場合、これは [接続 ID] に表示される完全修飾接続 ID の最後のセクションの値です。例: projects/myproject/locations/connection_location/connections/myconnection

    • ENDPOINT: 使用するエンベディング モデルの名前。これは text-embeddingtext-multilingual-embedding、または multimodalembedding モデルにする必要があります。サポートされているモデル バージョンとエイリアスの詳細については、ENDPOINT をご覧ください。

テーブルのデータを使用してテキスト エンベディングを生成する

テーブル列のテキストデータを使用して、ML.GENERATE_EMBEDDING 関数でテキスト エンベディングを生成します。

通常、テキストのみのユースケースには text-embedding モデルまたは text-multilingual-embedding モデルを使用し、クロスモーダル検索のユースケースには multimodalembedding モデルを使用します。ここで、テキストとビジュアル コンテンツのエンベディングは、同じセマンティック空間に生成されます。

テキスト エンベディング

エンベディング モデルでリモートモデルを使用してテキスト エンベディングを生成します。

SELECT *
FROM ML.GENERATE_EMBEDDING(
  MODEL `PROJECT_ID.DATASET_ID.MODEL_NAME`,
  TABLE PROJECT_ID.DATASET_ID.TABLE_NAME,
  STRUCT(FLATTEN_JSON AS flatten_json_output,
    TASK_TYPE AS task_type,
    OUTPUT_DIMENSIONALITY AS output_dimensionality)
);

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID。
  • DATASET_ID: モデルを保存するデータセットの ID。
  • MODEL_NAME: エンベディング モデルのリモートモデルの名前。
  • TABLE_NAME: 埋め込むテキストを含むテーブルの名前。このテーブルには、content という名前の列が必要です。または、エイリアスを使用して別の名前の列を使用することもできます。
  • FLATTEN_JSON: エンベディングを別の列にパースするかどうかを示す BOOL 値。デフォルト値は TRUE です。
  • TASK_TYPE: モデルが質の高いエンベディングを生成できるように、対象のダウンストリーム アプリケーションを指定する STRING リテラル。TASK_TYPE には、次の値を使用できます。
    • RETRIEVAL_QUERY: 指定したテキストが検索または取得設定のクエリであることを指定します。
    • RETRIEVAL_DOCUMENT: 指定したテキストが検索または取得設定のドキュメントであることを指定します。

      このタスクタイプを使用する場合は、エンベディングの品質を改善するために、クエリ ステートメントにドキュメントのタイトルを含めることをおすすめします。title オプションを使用すると、ドキュメントのタイトルを含む列の名前を指定できます。指定しない場合、ドキュメントのタイトルは title という名前の列か、title というエイリアスの列に含まれている必要があります。次に例を示します。

            SELECT *
            FROM
              ML.GENERATE_EMBEDDING(
                MODEL mydataset.embedding_model,
                (SELECT abstract as content, header as title, publication_number
                FROM mydataset.publications),
                STRUCT(TRUE AS flatten_json_output, 'RETRIEVAL_DOCUMENT' as task_type)
            );
            
    • SEMANTIC_SIMILARITY: 指定したテキストが意味論的テキスト類似性(STS)で使用されることを指定します。
    • CLASSIFICATION: エンベディングを分類に使用することを指定します。
    • CLUSTERING: エンベディングをクラスタ化に使用することを指定します。
  • OUTPUT_DIMENSIONALITY: エンベディングの生成時に使用する次元の数を指定する INT64 値。たとえば、256 AS output_dimensionality を指定すると、ml_generate_embedding_result 出力列には、入力値ごとに 256 個のエンベディングが含まれます。

    この引数は、model 引数で指定したリモートモデルが次のいずれかのモデルをエンドポイントとして使用する場合にのみ使用できます。

    • text-embedding-004 以降
    • text-multilingual-embedding-002 以降

マルチモーダル エンベディング

multimodalembedding モデルでリモートモデルを使用してテキスト エンベディングを生成します。

SELECT *
FROM ML.GENERATE_EMBEDDING(
  MODEL `PROJECT_ID.DATASET_ID.MODEL_NAME`,
  TABLE PROJECT_ID.DATASET_ID.TABLE_NAME,
  STRUCT(FLATTEN_JSON AS flatten_json_output
  OUTPUT_DIMENSIONALITY AS output_dimensionality)
);

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID。
  • DATASET_ID: モデルを保存するデータセットの ID。
  • MODEL_NAME: multimodalembedding@001 モデルのリモートモデルの名前。
  • TABLE_NAME: 埋め込むテキストを含むテーブルの名前。このテーブルには、content という名前の列が必要です。または、エイリアスを使用して別の名前の列を使用することもできます。
  • FLATTEN_JSON: 埋め込みを解析して別の列に変換するかどうかを示す BOOL。デフォルト値は TRUE です。
  • OUTPUT_DIMENSIONALITY: エンベディングの生成時に使用する次元の数を指定する INT64 値。有効な値は 1282565121408 です。デフォルト値は 1408 です。たとえば、256 AS output_dimensionality を指定すると、ml_generate_embedding_result 出力列には、入力値ごとに 256 個のエンベディングが含まれます。

クエリのデータを使用してテキスト エンベディングを生成する

エンベディング モデルに対するクエリとリモートモデルから提供されたテキストデータと、ML.GENERATE_EMBEDDING 関数を使用して、テキスト エンベディングを生成します。

通常、テキストのみのユースケースには text-embedding モデルまたは text-multilingual-embedding モデルを使用し、クロスモーダル検索のユースケースには multimodalembedding モデルを使用します。ここで、テキストとビジュアル コンテンツのエンベディングは、同じセマンティック空間に生成されます。

テキスト エンベディング

エンベディング モデルでリモートモデルを使用してテキスト エンベディングを生成します。

SELECT *
FROM ML.GENERATE_EMBEDDING(
  MODEL `PROJECT_ID.DATASET_ID.MODEL_NAME`,
  (CONTENT_QUERY),
  STRUCT(FLATTEN_JSON AS flatten_json_output,
    TASK_TYPE AS task_type,
    OUTPUT_DIMENSIONALITY AS output_dimensionality)
  );

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID。
  • DATASET_ID: モデルを保存するデータセットの ID。
  • MODEL_NAME: エンベディング モデルのリモートモデルの名前。
  • CONTENT_QUERY: 結果に content という STRING 列が含まれるクエリ。
  • FLATTEN_JSON: エンベディングを別の列にパースするかどうかを示す BOOL 値。デフォルト値は TRUE です。
  • TASK_TYPE: モデルが質の高いエンベディングを生成できるように、対象となるダウンストリーム アプリケーションを指定する STRING リテラル。TASK_TYPE には、次の値を使用できます。
    • RETRIEVAL_QUERY: 指定したテキストが検索または取得設定のクエリであることを指定します。
    • RETRIEVAL_DOCUMENT: 指定したテキストが検索または取得設定のドキュメントであることを指定します。

      このタスクタイプを使用する場合は、エンベディングの品質を改善するために、クエリ ステートメントにドキュメントのタイトルを含めることをおすすめします。title オプションを使用すると、ドキュメントのタイトルを含む列の名前を指定できます。指定しない場合、ドキュメントのタイトルは title という名前の列か、title というエイリアスの列に含まれている必要があります。次に例を示します。

                SELECT *
                FROM
                  ML.GENERATE_EMBEDDING(
                    MODEL mydataset.embedding_model,
                    (SELECT abstract as content, header as title, publication_number
                    FROM mydataset.publications),
                    STRUCT(TRUE AS flatten_json_output, 'RETRIEVAL_DOCUMENT' as task_type)
                );
                
    • SEMANTIC_SIMILARITY: 指定したテキストが意味論的テキスト類似性(STS)で使用されることを指定します。
    • CLASSIFICATION: エンベディングを分類に使用することを指定します。
    • CLUSTERING: エンベディングをクラスタ化に使用することを指定します。
  • OUTPUT_DIMENSIONALITY: エンベディングの生成時に使用する次元の数を指定する INT64 値。たとえば、256 AS output_dimensionality を指定すると、ml_generate_embedding_result 出力列には、入力値ごとに 256 個のエンベディングが含まれます。

    この引数は、model 引数で指定したリモートモデルが次のいずれかのモデルをエンドポイントとして使用する場合にのみ使用できます。

    • text-embedding-004 以降
    • text-multilingual-embedding-002 以降

マルチモーダル エンベディング

multimodalembedding モデルでリモートモデルを使用してテキスト エンベディングを生成します。

SELECT *
FROM ML.GENERATE_EMBEDDING(
  MODEL `PROJECT_ID.DATASET_ID.MODEL_NAME`,
  (CONTENT_QUERY),
  STRUCT(FLATTEN_JSON AS flatten_json_output,
  OUTPUT_DIMENSIONALITY AS output_dimensionality)
);

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID。
  • DATASET_ID: モデルを保存するデータセットの ID。
  • MODEL_NAME: multimodalembedding@001 モデルのリモートモデルの名前。
  • CONTENT_QUERY: 結果に content という STRING 列が含まれるクエリ。
  • FLATTEN_JSON: 埋め込みを解析して別の列に変換するかどうかを示す BOOL。デフォルト値は TRUE です。
  • OUTPUT_DIMENSIONALITY: エンベディングの生成時に使用する次元の数を指定する INT64 値。有効な値は 1282565121408 です。デフォルト値は 1408 です。たとえば、256 AS output_dimensionality を指定すると、ml_generate_embedding_result 出力列には、入力値ごとに 256 個のエンベディングが含まれます。

次の例は、テーブルとクエリで ML.GENERATE_EMBEDDING 関数を呼び出す方法を示しています。

テーブルにテキストを埋め込む

次の例は、text_data テーブルの content 列への埋め込みリクエストを示しています。

SELECT *
FROM
  ML.GENERATE_EMBEDDING(
    MODEL `mydataset.embedding_model`,
    TABLE mydataset.text_data,
    STRUCT(TRUE AS flatten_json_output, 'CLASSIFICATION' AS task_type)
  );

埋め込みを使用して意味的類似度をランク付けする

次の例では、映画レビューのコレクションを埋め込み、ML.DISTANCE 関数を使用してレビュー「This movie was average」へのコサイン距離順にそれらを並べ替えます。距離が短いほど、意味的類似性が高くなります。

WITH movie_review_embeddings AS (
  SELECT *
  FROM
    ML.GENERATE_EMBEDDING(
      MODEL `bqml_tutorial.embedding_model`,
      (
        SELECT "Movie 1" AS title, "This movie was fantastic" AS content
        UNION ALL
        SELECT "Movie 2" AS title, "This was the best movie I've ever seen!!" AS content
        UNION ALL
        SELECT "Movie 3" AS title, "This movie was just okay..." AS content
        UNION ALL
        SELECT "Movie 4" AS title, "This movie was terrible." AS content
      ),
      STRUCT(TRUE AS flatten_json_output)
    )
),
average_review_embedding AS (
  SELECT ml_generate_embedding_result
  FROM
    ML.GENERATE_EMBEDDING(
      MODEL `bqml_tutorial.embedding_model`,
      (SELECT "This movie was average" AS content),
      STRUCT(TRUE AS flatten_json_output)
    )
)
SELECT
  content,
  ML.DISTANCE(
    (SELECT ml_generate_embedding_result FROM average_review_embedding),
    ml_generate_embedding_result,
    'COSINE'
  ) AS distance_to_average_review
FROM
  movie_review_embeddings
ORDER BY distance_to_average_review;

結果は次のようになります。

+------------------------------------------+----------------------------+
| content                                  | distance_to_average_review |
+------------------------------------------+----------------------------+
| This movie was just okay...              | 0.062789813467745592       |
| This movie was fantastic                 |  0.18579561313064263       |
| This movie was terrible.                 |  0.35707466240930985       |
| This was the best movie I've ever seen!! |  0.41844932504542975       |
+------------------------------------------+----------------------------+