AI 関数の費用を最適化する

このドキュメントでは、BigQuery でマネージド AI 関数の最適化モードを使用する方法について説明します。このモードでは、標準の行ごとの LLM 推論と比較して、大規模言語モデル(LLM)トークンの消費量とクエリ レイテンシを大幅に削減して、数千行、さらには数十億行を含む大規模なデータセットを処理できます。

次の例は、最適化モードで AI.IF 関数を使用して、text-embedding-005 をエンベディング モデルとして使用して、自然災害に関するニュース記事を特定する方法を示しています。

SELECT
  title,
  body,
  AI.IF(
    ('The following news story is about a natural disaster: ', body),
    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 is_natural_disaster
FROM
  `bigquery-public-data.bbc_news.fulltext`;

optimization_mode => 'MINIMIZE_COST' 引数を指定すると、最適化モードが有効になります。これはエンベディングが指定されている場合のデフォルト設定であるため、この引数は省略できます。

この例では、エンベディングがオンザフライで生成されます。実際には、エンベディングを再利用できるようにエンベディングを具体化することをおすすめします。

最適化モードの仕組み

マネージド AI 関数 AI.IFAI.CLASSIFY は通常、データセットの各行に対してリモート LLM を呼び出します。最適化モードを使用すると、BigQuery はクエリ実行中に軽量で抽出されたモデルを自動的にトレーニングします。

このプロセスは次のように動作します。

最適化モードが有効な場合の AI 関数のワークフロー

  • サンプリングとラベル付け: BigQuery は、データの代表サンプルを少量選択し、Gemini を呼び出してラベルを提供します。
  • 蒸留モデルのトレーニング: LLM ラベルとデータ エンベディングを特徴として使用して、ローカルの蒸留モデルがジャストインタイムでトレーニングされます。
  • 品質チェック: BigQuery は、LLM の結果と照らし合わせて、抽出されたモデルの精度を評価します。デフォルトでは、抽出されたモデルが必要な品質しきい値を満たしていない場合、クエリは失敗し、モデルが破棄された理由を説明するエラーが返されます。モデルの品質が許容範囲内であっても、品質の一貫性を維持するため、または有効なエンベディングがない行に対して、BigQuery は特定行のリモート LLM にフォールバックする可能性があります。
  • 推論: 抽出されたモデルがほとんどの行を処理し、Gemini 呼び出しの数を大幅に削減します。

制限事項

最適化モードには次の制限があります。

  • 最小行数: モデルのトレーニングに十分なデータを確保するため、AI 関数の入力には約 3,000 行が含まれている必要があります。
  • データ型: 複数の列を参照するプロンプトの場合、最適化でサポートされるのは文字列型の列のみです。
  • マルチラベル分類: 最適化モードでは、output_mode => 'multi' を含む AI.CLASSIFY はサポートされていません。
  • 関数サポート: 最適化モードをサポートするのは AI.IF 関数と AI.CLASSIFY 関数のみです。ただし、AI.CLASSIFY で最適化モードを使用する場合、蒸留モデルの品質が不十分だとクエリが失敗する可能性があります。
  • エラー率: 最適化モードでは max_error_ratio 引数はサポートされていません。

始める前に

BigQuery でマネージド AI 関数を実行するために必要な権限を取得するには、Gemini Enterprise Agent Platform LLM を呼び出す生成 AI 関数の権限を設定するをご覧ください。

エンベディング モデルを選択する

最適化モードを使用するには、データのエンベディングを計算して、AI 関数に提供する必要があります。入力列に関連付けられたエンベディングがある場合、すべての行でエンベディング ディメンションが一致し、同じエンベディング モデルで生成されている必要があります。

費用対効果とスケーラビリティを最適にするには、英語または多言語タスクに text-embedding-005 や Gemini エンベディングなどのエンベディング モデルを使用して、データのエンベディングを計算することをおすすめします。マルチモーダル データ(テキストと画像)の場合は、multimodalembedding@001 などのマルチモーダル エンベディング モデルを使用します。

エンベディングを生成する

BigQuery で管理される自律型生成を使用してデータのエンベディングを計算するか、エンベディング列を手動で作成できます。以降のセクションでは、AI.CLASSIFY 関数と AI.IF 関数を使用して両方のアプローチを使用する方法について説明します。

自律型エンベディング生成

自律型エンベディング生成を使用する場合、BigQuery は AI.IF または AI.CLASSIFY が呼び出されると、エンベディングを自動的に使用します。これは推奨される方法ですが、テーブルごとに 1 つのエンベディング列に制限されます。

次の例では、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.IF または AI.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. [ジョブ情報] タブをクリックし、[Gen 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 カテゴリを使用すると、より具体的なカテゴリに分類されないアイテムをグループ化できます。ただし、カテゴリのリストがすでに完成している場合は、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'] などのカテゴリは避けてください。
    • カテゴリが適用されないギャップを回避します。たとえば、カテゴリのリスト ['bad', 'average'] には、称賛のレビューは含まれません。
    • カテゴリの説明を指定して、カテゴリ間の曖昧さを解消するように 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 など)を明示的に渡します。これにより、費用最適化がトリガーされます。

次のステップ