Join the Webinar
Loading...
このウェビナーについて
RAG のセットアップを本番環境で利用できるように最適化するための効果的な戦略を探ります。RAG システムにおける情報検索の精度を高めるために、データの前処理、クエリ拡張と再定式化、適応的なチャンクサイズ調整、クロスエンコーダーによる再ランキング、Colbertv2 リランカー、アンサンブル検索などの実践的な手法を取り上げます。また、関連するツールや指標を用いた RAG パフォーマンスの評価についても掘り下げ、RAG パイプラインを最適化し評価する方法を包括的に理解できるようにします。
取り上げるトピック
- RAG システムにおける情報検索の精度を高める方法
- クエリ変換、Colbert リランカーなどを含む、本番環境向けに RAG システムを最適化する高度な手法
- 関連するツールや指標を用いた RAG パフォーマンスの評価
さて、本日は今日のセッション、「本番環境対応のRAGを構築して出荷するための高度なRAG最適化」をご紹介できることを嬉しく思います。そしてゲストスピーカーのRavinは、ええ、ええ、ええ、うーん、そうですね、データ分析とプロダクトに15年の経験を持つデータとプロダクトの愛好家です。彼は現在、オープンソースツールrag builder@ragbuilder. ioのメーカーであるcrux. aiの共同創業者です。
彼はこれまでのキャリアで、アナリスト、テクノロジーアーキテクト、データエンジニア、プロダクトマネージャーなど、さまざまな役割を担ってきました。また以前はCultFitとMeta、ええと、または、Facebookとしてご存じかもしれませんが、そこで部門横断型チームを率いていました。それでは、Arvinを歓迎します。ええ、では、お願いします。本当にその、ええ、プレゼンテーションを楽しみにしています。ご紹介ありがとうございます、Stefan。皆さん、こんにちは。ここに参加できて、RAG最適化についてお話しできることをとても楽しみにしています。
ええと、Stefan、ええ、ええ、ええ、何人くらい参加していますか?ちょっと、ええ、気になって。現在24名の参加者がいるようです。素晴らしい、素晴らしい、素晴らしい。思うに、ええ、木曜の朝、あるいは場所によっては夕方、あるいは深夜かもしれません。ええ、ですので、皆さんに参加いただき本当に感謝しています。
ええ、これは、私にとって非常に思い入れのあるトピックだと思っていて、ええ、皆さんと一緒に、いくつかの高度なRAG最適化、ええ、テクニックを見ていけることを、ええ、とても楽しみにしています。ええと、始める前に、ええと、ええと、Stefanがすでに私を紹介してくれたと思います。ええと、でも、ええ、すごく簡単に言うと、私はArvinで、Crux aiの共同創業者です。ええと、私たちはRAG最適化の領域で開発しています。ええ、私たちはオープンソースを開発しています。
ええ、それについても、ええ、トークの最後のほうで少しお話しできるのをとても楽しみにしています。ええ、もし皆さんの中でLinkedInでつながりたい方がいれば、画面にQRコードがありますので、ええ、どうぞお気軽にご連絡ください。ええ、喜んでお話しします。さて、今日は、ええ、高度なRAG最適化についてお話しします。ええ、ただ始める前に、ええ、皆さんの何人かからぜひ聞いてみたいのですが、RAGを構築しようとしたときに最大の課題は何でしたか?そして、多くの方が何らかのRAG、POCかプロトタイプのいずれかを構築しようとしたことがあると想定していますよね?そして、中にはRAGに基づいた本番グレードのアプリケーションを作ろうとした方もいるかもしれませんよね?なので、皆さんが直面してきた課題にはどんなものがあるのか、とても興味があります。データ規模、正確な検索、効率的なチャンク化。
はい。はい。RAGパイプラインのフロー。RAGパイプラインのフローをどう設計するか、ですよね?Fed承認済みのLLMを扱うこと。なるほど、興味深いですね。
推論のレイヤーを追加すること。わあ、それは、それはすごくクールですね。とても興味深い、正しいコンテキストデータを渡すこと。はい。はい。
多くの皆さんがすでにご存じのとおり、RAGには多くの可動部分がありますよね?ええと、この中にはRAGというトピックが初めてという方もおそらく何人かいると思います。なので、RAGとは何かについて簡単に30秒だけ入門的に説明します。RAGは非常に興味深い技術です。retrieval augmented generationの略です。これは、外部の知識ソースやデータソースを持ち込み、それらをLLMに接続できるようにする技術で、ユーザーのクエリが入ってきたときに、その学習データに頼る必要がないようにするものです。接続したデータソースからコンテキストを動的に取得し、関連するコンテキストを取得して、ええ、それをプロンプトに入れ、ユーザーの質問に答えることができますよね?たとえば、あなたが企業で、自社のWebサイト上に、製品やサービスに関する顧客からの質問に答えられるAIチャットボットを作りたいとします。
そうですよね?さて、既製のLLMをそのまま使っても、ええと、ご存じのとおり、あなたの独自データを認識しているわけではありませんよね?あなたの製品やサービスのことですよね?ですから、顧客からの問い合わせには答えられないわけです。そういうところでRAGが登場します。やることは、要するに、あなたが持っているこの、ええと、ナレッジベースを使うだけです。たとえば、PDFドキュメントの集まりかもしれませんし、あなたの製品やサービスに関するテキストドキュメントの集まりかもしれません。そして基本的には、こうしたエンジニアリングパターンがあります。つまり、その、ドキュメントをチャンクに分割し、何らかの埋め込みモデルを使って埋め込み、Vectorデータベースに保存します。そしてユーザーのクエリが入ってきたら、ええと、そのクエリに関連する適切なコンテキストの断片を、いわば動的に取得します。ええと、それをプロンプトに入れてLLMに送ります。そうするとLLMは、ユーザーが持っているその質問に魔法のように答えられるようになる、というわけです。ですから、非常に興味深い手法です。
これは多くの興味深いユースケースを可能にします。うーん、皆さんの多くはすでにragに取り組んでいるように見えます。ええと、皆さんが取り組んでいるユースケースのいくつかについて、ぜひもっと聞いてみたいですね。そうですよね?うーん、ただ、ええと、全体として、ええと、RAGには多くの可動部分がありますよね?ご覧のとおり、ええと、データ取り込みがあり、検索があり、ええと、再ランキングがあり、生成があり、その他もろもろがありますよね?そしてragの内部には、さまざまな障害ポイントがたくさんありますよね?つまり、ええと、どんなエンジニアリングシステムでも、ええと、コンポーネントや可動部分が多ければ多いほど、うまく動かない可能性が高くなり、障害ポイントも増えるわけです。そうですよね?ですから通常、Iraqでは、ええと、可動部分の数を考えると、さまざまな障害ポイントがたくさんあります。たとえば、まずユーザーの質問そのものから始めると、その質問が十分に明確でない場合がありますよね?あるいは曖昧な場合もありますよね?それが障害の原因になることがあります。あるいは、取り込んだデータが最適な形式で保存されていないかもしれません。皆さんの中には、非効果的、あるいは、ええと、非効率なチャンク化といったことを指摘した方もいたと思います。それはragの精度に影響しますよね?ええと、同様に、埋め込みモデルはragの精度に非常に重要な役割を果たしますよね?あなたが使っている埋め込みモデルには、ええと、十分な意味表現能力がないかもしれません。ええと、もしかすると非常に特定のドメインで作業していて、その結果として、あなたのagの性能が良くないのかもしれません。そうですよね?同様に、Vectorデータベースには、さまざまなインデックス技術がいくつもあります。
うーん、これは、ええと、Zell eventsか、皆さん全員がvisに詳しいと仮定しますが、うーん、そして、ご存じのとおり、それは多くの異なるインデックス技術をサポートしています。では、使用すべき適切なインデックス技術とは何でしょうか?あなたのユースケースに対して、そして、あなたが扱っているデータの種類に対して、ですよね?うーん、同様に検索側では、ええと、ご存じのとおり、低い適合率や低い再現率になってしまう可能性があります。うーん、そして最後に生成に近いところでは、ええと、たとえ適切なコンテキストを取得できたとしても、ご存じのとおり、望ましい形式で答えが得られないかもしれませんし、特異性が不適切かもしれませんし、ええと、誤った答えが返ってくるかもしれません。そうですよね?つまり全体として、rankにはさまざまな障害ポイントがたくさんあります。うーん、そして、ええと、素朴なragで到達できるのはそこまでです。そうですよね?私が素朴なragと言うとき、それは基本的に、ええと、ご存じのとおり、ragの非常に骨組みだけのバージョンのことです。そこでは、ええと、ご存じのとおり、ええと、保存しているすべてのデータの、このBering、ええと、vector membraneだけがあります。ええと、そしてそのデータの上で単純なセマンティック検索、単純な、ええと、意味的類似性検索を行っているだけです。そうですよね?これが、私たちがこの議論をしている理由の全体的な背景です。私たちは、あなたのragを本番対応にし、顧客の前に出せるほど信頼性が高く堅牢なものにするために、何ができるのかを見ていきたいのです。そうですよね?ですから、これは非常に幅広いテーマです。
これから1分くらいかけて、どんな異なるテクニックがあるのかを、ええと、大まかな概要として、つまり高いレベルでお話しします。ええと、これからやることは、それらのテクニックの一部を取り上げて、少し詳しく掘り下げ、いくつかのテクニックを詳しく見ていくことです。そして、ええと、特定のテクニックについて何か質問があれば、喜んで、ええと、別途対応します。時間を取って一緒にお話しします、いいですよね?ええと、全体として、これらのテクニックは、ええと、4つの異なるバケットに分かれます。まず、pre retrievalに分類されるテクニックがたくさんありますよね?ええと、retrievalを見る前、ええと、データ取り込みフェーズ全体で、ええと、RAGの精度とパフォーマンスを向上させるために、ええと、できることは何か?ええと、情報密度を向上させることができます。チャンク化を最適化することもできます。
データに対して、ええと、いろいろな変換を行うことができます。ええと、そうすることでretrievalを行うときに、retrievalがより効果的になります。次に、retrievalそのもの、ええと、retrievalの内部にも、さまざまなテクニックがあります。クエリルーティングや、recursive retrieval、fusion retrievalなどを行うことができます。ええと、皆さんの多くはGraph RAGについても聞いたことがあるかもしれませんよね?つまり、graph Act、pro、speca searchなどを組み合わせるわけです、そうですよね?ええと、そして最後にpost retrievalでは、ええと、retrieveした後に、取得結果の関連性や情報密度をさらに高めるために、ええと、適用できるテクニックがいくつかあります。ええと、それによって最良の成果、ええと、あるいはrankから最良の、ええと、回答の正確性を得るわけです。そうですよね?当然、re-rankingがあります。皆さんの多くはre-rankingについて聞いたことがあると思います。
そこにあるテクニックのいくつかを見ていきます。ええと、それから、ええと、contextual compression、correcter、bragなどの他のものもいくつかありますよね?そして最後にgenerationでは、ええと、最適化できることもたくさんあります。たとえば、promptで使用されるtop K chunksなどです。もちろんprompt optimizationもあります。ええと、皆さんの多くはD spyにおそらく馴染みがあるでしょう。ええと、それから、self ragのようなものや、ええと、そこには他にもいろいろありますよね?では、これらそれぞれの中からいくつかのテクニックを見ていきましょう。ええと、そのうえで皆さんと時間をかけて話したいのは、ええと、この領域をどう進んでいくかということです。そうですよね?RAGには本当にたくさんのテクニックと、たくさんの可動部分があります。
与えられたデータセット、与えられたユースケースにおいて、この領域をどのように進んでいくべきでしょうか?本番環境に今すぐ投入できる、本当に優れたプロダクショングレードで、信頼性が高く、堅牢なRAGを構築するための、事前検索最適化における正しいアプローチとは何でしょうか?私が多くのチームであまり使われていないと感じる、非常に基本的で根本的なテクニックが1つあります。そこで、これについて本当に手短に話したいと思います。ええと、基本的に、RAGについて話すとき、通常は大量の非構造化データを扱っていますよね?そして非構造化データは、一般的に、RAGのセットアップに最適化されていない形式、検索と取得に最適化されていない形式になっていますよね?つまり、基本的には、情報の段落が何段落も続いているようなものだと考えてください。事実密度は非常に低いですよね?関連する事実が1つあるかもしれませんが、それが3つの異なる段落にまたがって広がっている、ということがありますよね?したがって、非構造化データを元の形のまま取り込むときに生じる非常に基本的な問題の1つは、たとえ非常に効率的な検索アプローチを持っていたとしても、LLMのコンテキスト内に大量のチャンクが入ってしまうということです。そしてそれは、誤った応答の確率を高めるだけですよね?つまり、チャンクが多ければ多いほど、誤った応答の確率が高くなり、さらに重要なことに、トークン使用量が増え、コストが非常に高くなりますよね?ですから、ここで行うべき非常に基本的なことの1つは、情報密度を高めることです。つまり、関係のない情報やノイズを取り除くようなことです。情報の重複排除を行う、ということですね。そこで、興味深いユースケース、すみません、私が目にした興味深いケーススタディの1つで、この特定のアプローチに関連するものがあります。それは、金融機関が自社の製品やサービスの上に顧客向けチャットボットのようなものを作りたいと考えた事例です。この会社は、データソースとして使用していたHTMLページを大量に持っていました。そこで、非常に基本的に行うべきことの1つは、すべてのC-S-S-S-T-M-Lタグをプログラムで削除することです。ここで見える最初のボックス、それが生のSTMLで、自然で明白なことは、STMLタグを取り除くことです。
しかしそれでも、情報密度は低いままでした。そこで彼らが行ったのは、GPD fourを使って1段階のデータ処理を行うことでした。つまり、この生の形式のデータをg PT fourに通して、情報密度を高めたのです。彼らは、「あなたはナレッジベースの構築を支援しています。各段落について、それを取り出して、最も事実に基づき関連性の高い情報に凝縮してください」といったプロンプトを使いました。つまり、それがこの会社が最終的に行ったことです。そしてご覧のとおり、精度が上がった一方で、本当に興味深かったのはコスト削減でした。このアプローチによって、トークンコストが4倍削減されたのです。非常に興味深いですね。ただし、ここでの注意点の1つは、この情報の前処理を行うためにLLMを使用しているため、情報損失のリスクがあるということです。なぜなら、やはりLLMはハルシネーションを起こす可能性があるからです。したがって、これはG PT fourグレードのような、本当に強力なLLMで行うことが推奨されます。以上が1つ目です。
もう一つのテクニック、ええと、検索前最適化に関連するものとして、クエリ変換がありますよね?私たち人間は、本質的に質問をするのがとても下手ですよね?つまり、たいていの場合、ええと、まあ、正しい形で質問するのが苦手なんですよね?そのため、曖昧なクエリや、まあ、言い回しの悪いクエリがよくあります。うーん、そして多くの場合、まあ、あなたの RAG はおそらくあまり技術的ではない顧客に向き合っているわけですよね?つまり、あなたの、あなたのおそらく最終顧客、エンドユーザーは、まあ、一般の人のような存在になるわけですよね?ですから彼らにとっては、ええと、曖昧だったり言い回しが悪かったりするクエリ、あるいは本当に複雑なクエリになることがよくありますよね?では、それにどう対処するのでしょうか?うーん、ここでも行うのは、ええと、基本的に何らかのクエリ変換を行うことです。そこでは、全体的な、ええと、まあ、ええと、文脈や会話の少しの履歴を、ええと、手元にあるクエリと合わせて取り込み、それから別の LLM を使って、それをより関連性が高く、より効果的なクエリに戻し、それを検索に使う、ということです。つまり、だから検索前最適化なんですよね?この具体的な例では、うーん、ご覧のように、顧客がこのチャットボットと会話していて、CD の金利について話していました。ええと、そして突然会話が、ええと、まあ、クレジットカードの話になったわけですよね?例えば、旅行に良いクレジットカードはどれか?うーん、そして今その顧客が、「それの金利についてもっと教えて」と尋ねているわけですよね?そして今、ええと、このクエリ単体では検索を行うには非常に悪いものになりますよね?なぜなら、ええと、まあ、クエリの中に金利はありますが、顧客がどの製品について話しているのかがわからないからですよね?ですから、ここである種の前処理を行うことが非常に重要です。なので、ここでは何らかのプロンプトを使って、「ねえ、あなたは顧客と、ええと、チャットボットの会話を調べています。ええと、まあ、ええと、関連するドキュメントを取得するために使われる検索クエリを構築してください」といったことを言うわけです。うーん、そうするとそれは、この会話の履歴を取り込み、より良いクエリに変換しますよね?うーん、つまりそれが、ええと、クエリ変換です。うーん、ただし複雑なクエリの場合は、まあ、それらをサブクエリに分解して、それから、まあ、それらのサブクエリに対して個別に検索を実行し、その後結果を組み合わせるのが理にかなっています。
うーん、ええと、では、ええと、その流れで、うーん、アンサンブル検索、フュージョンリトリーバーについて話しましょう。そうですね?このテクニックで基本的に行うのは、うーん、多くの場合、特定の単一の検索アプローチだけでは、ユーザーが持っているどんな質問にも、まあ、可能な限り最も効果的な形で答えるには不十分だということです。ですから、やりたいことは複数のテクニックの力を活用することです。この図の例では、ええと、ベクトルインデックスがありますよね?うーん、ええと、これは密な検索手法のようなものです。つまり、クエリが入ってくると、それに対してセマンティック類似度検索を行い、上位 k 件の結果を取得しますよね?でも、それだけでは不十分かもしれませんよね?そして、もしかするとユーザーは、まあ、クエリの中に特定の、ええと、まあ、省略形や頭字語を含めていたかもしれませんし、あるいは、ベクトルデータベース内で意味的に表現されていない、本当に重要なキーワードを含めていたかもしれません。だから何をしたいかというと、ええと、ベクトル検索とキーワード検索を組み合わせたいわけですよね?そこでは基本的に、ある種の疎な検索手法を使いますよね?BM 25 が最も人気のあるものです。
ええと、でも基本的に行うのは、あなたは、その、同じクエリを並列で使うことです。それを、まあ、この別の検索に送ります。そこでは BM 25 ベースのキーワード検索が行われます。ええと、そしてもしかすると、ここでは少し異なる結果のサブセットが得られるかもしれません。そしてその後、あなたが行うのは、結果を実行、つまり組み合わせることです。そうですね?では、どのように結果を組み合わせるのでしょうか?あなたは、ええと、retrie、ええと、reciprocal run fusion と呼ばれるテクニックを使うことができます。
ええと、これは非常に人気のあるアルゴリズムで、新しいものではありません。以前から存在していて、ええ、情報検索の世界では非常に人気があります。ええと、ただ本質的には、ええ、重み付きスコアのようなものを計算して、そこで、ええと、両方のリトリーバーからの結果を組み合わせて、ええ、それをLLに送る、ということですね。ええと、ここにケーススタディがあります。これは、ええ、まあ、正確にはケーススタディではないのですが、ええと、Microsoftによって行われた実験のようなものです。ええと、基本的にここで見てわかるように、ええ、キーワード検索対ベクトル検索対ハイブリッド検索の比較があります。ええ、そしてハイブリッド検索が明らかに優れた性能を示していますよね?つまり、ある意味当然ですよね?2つの異なる手法の、ええ、技術を組み合わせているわけですからね。ええと、このケースで興味深いのは、4つ目の選択肢も用意していたことです。そこではハイブリッド検索を行ったうえで、さらにその上に、ええと、再ランキングも実行しました。
ええと、そして、ええ、それはさらに良かったわけです。つまり全体の検索結果で、ええ、ほぼ20パーセントポイントの改善、という感じですね。ええと、以上が、ええ、フュージョン検索についてです。ええと、次に再ランキングについてですが、ええと、非常に興味深い手法が1つあります。おそらく皆さんの多くはすでに、ええ、この手法について聞いたことがあると思いますが、ええと、クロスエンコーダ再ランキングは別の手法で、そこでやりたいことは、ええと、まず初回の検索を行うことです。そこで、ええと、バイエンコーダアプローチを使います。ええと、バイエンコーダアプローチというのは基本的に、ドキュメントを、ええ、別々に埋め込むということです。つまり、オフライン処理としてそれを行い、その1つの単一ベクトルに圧縮するわけですね。つまりそれは、ええ、先ほど議論したように、前処理ステップとして行われます。そしてクエリが入ってくると、同じようなことを行います。つまり、ええ、それをモデルに通して、するとそのクエリについても1つの単一ベクトル表現が得られます。そして基本的には、その後コサイン類似度検索を行うだけです。
ええと、それで、あの、ご存じのとおり、基本的には、入ってきたクエリに非常によく似た多数のドキュメントが得られるわけですよね?しかし、このアプローチの問題は、ほぼ1ページ分、あるいは1段落分の、あの、情報を取り出して、それを埋め込み、単一のベクトル表現に変換しているため、あの、ご存じのとおり、意味的な意味の一部が失われる可能性があるということです。ですよね?そのため、類似性検索を行うとき、おそらくそれほど効果的ではないでしょう。ですよね?そして、これの反対側にあるのが、クロスエンコードアプローチを使う場合です。ですよね?クロスエンコードアプローチでは、基本的にクエリとドキュメントを一緒にモジュールへ送ります。ですよね?そこで基本的には、あの、ご存じのとおり、分類のような処理を行い、ええと、あの、この2つのドキュメントが類似しているかどうかを特定します。あの、その方法では、Transformerの、あの、その、その優れた側面の多くを保持できます。ですよね?たとえば、あの、このドキュメントが、この別のドキュメント、私たちの場合はクエリですが、それに関連しているかどうかを非常に高い精度で判断するための、意味的に非常に豊かな情報を持っています。ですよね?ドキュメントBがクエリだと仮定しましょう。さて、クロスエンコーダの問題は、それを行うのに非常にコストが高いということです。ですよね?そして、あの、その理由は、先ほど言ったように、ご存じのとおり、ドキュメントとクエリを一緒にTransformerに渡さなければならないからです。ですよね?ええと、つまりそれは、あの、ご存じのとおり、早期相互作用モデルのようなものです。そして、それを行うのは非常に高コストです。ですから、10億個のベクトル、あるいは失礼、10億個のドキュメントを扱っている場合、あの、これはまったくスケーラブルではありません。ですよね?あの、ご存じのとおり、ユーザークエリが入ってきたとき、誰が答えが出るまで30分も待つでしょうか。ですよね?では、どうするのでしょうか。ですよね?1つのアプローチは、2パス方式を行うことです。そこではバイエンコードアプローチを使って、たとえば100件の候補ドキュメントを得ます。それらは、私たちが答えようとしているクエリに対して潜在的に最も類似しているものです。そして、その100件のドキュメントの上でクロスエンコーダを使います。ですよね?つまり、全体のドキュメントのごく小さなサブセットだけを使って、あの、ご存じのとおり、あの、あの、クロスエンコードアプローチによる再ランキングを実行しているわけです。
そして今では、はるかに優れたアプローチになり、私たちが答えようとしているこの質問に答えられる、正しいドキュメント、つまり、あの、正しいコンテキストを見つけられる可能性がはるかに高くなります。ですよね?ここに、それを示す、あの、ブロック図があります。あの、ご存じのとおり、ここには数百万のドキュメントがあります。あの、ここで、ご存じのとおり、セマンティック検索またはキーワード検索を実行し、ご存じのとおり、100件の結果を取得します。あの、たとえば、あの、最初のパスとしてです。そして基本的に、クエリとこの100件のドキュメントを使って、ええと、クロスエンコードによる再ランキングを実行します。そして今、ご存じのとおり、この再ランキング結果、または再取得結果があります。おそらくサブセットを取り、おそらく上位5件または上位10件を取り、それをLLMに渡します。すると今度は、あの、ご存じのとおり、結果はずっと、ずっと良く見えるでしょう。ですよね?さて、それは素晴らしいことです。ええと、しかし先ほど言ったように、ええと、それを行うのは非常に高コストです。ですよね?たとえば、その、そのクロスエンコーダの再ランキングはかなり高コストです。ですよね?そこで3つ目のアプローチは、あの、Cobraアプローチを使うことです。ですよね?Cobraアプローチは、あの、あの、非常に興味深い、ええと、この場合に行うことは、あの、バイエンコーダとクロスエンコーダの中間のようなものです。ですよね?バイエンコーダでは、クエリとドキュメントの間に相互作用はありません。
ええと、クロスエンコーダーでは、クエリとドキュメントの間に非常に重い相互作用があります。これを早期相互作用と呼んでいます。ええと、Colbert のアプローチでは、いわば後期相互作用のアプローチを取るわけですよね?ええと、それは正確にはどういう意味なのでしょうか?それが意味するのは、ええと、Colbert のアプローチでは、トークンレベルの埋め込みを保持しようとする、ということです。つまり、ドキュメントを取り出して、それを単一のベクトルに圧縮することはしません。むしろ、何をするかというと、ええと、その、トークンレベルで、トークンレベルの埋め込みを作成し、それをトークンレベルのまま保持します。そしてクエリが入ってくると、ええと、再び、その、トークンレベルで埋め込みます。そして何をするかというと、クエリ内の各トークンについて、ええと、その、自分が持っているトークンのコーパス全体にわたって、意味的に類似しているトークンが何かを見つけ出し、ええと、最大値演算のようなものを実行します。これは、ええと、非常に効率的に実行でき、とても簡単に、ええと、そして、ええと、ええ、Stefan がちょうど、ええと、Cold Pal を使うことについてのドキュメントをいくつか送ってくれました。ええと、これは、その、視覚データの上での Colbert で、ええと、malware を使うものです。
ええと、ありがとう、Stefan。ええと、ただ、これの例をすばやくお見せすると、そうですね?では、これがあなたのクエリだと仮定しましょう。ええと、これらはそれぞれトークンです。たとえば、ええと、クエリには3つのトークンがあると仮定して、そして、その、これらのドキュメントがあります。ええと、つまり何をしているかというと、クエリ内の各トークンについて、ええと、最大値が何か、これらすべてのトークンの中で最大値が何かを見つけようとしているわけです。
そして、ええと、その、この場合は9 7、この場合は8 4、そしてこの場合は8 5であることがわかります。ですから基本的に最大値を取り、それを集約するわけです。そうですよね?ええと、これが役立つのは、ドキュメント内にある意味的な豊かさの多くを依然として保持できるからです。そうですよね?つまり、トークンレベルに保つことで、その意味的に豊かな情報を保持しているのです。しかし同時に、これははるかに、ええと、効率的な操作です。なぜなら、単に最大値演算を行っているだけで、それは非常に簡単に実行でき、非常に効率的に実行できるからです。ですから、ええと、これは、これは素晴らしい技術で、ええと、素晴らしい結果を示していますよね?ただし、その裏側としては、ええと、実は、その裏側についてすぐに触れます。ここに、ええと、Coldwell モデルの実際の例があります。ここで、ええと、その、これがあなたの質問で、ええと、これが、あなたが持っているドキュメントだと仮定します。ええと、ご覧のように、transformer と transformer の一致が最も高くなります。ええと、同じ単語だからです。
ええと、しかし次に、その、cartoon は animated と一致し、the when は、その、August と 1986 に一致し、そして、ええと、come out は、その、released と一致しますよね?つまり、ええと、これは基本的にトークンレベルのマッチングのようなことをしているわけです。そう言えるでしょう。そうですよね?ええと、そしてそれにより、rag の文脈では非常に関連性が高く、非常に正確になりますよね?さて、これの裏側は、検索空間を大量に必要とするということです。そうですよね?ええと、トークンレベルで保存しているからです。ええと、その、ストレージは本当に、ええと、大きな課題になり得ます。ええと、そこで Colbert VI two が登場しました。ですから、ええと、Colbert VI two はセントラルベースのアプローチを使っていて、ええと、何をするかというと、ええと、基本的には、ええと、ええと、その、OID のようなものを保存します。なぜなら、意味的に豊かな情報、つまりトークンレベルの情報があるからです。そのトークンレベルの、ええと、その、自分が持っている埋め込みの上でクラスタリングのようなことができ、いくつかの OID を作成できます。ええと、そして基本的には、それらの OID に対して最初のパスマッチングのようなことを行い、ええと、その、このトークンに最も近いトークンが何かを見つけ出します。
そして、トークンからドキュメントにたどり着くわけですが、ええと、ええと、それによって、ええ、つまり、はるかに優れた効率的なアプローチになるわけですよね?それは素晴らしいのですが、ただ、ええと、私たちは多くの異なる、ええと、アプローチやテクニックについて話しましたよね?ええと、ここでいったん止めて、皆さんに手短にお聞きしたいのですが、皆さんはどのテクニックを使うのが正しいのかをどうやって判断していますか?たとえば、どのチャンク化アプローチを使うのが正しいのか、どうやって判断していますか?自分が扱っているデータセットに対して、適切なチャンクサイズは何でしょうか?どのテクニックを使っていますか?あるいは、ええと、つまり、どの、ええと、値を使うべきかをどうやって判断していますか?どのチャンクサイズを使うか、どのチャンク化戦略を使うか?どのような検索を使うか?皆さん、チャットに入力して、共有してもらえますか?皆さんは、trial and error のための最適なセットアップをどうやって見つけていますか?はい、まだそこまで行っていない。わかりました。つまり、試行錯誤が、ええと、最も一般的な方法で、つまり、ええと、実際には、ほかに方法はないですよね?たとえば、自分にとってどのチャンク化戦略やどのチャンクサイズが、ええと、より良いかなんて、どうやってわかるのでしょうか?ええと、ええと、まあ高いレベルでは、はい。ここで誰かが言及していますが、関連性に基づいてチャンク化する、部門や情報のトピックに基づいて別々のドキュメントを作成する、ということですね。ええ、いいですね、いいですね。
はい。でも、ええと、一般化する方法はないですよね?たとえば、「金融文書を扱っているなら、チャンク、チャンク化アプローチ X、y、z を使う」というような、そういう一般化を行うことは不可能です、よね?なぜなら、すべてのデータセットはユニークで、すべてに当てはまる万能の RAG など存在しないからです、よね?ええと、ですから最適化された RAG を作るのは実際には本当に、本当に難しいのです、よね?そして、それには、ええと、多くの試行錯誤が必要で、それには多くの時間と労力がかかります。ですので、ええと、たとえば、ええと、仮に、ある特定の RAG ユースケースに取り組んでいて、5つの異なるチャンク化手法、5つの異なるチャンクサイズ、5つの異なる numbering models、などなどから選ばなければならないとしますよね?これがいくつの RAG 構成を生み出すか、誰かわかりますか?組み合わせの数で言うと?数学の問題です。さて、何人が当てられるでしょうか。5 の 7 乗。そうです。
その通りです。はい。つまり、これは 5 の 7 乗のようなものを作ることになり、それは約 78,000 種類の異なる RAG 構成になりますよね?そして、1つずつ試すのにたった5分しかかからなかったとしても、それでもノンストップの試行錯誤で 271 日くらいかかることになりますよね?ですから明らかに、データセットとユースケースに最適な RAG セットアップを手動の試行錯誤アプローチで見つけるのは、かなり非現実的です、よね?だからこそ、私たちは Rag Builder を作ることになりました。Rag Builder は、RAG のさまざまな可動部分に対してハイパーパラメータ最適化を行うツールキットです、よね?たとえば、データセットにとって適切なチャンクサイズが何かを見つけ出そうとします。たくさんの異なるチャンクサイズ、たくさんの異なるチャンク化戦略、ええと、そしてたくさんの異なる numbering models、などなどを試します。
そして、各試行ごとに、何がうまく機能していて、何が機能していないかを把握し、そのうえで、これらの各パラメータにわたって最も最適なパラメータ値のセットに収束していくようにします、よね?ええと、ally には、あらかじめ定義された RAG テンプレートがたくさん含まれています。ええと、また、ええと、つまり、ええと、ragas を使って、ええと、合成テストデータ生成を行う機能もあります。ええと、皆さん全員が Ragas に詳しいかどうかはわかりませんが、ragas は別のオープンソースライブラリで、ええと、特に RAG 評価に焦点を当てています。ですので、ええと、合成テストデータ生成があります、ええと、ただ、ええと、ええ、graph rank の knowledge base もサポートしています。ええと、そして、ええと、いくつかの、ええと、興味深いロードマップ項目にも取り組んでいます。たとえば、自分のコンポーネントを持ち込める機能や、クラウドホスト型オプションなどです、よね?ええと、完全にオープンソースです。
ええと、ぜひチェックしてみてください。ええと、皆さんがどんな感じかつかめるように、たぶん本当に短いデモをできます。うん、素晴らしいです。Stefan が今後のウェビナーで Ranga を取り上げる予定です。素晴らしいです。
うん、いいですね。インストールはとても簡単です。rag builder. io に行くと、コピー&ペーストできるこの1行コマンドがあり、ええと、それで準備完了です。基本的にはいくつかの brew ライブラリをインストールして、PIP install Rag Builder を実行します。
ええと、Rag Build をインストールしたら、ターミナルに行って Rag Builder と入力するだけで、ローカルで動作する ucon fast, API app が立ち上がります。そうですね?すると、もう少しでブラウザが開きます。うん、そして、先ほど言ったように、すべてローカルで動いています。ここで IP アドレスを見ると、1 27 0. 2,2. 1 で、ええと、ローカルで動いています。
なので、データがシステムやプラットフォームの外に出ることを懸念しているなら、ええと、これはかなり便利なソリューションです。そうですね、OpenAI や Cohere のようなサードパーティの AI service を使っていない限り、データはあなたのシステム内に残ります。そうですよね?さて、RAG を構築しているとしましょう。そこで new project をクリックして、ええと、説明を入力します。たとえば、いったん documentationchat bot を作っているとしましょう。via land chain と仮定して、私たちには大量のドキュメントがあり、ええと、開発者がこれに AI chat bot 経由でアクセスしやすくしたいとします。なので、documentation chat bot を作りましょう。
今、私はすでに long chain documentation をスクレイピングしているので、ええと、このディレクトリには、私が、ええと、入れておいた hundreds of markdown files があります。ええと、ただこのフィールドはかなり柔軟です。URL を指すこともできます。ええと、当然、複数のファイルを含むディレクトリを指すこともできますし、うん、特定のファイルを指すこともできます。そうですよね?さて、データセットが大きい場合は、自動的にスキャンして、やあ、あなたの dataset は、ええと、かなり大きいですよ、と教えてくれます。ええと、ここではしきい値を本当に低く設定しています。
なので、だからこそ、たとえば 1 M file くらいのものでも、データセットが大きいと言っています。ええと、ただ、データセットが大きい場合は、sampling から始めたいですよね?そうすれば、多くのトークンを消費せずに済み、ええと、より速く反復できますよね?ええと、なのでこれはかなり便利なものです。うん、先ほど言ったように、私たちはたくさんの predefined templates を用意しています。うん、そして、ええと、これをちょっとお見せすると、うん、ええと、これらのテンプレートを使えば、zero から one まで非常に素早く進められます。そうですよね?なので、graph drag や hybrid drag のようなものを作りたい場合、ええと、それを行うのはとても簡単です。うん、ここにはたくさんのテンプレートがあります。ええと、そうですね、ただ、このツールが本当に力を発揮するのは2つ目のオプションで、ここでは custom rack configuration をゼロから作成できます。そうですよね?では、それを本当にさっとお見せします。
ここで next に進むと、この画面で個々のコンポーネントをより細かいレベルで調整できます。たとえば、chunk sizes を 503,000 の間で検討したい場合、スライダーを使うだけで、この範囲内で最適な chunk size が何かを見つけてくれます。そうですよね?これらの異なる chunking approaches をすべて試して、どれが最適かを見つけます。複数の ING models を検討したい場合、それもできます。あるいは、作業している非常に特定の embed model がある場合、それもできます。ご存じの通り、私たちは、ええと、hugging face をサポートしています。ええと、ええと、モデルがクラウド上でホストされているなら、それもできます。
ええと、はい、では、あー、visを選びましょう、そうですね?ええと、それで、あー、あー、はい、私たちはたくさんの異なるベクトルデータベースをサポートしています、あー、でももちろんvesはかなり良いです。ええと、それで、あー、それはたくさんの検索をサポートしています。なので、いくつもの異なる、あー、あー、いわゆる検索最適化アプローチについて話しましたよね?あー、たとえば、マルチクエリリトリーバーについて話しましたよね?つまり、クエリを複数の、あー、いわゆるバージョンに分解して、それで、あー、いわゆるクエリを、あー、複数の、あー、クエリの複数バージョンに基づいて複数の、あー、ドキュメントを取得します。そしてその上で、あー、取得、あー、すみません、reciprocal rank fusionを行います。なので、BM 25リトリーバーやベクトル類似度検索のように、それらすべてを実行できます。
それらをすべて組み合わせるか、個別に試して、最適なリトリーバー設定が何かを見つけ出します。あー、もちろんtop Kパラメータもあります。そしてreranの中でも、今話したように、非常に多くの異なる手法があります。あー、たとえば、crossとcoder reranがありますよね、もちろん、あー、cohereや、あー、BGなど、その他いろいろ、Ginaなど、その他いろいろです。でもColbert reranもあります、先ほど話したものですね、ええと、それから、あー、他にもたくさんありますよね?そして最後にLLMもあります。
なので、あー、使用したいLMを、あー、選択できます。GRを使いたい場合でも、ローカルで使用しているモデル、たとえばLAMA 3. 1や3. 2のようなモデルにulamaを使いたい場合でも、それもできますよね?先ほど言ったように、私たちはbe最適化を行います。なので、グリッドサーチやブルートフォースサーチのように、これらすべてのパラメータを総当たりするわけではありません。あー、インテリジェントに動作し、つまり、ランダムな値のセットから開始しますが、各実行ごとに何が、何がうまく機能していて、何が機能していないのかを見つけ出します。
では、それをどうやって行うのでしょうか?それは、その場でrag評価を使うことで行いますよね?基本的に、ええと、あなたが、あー、データセットを提供します、ええと、それはゴールデンデータセットのようなものだと考えてください。あー、皆さん全員がゴールデンデータセットに詳しいかどうかはわかりませんが、ゴールデンデータセットというのは、ragを評価して、あー、ragの精度を把握するために使える質問と回答のペアの集合は何か、ということを表す用語にすぎませんよね?なので、ゴールデンデータセットは通常、いわゆるすべての異なるシナリオをカバーします。あー、基本的に十分に包括的です。あー、もしそのようなデータセットがあるなら、そのデータセットを持ち込んで、あー、あー、そのデータセットを含むファイルを、いわゆる、あー、指し示すだけです。もしそのデータセットがない場合、大多数の場合、手元にそれはありませんが、あー、先ほど言ったように、ソースデータセットを使って、あー、それを合成的に生成できますよね?なのでこの場合、私がソースデータセットとしてlong chain documentationを持っていたように、ユーザーがどんな質問をスキャンする可能性があるか、それらの質問に対するグラウンドトゥルースは何か、ということをシミュレートするような合成テストデータを生成できますよね?なので、それを合成的に生成できます。
Meet the Speaker
Join the session for live Q&A with the speaker

Aravind Parameswaran
Co-Founder at Krux AI
Aravind Parameswaran is a data & product enthusiast, with 15+ years of experience in data, analytics & product. He’s currently co-founder at Krux AI, makers of the open-source tool RAGBuilder (ragbuilder.io). He has worn multiple hats in his career - analyst, technology architect, data engineer, product manager, and was previously leading cross-functional teams at Cult Fit, and at Meta/ Facebook.


