
RAGとの格闘
生成AIを活用したシステムを作ろうとRAGを学んでいます。
以前の一から作るよりは楽そうですが、結構てこずっています。
はじめに、少し用語を説明しておきましょう。
私たちが普段使っている「生成AI」の多くは、「LLM (Large Language Model)」というデータモデルを基に動いています。
私たちがチャットで入力した文章は、その「LLM」で検索され、最適な答えが返ってきます。
一方で、「RAG (Retrieval Augmented Generation) 」という技術があります。
これは、私たちがチャットで入力する文章に、情報を追加する技術です。
「LLM」に文章を入力する前に「RAG」のデータを検索し、よりよい結果を得られるように、追加の情報を取得します。
この「RAG」という技術を利用すると、「LLM」を直接加工できなくても、生成AIの動きをカスタマイズできるようになります。
今回、私がやろうとしているのは、FAISSという種類のベクトルデータベースを用いた「RAG」の構築です。
また難しい用語が出てきていますが、とりあえず置いておいて結構です。
というか、これ以上深入りすると沼ります。
さて、今回のテーマである「RAG」ですが、作ること自体はそんなに難しくないです。
以前紹介したDiFyにも「RAG」を作る機能がついていますし、ChatGPT(有料版)などであればアップロード機能で簡単に利用できます。
私がやろうとしているのは、python というプログラミング言語を使って作るものですが、これもさして難しいものではありません。
というか、私は python は得意でないので、ChatGPT に書かせています。
それでパパッと書けるぐらいには簡単です。
が。
それだけで組み立てられるなら、もっと簡単に広まっているわけで。
実際に学習データを用意し「RAG」を作ってみたものの、検索が中々思うようにいかない。
検索自体はできるものの、期待していたような回答が得られない。
色々と弄れるパラメータがあるのですが、アレやコレやと弄ってもうまくいかない。
参考までに、調整した内容を列挙しておきます。(専門用語の説明は割愛します)
- tempature を 0.2, 0.3, 0.5, 0.75 で調整
- top_p を 0.3, 0.7, 0.9, 0.95 で調整
- サンプリングの k を 3, 5, 10, 30, 50 で調整
- 「RAG」を構築する「LLM」を「text-embedding-3-small」に変更
- 「RAG」構築時のチャンクサイズを 300, 500, 800 で調整
- 「RAG」構築時のオーバーレイを 50, 100 で調整
- 検索時の「LLM」を「gpt-4-1106-preview」に変更
- 検索時の再帰検索のモードを refine に変更
- 再帰検索時のプロンプトをアレコレと調整
うーむ……。
これはやはり……。
『ChatGPTなどでは、このような点に何か工夫がされているのですか?』
ChatGPT大先生に、手の内を明かしてくれないか聞いてみました。
……割と正直に答えてくれました。
やはり、検索を『恣意的』に調整しているようです。
おかしいと思ったんですよ。
何も考えずに python のライブラリを使ったところで、ChatGPT のようなランダム性は得られない。
これはもう、入力プロンプトを加工したり、再検索してるとしか思えない。
そうでなければ説明がつかないのです。
ChatGPT が提案してくれた python のコードでは、検索結果の候補となるチャンク(サンプリングの k で指定される個数のチャンク)は、ほぼ固定になります。
ですが、そうなると、大量に学習させたデータの全体を使った回答が作成できません。
膨大な量のチャンクの中から、たった k 個しか参照できない。
そんなことで、ChatGPT のような高度な検索ができるわけがない。
……やはり、ただ API を使うだけではダメなようです。
もっと「RAG」の特性をつかみ、調整しなければ使い物にならないようです。
というわけで、休日を1日つぶして、そこまでの結論にたどり着きました。
なんというか、やっぱり知らないことを学ぶのは楽しいですね。
うまくいかない間はじれったいですが、成功を考えるとわくわくします。
それに、このシステムが成功したら、事業への投入も考えています。
そうそう簡単に諦めるわけにはいきません。
もっと完成度を上げなければ……。
これは、腕が鳴りますね。
それでは、ようやく「RAG」の入口に立った、山本慎一郎でした。