Cortex

BigQueryとSnowflakeのLLM関数を比較してみた

はじめに

こんにちは、石原です。

生成 AI と大規模言語モデル(LLM)の普及により、SQL だけでテーブル内データを直接プロンプトに渡し、その場で要約や翻訳を返す 方法が主要データウェアハウスに実装され始めています。従来は Python などで外部 API を呼び出し、結果を再ロードする必要がありましたが、現在ではクエリと生成をワンステップで統合可能になりました。

代表例が BigQueryML.GENERATE_TEXTと、SnowflakeCortex LLM 関数COMPLETEなど)。どちらも「SQL ネイティブに LLM を呼び出し、レスポンスを行・列として受け取る」という共通コンセプトを持っていますが記述方法には違いがあります。

本記事では BigQuery と Snowflake の LLM 関数を実際に比較し、それぞれ実装されている処理や呼び出し方法について比較してみます。

比較対象の概要

それぞれの関数についてまとめてみました。

観点BigQuery MLSnowflake Cortex
実装されている関数ML.GENERATE_TEXT ML.GENERATE_EMBEDDING
AI.GENERATE_TABLE
AI.FORECAST
AI.GENERATE
AI.GENERATE_BOOL
AI.GENERATE_DOUBLE
AI.GENERATE_INT
COMPLETE
CLASSIFY_TEXT
EXTRACT_ANSWER
PARSE_DOCUMENT
SENTIMENT
SUMMARIZE
TRANSLATE
EMBED_TEXT _768
EMBED_TEXT _1024
バックエンド LLMgemini-1.5-pro-002, gemini-1.5-flash-002, claude-3-sonnet, mistral-large, llama-3.3-70B などclaude-3-7-sonnet, llama4-maverick, mistral-large2, jamba-1.5-large, snowflake-arctic など

BigQuery MLのポイント

パラメータはSTRUCTで入力

STRUCT(.15 AS TEMPERATURE) のように埋め込みます。

MODEL 句を介して呼び出す

Remote Model を CREATE MODEL で登録 → ML.GENERATE_TEXT に渡すフローが必須です。

呼び出し例

SELECT *
FROM
  ML.GENERATE_TEXT(
    MODEL `mydataset.gemini_flash`,
    (SELECT 'What is the purpose of dreams?' AS prompt),
    STRUCT( .15 AS TEMPERATURE)
);

Snowflake Cortex のポイント

シンプルな関数の呼び出し

COMPLETE(), EMBED() などをそのまま SELECT 句で呼ぶことができます。また、モデルは関数の引数としてシンプルに指定可能です。

パラメータは関数のオプション引数として入力

pythonなどでよく使われるjson形式での入力ができます。

呼び出し例

SELECT SNOWFLAKE.CORTEX.COMPLETE(
    'mistral-7b',
    [
        {
            'role': 'user',
            'content': 'What are large language models?'
        }
    ],
    {
        'temperature': 0.7,
        'max_tokens': 10
    }
);

それぞれを実行してみる

BigQueryML

下記のコードを実行してみます。

SELECT *
FROM
  ML.GENERATE_TEXT(
    MODEL `mydataset.gemini_flash`,
    (SELECT 'What are large language models??' AS prompt),
    STRUCT( .15 AS TEMPERATURE)
);

出力結果が長いですね。もう少し出力結果を絞りこむには下記で対応できます。

SELECT
ml_generate_text_result['candidates'][0]['content'] AS generated_text,
  * EXCEPT (ml_generate_text_result)
FROM
  ML.GENERATE_TEXT(
    MODEL `mydataset.gemini_flash`,
    (SELECT 'What are large language models?' AS prompt),
    STRUCT( .15 AS TEMPERATURE)
);

ただし、この方法でもJSON形式での出力なのでよりシンプルに文字列として取得したい場合はflatten_json_output=Trueにするのが良いかと思います。

SELECT
ml_generate_text_result[‘candidates’][0][‘content’] AS generated_text,

  • EXCEPT (ml_generate_text_result)
    FROM
    ML.GENERATE_TEXT(
    MODEL mydataset.gemini_flash,
    (SELECT ‘What is the purpose of dreams?’ AS prompt),
    STRUCT( .15 AS TEMPERATURE)
    );

これならml_generate_text_llm_resultが出力結果としてそのまま利用できます。

画像や動画などの非構造データの入力も可能です。その場合、オブジェクトテーブルを使用する構文を使用する必要があります。

Snowflake Cortex

下記のコードを実行してみます。

SELECT SNOWFLAKE.CORTEX.COMPLETE(
    'mistral-7b',
    [
        {
            'role': 'user',
            'content': 'What are large language models?'
        }
    ],
    {
        'temperature': 0.7,
        'max_tokens': 10
    }
) as genetated_text;

こちらも、出力結果を絞りこむには下記で対応できます。

SELECT SNOWFLAKE.CORTEX.COMPLETE(
    'mistral-7b',
    [
        {
            'role': 'user',
            'content': 'What are large language models?'
        }
    ],
    {
        'temperature': 0.7,
        'max_tokens': 10
    }
)['choices'][0]['messages'] as genetated_text;

Snowflake Cortexでの画像の入力方法についてはこちらの記事もあわせてご確認下さい。

テーブルのそれぞれの値に対して適用する方法

上記で紹介した方法は単発のプロンプトに対しての回答のみです。

それぞれテーブルの特定のカラムについて処理を行う場合は下記のように記述することが出来ます。

BigQueryML

SELECT
  *
FROM
  ML.GENERATE_TEXT(
    MODEL `exture-common-sandbox-lab.ml_model.gemini_flash`,
    (
      SELECT
        id,
        name,
        CONCAT(
          'Provide a category name appropriate for the following product in one word only. If it cannot be determined, return as not determinable.',
          name,
          '\nCategory:') AS prompt
      FROM product
          ),
    STRUCT(TRUE AS flatten_json_output));

Snowflake Cortex

SELECT
      id,
      name,
      SNOWFLAKE.CORTEX.COMPLETE(
      'mistral-large',
          CONCAT('Provide a category name appropriate for the following product in one word only. If it cannot be determined, return as not determinable.', name)
      )
      FROM product;

これらのクエリではCONCAT句で、productテーブルのname要素からカテゴリーを作成するような処理を実行しています。こちらで作成した結果からテーブルの要素全てに処理を適応することが出来ます。

その他のLLM関数について紹介

今回紹介した汎用関数以外にもタスク固有の関数や出力が特殊なものがありますのでいくつか紹介します。

BigQueryML

エンベディング関数を除く関数については現段階ではプレビューになっています。

ML.GENERATE_EMBEDDING

エンベディングモデルを使用してエンベディングを実施します。

エンベディングモデルによっては、オブジェクトテーブルやObject Ref型として定義されている画像などのエンベディングも実行可能です。

AI.GENERATE_TABLE

下記のように文字列からoutput_schemaに従ったテーブルを作成可能です。

SELECT
  address,
  age,
  is_married,
  name,
  phone_number,
  weight_in_pounds
FROM
AI.GENERATE_TABLE( MODEL `mydataset.gemini_model`,
  (
      SELECT
        'John Smith is a 20-year old single man living at 1234 NW 45th St, Kirkland WA, 98033. He has two phone numbers 123-123-1234, and 234-234-2345. He is 200.5 pounds.'
          AS prompt
  ),
  STRUCT("address STRING, age INT64, is_married BOOL, name STRING, phone_number ARRAY<STRING>, weight_in_pounds FLOAT64"
          AS output_schema, 8192 AS max_output_tokens));

AI.FORECAST

組み込みの TimesFM モデルを使用して時系列予測を事前学習なしで実施します。

horizon:予測ポイント数

confidence_level:信頼区間の設定
SELECT *
FROM
  AI.FORECAST(
    (
      SELECT TIMESTAMP_TRUNC(start_date, HOUR) as trip_hour, COUNT(*) as num_trips
FROM `bigquery-public-data.san_francisco_bikeshare.bikeshare_trips`
WHERE subscriber_type = 'Subscriber' AND start_date >= TIMESTAMP('2018-01-01')
GROUP BY TIMESTAMP_TRUNC(start_date, HOUR)
    ),
    horizon => 720,
    confidence_level => 0.95,
    timestamp_col => 'trip_hour',
    data_col => 'num_trips');

AI.GENERATE

Geminiモデルに対してプロンプトを投げる関数です。ML.GENERATE_TEXTとほぼ同じ用途で用いることができます。(出力型の指定もoutput_schemaにより可能)
エンドポイント経由でアクセスするため、リモートモデルの作成が不要です。

AI.GENERATE_BOOL
AI.GENERATE_DOUBLE
AI.GENERATE_INT

上記はそれぞれ関数名にある通りの型だけを返します。

Snowflake Cortex

タスク固有の関数が作成されており、用途に合致する場合、プロンプトエンジニアリングによる調整がなくとも高い精度で実行が可能になっています。

CLASSIFY_TEXT

テキストを指定したカテゴリの内のいずれかに分類します。

EXTRACT_ANSWER

ソースの情報をもとに質問に対して回答を行います。

PARSE_DOCUMENT

ステージに保存されているドキュメントを解析します。

OCRモードとLAYOUTモードが存在し、OCRモードではテキストを抽出、LAYOUTモードではマークダウン形式で表などをそのままの形で抽出します。

SENTIMENT or ENTITY_SENTIMENT

感情分析を実行できます。ENTITY_SENTIMENT関数は全体的な感情分析と詳細な感情分析の双方を提供します。一方で、SENTIMENT関数はネガティブ・ポジティブの感情スコアを返し、より高速で低コストに実行可能です。

製品分析のためのレビューや肯定的・中立的・否定的・混合など微妙な感情の識別を必要とするケースではENTITY_SENTIMENT関数が適しており、大量の顧客フィードバックへのラベル付けなどのケースではSENTIMENT関数が適しています。

SUMMARIZE

文章の要約を行います。現状英語のみ対応で、日本語文章を入れた場合にも英語へ変換されてしまいます。

TRANSLATE

文章を別の言語に翻訳します。精度としては英語をソースかターゲットにしている場合が最良の結果となります。

上記SUMMARIZE関数の結果から翻訳することで実質的に日本語文書の要約も可能です。

EMBED_TEXT _768
EMBED_TEXT _1024

テキストからエンベディングを生成します。それぞれの関数末尾の数値だけの次元のベクトルを作成します。

まとめ

  • 呼び出し方の思想が異なる
    • BigQuery MLリモートモデルを作成 → 関数で利用 という 2 ステップ。
      • プレビューで公開されているAI.GENERATE関数ではよりシンプルに呼び出しが可能
    • Snowflake Cortexシンプルな関数で即実行できる。
  • 仕様について
    • BigQuery ML は出力が特定の列に格納されるので実装時にドキュメントの確認は必要。デフォルトでsafety_settingsが有効になっている。Google検索によるGroundingに対応。
    • Snowflake Cortex は 入力形式がシンプルで使いやすい。ロール・履歴の設定が可能(OpenAIの形式やLangChainなどの形式で入力可能)。Cortex Guardを使用したフィルタリングがオプションで対応可能。
  • モデル選択の柔軟性
    • BigQuery ML:Gemini、Claude、Mistral、Llama 3 系など Vertex AIのモデルガーデン上で提供される複数のモデルを使用できる
    • Snowflake Cortex:Claude 3 Sonnet、Llama 4 Maverick、Mistral Large2、Jamba 1.5 Large、Snowflake Arctic など複数のモデルを使用できる
  • どちらを選ぶか
    • 既にGCP上で分析基盤を運用しており、Looker StudioやBQ とでの処理と連携したい。Google検索によるGroundingを使用したい → BigQuery ML
    • 複数のモデルでの結果を元に簡単にA/Bテストしたい、または Snowflake 内でアプリ(Streamlit、Native App)まで完結させたい、定義済みの関数を利用したい → Snowflake Cortex

結論としては、呼び出しやすさという点ではSnowflakeの方が簡単であると思いましたが、Google特有のGroudingオプションの有無など踏まえるとどちらかが優位という違いはないというように感じました。使用されているDWHによってそれぞれの関数を使用するのが良いかと思います。

参考

dbt Cloud使ってみた前のページ

dbt_expectationsでデータ品質を向上させよう次のページ

ピックアップ記事

  1. 最速で理解したい人のためのIT用語集

関連記事

  1. Snowflake

    SnowPro Advanced: Architect 合格体験記

    こんにちは、エクスチュアの黒岩と申します。2年前に取得したS…

  2. Google BigQuery

    Tableau×BigQueryをコスパ良く使う方法

    こんにちは、エクスチュア渡部です。TableauでBigQue…

  3. Data Clean Room

    忘年会シーズンに「DCRごっこ」のご提案

    こんにちは、喜田です。本投稿は Snowflake Advent C…

  4. Snowflake

    Snowflake Summit 2025 参加レポート【Day1】

    こんにちは、エクスチュアの黒岩です。現在、アメリカ・サンフラ…

  5. RevOps

    Snowflakeや最新データ基盤が広義のマーケティングにもたらす価値 in 2024

    こんにちは、喜田です。この投稿はSnowflake Adve…

カテゴリ
最近の記事
  1. dbt Fusion使ってみた
  2. Manusを使ってみたうえでManusに感想ブログを書かせて…
  3. SquadbaseとStreamlitでお手軽アプリ開発
  4. [Snowflake Summit 2025] Snowfl…
  5. [Snowflake新機能]AI_AGGを試してみた
  1. ChatGPT

    LangChainって何?: 次世代AIアプリケーション構築 その2
  2. Tableau

    TableauでTreasure Data上のデータへ接続する方法(2019/1…
  3. Adobe Analytics

    Metabase: カスタムマップで日本地図を追加する
  4. 海外カンファレンス

    Adobe Summit 2018 参加レポート(M)
  5. IT用語集

    アプライアンス(Appliance)って何?
PAGE TOP