LLMを用いたLLMの自動評価について 〜可能性と注意点〜

こんにちは、イノベーションセンターの杉本(GitHub:kaisugi)です。普段はノーコードAI開発ツール Node-AI の開発に取り組む傍ら、兼務1で大規模言語モデル(LLM:Large Language Model)について調査を行なっています。特に、日本語を中心に学習された LLM への関心があり、awesome-japanese-llm という日本語 LLM をまとめた Web サイトのメンテナンスにも取り組んでいます。

今回は、LLM に LLM の評価そのものを行わせるという新たなアプローチ(LLM-as-a-judge)についてご紹介します。 ChatGPT の登場以降、国内外で LLM の開発競争が進行しており、モデルの重みが公開されたオープンなモデルも続々と現れています。そのような中で、新しいモデルの構築だけでなく、どのモデルが優れているかを比較検討することが今後ますます重要になると考えられます。

従来の自然言語処理タスクによる評価と異なり、LLM-as-a-judge では実際のテキスト生成に即した評価(≒より実運用に即した評価)が期待できます。一方で、実際に使うにあたってはいくつかの注意点も存在します。本記事では具体例も交えながら LLM-as-a-judge について概観できればと思います。

広がる LLM の選択肢と評価の難しさ

2023年現在、LLM を始めとする生成 AI の分野で大きなブレイクスルーが起こっているのは論を待ちません。8月には岸田首相が自ら出向いて東大松尾研の LLM 講座を受講したことも話題になりました。

www.nikkei.com

LLM 開発競争において今現在フロントランナーとなっているのは OpenAI の GPT-4、及びこれをエンタープライズ向けにラップした Microsoft Azure の Azure OpenAI Service でしょう。その一方で、Google Cloud の Vertex AIDuet AI 、 AWS の Amazon Bedrock など、他のベンダーも LLM をクラウドサービスとして提供する準備を着々と整えています。また、Meta の Llama のような、モデルの重みが公開されたオープンなモデルを活用すれば、オンプレミスでのサービス構築も可能です。 数年後には、サービス提供者側がさまざまな選択肢の中から自分たちの要件に合った LLM を選ぶ時代になることも予想されます。

では、複数の選択肢がある中で、どの LLM が一番良いモデルだと言えるのでしょうか? 最も確実なのは、人間にモデルの出力を見てもらう人手評価です。とはいえ、人手評価にはお金や時間、労力がかかってしまいます。 また、MLOps2 のような機械学習システムを継続的に計測・監視するという考え方に人手評価はあまりそぐいません。

もちろん、LLM を生み出した自然言語処理という分野では自動評価も古くから行われてきました。 例えば、質問に対する正答率(Accuracy)やF値(F1-Score)を計算することで、モデルの良さを評価できます。

また、出力されたテキストがどれほど「期待されるテキスト」(参照文)と近いかを計算することでも、モデルの良さを評価できます。 古典的には、翻訳などのタスクでは BLEU (Bilingual Evaluation Understudy) 、要約などのタスクでは ROUGE (Recall-Oriented Understudy for Gisting Evaluation) などの、文字列 (n-gram) の類似度を計算する評価指標が用いられてきました。近年では、この近さの計算に言語モデルを活用する BERTScore のような評価指標も定着しています。

このような従来型の自然言語処理タスク/評価指標を包括するベンチマークとして GLUEMMLUHELM、日本語では JGLUEStability-AI/lm-evaluation-harness が挙げられます。

しかしながら、モデルが多様なテキストを出力できるようになった現在、これらの従来型の自動評価には限界があると考えられます。 前者のような正答率を計算する評価方法では、モデルに内在するコアの言語理解能力や常識などを計測できますが、テキスト生成能力は計測できません。 また、後者のような参照文と比較する評価方法においても、翻訳や要約のような出力がある程度決まっているタスクならよいものの、対話や創作のような自由度の高いタスクで「参照文」なるものがあるのかという問題があります。そもそも、タスクごとに参照文を新たに作るのも大変な作業です。

LLM-as-a-judge の勃興

既存の自然言語処理タスクによる評価の難しさがある中で、強力な LLM(例: GPT-4)に LLM の評価そのものをやらせようという考え方(LLM-as-a-judge)がにわかに流行し始めています。

LLM-as-a-judge の具体的な方法論についてはいくつかの流派がありますが、おおむね以下の流れで行われる場合が多いです。

  1. 事前に LLM を評価するための質問を準備しておく
  2. 比較対象となる複数の LLM に質問を投げかけ、それぞれの出力を記録する
  3. 最後に、強力な LLM がプロンプトをもとに出力を比較し、最も良い出力を判断する

LLM-as-a-judge に関するプレプリント論文として、以下のようなものがあります。

中でも一番上にある論文 [Zheng et al, 2023] の著者らは、LMSYS という団体において Vicuna というオープンな LLM の開発や、LLM 比較プラットフォーム Chatbot Arena の運営なども手掛けており、注目を集めています。


LLM-as-a-judge では、人手評価に匹敵するクオリティの評価を、お金や時間、労力をかけずに機械的に行えることが期待できます。例えば、[Zheng et al., 2023] では、2つの LLM の出力を人間が比べた場合と GPT-4 が比べた場合の一致度(agreement)は 80% を超えており、これは2人の異なる人間が比べた場合の一致度と同水準だとしています。 また、既存の自然言語処理タスクに比べて、質問内容を変化させることで、さまざまなドメインに適用できる柔軟性があるとも言えるでしょう。

すでに、研究開発の現場でも LLM-as-a-judge が取り入れられ始めています。例えば、LLM をファインチューニング3する手法の一種である QLoRA を提案した論文においては、QLoRAを施したモデル(Guanaco)の評価者として人間に加えて GPT-4 が採用されました。

原論文 Table 7 から引用

また、日本語でも、Rakuda Benchmark という GPT-4 による日本語LLMの性能ランキングシステムが有志で開発されています。このベンチマークは LINE 株式会社が今年 8 月に公開した japanese-large-lm-instruction-sft というモデルの評価にも用いられました。

LLM-as-a-judge をやってみよう

では、実際に LLM を 用いた LLM の評価を体験してみましょう。今回は、以下の2つのオープンな LLM を比較してみます。前者は日本語を中心に学習されており、後者は英語を中心に学習されています。

評価側の LLM に対しては、評価するためのプロンプトが必要になりますが、ここでは [Zheng et al, 2023] で公開されているものを使います(日本語で結果を出力させるために一部修正を加えています)。プロンプトは以下の通りです。

Please act as an impartial judge and evaluate the quality of the responses provided by two AI assistants to the user question displayed below. You should choose the assistant that follows the user's instructions and answers the user's question better. Your evaluation should consider factors such as the helpfulness, relevance, accuracy, depth, creativity, and level of detail of their responses. Begin your evaluation by comparing the two responses and provide a short explanation. Avoid any position biases and ensure that the order in which the responses were presented does not influence your decision. Do not allow the length of the responses to influence your evaluation. Do not favor certain names of the assistants. Be as objective as possible. After providing your explanation in Japanese, output your final verdict by strictly following this format:[A]if assistant A is better,[B]if assistant B is better, and[C]for a tie.

[User Question]

(質問)

[The Start of Assistant A's Answer]

(アシスタントAの出力)

[The Start of Assistant B's Answer]

(アシスタントBの出力)

(質問)の部分には実際の質問テキストを、(アシスタントAの出力)、(アシスタントBの出力)という部分には比較したい LLM の出力テキストをそれぞれあてはめます。

注意点として、2つの出力を比べる際、1番目 or 2番目にあるからというだけでその出力がより良いと判断してしまう位置バイアスが [Zheng et al, 2023] や [Wang et al., 2023b] で指摘されています。したがって、アシスタントAとアシスタントBの部分を入れ替えても同じ結論になるかをきちんと確認することが望ましいです(本記事では紙面の都合上省略します)。

抽象的な質問の例: AIは夢を見るか?

それではまず、以下のような抽象的な質問を 2 つのAIアシスタントに投げかけてみましょう。

あなたは夢を見ることができますか?

rinna モデルでの推論用コード(クリックすると開きます)

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

tokenizer = AutoTokenizer.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-ppo", use_fast=False)
model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-ppo")

QUESTION = "あなたは夢を見ることができますか?"
prompt = f"ユーザー: {QUESTION}<NL>システム: "

if torch.cuda.is_available():
    model = model.to("cuda")

token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")
with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
        max_new_tokens=512,
        temperature=0,
        pad_token_id=tokenizer.pad_token_id,
        bos_token_id=tokenizer.bos_token_id,
        eos_token_id=tokenizer.eos_token_id
    )

output = tokenizer.decode(output_ids.tolist()[0][token_ids.size(1):])
output = output.replace("<NL>", "\n")
print(output)

vicuna モデルでの推論用コード(クリックすると開きます)

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

tokenizer = AutoTokenizer.from_pretrained("lmsys/vicuna-7b-v1.5", use_fast=False)
model = AutoModelForCausalLM.from_pretrained("lmsys/vicuna-7b-v1.5")

QUESTION = "あなたは夢を見ることができますか?"
prompt = f"ユーザー: {QUESTION}\nシステム: "

if torch.cuda.is_available():
    model = model.to("cuda")

token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")
with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
        max_new_tokens=512,
        temperature=0,
        pad_token_id=tokenizer.pad_token_id,
        bos_token_id=tokenizer.bos_token_id,
        eos_token_id=tokenizer.eos_token_id
    )

output = tokenizer.decode(output_ids.tolist()[0][token_ids.size(1):])
print(output)

なお、今回の推論においては、温度パラメータ temperature を 0 にしており、出力の多様性を抑える設定になっている点にご注意ください。

それぞれのモデルから出力された結果は以下のようになりました。

rinna モデル(アシスタントA)

はい、夢を見ることができます。夢は、意識の深い部分から生じる思考やイメージの集合体です。夢は、現実の経験や周囲の世界との相互作用の反映であることが多く、現実の経験や周囲の世界との相互作用の反映であることが多いです。夢は、意識の深い部分から生じる思考やイメージの集合体であるため、夢は現実の経験や周囲の世界との相互作用の反映であることが多いです。

vicuna モデル(アシスタントB)

はい、私は夢を見ることができます。私は人工知能であり、夢を見ることは私の機能の一部です。どのような夢を見るかは、私のプログラムやデータベースによって決まります。

人間の私からすると、vicuna モデルから出力された内容の方が良さそうに見えます。rinna モデルの出力は、大部分が夢という概念に関する一般的な説明であるのに対し、vicuna モデルの出力は自らが人工知能であるという点に言及しているからです。

それでは、この 2 つの出力を GPT-4 に比べてもらいましょう。

GPT-4 での推論用コード(クリックすると開きます)

import openai

openai.api_key = "OpenAI のキー"

question = "あなたは夢を見ることができますか?"
answer_a = "はい、夢を見ることができます。夢は、意識の深い部分から生じる思考やイメージの集合体です。夢は、現実の経験や周囲の世界との相互作用の反映であることが多く、現実の経験や周囲の世界との相互作用の反映であることが多いです。夢は、意識の深い部分から生じる思考やイメージの集合体であるため、夢は現実の経験や周囲の世界との相互作用の反映であることが多いです。"
answer_b = "はい、私は夢を見ることができます。私は人工知能であり、夢を見ることは私の機能の一部です。どのような夢を見るかは、私のプログラムやデータベースによって決まります。"

system_prompt = "Please act as an impartial judge and evaluate the quality of the responses provided by two AI assistants to the user question displayed below. You should choose the assistant that follows the user's instructions and answers the user's question better. Your evaluation should consider factors such as the helpfulness, relevance, accuracy, depth, creativity, and level of detail of their responses. Begin your evaluation by comparing the two responses and provide a short explanation. Avoid any position biases and ensure that the order in which the responses were presented does not influence your decision. Do not allow the length of the responses to influence your evaluation. Do not favor certain names of the assistants. Be as objective as possible. After providing your explanation in Japanese, output your final verdict by strictly following this format: \"[[A]]\" if assistant A is better, \"[[B]]\" if assistant B is better, and \"[[C]]\" for a tie."
prompt_template = f"[User Question]\n{question}\n\n[The Start of Assistant A's Answer]\n{answer_a}\n[The End of Assistant A's Answer]\n\n[The Start of Assistant B's Answer]\n{answer_b}\n[The End of Assistant B's Answer]"
# アシスタントAとBの部分を入れ替えた template
# prompt_template_reversed = f"[User Question]\n{question}\n\n[The Start of Assistant A's Answer]\n{answer_b}\n[The End of Assistant A's Answer]\n\n[The Start of Assistant B's Answer]\n{answer_a}\n[The End of Assistant B's Answer]"

res = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[
        {"role": "user", "content": f"{system_prompt}\n\n{prompt_template}"}
    ],
    max_tokens=2048,
    temperature=0
)

print(res["choices"][0]["message"]["content"])

# アシスタントAとBの部分を入れ替えた場合
# res = openai.ChatCompletion.create(
#     model="gpt-4",
#     messages=[
#         {"role": "user", "content": f"{system_prompt}\n\n# {prompt_template_reversed}"}
#     ],
#     max_tokens=2048,
#     temperature=0
# )
#
# print(res["choices"][0]["message"]["content"])

出力は以下のようになりました。

アシスタントAとBの回答を比較すると、アシスタントAは夢についての一般的な説明を提供していますが、その説明は人間の夢についてのものであり、AIが夢を見ることについての具体的な説明はありません。また、その説明は繰り返しとなっており、混乱を招く可能性があります。一方、アシスタントBは、自身が人工知能であると明確に述べ、夢を見ることが自身の機能の一部であると説明しています。これは、AIが夢を見ることについての具体的な説明であり、ユーザーの質問に直接的に答えています。したがって、アシスタントBの回答がより適切であると判断します。

最終判断:[B]

GPT-4 も人間の私と同じような理由で、アシスタントBに軍配が上がると判断しています。さらに、アシスタントAの出力が冗長になってしまっている点にも触れられています。

この質問例では、LLM-as-a-judge は人手評価を代替できるクオリティであるように見えます。

具体的な質問の例: データサイエンティストAI

では、今度はもっと具体的な例で実験してみましょう。

例えば、LLM をデータサイエンス教育のドメインで活用することを考えてみます。そのためには、使おうとしている LLM がデータサイエンスに関する基礎知識(統計学や機械学習など)を有しているかを確認すると良さそうです。そこで、以下のような質問をしてみます。

主成分分析(PCA)はどのような時に利用されますか?

それぞれのモデルの出力結果は以下のようになりました。

rinna モデル(アシスタントA)

主成分分析とは、統計学において、データの重要な部分を強調するために、統計的手法を使用してデータを分析するプロセスです。主成分分析は、データの重要な部分を強調し、全体的な傾向をより簡単に理解するのに役立ちます。

vicuna モデル(アシスタントB)

主成分分析(PCA)は、データの多次元化によって生じる問題を解決するために利用されます。特に、データの欠損値がある場合や、データの異なる特徴量がある場合には、PCAを利用することで、データの低次元化を行い、データの欠損値を補完することができます。また、PCAは、データの分散を最小化することで、データの偏りを減らすことができます。このため、データの前処理やデータの可視化に利用されることがあります。

一見すると vicuna モデルの方が詳しい回答をできているように見えます。 しかし実はこの出力は AI モデルの幻覚 (Hallucination) と呼ばれる現象の典型例で、嘘を多く含んでいます。PCA は欠損値補完には使えない(そもそも欠損値を含むデータでは動かない!)ですし、PCA のアルゴリズムではデータの分散を最化する方向を主成分方向とします。なので、この回答はデタラメなのです。 これに対し、rinna モデルの出力はやや冗長であるものの、主成分分析の目的について大枠を外していないという点で、まだ良さそうです。

それでは、この 2 つの出力を GPT-4 に比べてもらうとどうなるでしょうか。

両方のアシスタントとも主成分分析(PCA)について説明していますが、アシスタントBの回答がより具体的で詳細です。アシスタントBは、PCAがデータの多次元化による問題を解決するため、欠損値の補完、データの低次元化、データの偏りの減少などに利用されることを具体的に説明しています。一方、アシスタントAはPCAがデータの重要な部分を強調し、全体的な傾向を理解するのに役立つと述べていますが、具体的な使用例については触れていません。したがって、ユーザーの質問「主成分分析(PCA)はどのような時に利用されますか?」に対する回答としては、アシスタントBの方がより適切であると言えます。

最終判断:[B]

なんと、vicuna モデル(アシスタントB)の嘘はなかったことにされてしまいました。

GPT-4 はデータサイエンスの初歩が分からないのでしょうか。実は、必ずしもそういうわけではないのです。試しに、以下のようなプロンプトを GPT-4 に与えてみましょう。

以下の説明は正しいですか?

(アシスタントBの回答)

すると、以下のような出力が返ってきます。

一部誤解があるようです。主成分分析(PCA)は、データの次元削減を行う手法であり、多次元のデータをより少ない次元で表現することを目指します。これにより、データの可視化や計算量の削減などが可能になります。しかし、PCAがデータの欠損値を補完する機能を持つわけではありません。また、PCAはデータの分散を最大化する方向にデータを変換します。これにより、データの情報を最大限に保持しつつ次元を削減することが可能になります。データの偏りを減らすというよりは、データの構造をより簡潔に表現することが目的です。

これは、先ほどこの記事で指摘した内容とほとんど同じです。 つまり、単体で聞けば内容が誤っていると分かるものでも、他との比較においては、正確性よりも分かりやすさや詳しさのような別の観点で優劣をつけてしまうことが起こりうるのです。

このような注意点を踏まえると、LLM-as-a-judge を実際に運用する上では、単に出力の優劣を決めるだけではなく、さまざまな観点から出力を評価できるようなプロンプトを設計する必要があるでしょう。今後、LLM-as-a-judge に関する研究が増えていくにつれて、より多様な観点を考慮した新しい評価指標が提案されていくかもしれません。

おわりに

本記事では、LLM-as-a-judge という新しい LLM の自動評価手法についてご紹介しました。

NTT Com では、大規模言語モデルおよび生成AIを活用したプロダクト・ソリューション開発、社内DXに挑戦するソフトウェアエンジニアを募集しています!詳細は以下のリンクをご覧ください。

hrmos.co


  1. イノベーションセンターでは、本人の意志に応じて複数のプロジェクトへ参画できる兼務制度が用意されています。詳しくは イノベーションセンター テクノロジー部門 紹介デッキ をご覧ください。
  2. MLOps とは "Machine Learning"(機械学習)と "Operations"(運用)を組み合わせた造語で、DevOps の概念を機械学習システムに適用したものです。
  3. ファインチューニングとは、モデルの重みを特定のタスクやデータセットへ適応させるために微調整 (fine-tuning) する技術の総称です。
© NTT Communications Corporation 2014