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. ChatGPT

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

    こんにちは、エクスチュアの石原です。近年、大規模言語モデル(…

  2. Google BigQuery

    GCPのBQMLを使ってKaggleコンペに挑んでみた(その1)

    こんにちは。エクスチュアでインターンをさせて頂いている中野智基です。…

  3. Data Clean Room

    SnowflakeのData Clean Roomを基礎から一番詳しく解説(2回目)

    こんにちは、喜田です。複雑なSnowflakeのデータクリー…

  4. Snowflake

    SnowPro Associate: Platform 合格体験記

    こんにちは、中村です。先日、SnowPro Associate: P…

  5. Data Clean Room

    Snowflake の新しいData Clean Roomの見どころを解説

    こんにちは、喜田です。私は昨年Snowflakeのデータクリーンルー…

カテゴリ
最近の記事
  1. dbt Projects on Snowflake使ってみた…
  2. Cortex Analystを使ってみた
  3. SnowflakeのAI_SQLと再帰CTEで遊ぶ(Snow…
  4. dbt Fusion使ってみた
  5. Manusを使ってみたうえでManusに感想ブログを書かせて…
  1. GA 360 Suite

    Google Analytics 360: BigQueryを使ってアトリビュー…
  2. ObservePoint

    Webサイトのプライバシーポリシー検証(1/6):プライバシーポリシーを設置する…
  3. Mouseflow

    Mouseflowを採用するWebサイトが10万を突破!
  4. IT用語集

    CAD・CAM・CAEって何?
  5. ヒートマップ

    Mouseflowの新機能:ライブヒートマップで動的なヒートマップ分析が可能に!…
PAGE TOP