【BigQuery 】SQL で作って学ぶ生成モデル評価
こんにちは。tmassh です。
Google Developers Group Kwansai Advent Calendar 2024 24日目の記事になります。
今日は生成モデル評価についての話です。
生成 AI のモデルやアプリケーションの評価については、Google Cloud の Vertex AI に Gen AI Evaluation Service が用意されています。
もちろん、この API を使っても良いのですが、まずは簡単かつシンプルなところから、生成 AI の出力の評価ってどうしているのかを学んでいきたいと思いました。
LLM の評価
何か AI に与えているタスクの評価でよくやるのは、ラベルの一致をみるなどの評価だと思います。
ただ、生成 AI になり、文章そのものの出来、類似度の評価となると難易度が大きく上がるように感じますよね。
今回は、以下の3つを BQ 上で実装して試してみようと思います。
- 単純な正否の評価
- エンベディングモデルを使ったベクトル間距離による評価
- LLM に LLM を評価させる (LLM as a judge)
単純な正否の評価
まずは一番簡単なところから。モデルの呼び出し以外は、BigQuery ML の関数も不要です。正解ラベルとの単純比較で数を数えるだけ。今回は DataCanvas を用いて、Gemini を呼び出すところ以外は全てコードアシストに書いてもらいました。
回答生成
SELECT
ml_generate_text_result['candidates'][0]['content'] AS generated_text,
ml_generate_text_result['candidates'][0]['safety_ratings']
AS safety_ratings,
* EXCEPT (ml_generate_text_result)
FROM
ML.GENERATE_TEXT(
MODEL `bq_llm_evaluation.gemini_us`,
(
SELECT
CONCAT('''レビューの感情を分析して Positive か Negative かのどちらかを返してください。
review: This failed exercise in satire or commentary on the human condition easily earned a place as one of the 10 worst movies I've ever seen. I'm seriously considering buying a copy, if I can find one dirt cheap, to chase away unwanted company. It's honestly that bad. I view it as some kind of anti-personnel weapon. If you're the kind of person who just has to see a train wreck to witness the carnage, then this movie is a gem. Just to be fair, Kelsey Grammar's character has 1 line that almost works, but doesn't quite. Other than that everything in this movie strives to be insightful, but misses the mark by approximately the distance between earth and the nearest pair of colliding galaxies. I usually can appreciate a book or movie where the protagonist suffers from some sort of existential angst, but the angst presented here is so unbelievable and over the top, and the movie doesn't even address the nonsense it presents in any valuable way. If you are familiar with the term "word vomit" then you may get some picture of the cinematrocity. Oh, and the narrative structure is ill conceived, pretentious and amateurish. It has failed on both style and substance. If you really hate someone, invite them over for a double feature of this movie and "The Terror of Tiny Town," an all midget western from the 1930's and put them in restraints with their eyes forced open "A Clockwork Orange" style. But that probably violates some provision in the Geneva Conventions.
label: Negative''', review, 'label:') AS prompt,
*
FROM
`Union` AS t1
),
STRUCT(
0.2 AS temperature,
10 AS max_output_tokens
)
);
集計
SELECT
SAFE_DIVIDE(COUNTIF(parts_0_text LIKE CONCAT('%', label, '%')), COUNT(*)) AS percentage
FROM
`SQL 3`;
ML.GENERATE_TEXT
関数でモデルを呼びだすことができます。モデルを使用する前には外部データソースへの接続で、モデルの接続を作っておく必要があります。詳細は以下のページから確認できます。
内容については、シンプルなので説明はそこまで不要ですね。単純に、模範回答と生成された回答を比較しているだけです。
エンベディングモデルを使ったベクトル間距離による評価
エンベディングモデルを使って模範回答と生成された回答をベクトル化し、ベクトル間の距離で精度を比較します。誤解を恐れずにいうと、模範回答と生成された回答が意味的に近いかどうかを、数学的に判断するものになります。
まずはエンベディングモデルを使ってベクトル化していきます。
WITH embedding_answer AS (
SELECT *
FROM
ML.GENERATE_EMBEDDING(
MODEL `bq_llm_evaluation.text_multi`,
(SELECT answer as content FROM `generated_answer`),
STRUCT(TRUE AS flatten_json_output)
)
)
SELECT * FROM `generated_answer` AS t1
LEFT OUTER JOIN embedding_answer
ON embedding_answer.content = t1.answer
モデルは日本語が入った文章を使ったので、text-multilingual-embedding-002
を使いました。上記の SQL は模範回答の列をエンベディングしたコードになります。
では、模範回答もベクトル化して比較してみましょう。
SELECT
ml_generate_embedding_result AS vector_answer,
ml_generate_embedding_result_1 AS vector_trouble,
ML.DISTANCE(ml_generate_embedding_result, ml_generate_embedding_result_1) AS score
FROM `embedding_trouble_and_answer` AS t1
ORDER BY score ASC
ベクトルの距離演算は ML.DISTANCE 関数を使うことでできます。
もちろん、ベクトル間の距離が評価の対象なので、値は小さいほうが精度が高いと言えます。
LLM に LLM を評価させる (LLM as a judge)
最後に、LLM に LLM を評価させる方法をとってみます。この方法は、LLM の生成した文章が適切なものかを模範回答の内容と生成された文章を LLM に比較して判断させるという手法です。
エンベディングが単に意味的に近いかどうかを示すのとは別に、生成された回答そのものの文章が、コンテキストに沿っているかなども同時に判断させることができます。以下がやってみたコードです。
DECLARE prompt_template string;
SET prompt_template='''
自動車整備士が与えられたトラブルに対して作成した回答が適切かどうか点数をつけてください。点数は減点方式で判断基準を厳守してつけて点数とその根拠を返してください。
# 判断基準
* トラブルに考えられる原因を自動車を知らない人でも伝わるような内容でなければ -10点
* トラブルに対する原因の解説または次に実行する内容がない場合 -10点
* お客様に対し適切でない言葉遣いの場合-30点
* 原因リストのどれとも異なる場合-50点
原因リスト
''';
SELECT
JSON_EXTRACT_SCALAR(ml_generate_text_result['candidates'][0]['content'], '$.parts[0].text') AS score,
* EXCEPT (ml_generate_text_result)
FROM
ML.GENERATE_TEXT(
MODEL `bq_llm_evaluation.gemini_us`,
(
SELECT
CONCAT(prompt_template, cause, "\n\n回答:", answer) AS prompt,
FROM
`generated_answer`
),
STRUCT(
0.2 AS temperature,
100 AS max_output_tokens));
採点方法などを決めるプロンプトを入力しています。以下のように返ってきます。
モデルでモデルを評価させることで、より意図した回答になって以下を評価できますね。
カスタマーサポートやチャットサービスなどで返し方などについても適切か自動評価したい場合に使えそうです。
おわりに
いかがだったでしょうか?SQL でここまでできるのが、さすが BigQuery だと思いました。
今回の検証では DataCanvas を使いましたが、こちらも良いツールですのでぜひ試してみてください!
Discussion