記事
· 2024年12月10日 9m read

詳説: RAG、ベクトル検索、および IRIS RAG アプリにおける IRIS での実装方法

コミュニティメンバーから、Python 2024 コンテストでの出品に対する非常に素晴らしいフィードバックが届きました。 ここで紹介させていただきます。

純粋な IRIS の 5 倍以上のサイズでコンテナーをビルドしているため、時間がかかっています

コンテナーの始動も時間はかかりますが、完了します

バックエンドは説明通りにアクセス可能です

プロダクションは稼動しています

フロントエンドは反応します

何を説明したいのかがよくわかりません

私以外のエキスパート向けに書かれた説明のようです

出品はこちら: https://openexchange.intersystems.com/package/IRIS-RAG-App

このようなフィードバックをいただけて、本当に感謝しています。プロジェクトに関する記事を書く素晴らしいきっかけとなりました。 このプロジェクトにはかなり包括的なドキュメントが含まれてはいますが、ベクトル埋め込み、RAG パイプライン、LLM テキスト生成のほか、Python や LLamaIndex などの人気の Python ライブラリに精通していることが前提です。

この記事は、IRIS での RAG ワークフローを実証するに当たって、上記の前提事項や、それらが IRIS で RAG ワークフローをこのプロジェクトにどのように適合するかについてを説明する試みです。AI をまったく使用せずに書かれています。

コンテナーが大きいのは、ベクトル埋め込みの作成に関わる Python パッケージに必要なライブラリ依存関係が非常に大きいためです。 より選択的にインポートすることで、サイズを大幅に縮小することが可能です。

コンテナーの初回ビルドには確かに時間がかかりますが、一度ビルドすれば起動時間は短くなります。 とはいえ、起動時間は確かに改善できるかもしれません。 起動にこれほどの時間がかかる主な理由は、アプリケーションのある個所が最後の起動から変更されていることを想定して entrypoint.sh が更新されているためです。これには、データベースの移行、CSS 構成、JavaScript 構成、Python バックエンドコードも含まれており、起動のたびにプロジェクト全体がリコンパイルされます。 これは、このプロジェクトを開発し始めやすくするためで、そうでない場合は、変更が適用されるたびに、フロントエンドとバックエンドのビルドを適切に実行するのが困難になってしまいます。 こうすることで、プロジェクトのコードを変更した場合はコンテナーを再起動し、場合によってはバックエンドのプロダクションを復旧すれば、アプリケーションのインターフェースと操作に変更が反映されます。

バックエンドのプロダクションは、HTTP リクエストを Django アプリケーションに渡すものであり、このパッケージの相互運用性にとって非常に重要であると確信しています。 ただし、私自身は IRIS プラットフォームの初心者であるため、プロダクションについてもっと学ぶ必要があります。

次に、ベクトル埋め込み、LLM、および RAG について、包括的に説明したいと思います。 この内最初に作られたのはベクトル埋め込みです。 まず、ベクトルについて説明します。 ほとんどのコンテキストにおいて、ベクトルは方向です。 空間のどこかを指す矢印です。 より正式には、ベクトルは「大きさだけでなく方向も持つ量」です。 これは、特定の方向へ移動し、空間内の特定の地点で爆発する花火によって例えることができます。 すべての花火が同じ中心点、つまり原点である [0,0,0] から発射され、その原点の周囲に雲となって飛び散るとします。 数学的には、3 つの座標系 [x,y,z] を使用して各花火の爆発の位置を表現することができ、これが花火の爆発の「ベクトル埋め込み」となります。 花火のビデオをたくさん撮影し、花火の爆発をすべてデータセットとして記録すると、花火の一種のベクトル埋め込みデータベース、つまりベクトルストアが作成されることになります。

花火に関する情報を使って何ができるでしょうか? 特定の花火を指して、花火全体の中から同じ点に最も近い位置で爆発した花火について尋ねると、空間の近くの点で爆発した他の花火を検索できます。 最もちかいものを見つけるだけですが、これを行うために数式があります。

花火ごとに、x、y、z の 3 つの数値のみを記録したことに注意してください。3 次元空間において、地上の花火発射台を [0,0,0] としています。

他の特定の花火に対して、距離と時間の両方の観点で最も近く爆発した花火も知りたい場合はどうでしょうか? それを知るには、花火の映像を確認して、各爆発の時間も記録しなければなりません。 これで、4 つの数値を持つ 4 次元ベクトルが取得されました。花火の爆発の 3 次元の位置に爆発の時間を加えたベクトルです。 ベクトル埋め込みにもう 1 つの次元を追加することで、花火の埋め込みがより記述的になりました。

これを機械学習に変換するとどうなるでしょうか? 手短に言えば、大量のテキストデータを処理することで、コンピューター科学者は、フレーズ、文章、段落、またはページなどのテキストを変換し、理論的な高次元空間の点を表現する非常に長い一連の数値に変換できる埋め込みモデルを作成することができました。

4 つの数字ではなく、300、700、さらには 1500 もの数字があります。 これらは、1 つのテキストが互いに「近い」か「遠い」かを 1500 通りまたは1500 次元の意味で表します。 テキストの意味を何らかの方法で表す数字を作成する手段があるというわけですから、多くの人にとって魅力的な概念と言えるでしょう。

数学を使用すると、これらの高次元テキストベクトル埋め込みのうち 2 つを比較して、同じモデルによって作成された場合に、それらが互いにどの程度類似しているか、つまり「近い」かを調べることができます。

このアプリで最初の行われているのが正にこれです。ユーザーはドキュメントを追加して名前を付け、埋め込みのタイプを選択する必要があります。 サーバーはそのドキュメントを受け取り、テキストのチャンクに分割してから、それぞれのチャンクをベクトル埋め込みに変換します。そのチャンクはそのドキュメントの専用のテーブルの行として保存されます。 各ドキュメントは、さまざまなテキスト埋め込みモデルによって作成されるベクトル埋め込みの可変長に対応できるように、それぞれの専用テーブルに保存されます。

ドキュメントがベクトル埋め込みとしてデータベースに保存されると、ユーザーはドキュメントに「尋ねる」クエリを入力できるようになります。 このクエリは 2 つの方法で使用されます。 1 つは、ドキュメントを検索するためです。 従来のテキスト検索は実行せずに、「ベクトル検索」を実行します。 アプリはクエリを受け取り、それをベクトル埋め込みに変換してから、クエリベクトル埋め込みに最も築地する埋め込みのあるドキュメントのセクションを検索します。 各ドキュメントセクションには 0 と 1 の間の類似性スコアが生成され、top_k_similarity と similarity_threshold に基づいて、ベクトルデータベースから複数のセクションが検索されます。 基本的に、取得するドキュメントのセクション数と取得の対象となるためにクエリとどの程度類似している必要があるかを指定することができます。

これが、検索拡張生成における取得です。 次は生成に移りましょう。

コンピューター科学者がテキストを意味的に重要な数値ベクトル埋め込みに変換する方法を見つけると、次に、テキストを生成するモデルの作成に移りました。 これは大きな成功を生み出し、現在では GPT-4、LLama3、Claude 3.5 などの大規模言語モデルとなっています。 これらの LLM はプロンプトまたはクエリを受け取り、補完または回答を提供します。これは LLM が提示されたテキストであるプロンプトから最も続行できる可能性があると考えるテキストです。

LLM は大量のテキストデータに対してトレーニングする必要があり、その回答または補完はそのトレーニングデータに制限されます。 トレーニングセットにないデータを含む可能性のある補完を LLM に提供させる場合、または補完を特定のナレッジセットに基づかせる場合は、1 つの方法として、プロンプトに追加のコンテキストデータを含めることができます。 基本的に、トレーニングされていない内容について LLM から回答を得たい場合、プロンプトに情報を提供する必要があるということです。

多くの人は、ChatGPT やローカルの LLama インストールが自分の個人文書に基づいて回答を提供してくれることを望む状況に陥っていました。 ドキュメント内でその情報を検索し、プロンプトに貼り付けて、質問を入力するだけの単純な操作であり、手作業で行っていました。 それ自体が検索拡張生成です。 RAG は、より正確または利便的な応答を得られるように、ユーザークエリに関連する情報を検索し、LLM にクエリを提供する操作を自動化したに過ぎません。

このアプリでは、ベクトル検索で取得したドキュメントセクションは、インターフェースでモデルとしてラベル付けされている選択された LLM にクエリとともに送信され、回答のコンテキストが提供されます。

このプロジェクト用に制作した動画の例では、シェイクスピアの 2 つの戯曲の全文を含むドキュメント「ハムレット」と「リア王」を使って、「この戯曲の悪役は誰ですか?」と尋ねています。 IRIS データベースには、ハムレットとリア王の 2 つのテーブルがすでに存在します。 各テーブルには、各戯曲のテキストをセクションに分割して作成されたベクトル埋め込みの行が入力されています。 これらの埋め込みは、一連の長い数値によって各ドキュメントセクションの多次元を表現しています。

サーバーは、「この戯曲の悪役は誰ですか」という質問を、リア王のベクトル埋め込みを生成した Text-to-Vector モデルを使用して数値ベクトルに変換し、リア王テーブル内でそれに最も類似するセクションを見つけます。 これらはおそらく悪役という語が言及されたセクションかもしれませんが、悪役が明示的に言及されていない場合でも、裏切り、裏切り、欺瞞などの他の悪役についても言及されている可能性があります。 こういったドキュメントのセクションは、クエリに追加され、合わせてプロンプトとして LLM に送信されます。LLM は提供されたドキュメントのセクションに基づいて質問に回答します。

これはドキュメントごとに個別に実行されるため、クエリの回答はクエリされているドキュメントに応じて異なります。 これにより頭字語が補完されます。ベクトル検索の力を使用して関連するコンテキスト情報を取得することで、LLM からの応答の生成を強化しているためです。

この記事をお読みいただきありがとうございました。このトピックについては今後の記事でも発展させたいと思います。 フィードバックをお待ちしています。

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください