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. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  2. Google Cloud プロジェクトで課金が有効になっていることを確認します

  3. BigQuery, BigQuery Connection, and Vertex AI API を有効にします。

    API を有効にする

データセットを作成する

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

main.tf ファイルに次のセクションを追加します。

 ## This creates a cloud resource connection.
 ## Note: The cloud resource nested object has only one output only field - serviceAccountId.
 resource "google_bigquery_connection" "connection" {
    connection_id = "CONNECTION_ID"
    project = "PROJECT_ID"
    location = "REGION"
    cloud_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 `PROJECT_ID.REGION.CONNECTION_ID`
    OPTIONS (ENDPOINT = 'ENDPOINT');
    

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

    • PROJECT_ID: プロジェクト ID
    • DATASET_ID: モデルを格納するデータセットの ID
    • MODEL_NAME: モデルの名前
    • REGION: 接続で使用されるリージョン
    • CONNECTION_ID: BigQuery 接続の ID

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

    • ENDPOINT: 使用するエンベディング LLM。たとえば、ENDPOINT='multimodalembedding' のようにします。

      モデルの種類によっては、モデル名に @version を追加して、モデルの特定のバージョンを指定できます。たとえば、textembedding-gecko@001 のようにします。さまざまなモデルタイプでサポートされているモデル バージョンについては、ENDPOINT をご覧ください。

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

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

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

textembedding-gecko*

textembedding-gecko または textembedding-gecko-multilingual LLM でリモートモデルを使用してテキスト エンベディングを生成します。

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)
);

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

  • PROJECT_ID: プロジェクト ID。
  • DATASET_ID: モデルを保存するデータセットの ID。
  • MODEL_NAME: textembedding-gecko または textembedding-gecko-multilingual モデルのリモートモデルの名前。
  • 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: エンベディングをクラスタ化に使用することを指定します。

multimodalembedding

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

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)
);

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

  • PROJECT_ID: プロジェクト ID。
  • DATASET_ID: モデルを保存するデータセットの ID。
  • MODEL_NAME: multimodalembedding@001 モデルのリモートモデルの名前。
  • TABLE_NAME: 埋め込むテキストを含むテーブルの名前。このテーブルには、content という名前の列が必要です。または、エイリアスを使用して別の名前の列を使用することもできます。
  • FLATTEN_JSON: 埋め込みを解析して別の列に変換するかどうかを示す BOOL。デフォルト値は TRUE です。

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

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

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

textembedding-gecko*

textembedding-gecko または textembedding-gecko-multilingual LLM でリモートモデルを使用してテキスト エンベディングを生成します。

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
  );

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

  • PROJECT_ID: プロジェクト ID。
  • DATASET_ID: モデルを保存するデータセットの ID。
  • MODEL_NAME: textembedding-gecko または textembedding-gecko-multilingual モデルのリモートモデルの名前。
  • 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: エンベディングをクラスタ化に使用することを指定します。

multimodalembedding

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

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

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

  • PROJECT_ID: プロジェクト ID。
  • DATASET_ID: モデルを保存するデータセットの ID。
  • MODEL_NAME: multimodalembedding@001 モデルのリモートモデルの名前。
  • CONTENT_QUERY: 結果に content という STRING 列が含まれるクエリ。
  • FLATTEN_JSON: 埋め込みを解析して別の列に変換するかどうかを示す BOOL。デフォルト値は TRUE です。

次の例は、テーブルとクエリで 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)
  );

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

次の例では、映画レビューのコレクションを埋め込み、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 fantastic                 | 0.10028859431058901        |
| This movie was terrible.                 |   0.142427236973374        |
| This was the best movie I've ever seen!! | 0.46742391210381995        |
| This movie was just okay...              | 0.47399255715360622        |
+------------------------------------------+----------------------------+