精度評価

中村龍矢氏:では具体的に、精度評価と改善にいければと思います。

まず精度評価というと、パッとイメージしやすいのが、「どういうスコアをやるか」というところで。これは最近はツールもノウハウもいろいろ出ているので、あまり悩むことはないんじゃないかなと思っています。LLMが吐いた答えが正しいかどうかを判定する方法ですね。

一番シンプルなのは、完全一致というかたちです。人間はこれを出してくれる。LLMはこれを出す。それが完全に一致するかどうかというやつですが、これをやるとあまりにも厳しすぎて。

例えば、数字や金額を出力する時に、カンマがあるかないかみたいなフォーマットの違いすらもバツになってしまったりするので、このあたりは少し厳しすぎるかなと思います。

その次に考えられるのが部分一致みたいなもので、これは古典的な機械学習や自然言語処理の領域として、ROUGEとかいろいろな便利な指標があるので、そのあたりが使えるんじゃないかなと思います。ほかにも、もっと理論的な方法としてEmbedding、その出力の意味をベクトルで表して、それが近いかどうかを判定したり。

あとは、採点自体をLLMにやらせる方法もあります。LLMに採点させる方法に関しては一番柔軟なのですが、それ自体に改善が必要になるので、個人的にはこのうちの真ん中2つ(単語の部分一致、Embedding)ぐらいでやっていくのがベーシックかなと思います。

このあたりはいろいろな資料が既存で出てたりするので、今日は割愛できればと思います。

LLMのユースケースにおいてありがちな原因分析

(スライドを示して)ここは簡単なのですが、その次が問題です。採点できました。どれぐらい合っているか、まず分かってきましたというところの次のステップとして、うまくいかないところをどういうふうに改善するのかという時に、その原因を突き止めるのが非常に大事なのかなと思っています。

原因を突き止めるという時に、LLM特有のありがちなところを今日は紹介できればと思います。

いろいろなLLMの使い方があると思いますが、すごく一般的なちょっと抽象的な使い方の流れとして、テキストでもPDFでも「Word」でもなんでもいいのですが、なんらかの食わせたい文章のファイルがあります。

それを検索などで取ってきて、プロンプトにしてLLMに食わせて何かを出力させます。この出力において、先ほど期待したい正解があって、その正誤判定をするケースを考えています。

(スライドを示して)この時に注意がいきがちなのが、④と書いてあるLLMの処理のところで。これが一番花形っぽく見えるので、そこに原因を求めたり、そこばかり改善をやりがちかなと思います。

しかし、我々の観測範囲だと意外と(原因が)そこじゃないこともけっこう多いかなと思っていて、それを①②③として今日紹介できればと思います。特に、プロンプトばっかりやりがちというか、プロンプトばっかりいじりがちだけど、プロンプト以外が問題だったりするかなと思っています。

考えられる原因1 前処理での欠損・毀損

(スライドを示して)1個目が前処理のところで、基本的に今のLLMはテキストしか食えないので、完全にテキストじゃないものを入れる時は、テキストに変換したりして入れるわけですよね。

「LangChain」とかの既存の便利ツールにも、抜き出すツールがいっぱいあるので、使っている方がけっこう多いんじゃないかなと思いますが、あれをよく分析すると、意図しない抜き出し方をしていることもけっこうあるかなと思います。

すごくシンプルな例だと、文字化けしているとか、英単語が謎に分割されているとか、よく見ると「あれ?」となることがけっこうあったりするかなと思います。

(スライドを示して)ちょっと高度なレベルで例に記載しているものとしては、論文で縦割りの文章になった時に、人間、論文を読める人は「こういう順番で読む」とわかるのですが、人間が読むとおりにテキストが抽出されていないこともけっこうあったりします。

順番が食い違うというところの狭間で意図しない答えが作られている可能性があるので、①番の前処理のところで勝負が決まっている可能性があるので書いています。

考えられる原因2 検索での欠損

2点目が検索での欠損というところで、基本的にコンテキストサイズに限界があるので、なんらかの……。呼び方はなんでもいいですが、チャンクに分割して、そこから検索して取ってくることがけっこう多いんじゃないかなと思います。

この時に、正しい答えを作る上で必要な情報が入っているチャンクと、それ以外に分かれるわけですね。その検索の時に、必要なチャンクが選ばれていない場合は、プロンプトをどうがんばっても答えは出ないので、この検索部分でしっかり答えが入っているものが取られているかをしっかりチェックすることが大事かなと思います。

考えられる原因3 結果をまとめる際の欠損・毀損

3番目が、結果をまとめる際の欠損・毀損です。先ほどの話で、文章が大きいのでチャンクに分割した場合、基本的にLangChainなどいろいろな既存のツールでも、その結果をまとめる処理はやってくれる、もしくは作ってくれます。

1個1個のチャンクに対して答えが得られました。ということを全部のチャンクに対してやって、最後どうまとめるかというのがあったりします。

この時のまとめ方の戦略がいっぱいあって、map_reduceとかrefineとか、いろいろなものが作られているわけですが、合体する過程でグチャってなったり消えたりしていることがあります。1個1個のチャンクでしっかり取れているんだったらLLMのプロンプトは悪くなくて、まとめ部分が悪いので、まとめる部分を改善しようとなります。

これを見極めるために、LangChainとかだと、最後のまとめられた結果しか返ってこないこともあるので、その途中の中間結果をしっかり出力して確認することが大事かなと思います。

(スライドを示して)というところで3つ挙げました。この3つがどれも違ったら初めてLLMの本丸のところが怪しいかということを見るのがいいんじゃないかなと思っています。

チューニングにおける一般的な心掛け

このあたりのチューニングは、LLMに限らず、アルゴリズム改善など一般的な話がかなりあるのかなと思っています。「いろいろ変えると訳がわからないから1個ずつ変更しよう」とか「問題を分解しましょう」とか。あとは、解きたい問題、業務で本番で使う本丸のやつは難しかったりするので、ちょっと恣意的で簡単な例を作って、それでそれどおり動くかをチェックして、だんだん難しくしていくとか。このあたりの一般的なところに取り組めるといいんじゃないかなと思います。

というところで、精度改善をがんばっていければと思うので、みなさん、よろしくお願いします。以上です。