Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

GPTが出した回答の確からしさを見えるようにしてみる

皆さんこんにちは。データサイエンティストチームYAMALEXSsk1029Takashiです。
YAMALEXは Acroquest 社内で発足した、会社の未来の技術を創る、機械学習がメインテーマのデータサイエンスチームです。

この記事はGPTでチャットボットを作ってみるシリーズ第3弾です。
第1弾と第2弾もぜひご覧ください。
acro-engineer.hatenablog.com
acro-engineer.hatenablog.com

第1弾では、GPTになるべく正確な回答をさせるために、回答の情報を持つ文書を検索し、それをもとに回答を生成するという内容を試しました。
文書をもとに回答を生成することで比較的正確な回答を取得することができました。

ただし、この回答も必ずしも正確な回答とは限らないので、どれくらい信頼していいのかを自動で判定する仕組みが欲しくなります。
今回は第1弾のシステムをもとに、システムが出した回答の信頼性を可視化する仕組みをGPT-3を使って検証してみます。

概要

第1弾のシステムでは、聞きたい内容に関連する文書をシステムが持っていなかった場合、もしくは正しく検索できなかった場合に回答の信頼性が下がるという課題があります。
例えば、システムが持っている文書がコロナウイルス関連の文書しかないのに、インフルエンザウイルスに関する質問が来た場合を考えてみます。

第1弾のシステムをもとにコロナウイルスのFAQページの文書を検索対象としたときにインフルエンザの質問をするとどうなるか試してみましょう。

質問
インフルエンザが感染する可能性がある期間は?
元文章
  一般的に、肺炎などを起こすウイルス感染症の場合は、症状が最も強く現れる時期に、他者へウイルスを感染させる可能性も最も高くなると考えられています。 
しかし、新型コロナウイルスでは、発症の2日前から発症後7~10日間程度他の人に感染させる可能性があるとされています。
特に、発症の直前・直後でウイルス排出量が高くなるため、無症状病原体保有者(症状はないが検査が陽性だった者)からも、感染する可能性があります。 
SARS-CoV-2 オミクロン株感染による新型コロナウイルス感染症の積極的疫学調査によると、オミクロン株症例の呼吸器検体における感染性ウイルス検出率は、
有症状者の場合、発症後5日目からウイルス分離効率が低下し、発症後10日目から14日目までに採取された検体におけるウイルス分離効率は4.1%で、
発症後15日目以降に採取された検体からはウイルスが分離されず、無症状者の場合、診断後8日目以降に採取された検体からはウイルスが分離されなかったと報告されています。
 新型コロナウイルスに感染した方が、他の人に感染させる事例は、全体の2割以下と考えられますが、マスク無しの会話や3密(密閉・密集・密接)が感染拡大リスクとなっています。
 体調が悪いときは不要・不急の外出を控えることや、人と接するときにはマスクを着用すること、普段会わない人とは会わないことなど、新型コロナウイルスに感染していた場合に多くの人に感染させることのないように行動することが大切です。 
※ マスクの着用により、感染者と接する人のウイルス吸入量が減少することがわかっています。  
回答

A: インフルエンザは、ウイルスが感染した後から約1週間後になるまで、感染を他の人に広げる可能性が十分にあります。発症から病気の全期間、主な症状が出現する前に、いわゆる「無症状病原体保有者」からも感染が広がる可能性があります。

上記を見ると、根拠にした文章の中にない回答を生成していることがわかります。
回答自体もインフルエンザについて正確な記述ではありません。

上記のように、根拠にした文章を正しく取得できない場合、回答の精度は当然下がります。
これを確かめるために根拠を元文章として見えるようにしているのですが、毎回元文章を読んで確認するのは大変です。
なので、この記事では、出力した回答がどれくらい信頼できるものなのかを後付けで見えるようにしてみます。

コンセプト

回答の確からしさを確かめる方法は、根拠となった文書の中に回答として出力した文章と同じ意味が含まれているかということで確認します。

例えば、以下は正しい回答を生成できている例です。

質問
コロナウイルスが感染する可能性がある期間は?
元文章
  一般的に、肺炎などを起こすウイルス感染症の場合は、症状が最も強く現れる時期に、他者へウイルスを感染させる可能性も最も高くなると考えられています。 
しかし、新型コロナウイルスでは、発症の2日前から発症後7~10日間程度他の人に感染させる可能性があるとされています。
特に、発症の直前・直後でウイルス排出量が高くなるため、無症状病原体保有者(症状はないが検査が陽性だった者)からも、感染する可能性があります。 
SARS-CoV-2 オミクロン株感染による新型コロナウイルス感染症の積極的疫学調査によると、オミクロン株症例の呼吸器検体における感染性ウイルス検出率は、
有症状者の場合、発症後5日目からウイルス分離効率が低下し、発症後10日目から14日目までに採取された検体におけるウイルス分離効率は4.1%で、
発症後15日目以降に採取された検体からはウイルスが分離されず、無症状者の場合、診断後8日目以降に採取された検体からはウイルスが分離されなかったと報告されています。
 新型コロナウイルスに感染した方が、他の人に感染させる事例は、全体の2割以下と考えられますが、マスク無しの会話や3密(密閉・密集・密接)が感染拡大リスクとなっています。
 体調が悪いときは不要・不急の外出を控えることや、人と接するときにはマスクを着用すること、普段会わない人とは会わないことなど、新型コロナウイルスに感染していた場合に多くの人に感染させることのないように行動することが大切です。 
※ マスクの着用により、感染者と接する人のウイルス吸入量が減少することがわかっています。  
回答

A: 新型コロナウイルスに感染しているとした場合、発症の2日前から発症後7~10日間の間に他の人へ感染させる可能性があるとされています。また、無症状病原体保有者(症状はないが検査が陽性だった者)からも、感染する可能性があります。

上記の回答を見ると、回答の内容は根拠となる文書に記載のある内容をもとに回答していることが分かります。
間違った回答の場合は、ここが根拠となる文書にはない記載になることが多いです。

つまり、根拠となる文書を前提にしたときに、回答の文章が成り立つのかどうかを見ればある程度回答の信頼性を見れるかを試します。
根拠から回答が意味的に成立すれば、根拠をうまく参照して回答しているので信頼できるが、成立しない場合は信頼性が下がる。。といったことが分かりそうです。

ただし、毎回根拠となる文書を人が参照して確認するのは手間なので、AIで判断してほしいところです。
そのためにこの記事では、GPT-3のFine-tuningを利用して、NLIという2つの文章の関係性を推論するタスクを学習したモデルを作成し、回答の正しさを判断できるか検証します。

NLI(Natural Language Inference)とは

まず、今回GPT-3をFine-tuningするNLIタスクについて軽く説明します。

NLIタスクは、前提文と仮説文が与えられたときに、仮説文が前提文に対して、以下のいずれかの関係であることを推論するタスクです。

  1. 含意(entailment):前提から仮説が成り立つ
  2. 矛盾(contradiction):前提に対して仮説が矛盾している
  3. 中立(neutral):どちらともいえない

また、NLIを日本語で学習するためのJNLIというデータセットが公開されています。
github.com

実際の中身のデータとしては以下のようなJSONが複数与えられています。

{"sentence_pair_id": "0", "yjcaptions_id": "10125-11130-11134", "sentence1": "時計がついている場所にパブリックマーケットセンターとかかれた看板が設置されています。", "sentence2": "屋根の上に看板があり時計もついています。", "label": "neutral"}

このように二つの文章とその関係がラベルとして与えられています。

ただ、今回はこの中で含意(entailment)かどうかを見分けられれば良いので、含意かそれ以外の2値分類にしてモデルを学習してみます。

GPT-3をFine-tuningする

OpenAIのAPIでは、学習データのファイルを用意すれば、CLIREST APIからFine-tuningを実行できます。

学習データを用意する

用意する学習データは以下のようなフォーマットになります。
文章を2つ入れて、entailment(含意)にyesかnoで回答するモデルになります。

{"prompt": "sentence1=机上に湯気の立ち上るカップが置いてあります。\nsentence2=机上に氷の入ったカップが置いてあります。\n\nenteilment=", "completion": " no"}
{"prompt": "sentence1=草原にある水場にに10頭ものシマウマがいる。\nsentence2=草原の水場に多くのシマウマ達がいます。\n\nenteilment=", "completion": " yes"}
(省略)

GPT-3を使ってクラス分類を学習するときのデータセットは以下のルールを守る必要があります。

  1. promptに入力文、completionに予測するラベルを入れる
  2. 入力の文章ペアは改行を使って区切る
  3. promptの最後には終了をモデルに知らせるフォーマットが必要。今回は"\n\nentailment="を入れている。
  4. promptとcompletionは合わせて2048token以内にする必要がある。なので、日本語の場合は2048文字以内が基準。
  5. completionは必ず1tokenになるようにする。

また、クラス分類の場合はデータの数は100以上あることが推奨されます。
なので、JNLIの学習データを加工して、上記のフォーマットが100行あるdataset.jsonlというファイルを作成しました。

学習を実行する

学習は以下のコマンドで実行できます。
(下記コマンドにはopenaiコマンドのインストールが必要なので第2弾の記事を参照ください。)

openai api fine_tunes.create -t "dataset.jsonl"  -m "davinci" --n_epochs 10
  • t引数にはデータセットのファイル名を与えて、-mにはFine-tuningするベースのモデル名を与えます。

ベースのモデルに指定できるのは、davinci,curie,babbage,adaのいずれかで、davinceが最も重くadaが最も軽量なモデルです。
また、必須ではないですが、--n_epochesでエポック数も指定できます。指定がない場合は4エポックがデフォルトになります。

学習が正常に実行されると以下のような出力が取得できます。

[2023-03-06 23:39:55] Fine-tune started
[2023-03-06 23:49:34] Completed epoch 1/10
[2023-03-06 23:57:21] Completed epoch 2/10
[2023-03-07 00:05:10] Completed epoch 3/10
[2023-03-07 00:12:56] Completed epoch 4/10
[2023-03-07 00:20:43] Completed epoch 5/10
[2023-03-07 00:28:30] Completed epoch 6/10
[2023-03-07 00:36:17] Completed epoch 7/10
[2023-03-07 00:44:04] Completed epoch 8/10
[2023-03-07 00:51:51] Completed epoch 9/10
[2023-03-07 00:59:38] Completed epoch 10/10
[2023-03-07 01:00:30] Uploaded model: davinci:ft-personal-2023-03-07-01-00-29
[2023-03-07 01:00:32] Uploaded result file: file-9kD7eXVLr8l1iV3v3xlIEsaz
[2023-03-07 01:00:32] Fine-tune succeeded

Job complete! Status: succeeded 🎉
Try out your fine-tuned model:

openai api completions.create -m davinci:ft-personal-2023-03-07-01-00-29 -p <YOUR_PROMPT>

ここまでで学習はできたので、次は作成したモデルを使用して推論してみます。

モデルを使って推論してみる

作成したモデルはPlaygroundから試してみることができます。
試しに、含意関係のある文章を試してみましょう。

期待通り含意関係があることを示すyesが取れています。

例えば、sentence2の「新型コロナウイルス」の部分を「インフルエンザ」にするとどうなるでしょうか?
期待としては、関係ない文章なのでnoが取れてほしいところです。

期待通り取れています。結構難しいタスクのはずなのですが、すごいですね。。。
また、学習に使ったデータは新型コロナウイルスとは全く関係ない文章ですが、2つの文章が意味が通るかどうかというタスクだけを学習できているようです。

回答の確からしさを可視化してみる

モデルも作れたので、本筋であるGPTが出した回答の確からしさを可視化してみましょう。

例題として、第1弾と同じくコロナウイルスのQAのページを元文書として持っているときに、以下2つの質問が来た時を試してみましょう。

  1. 新型コロナウイルスで感染の可能性がある期間は?」
  2. 「インフルエンザで感染の可能性がある期間は?」

質問としては似ていますが、後者の質問根拠となる文書をシステムは持っていないはずなので、回答の信頼性は下がるはずです。

それではまずは、第1弾のシステムを使って、根拠となる文書を検索して、回答を生成してみましょう。
すると以下の結果が得られます。

新型コロナウイルスで感染の可能性がある期間は?」

質問
コロナウイルスが感染する可能性がある期間は?
元文章
  一般的に、肺炎などを起こすウイルス感染症の場合は、症状が最も強く現れる時期に、他者へウイルスを感染させる可能性も最も高くなると考えられています。 
しかし、新型コロナウイルスでは、発症の2日前から発症後7~10日間程度他の人に感染させる可能性があるとされています。
特に、発症の直前・直後でウイルス排出量が高くなるため、無症状病原体保有者(症状はないが検査が陽性だった者)からも、感染する可能性があります。 
SARS-CoV-2 オミクロン株感染による新型コロナウイルス感染症の積極的疫学調査によると、オミクロン株症例の呼吸器検体における感染性ウイルス検出率は、
有症状者の場合、発症後5日目からウイルス分離効率が低下し、発症後10日目から14日目までに採取された検体におけるウイルス分離効率は4.1%で、
発症後15日目以降に採取された検体からはウイルスが分離されず、無症状者の場合、診断後8日目以降に採取された検体からはウイルスが分離されなかったと報告されています。
 新型コロナウイルスに感染した方が、他の人に感染させる事例は、全体の2割以下と考えられますが、マスク無しの会話や3密(密閉・密集・密接)が感染拡大リスクとなっています。
 体調が悪いときは不要・不急の外出を控えることや、人と接するときにはマスクを着用すること、普段会わない人とは会わないことなど、新型コロナウイルスに感染していた場合に多くの人に感染させることのないように行動することが大切です。 
※ マスクの着用により、感染者と接する人のウイルス吸入量が減少することがわかっています。  
回答

A: 新型コロナウイルスに感染した場合、発症の2日前から発症後7~10日間程度他の人に感染させる可能性があります。

「インフルエンザで感染の可能性がある期間は?」

質問
インフルエンザが感染する可能性がある期間は?
元文章
  一般的に、肺炎などを起こすウイルス感染症の場合は、症状が最も強く現れる時期に、他者へウイルスを感染させる可能性も最も高くなると考えられています。 
しかし、新型コロナウイルスでは、発症の2日前から発症後7~10日間程度他の人に感染させる可能性があるとされています。
特に、発症の直前・直後でウイルス排出量が高くなるため、無症状病原体保有者(症状はないが検査が陽性だった者)からも、感染する可能性があります。 
SARS-CoV-2 オミクロン株感染による新型コロナウイルス感染症の積極的疫学調査によると、オミクロン株症例の呼吸器検体における感染性ウイルス検出率は、
有症状者の場合、発症後5日目からウイルス分離効率が低下し、発症後10日目から14日目までに採取された検体におけるウイルス分離効率は4.1%で、
発症後15日目以降に採取された検体からはウイルスが分離されず、無症状者の場合、診断後8日目以降に採取された検体からはウイルスが分離されなかったと報告されています。
 新型コロナウイルスに感染した方が、他の人に感染させる事例は、全体の2割以下と考えられますが、マスク無しの会話や3密(密閉・密集・密接)が感染拡大リスクとなっています。
 体調が悪いときは不要・不急の外出を控えることや、人と接するときにはマスクを着用すること、普段会わない人とは会わないことなど、新型コロナウイルスに感染していた場合に多くの人に感染させることのないように行動することが大切です。 
※ マスクの着用により、感染者と接する人のウイルス吸入量が減少することがわかっています。  
回答

A: インフルエンザでは発症の1日前から現在までの約7~10日間の範囲で他の人に感染する可能性があります。特に、発症の直前の1日あたりの病原体量が最大となるため、他者に感染する危険性が最も高いと考えられます。また、症状がなくてもウイルスを排出し続ける無症状病原体保有者から感染する事例もあるため、警戒を怠ってはいけません。

この結果の元文章を文章ごとに分割して、各文ごとに回答との関係を予測して、含意関係がある文章は緑色、そうでない文章は赤色で表示するようにしてみましょう。
一つでも含意関係が成立している文章が元文章の中にあれば、回答は比較的信頼できます。

下記はすでにanswer変数に回答文、result変数に根拠となる文章が入っている状態から回答の信頼性を可視化するコードです。

print("回答")
print(answer)
print("")

print("根拠との関係")
# 元文章のresultを文章ごとに区切る
result_sentences = result.split("。")
for sentence in result_sentences:
    # 含意関係を予測する
    entailment_prompt = f"sentence1={sentence}\nsentence2={answer}\n\nentailment="
    entailment = openai.Completion.create(engine="davinci:ft-personal-2023-03-07-01-00-29", prompt=entailment_prompt, max_tokens=1)["choices"][0]["text"]
    
    # 含意関係がある文章は緑色で表示する
    if entailment==" yes":
        print(f"\033[32m{sentence}\033[0m")
    # そうでない文章は赤色で表示する
    else:
        print(f"\033[31m{sentence}\033[0m")

上記のコードを動かすと以下のような結果を得られます。

新型コロナウイルスで感染の可能性がある期間は?」という質問の回答の信頼性

参照されたと思われる箇所が緑色で表示されているので、この回答は比較的信頼できることがわかります。

対して、「インフルエンザで感染の可能性がある期間は?」という質問の結果はどうでしょうか?

上記のように、根拠となった文書はすべて回答と関連がないことを示す赤色で表示されています。
なので、この回答は根拠の文章が適切に取得できておらず、信頼性が薄い回答ということがわかります。

このように、回答と根拠となる文書の関係性を推測して、回答の確からしさを可視化してみました。

まとめ

今回は、含意関係を推測するモデルをGPT-3のFine-Tuningから学習して回答の確からしさを可視化してみました。
Fine-tuningを使うことで、出力の形を制御しつつ高い精度のモデルを作れて、回答の確からしさを出力することができました。

ただし、含意関係の推測は比較的難しいタスクとされているので、この結果も完全には信用できません。
キーワード検索など他のロジックと併用することで精度があげることが必要になるかと思います。

今後、このようにAIが出した回答の信頼性をどのように見分けるかというのは色々な技術が出てきそうなので、追っていきたいですね。
それではまた。

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。


www.wantedly.com