优化 AI 函数费用

本文档介绍了如何在 BigQuery 中使用受管 AI 函数的优化模式。与标准的逐行 LLM 推理相比,此模式可让您处理包含数千甚至数十亿行的大规模数据集,同时大幅减少大语言模型 (LLM) 的令牌消耗量和查询延迟时间。

以下示例演示了如何使用优化模式下的 AI.CLASSIFY 函数(以 text-embedding-005 作为嵌入模型)对新闻文章进行分类:

SELECT
  title,
  body,
  AI.CLASSIFY(
    body,
    categories => ['tech', 'sport', 'business', 'other'],
    embeddings => AI.EMBED(body, endpoint => 'text-embedding-005', task_type => 'CLASSIFICATION').result,
    -- Optional, 'MINIMIZE_COST' is the default when embeddings are provided.
    optimization_mode => 'MINIMIZE_COST'
   ) AS category
FROM
  `bigquery-public-data.bbc_news.fulltext`;

optimization_mode => 'MINIMIZE_COST' 实参可启用优化模式。这是提供嵌入时的默认设置,因此您可以省略此实参。

在此示例中,嵌入是即时生成的。在实践中,我们建议您实现嵌入,以便重复使用。

优化模式的工作原理

对于数据集中的每一行,受管理的 AI 函数 AI.IFAI.CLASSIFY 通常会调用远程 LLM。使用优化模式时,BigQuery 会在查询执行期间自动训练轻量级精简模型。

该过程的工作原理如下:

启用优化模式时的 AI 函数工作流

  • 抽样和标记:BigQuery 会选择一小部分代表性样本数据,并调用 Gemini 来提供标签。
  • 精简模型训练:使用 LLM 标签和数据嵌入作为特征,及时训练本地精简模型。
  • 质量检查:BigQuery 会根据大语言模型的结果评估精简模型的准确性。默认情况下,如果精简模型未能达到所需的质量阈值,查询会失败,并显示一条错误消息,说明模型被舍弃的原因。如果模型质量可接受,BigQuery 仍可能会针对特定行回退到远程大语言模型,以保持一致的质量,或者针对缺少有效嵌入的行回退到远程大语言模型。
  • 推理:精简模型处理大部分行,从而显著减少 Gemini 调用次数。

限制

优化模式具有以下限制:

  • 最少行数:AI 函数的输入必须包含大约 3,000 行,以确保有足够的数据用于模型训练。
  • 数据类型:对于引用多个列的提示,优化仅支持字符串列。
  • 多标签分类:优化模式下不支持使用 output_mode => 'multi'AI.CLASSIFY
  • 功能支持:只有 AI.IFAI.CLASSIFY 函数支持优化模式。
  • 错误比率:优化模式不支持 max_error_ratio 实参。

准备工作

如需获得在 BigQuery 中运行受管 AI 函数所需的权限,请参阅为调用 Vertex AI LLM 的生成式 AI 函数设置权限

选择嵌入模型

如需使用优化模式,您必须计算数据的嵌入内容并将其提供给 AI 函数。对于具有关联嵌入的输入列,所有行的嵌入维度必须保持一致,并且必须由同一嵌入模型生成。

为了获得最佳的成本-质量比和可伸缩性,我们建议您使用嵌入模型(例如 text-embedding-005 或 Gemini 嵌入模型)来计算数据的嵌入,以完成英语或多语言任务。对于多模态数据(文本和图片),请使用多模态嵌入模型,例如 multimodalembedding@001

生成嵌入

您可以使用由 BigQuery 管理的自主生成功能来计算数据的嵌入,也可以手动创建嵌入列。以下部分介绍了如何结合使用这两种方法以及 AI.CLASSIFYAI.IF 函数。

自主嵌入生成

如果您使用自主嵌入生成,则在调用 AI.IFAI.CLASSIFY 时,BigQuery 会自动使用嵌入。这是推荐的方法,但每个表只能有一个嵌入列。

以下示例创建了一个包含自主生成的嵌入列的表,使用 text-embedding-005 作为嵌入模型,然后使用 AI.CLASSIFY 函数对数据进行分类:

-- Create a table with an autonomously generated embedding column
CREATE TABLE my_dataset.bbc_news (
  title STRING,
  body STRING,
  body_embedding STRUCT<result ARRAY<FLOAT64>, status STRING>
    GENERATED ALWAYS AS (
      AI.EMBED(
        body,
        connection_id => '<my_connection_id>',
        task_type => 'CLASSIFICATION',
        endpoint => 'text-embedding-005')
    ) STORED
    OPTIONS(asynchronous = TRUE)
);

-- Insert data into the table
INSERT INTO my_dataset.bbc_news (title, body)
SELECT title, body FROM `bigquery-public-data.bbc_news.fulltext`;

-- Run the optimized query.
-- Wait for the background job to finish generating embeddings before running.
SELECT
  title,
  body,
  AI.CLASSIFY(
    body,
    categories => ['tech', 'sport', 'business', 'other']
  ) AS category
FROM
  my_dataset.bbc_news;

手动指定列

如果您有现有的嵌入列,请在 AI.IFAI.CLASSIFYembeddings 实参中指定该列。您可以使用 AI.EMBED 函数生成此内容。

以下示例演示了如何创建包含嵌入列的表,使用 text-embedding-005 作为嵌入模型,然后在 AI.CLASSIFY 查询中使用该列:

-- Create a table with an embedding column
CREATE TABLE my_dataset.bbc_news AS
SELECT
  title,
  body,
  AI.EMBED(
    body,
    endpoint => 'text-embedding-005',
    task_type => 'CLASSIFICATION'
  ).result AS body_embedding
FROM
  `bigquery-public-data.bbc_news.fulltext`;

-- Run the optimized query
SELECT
  title,
  body,
  AI.CLASSIFY(
    body,
    categories => ['tech', 'sport', 'business', 'other'],
    embeddings => body_embedding,
  ) AS category
FROM
  my_dataset.bbc_news;

如果提示引用了多个列,请在 embeddings 实参中提供列名称及其对应的嵌入内容的列表。例如:embeddings => [('body', body_embedding), ('title', title_embedding)]

监控查询优化

如需验证查询执行期间优化了多少行,您可以在 Google Cloud 控制台中或通过 API 查看执行统计信息:

控制台

如需查看优化了多少行,以及查看有关优化状态的系统消息,请执行以下操作:

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

    转到 BigQuery

  2. 在导航菜单中,点击作业探索器

  3. 点击作业 ID 以查看作业详情窗格。

  4. 点击作业信息标签页,然后在生成式 AI 函数优化字段中查看指标和状态。

    “作业信息”标签页中的“生成式 AI 函数优化”字段

API

检查作业元数据的 GenAIFunctionStats 对象中的 FunctionGenAiCostOptimizationStats。此对象包含通过优化后的工作流推断出的行数,以及提供优化状态相关数据洞见的系统生成的消息。

问题排查

以下部分介绍了如何诊断和解决使用优化模式时的常见问题。

数据规模过小

问题:用于模型训练的数据不足。您可能会看到以下错误消息:Fail to apply cost optimization because the data size is too small.

解决方案:将输入的大小增加到大约 3,000 行,并验证是否已为所有行正确生成有效的嵌入。

某些类别的样本数量很少或没有样本

问题:在抽样阶段,某些类别的样本数量不足,导致无法进行模型训练。您可能会看到以下错误消息:Fail to apply cost optimization because some classes have few or no samples.

解决方案

  • AI.CLASSIFY 函数调用中移除稀有类别。
  • 将多个稀有类别合并为一个更广泛的类别,以增加合并后类别中的样本量。例如,将多个稀疏类别合并为一个 OTHER 类别。

嵌入的维度不一致

问题:各行之间的嵌入维度不一致。您可能会看到以下错误消息:Fail to apply cost optimization because the embeddings have inconsistent dimensions.

解决方案:验证嵌入是否由同一模型生成,并且具有相同的嵌入向量长度。您可以使用类似于以下内容的 SQL 查询来检查列中的嵌入是否具有相同的长度:

SELECT ARRAY_LENGTH(body_embedding.result), COUNT(*)
FROM `PROJECT_ID.DATASET.TABLE_NAME`
GROUP BY 1;

提示过于复杂

问题:精简模型无法达到较高的准确率阈值。您可能会看到以下错误消息:Fail to apply cost optimization because the prompt complexity is too high.

解决方案

  • 使用互斥的类别。

    • 避免出现重叠类别,即输入可能同时属于多个类别。例如,避免使用 ['terrible', 'bad', 'okay', 'good', 'excellent'] 等类别。
    • 提供类别说明,以指导 LLM 消除类别之间的歧义。例如:

      AI.CLASSIFY(
        review,
        categories => [
          ('terrible', 'Review where customer was not happy and the message indicates they will never try this product again'),
          ('bad', 'Review where customer was not happy but suggested improvements to the product'),
          ('okay', 'Review where customer was neutral about the product. Short reviews qualify for this category'),
          ('good', 'Review where customers were happy using this product but had minor critiques'),
          ('excellent', 'Review where customers were very happy using this product and will recommend others to try it too')],
        embeddings => review_embeddings)
      
  • 尝试使用更高级的嵌入模型,例如 text-embedding-005multimodalembedding

  • 如需获得更多调试帮助,请发送电子邮件至 bqml-feedback@google.com

LLM 处理的行数超出预期

问题:查询执行统计信息显示,远程 LLM 处理的行数出乎意料地多,而不是精简模型处理的行数。这可能是由于以下原因造成的:

  • 精简模型已成功训练,但部分行的嵌入内容缺失。这些行由远程 LLM 处理。
  • 精简模型无法应用于每一行,因此必须回退到远程 LLM 才能保持一致的质量。

解决方案:验证嵌入是否已正确生成,并且对数据中的所有行都有效。如果问题仍然存在,请发送电子邮件至 bqml-feedback@google.com 以进行调试。

未检测到自主嵌入列

问题:BigQuery 无法检测到自主嵌入列。如果脚本使用临时表,并且对原始表的引用丢失,则可能会发生这种情况。

解决方案:使用 embeddings 参数显式传递一个自主嵌入列(例如 embeddings => content_embedding.result),以触发费用优化。

后续步骤