LLama Indexを使用してRAGパイプラインを構築する
「LLama Indexを活用したRAGパイプラインの構築」
イントロダクション
最も人気のある大規模言語モデル(LLM)の応用の一つは、カスタムデータセットに関する質問に回答することです。ChatGPTやBardなどのLLMは、優れたコミュニケーターであり、彼らが訓練されたものに関してはほとんど何でも答えることができます。これはLLMの最大のボトルネックの一つでもあります。彼らはモデルの訓練中に見た質問にしか答えられません。言語モデルは世界の知識に制限があります。例えば、Chatgptは2021年までのデータを利用して訓練されています。また、GPTはあなたの個人ファイルについて学ぶ方法はありません。では、モデルにまだ持っていない知識をどのようにして認識させることができるでしょうか?その答えが「検索補完生成パイプライン(RAG)」です。この記事では、RAG(検索補完生成)パイプラインについて学び、LLamaインデックスを使用してそれを構築する方法について説明します。
学習目標
- RAG(検索補完生成)とは何か、またいつ使用するべきかを探求する。
- RAGの異なるコンポーネントについて簡単に理解する。
- Llamaインデックスについて学び、PDFのためのシンプルなRAGパイプラインを構築する方法を理解する。
- 埋め込みとベクトルデータベースとは何か、またLlamaインデックスの組み込みモジュールを使用してPDFから知識ベースを構築する方法を学ぶ。
- RAGベースのアプリケーションの実世界での使用例を発見する。
この記事はData Science Blogathonの一環として公開されました。
RAGとは何ですか?
LLMは、これまでのところ最も効率的かつ強力なNLPモデルです。翻訳、エッセイの執筆、一般的な質問応答の分野でLLMの潜在能力を見てきました。しかし、特定のドメインに特化した質問応答においては、彼らは幻覚に苦しんでいます。また、ドメイン固有のQAアプリでは、クエリごとに関連する文脈を持つドキュメントはわずかです。したがって、ドキュメントの抽出から回答生成、およびその間のすべてのプロセスを統合する統一されたシステムが必要です。このプロセスは「検索補完生成」と呼ばれています。
- 「私たちのLLMモデルを強化するための素晴らしいプロンプトエンジニアリング技術」
- 「MozillaがFirefoxに偽レビューチェッカーAIツールを導入」
- K-平均クラスタリングのためのワンストップショップ
詳しくはこちらを参照:AIにおける検索補完生成(RAG)
では、なぜRAGが実世界の特定のドメインに特化したQAアプリケーションの構築に最も効果的なのかを理解しましょう。
なぜRAGを使用すべきか?
LLMが新しいデータを学ぶ方法は3つあります。
- トレーニング:兆個のトークンと数十億のパラメータを持つニューラルネットワークの大規模なメッシュが使用されて、大規模言語モデルを作成するために訓練されます。ディープラーニングモデルのパラメータは、特定のモデルに関するすべての情報を保持する係数または重みです。GPT-4のようなモデルを訓練するには、数億ドルがかかります。この方法は誰にでも容易にはできません。このような巨大なモデルを新しいデータで再訓練することは実現不可能です。
- ファインチューニング:別のオプションとして、既存のデータに対してモデルをファインチューニングすることが考えられます。ファインチューニングは、トレーニング中に事前に訓練されたモデルを起点として使用することを意味します。事前に訓練されたモデルの知識を利用して、異なるデータセット上で新たなモデルを訓練します。これは非常に強力ですが、時間とお金の面で高コストです。特別な要件がない限り、ファインチューニングは意味がありません。
- プロンプティング:プロンプティングは、LLMのコンテキストウィンドウ内に新しい情報を適応させ、提示された情報からクエリに回答させる方法です。これは、訓練やファインチューニングで学んだ知識ほど効果的ではありませんが、ドキュメントの質問応答など多くの実世界のユースケースには十分です。
テキストドキュメントからの回答を促すことは効果的ですが、これらのドキュメントはしばしばLarge Language Models(LLM)のコンテキストウィンドウよりもはるかに大きくなるため、課題を提起します。リトリーバルオーグメンテッドジェネレーション(RAG)パイプラインは、関連するドキュメントセクションの処理、保存、および検索を行うことで、LLMが効率的にクエリに答えることができるようにします。それでは、RAGパイプラインの重要なコンポーネントについて議論しましょう。
RAGコンポーネントとは何ですか?
典型的なRAGプロセスでは、いくつかのコンポーネントがあります。
- テキストスプリッター:LLMのコンテキストウィンドウに合わせてドキュメントを分割します。
- 埋め込みモデル:ドキュメントの埋め込みの取得に使用される深層学習モデルです。
- ベクトルストア:ドキュメントの埋め込みが格納され、メタデータとともにクエリされるデータベースです。
- LLM:クエリから回答を生成する大規模言語モデルです。
- ユーティリティ関数:これには、Webretriverやドキュメントパーサなどの追加のユーティリティ関数が含まれます。これらは、ファイルの取得と前処理を支援します。
上記の図は典型的なRAGプロセスの一例です。ドキュメント(PDF、Webページ、ドキュメント)、大きなテキストを小さなチャンクに分割するためのツール、テキストチャンクのベクトル表現を取得するための埋め込みモデル、データベースとしてのベクトルストア、およびテキストチャンクから回答を取得するためのLLMがあります。
Llamaインデックスとは何ですか?
Llamaインデックス(GPTIndex)は、LLMアプリケーションを構築するためのPythonで書かれたフレームワークです。カスタムデータソースを大規模言語モデルに接続するためのシンプルで柔軟なデータフレームワークです。さまざまなソースからのデータの取り込みをサポートする適切なツール、データインデックスのためのベクトルデータベース、および大規模ドキュメントのクエリインターフェースを提供します。要するに、Llamaインデックスはリトリーバルオーグメンテッドジェネレーションアプリケーションを構築するためのワンストップショップです。Langchain、Flask、Dockerなどの他のアプリケーションとの簡単な統合も可能です。詳細については、公式のGitHubリポジトリをご覧ください:https://github.com/run-llama/llama_index。
他にも読む: LlamaIndexの使用方法
RAGとLlamaインデックスについて知ったところで、PDFドキュメントを処理し、進行中の個別の概念を議論するためにRAGパイプラインを構築しましょう。
開発環境のセットアップ
Pythonプロジェクトを構築する際の最初のルールは、仮想環境を作成することです。準備ができたら、次のライブラリをインストールしてください。
llama-indexopenaitiktoken
次に、以下の関数をインポートします。
import osfrom llama_index import ServiceContext, LLMPredictor, OpenAIEmbedding, PromptHelperfrom llama_index.llms import OpenAIfrom llama_index.text_splitter import TokenTextSplitterfrom llama_index.node_parser import SimpleNodeParserfrom llama_index import VectorStoreIndex, SimpleDirectoryReaderfrom llama_index import set_global_service_context
次に、Open AI APIキーを設定します。
import osos.environ['OPENAI_API_KEY'] = "YOUR API KEY"
ドキュメントの読み込み
LLMは、世界の最新の知識や内部ドキュメントに関する知識を持っていません。LLMをサポートするために、関連する情報を知識源から提供する必要があります。これらの知識源には、CSV、スプレッドシート、SQLテーブルなどの構造化データ、テキスト、Wordドキュメント、Googleドキュメント、PDF、PPTなどの非構造化データ、Notion、Slack、Salesforceなどのセミストラクチャデータが含まれます。
この記事では、PDFを使用します。Llamaインデックスには、指定されたディレクトリから保存されたドキュメントを読み込むことができるSimpleDirectoryReaderクラスが含まれています。このクラスは、ファイルの拡張子に基づいて適切なパーサを自動的に選択します。
documents = SimpleDirectoryReader(input_dir='data').load_data()
PyMuPDFやPyPDF2などのパッケージを使用して、PDFリーダーのカスタム実装を行うこともできます。
テキストチャンクの作成
知識源から抽出されたデータはしばしばLLMのコンテキストウィンドウを超える長さになるため、問題が発生します。コンテキストウィンドウよりも長いテキストを送信すると、Chatgpt APIはデータを縮小し、重要な情報を省きます。この問題を解決する方法の1つは、テキストチャンキングです。テキストチャンキングでは、区切り文字に基づいて長いテキストを小さなチャンクに分割します。
テキストチャンキングには、大容量の言語モデルのコンテキストウィンドウにテキストを適合させること以外にも、他の利点があります。
- 小さなテキストチャンクは埋め込みの精度が向上し、検索の精度も向上します。
- 正確なコンテキスト:情報を絞り込むことで、より良い情報を取得できます。
Llama Indexには、テキストチャンキングのための組み込みツールがあります。以下に、その方法を示します。
text_splitter = TokenTextSplitter( separator=" ", chunk_size=1024, chunk_overlap=20, backup_separators=["\n"], tokenizer=tiktoken.encoding_for_model("gpt-3.5-turbo").encode)node_parser = SimpleNodeParser.from_defaults( text_splitter = TokenTextSplitter ))
SimpleNodeParserは、テキストチャンクをノードに変換し、テキストチャンクはLlama IndexのTokenTextSplitterを使用して作成されます。また、SentenceSplitterも使用できます。
text_splitter = SentenceSplitter( separator=" ", chunk_size=1024, chunk_overlap=20, paragraph_separator="\n\n\n", secondary_chunking_regex="[^,.;。]+[,.;。]?", tokenizer=tiktoken.encoding_for_model("gpt-3.5-turbo").encode)
ナレッジベースの構築
ナレッジソースから抽出されたテキストは、どこかに保存する必要があります。ただし、RAGベースのアプリケーションでは、データの埋め込みが必要です。これらの埋め込みは、高次元のベクトル空間でデータを表す浮動小数点数です。それらを保存し、操作するためには、ベクトルデータベースが必要です。ベクトルデータベースは、ベクトルを保存し、クエリを処理するために特化したデータストアです。
このセクションでは、埋め込みとベクトルデータベースの理解と、RAGパイプラインにおけるそれらの実装について説明します。
埋め込み
埋め込みについては、シンプルなスーパーマーケットの例から理解することができます。スーパーマーケットでは、常にリンゴとオレンジが同じコーナーにあります。石鹸を見つけるには、果物のセクションから日用品のセクションに向かって少し離れる必要がありますが、パフュームは同じセクションで数歩の距離で見つけることができます。
これが埋め込みの動作です。意味的に関連する2つのテキストは、ベクトル空間では近くにあり、異なるテキストは遠くにあります。埋め込みは、異なるデータポイント間の類推をマッピングする非凡な能力を持っています。以下はその簡単なイラストです。
では、なぜ埋め込みが必要なのでしょうか?
強力な深層学習モデルから生成された埋め込みは、テキストチャンクの意味的な意味を効率的に捉えることができます。ユーザーがテキストクエリを送信すると、同じモデルを使用して埋め込みに変換し、ベクトルデータベースに保存されているテキストの埋め込みの距離を比較し、最も類似した「n」個のテキストチャンクを取得します。これらのチャンクは、クエリされたテキストと意味的に最も類似したチャンクです。
埋め込みモデルには、特別な手続きは必要ありません。Llama Indexには、OpeanAIのAda、Cohere、Sentence transformersなど、人気のある埋め込みモデルのカスタム実装があります。
埋め込みモデルをカスタマイズするには、ServiceContextとPromptHelperを使用する必要があります。
llm = OpenAI(model='gpt-3.5-turbo', temperature=0, max_tokens=256)embed_model = OpenAIEmbedding()prompt_helper = PromptHelper( context_window=4096, num_output=256, chunk_overlap_ratio=0.1, chunk_size_limit=None)service_context = ServiceContext.from_defaults( llm=llm, embed_model=embed_model, node_parser=node_parser, prompt_helper=prompt_helper)
ベクトルデータベース
ベクトルデータベースは、埋め込みと関連するメタデータを保存し、クエリの効率的な検索を提供するために特化して設計されたものです。これがその動作です。
では、なぜ従来のデータベースを使用しないのでしょうか?技術的には、SQLiteやMySQLなどのデータベースを使用してベクトルを保存し、クエリテキストの埋め込みを全てのデータと線形に比較することはできます。しかし問題は、おそらくお分かりいただけるかと思いますが、O(n)の時間計算量を持つ線形検索です。 GPUを搭載したマシンなら数千のデータポイントを十分に処理できますが、何億もの埋め込みを処理する場合、現実世界のアプリケーションでは惨憺たる結果になります。
では、どのように解決するのでしょうか?答えは、HNSWなどの異なるANNアルゴリズムを使用して埋め込みをインデックス化することです。HNSWは、数十億の埋め込みを効率的に処理することができるグラフベースのアルゴリズムです。HNSWの平均クエリの複雑さはO(log n)です。
HNSW以外にも、いくつかのインデックス技術があります。例えば、Product quantization、Scalar quantization、そしてInverted fileのインデックス技術があります。ただし、HNSWはほとんどのベクトルデータベースでデフォルトのインデックスアルゴリズムとして使用されています。
埋め込みとベクトルストアについて学びました。今度は、コードにそれらを実装します。Llama Indexのデフォルトのベクトルストアを使用します。これはインメモリのベクトルデータベースです。他のベクトルストアとしては、Chroma、Weaviate、Qdrant、Milvusなどを選ぶこともできます。
index = VectorStoreIndex.from_documents(documents, service_context = service_context)
指定したディレクトリ内のドキュメントと、先に定義したサービスコンテキストのデフォルトを使用してインデックスが作成されます。
インデックスへのクエリ
最後のステップは、インデックスからクエリを行い、LLMから応答を得ることです。Llama Indexにはクエリエンジンがあります。クエリエンジンではクエリを行うためのエンジンが提供されます。一方、チャットエンジンではチャットの履歴が保存され、クエリエンジンでは保存されません。
query_engine = index.as_query_engine(service_context=service_context)
response = query_engine.query("HNSWとは何ですか?")
print(response)
画像とコードのGitHubリポジトリ: sunilkumardash9/llama_rag
フルコード:
from llama_index import ServiceContext, LLMPredictor, OpenAIEmbedding, PromptHelperfrom llama_index.llms import OpenAIfrom llama_index.text_splitter import TokenTextSplitterfrom llama_index.node_parser import SimpleNodeParserimport tiktokenllm = OpenAI(model='gpt-3.5-turbo', temperature=0, max_tokens=256)embed_model = OpenAIEmbedding()text_splitter = TokenTextSplitter( separator=" ", chunk_size=1024, chunk_overlap=20, backup_separators=["\n"], tokenizer=tiktoken.encoding_for_model("gpt-3.5-turbo").encode)node_parser = SimpleNodeParser.from_defaults( text_splitter=text_splitter)prompt_helper = PromptHelper( context_window=4096, num_output=256, chunk_overlap_ratio=0.1, chunk_size_limit=None)service_context = ServiceContext.from_defaults( llm=llm, embed_model=embed_model, node_parser=node_parser, prompt_helper=prompt_helper)documents = SimpleDirectoryReader(input_dir='data').load_data()index = VectorStoreIndex.from_documents(documents, service_context = service_context)index.storage_context.persist()query_engine = index.as_query_engine(service_context=service_context)response = query_engine.query("HNSWとは何ですか?")print(response)
実生活のユースケース
RAGベースのアプリケーションは、実生活のさまざまなユースケースで役立ちます。
- 学術研究:研究者はしばしば多くの研究論文やPDF形式の記事に取り組んでいます。RAGパイプラインは彼らが関連情報を抽出し、参考文献を作成し、効率的に参照を整理するのに役立ちます。
- 法律事務所:法律事務所はしばしば多くの法的文書に取り組んでいます。RAG対応のQ&Aチャットボットは文書の取得プロセスを効率化することができます。これにより時間を節約できます。
- 教育機関:教師や教育者は教育資料からコンテンツを抽出してカスタマイズされた学習教材やコースコンテンツを作成することができます。学生は大きなPDFから適用可能な情報をわずかな時間で抽出することができます。
- 行政:政府および非公開の行政部門はしばしば大量の文書、申請書、報告書に取り組んでいます。RAGチャットボットを導入することで、退屈な文書取得プロセスを効率化することができます。
- カスタマーケア:既存の知識ベースを持つRAG対応のQ&Aチャットボットを使用して、顧客の質問に回答することができます。
結論
私たちは見てきたように、RAGは検索生成を効率化します。これにより、膨大な文書から適切な文脈をクエリするのにかかる時間をわずかに短縮できます。そして、LLMはクエリの正しい文脈を提示されて回答を生成します。追加の文脈は、基本的にはLLMを文脈に固定し、文脈に関連する回答のみを生成するようにします。これにより、LLMは幻想を見ないようにしながら、優れた表現力と文章能力を保ちます。
この記事からの重要なポイントを以下にまとめます。
キーポイント
- パーソナルドキュメントに関するLLMの学習と幻覚の軽減の理想的な方法は、ナレッジベースからの取得文書でLLMを拡張することです。
- RAGは「Retrieval Augmented Generation」の略であり、カスタムドキュメントからの情報でLLMを拡張するために使用されます。
- 埋め込みは、テキストデータの数値表現であり、高次元ベクトル空間におけるテキストの意味的な特徴を捉えます。
- ユーザーは、高次元ベクトルを組織化するためのさまざまなインデックスアルゴリズムを利用して、ベクトルデータベースをナレッジベースとして利用し、高速かつ堅牢なクエリ能力を実現します。
- Llama Indexは、プロダクショングレードのRAGベースのアプリケーションを構築するための組み込みツールとメソッドを提供しています。
よくある質問
この記事に表示されているメディアはAnalytics Vidhyaの所有ではなく、著者の裁量で使用されています。
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles
- 9/10から15/10までの週のトップ重要なコンピュータビジョン論文
- ユニバーサルシミュレータ(UniSim)をご紹介します:生成モデリングを通じたリアルワールドの対話をインタラクティブにシミュレートするシミュレータ
- ChatGPT vs. BARD’の比較
- 「切り分けて学ぶ」による機械学習におけるオブジェクトの状態合成の認識と生成
- ウェアラブルテックを革命:エッジインパルスの超効率的な心拍数アルゴリズムと拡大するヘルスケアスイート
- このAI論文は、言語エージェントのための自然言語とコードの調和を目指して、LemurとLemur Chatを紹介しています
- Amazon SageMakerのマルチモデルエンドポイントを使用して、Veriffがデプロイ時間を80%削減する方法