使用 ML.GENERATE_EMBEDDING 函数生成文本嵌入

本文档介绍了如何创建引用 Vertex AI 嵌入模型的 BigQuery ML 远程模型。然后,将该模型与 ML.GENERATE_EMBEDDING 函数搭配使用,以使用 BigQuery 标准表中的数据创建文本嵌入。

所需的角色

如需创建远程模型并使用 ML.GENERATE_EMBEDDING 函数,您需要以下 Identity and Access Management (IAM) 角色:

  • 创建和使用 BigQuery 数据集、表和模型:项目的 BigQuery Data Editor (roles/bigquery.dataEditor)。
  • 创建、委托和使用 BigQuery 连接:项目的 BigQuery Connections Admin (roles/bigquery.connectionsAdmin)。

    如果您尚未配置默认连接,则可以在运行 CREATE MODEL 语句时创建并设置一个连接。为此,您必须拥有项目的 BigQuery Admin (roles/bigquery.admin) 角色。如需了解详情,请参阅配置默认连接

  • 为连接的服务账号授予权限:包含 Vertex AI 端点的项目的 Project IAM Admin (roles/resourcemanager.projectIamAdmin)。这是通过将模型名称指定为端点而创建的远程模型的当前项目。这是通过将网址指定为端点而创建的远程模型的网址中标识的项目。

  • 创建 BigQuery 作业:项目的 BigQuery Job User (roles/bigquery.jobUser)。

这些预定义角色包含执行本文档中的任务所需的权限。如需查看所需的确切权限,请展开所需权限部分:

所需权限

  • 创建数据集:bigquery.datasets.create
  • 创建、委托和使用连接:bigquery.connections.*
  • 设置服务账号权限:resourcemanager.projects.getIamPolicyresourcemanager.projects.setIamPolicy
  • 创建模型并运行推断:
    • bigquery.jobs.create
    • bigquery.models.create
    • bigquery.models.getData
    • bigquery.models.updateData
    • bigquery.models.updateMetadata
  • 查询表格数据:bigquery.tables.getData

您也可以使用自定义角色或其他预定义角色来获取这些权限。

准备工作

  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

创建数据集

创建 BigQuery 数据集以包含您的资源:

控制台

  1. 在 Google Cloud 控制台中,前往 BigQuery 页面。

    转到 BigQuery 页面

  2. 探索器窗格中,点击您的项目名称。

  3. 点击 查看操作 > 创建数据集

  4. 创建数据集 页面上,执行以下操作:

    • 数据集 ID 中,输入数据集的名称。

    • 位置类型中,为数据集选择一个位置。

    • 点击创建数据集

bq

  1. 如需创建新数据集,请使用带有 --location 标志的 bq mk 命令:

    bq --location=LOCATION mk -d DATASET_ID

    替换以下内容:

    • LOCATION:数据集的位置
    • DATASET_ID 是您要创建的数据集的 ID。
  2. 确认已创建数据集:

    bq ls

创建连接

如果您已配置默认连接,或者您具有 BigQuery Admin 角色,则可以跳过此步骤。

创建一个 Cloud 资源连接供远程模型使用,并获取连接的服务账号。在上一步中创建的数据集所在的位置创建连接。

从下列选项中选择一项:

控制台

  1. 转到 BigQuery 页面。

    转到 BigQuery

  2. 探索器窗格中,点击 添加数据

    “添加数据”界面元素。

    系统随即会打开添加数据对话框。

  3. 过滤条件窗格中的数据源类型部分,选择企业应用

    或者,在搜索数据源字段中,您可以输入 Vertex AI

  4. 精选数据源部分中,点击 Vertex AI

  5. 点击 Vertex AI 模型:BigQuery 联合解决方案卡片。

  6. 连接类型列表中,选择 Vertex AI 远程模型、远程函数和 BigLake(Cloud 资源)

  7. 连接 ID 字段中,输入连接的名称。

  8. 点击创建连接

  9. 点击转到连接

  10. 连接信息窗格中,复制服务账号 ID 以在后续步骤中使用。

bq

  1. 在命令行环境中,创建连接:

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

    --project_id 参数会替换默认项目。

    请替换以下内容:

    • REGION:您的连接区域
    • PROJECT_ID:您的 Google Cloud 项目 ID
    • CONNECTION_ID:您的连接的 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 项目。

    您只需为每个项目运行一次以下命令,即可在任何目录中运行它。

    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。您只需为每个目录执行一次此操作。
    terraform init

    (可选)如需使用最新的 Google 提供程序版本,请添加 -upgrade 选项:

    terraform init -upgrade

应用更改

  1. 查看配置并验证 Terraform 将创建或更新的资源是否符合您的预期:
    terraform plan

    根据需要更正配置。

  2. 通过运行以下命令并在提示符处输入 yes 来应用 Terraform 配置:
    terraform apply

    等待 Terraform 显示“应用完成!”消息。

  3. 打开您的 Google Cloud 项目以查看结果。在 Google Cloud 控制台的界面中找到资源,以确保 Terraform 已创建或更新它们。

向服务账号授予访问权限

向连接的服务账号授予 Vertex AI User 角色。

如果您打算在创建远程模型时将端点指定为网址(例如 endpoint = 'https://us-central1-aiplatform.googleapis.com/v1/projects/myproject/locations/us-central1/publishers/google/models/text-embedding-005'),请在您在该网址指定的项目中授予此角色。

如果您打算在创建远程模型时使用模型名称指定端点(例如 endpoint = 'text-embedding-005'),请在打算创建远程模型的项目中授予此角色。

在其他项目中授予此角色会导致错误 bqcx-1234567890-wxyz@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 User

  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 {DEFAULT | `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:要使用的嵌入模型的名称。必须是 text-embeddingtext-multilingual-embeddingmultimodalembedding 模型。如需详细了解支持的模型版本和别名,请参阅 ENDPOINT

      您指定的 Vertex AI 模型必须在您创建远程模型的位置可用。如需了解详情,请参阅位置

使用表中的数据生成文本嵌入

使用表列中的文本数据,通过 ML.GENERATE_EMBEDDING 函数生成文本嵌入。

通常,建议将 text-embeddingtext-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_TYPESTRING 字面量,指定预期的下游应用,可帮助模型生成质量更高的嵌入。TASK_TYPE 接受以下值:
    • RETRIEVAL_QUERY:在搜索或检索设置中指定给定文本是查询。
    • RETRIEVAL_DOCUMENT:在搜索或检索设置中指定给定文本是文档。

      使用此任务类型时,在查询语句中添加文档标题有助于提高嵌入质量。 文档标题必须位于名为 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)
            );
            

      在输入查询中指定标题列会填充发送到模型的请求正文的 title 字段。如果您在使用任何其他任务类型时指定了 title 值,系统会忽略该输入,并且该输入不会对嵌入结果产生任何影响。

    • SEMANTIC_SIMILARITY:指定给定文本用于语义文本相似度 (STS)。
    • CLASSIFICATION:指定嵌入用于分类。
    • CLUSTERING:指定嵌入用于聚类。
    • QUESTION_ANSWERING:指定嵌入用于问答。
    • FACT_VERIFICATION:指定嵌入用于事实验证。
    • CODE_RETRIEVAL_QUERY:指定嵌入用于代码检索。
  • 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-embeddingtext-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:结果包含名为 contentSTRING 列的查询。
  • FLATTEN_JSON:指示是否将嵌入解析为单独的列的 BOOL 值。默认值为 TRUE
  • TASK_TYPESTRING 字面量,指定预期的下游应用,可帮助模型生成质量更高的嵌入。TASK_TYPE 接受以下值:
    • RETRIEVAL_QUERY:在搜索或检索设置中指定给定文本是查询。
    • RETRIEVAL_DOCUMENT:在搜索或检索设置中指定给定文本是查询。

      使用此任务类型时,在查询语句中添加文档标题有助于提高嵌入质量。 文档标题必须位于名为 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)
              );
              

      在输入查询中指定标题列会填充发送到模型的请求正文的 title 字段。如果您在使用任何其他任务类型时指定了 title 值,系统会忽略该输入,并且该输入不会对嵌入结果产生任何影响。

    • SEMANTIC_SIMILARITY:指定给定文本用于语义文本相似度 (STS)。
    • CLASSIFICATION:指定嵌入用于分类。
    • CLUSTERING:指定嵌入用于聚类。
    • QUESTION_ANSWERING:指定嵌入用于问答。
    • FACT_VERIFICATION:指定嵌入用于事实验证。
    • CODE_RETRIEVAL_QUERY:指定嵌入用于代码检索。
  • 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:结果包含名为 contentSTRING 列的查询。
  • 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)
  );

使用嵌入对语义相似性进行排名

以下示例嵌入一组电影评论,并使用 VECTOR_SEARCH 函数按与评论“此电影比较一般”的余弦距离进行排序。距离越小表示语义相似性越高。

如需详细了解向量搜索和向量索引,请参阅向量搜索简介

CREATE TEMPORARY TABLE movie_review_embeddings AS (
  SELECT *
  FROM
    ML.GENERATE_EMBEDDING(
      MODEL `bqml_tutorial.embedding_model`,
      (
        SELECT "This movie was fantastic" AS content
        UNION ALL
        SELECT "This was the best movie I've ever seen!!" AS content
        UNION ALL
        SELECT "This movie was just okay..." AS content
        UNION ALL
        SELECT "This movie was terrible." AS content
      ),
      STRUCT(TRUE AS flatten_json_output)
    )
);

WITH 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
  base.content AS content,
  distance AS distance_to_average_review
FROM
  VECTOR_SEARCH(
    TABLE movie_review_embeddings,
    "ml_generate_embedding_result",
    (SELECT ml_generate_embedding_result FROM average_review_embedding),
    distance_type=>"COSINE",
    top_k=>-1
  )
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       |
+------------------------------------------+----------------------------+

后续步骤