LLMの苦手タスクにおけるMany-Shot In-Context Learningの検証

2024年12月3日掲載

キービジュアル

ソフトバンク アドベントカレンダー 2024 3日目の記事を担当する松岡です。

普段は、TASUKIというAIを構築するためのデータ作成代行、データコンサル、データ構造化ツールの事業開発に関わっています。

ChatGPTの登場により、大規模言語モデル(LLM)などの生成AIを業務で活用する案件が増加しています。特に、企業独自の非公開データをLLMに回答させたいと考えるお客様や、特定の用途でLLMの性能を向上させたいという相談が増えています。

本記事では、LLMが苦手とする未学習データや性能が低いタスクへの対応方法について、具体的な検証を交えながら説明します。特に、回文(前から読んでも後ろから読んでも同じ文字列)を生成するというタスクを題材とし、その回答精度を改善する検証を紹介します。

目次

この記事では以下の方を対象としています。
  • ChatGPTや生成AIをより効率的に活用したい方
  • 自分でも生成AIをより効率的に活用したい方
  • プロンプトチューニングの具体的な活用方法や、RAGやFine-tuningとの違いを知りたい方
  • 生成AIやプログラミングの基本的な知識をお持ちの方

未学習のデータの回答方法

ChatGPTを含む多くのLLMは、インターネット上の情報を学習しているため、一般的な知識(例:Wikipediaに掲載されている情報)については非常に高い精度で回答できます。一方で、以下のような場合にはその性能が大幅に低下します。

  • 非公開データ:企業内の独自データや機密情報を使った質問
  • マイナーな言語や専門用語:データセットに含まれていない言語や分野の知識
  • 特殊なタスク:例えば、回文作成や特定の規則に基づいた文章生成など

このような問題に対応するためには、大きく分けて以下の3つの手法が存在します:

  • Fine-tuning(追加学習)
  • RAG(Retrieval-Augmented Generation:検索拡張生成)
  • Prompt-tuning(プロンプト調整)

それぞれの手法には特徴があります。以下に詳しく説明します。

Fine-tuningは柔軟に回答できますが、学習データの準備、GPUを使ったコンピューティングコスト、専門家によるモデルのチューニングと高額な費用が発生します。さらに知識を更新するたびに継続的にモデルの更新が必要なので、費用対効果が見合わないユースケースが多いと言われています。また、コンピューティングコストの課題に加えて回答可能な知識の更新頻度が低くなる傾向があります。

RAGはLLMの学習を伴わないため、クラウドやWebアプリケーションの知識で構築が可能です。DBに登録されているデータを更新すると手作業を伴わずに即座に知識の更新を行うことができるため、運用コストは比較的低い傾向があります。RAGはDBから関連した情報を抽出するため、LLMの入力コンテキスト上限に影響を受けることは少なく、基本的には上限なくRAGに回答させるデータを増やすことができます。

Prompt-tuningはLLMの学習やクラウドの知識も必要ありません。一方で、入力コンテキストの上限や、ハルシネーションを抑制するため、プロンプトを人間が管理する必要があります。人間が管理するため、知識の更新は比較的遅くなります。

以上の傾向より、LLMを社内導入する初期段階はPrompt-tuningを用いると良いです。より大規模な知識を扱う場合にRAGシステムを構築すると良いと考えられています。Fine-tuningの導入を考えるユースケースは、高度な回答が求められる場合に限られており、多くの企業でRAGを用いて問い合わせの自動化を検証しています。

これまでの内容を以下の表にまとめました。次は特定のスキルの習得やパフォーマンスについて考えます。

特定のスキルの習得やパフォーマンスの改善

単純な要約や翻訳と比べて、RAGシステムに特化した要約や、マイノリティーな言語間の翻訳、APIを呼び出すFunction Callingなどのスキルは、OSSモデルで性能が低い傾向があります。

以下の図は、様々なLLMとそのRAGで危険物取扱者試験(甲種試験)の問題を解いたときの回答精度を示しています。OpenAI o1やClaude sonnetなどの有料のLLMではOriginal(LLM単体)よりもRAGの方が精度が高く、一方でllamaやswallowなどのOSSのLLMではOriginalよりもRAGの方が精度が低い傾向があります。

フロンティアモデルと言われるLLMは様々なスキルに対応する学習が行われている一方で、比較的小規模のOSSモデルでは特定のスキルに対して改善の余地があるとわかります。

LLMのタスクの性能を改善するために一般的にFine-tuningが使われています。一方でPrompt-tuningにも、プロンプト内に学習データを入れて一時的に回答精度をあげるIn-Context Learningという手法が存在します。

このあとのセクションからLLMが苦手とするタスクを説明し、In-Context Learningを使ったPrompt-tuningの検証結果を紹介します。

LLMが苦手な回文作成

生成AI(LLM)は回文が苦手という話 という記事をみて、LLMは回文の作成が苦手だと知りました。

GPT-4oに回文の定義を聞くと、「回文(かいぶん)は、文字列を前から読んでも後ろから読んでも同じになる言葉や文を指します。文字の順序が逆になっても意味が変わらないことが特徴です。」と完璧に回答していました。

一方で一緒に生成された例題をみると

  • たけやぶやけた(竹藪焼けた)→正しい
  • しんぶんし(新聞紙)→正しい
  • 「たちついた(!?)」→間違い

さっそく間違った回文を提示しています。

 

このような場合にはFine-tuningで回答の改善を行うことが一般的ですが、今回は学習を行わずにパフォーマンスを向上できるIn-Context LearningというPrompt-tuningに着目しました。

In-Context LearningとFew-Shot PromptingとMany-shot In-Context Learningについて

In-Context Learning(ICL)はLLMへの指示と同じタスクのデータをサンプルとしてプロンプトに載せて回答精度を上げる手法です。ICLのメカニズムについては諸説あり、2024年言語処理学会年次大会の発表In-Context Learning において LLM はフォーマットを学べるか では

  • プロンプト中に与えられたデモ(サンプル)を元に LLM が実際に新たなタスクを解く能力を獲得している
  • LLM が事前学習の段階で暗黙のうちにタスクを解く能力を獲得しており,ICLのデモは単に解くべきタスクの識別のために用いられている

の2つの説が紹介され、後者の可能性が高いという結論となっています。

このメカニズムを考慮するとPrompt-tuningとしてよく使われるFew-Shot PromptingもICLとほぼ同じ手法と見なすことができます。この記事ではICLで名称を統一したいと思います。

このICLについて、いくつサンプルを増やすと回答精度が向上するのか?という疑問がありますが、Many-Shot In-Context Learning という研究が今年発表されており、様々なタスクにおいてサンプルの数が多ければ多いほど性能改善が行われると報告されていました。

【論文瞬読】大規模言語モデルの可能性を広げるMany-Shot In-Context Learning のまとめがわかりやすいです。

 

論文では単純に人が作成したサンプルだけでなく、2つの合成手法も紹介されていました。Reinforced ICLという合成した解答を利用する手法や、Unsupervised ICLという合成された質問でサンプル数を増やす手法も有効だと報告されています。今回は単純に人が作成したサンプルを集めて検証しました。

プロンプトにおけるICLのサンプルは以下のような形式で書かれることが多いです。

回文を1個作成してください。-> しんぶんし
回文を1個作成してください。-> たけやぶやけた
回文を1個作成してください。-> みなみ
回文を1個作成してください。-> 

今回は、検証の準備の関係で少し書き方を省略して実装しています。サンプル数が0、 1、 3、 10のプロンプトを載せたので詳しくは以下のサンプルをご覧ください。ここで載せる回文は、面白い回文62選!子どもと楽しむポイント から引用しています。 

サンプル無しで回文を作成するプロンプト:


回文を100個作成してください。 ->

## Steps

- `## Task definition`に書かれた回文の定義に従って作成してください。
- 作成した回文が定義に基づいているか確認して正しいと判断した文を出力してください。
- csvに貼り付けやすいように`,`区切りの1行で全ての出力を表示してください。

## Task definition

回文(かいぶん)は、文字列を前から読んでも後ろから読んでも同じになる言葉や文を指します。文字の順序が逆になっても意味が変わらないことが特徴です。

サンプル1つを参考に回文を作成するプロンプト:


回文を1個作成してください。-> しんぶんし
回文を100個作成してください。 ->

## Steps

- 直前に記載した質問と解答例を参考に回答を生成してください。
- `## Task definition`に書かれた回文の定義に従って作成してください。
- 作成した回文が定義に基づいているか確認して正しいと判断した文を出力してください。
- csvに貼り付けやすいように`,`区切りの1行で全ての出力を表示してください。

## Task definition

回文(かいぶん)は、文字列を前から読んでも後ろから読んでも同じになる言葉や文を指します。文字の順序が逆になっても意味が変わらないことが特徴です。

サンプル3個を参考に回文を作成するプロンプト:


回文を1個作成してください。-> しんぶんし
回文を3個作成してください。-> しんぶんし,たけやぶやけた,みなみ
回文を100個作成してください。 ->

## Steps

- 直前に記載した質問と解答例を参考に回答を生成してください。
- `## Task definition`に書かれた回文の定義に従って作成してください。
- 作成した回文が定義に基づいているか確認して正しいと判断した文を出力してください。
- csvに貼り付けやすいように`,`区切りの1行で全ての出力を表示してください。

## Task definition

回文(かいぶん)は、文字列を前から読んでも後ろから読んでも同じになる言葉や文を指します。文字の順序が逆になっても意味が変わらないことが特徴です。

サンプル10個を参考に回文を作成するプロンプト:


回文を1個作成してください。-> しんぶんし
回文を3個作成してください。-> しんぶんし,たけやぶやけた,みなみ
回文を10個作成してください。-> しんぶんし,たけやぶやけた,みなみ,やおや,いらい,きせき,きつつき,いろしろい,うたうたう,よくいくよ
回文を100個作成してください。 ->

## Steps

- 直前に記載した質問と解答例を参考に回答を生成してください。
- `## Task definition`に書かれた回文の定義に従って作成してください。
- 作成した回文が定義に基づいているか確認して正しいと判断した文を出力してください。
- csvに貼り付けやすいように`,`区切りの1行で全ての出力を表示してください。

## Task definition

回文(かいぶん)は、文字列を前から読んでも後ろから読んでも同じになる言葉や文を指します。文字の順序が逆になっても意味が変わらないことが特徴です。

*サンプル30、100個記載したプロンプトは省略しています。

 

検証は以下の内容で検証を行いました。

  • 使用するLLM:ChatGPT GPT-4o(2024年11月28日のモデル)
  • データの作成方針:回文作成の指示を出し、プロンプトに参考となるサンプルを追加
  • 追加するサンプル数:0(サンプルなし), 1, 3, 10, 30, 100
  • 生成するデータ数:それぞれのサンプル数の検証につき100個を生成
  • 評価方法:以下のコードに基づきそれぞれの回文候補が回文か判定してN/100の正解率[%]を算出

評価に使うPythonコード:


import pandas as pd

# CSVファイルを読み込む
input_file = "kaibun_list.csv"

# CSVを読み込む
df = pd.read_csv(input_file)


# 回文判定関数
def is_palindrome(s):
    s = "".join(filter(str.isalnum, str(s))).lower()
    return s == s[::-1]


# 回文判定対象のカラムを取得(answer_1からanswer_100)
answer_columns = [col for col in df.columns if col.startswith("answer_")]

# 各列の文字列を判定
for index, row in df.iterrows():
    num_correct = sum(
        is_palindrome(row[col]) for col in answer_columns if not pd.isna(row[col])
    )
    df.at[index, "num_correct"] = int(num_correct)

# 結果をCSVとして保存
df.to_csv(input_file, index=False)

検証結果と考察

以下のように作成したプロンプトをChatGPTに入力すると、想定通り回文のリストが生成されました。

それぞれのサンプル数での回答結果は以下になります。

参考にするサンプル数が0個の場合は57%、1個の場合は61%、3個の場合は58%、10個の場合は78%、30個の場合は71%、100個の場合は99%になりました。この精度となった理由は2つ考えられます。1つ目は「100個作成してください」と指示してもサンプル数が足りない場合が多く、多くの場合で5%以上のロスが生じていました。2つ目は、サンプル数が多い場合には、サンプルをそのまま出力する傾向になりました。サンプル数100の場合には残念ながらサンプルと全く同じ回答をしました。正解数が99%なのはサンプルに負例が混じっていたためです。

また、生成された回文を眺めてみると、「ももたろううらとも,はなすことこのさなは,みずのみのみず,にわにはにわにわとりがいる」という出力があり、童話に出てくる単語や、ことわざが出てきている点は興味深かったです。

また、サンプル数が0の場合は、「けけけ,めめめ,ととのとと,あさあさあ,ううううう,よよよよ,ししししし,たたたた,ににににに,」など全部同じ文字で構成される単語が多く見られました。全て同じ文字の単語は、定義の「文字列を前から読んでも後ろから読んでも同じになる言葉や文」としては正しいですが、「文字の順序が逆になっても意味が変わらないことが特徴」は満たしていないと考えられます。与えたサンプル数が1個以上の場合にはこのような例が生じなかったので、In-Context Learningの効果は一定数あったと考えられます。

また別の観点で、サンプル数が10以上の場合にサンプルをそのまま出力する傾向がありました。特にサンプル数が100の場合はそのサンプルをそのまま出力しているので、「サンプルと同じ単語を出力した場合はノーカウント」と定義をより厳しく拡張した場合は精度0%とみなすことができます。

さらに「文字の順序が逆になっても意味が変わらないことが特徴」という定義はほぼ守られていない考えられます。そう考えると「LLMは単語や文章の意味を理解しておらず、確率的に類似度の高い単語を予測しているだけに過ぎない」という話は改めてしっくりときました。

以上より、実践的な内容として「生成AI(LLM)は回文が苦手」という説をより多くのサンプルで、より定量的に分析しました。そして回答精度を上げるためにMany-Shot In-Context LearningというPrompt-tuningの手法を調査して適用しました。結果として精度は上がりませんでしたが、サンプルの記載方法を変更したり、カンニングを防ぐためにルールを追加するなど改善案に結びついたので、次のPDCAを回すことができる状態となりました。

まとめ

LLMの出力を改善する手法を紹介し、実践的な内容としてLLMを改善するPDCAを回す様子を紹介しました。

TASUKIでは、生成AIの活用や、RAGの性能改善の支援、データ構造化ツールを提供しています。LLMを含む生成AI技術は日々進化しており、ベストプラクティスが定まっていません。現状の最前線を一緒に検証したい、生成AIの可能性を確認したいという方がいましたらぜひTASUKIにご相談ください。

以上、LLMの苦手タスクにおけるMany-Shot In-Context Learningの検証を紹介しました。

それでは、ソフトバンク アドベントカレンダー 2024 4日目にバトンを渡します。

 

データ構造化を代行し、検索拡張生成(RAG)の検索精度の向上をご支援。さらに構造化代行により リソース不足を解決し、企業のLLM活用を促進。

おすすめの記事

条件に該当するページがございません