「検索強化生成(RAG) 理論からLangChainの実装へ」
「美容とファッションのエキスパートが語る、魅力あるビューティーとファッションの世界」
オリジナルの学術論文の理論からOpenAI、Weaviate、およびLangChainを使用したPythonの実装まで
大規模な言語モデル(LLM)に独自のデータを追加することで、それを高速化することができることがわかって以来、LLMの一般的な知識と独自のデータとのギャップを最も効果的に埋める方法についての議論がありました。 fine-tuningとRetrieval-Augmented Generation(RAG)のどちらがこれに適しているかについては、多くの議論があります(ネタバレ:両方が適しています)。
この記事では、まずRAGの概念に焦点を当て、その理論について説明します。そして、LangChainをオーケストレーション、OpenAIの言語モデル、そしてWeaviateのベクトルデータベースを使用して、シンプルなRAGパイプラインを実装する方法を紹介します。
Retrieval-Augmented Generationとは何ですか
Retrieval-Augmented Generation(RAG)は、外部の知識源からLLMに追加情報を提供する概念です。これにより、より正確で文脈に即した回答を生成し、空想を減らすことができます。
課題
最先端のLLMは、広範な一般知識をニューラルネットワークの重み(パラメトリックメモリ)に格納するために大量のデータで訓練されます。しかし、LLMに対してトリガーすることで、トレーニングデータに含まれていない知識(新しい、独自の、またはドメイン固有の情報など)を必要とする生成を行わせると、事実に基づかない情報(空想)が生じることがあります。以下のスクリーンショットで示されているように:
したがって、LLMの一般的な知識と追加の文脈とのギャップを埋めることは重要です。これにより、LLMがより正確で文脈に即した生成を行う一方、空想を減らすことができます。
解決策
従来、ニューラルネットワークはモデルをドメイン固有の情報に適応させるために、ファインチューニングを行ってきました。このテクニックは効果的ですが、計算負荷が高く、コストがかかり、技術的な専門知識が必要であり、進化する情報に適応する柔軟性に欠けるため、適応性が低いです。
2020年、Lewisらは、論文「Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks」 [1]で、より柔軟な技術であるRetrieval-Augmented Generation(RAG)を提案しました。この論文では、研究者は生成モデルとリトリーバーモジュールを組み合わせることで、より簡単に更新できる外部の知識源からの追加情報を提供しました。
簡単に言えば、 RAGはLLMにとって人間のオープンブック試験のようなものです。オープンブック試験では、生徒は教科書やノートなどの参考資料を持ち込むことが許され、質問に答えるために関連する情報を参照することができます。オープンブック試験のアイデアは、テストが生徒の推論力に焦点を当てることで、特定の情報を暗記する能力よりも重視することです。
同様に、事実の知識はLLMの推論能力から分離され、外部の知識源に格納され、簡単にアクセスおよび更新できます:
- パラメトリックな知識:トレーニング中に学習され、ニューラルネットワークの重みに暗黙的に格納されます。
- ノンパラメトリックな知識:ベクトルデータベースなどの外部の知識源に格納されます。
(ところで、この天才的な比較は私が考え出したわけではありません。私の知る限り、この比較はKaggle – LLM Science Exam competition中にJJによって最初に言及されたものです。)。
バニラRAGワークフローは以下のように示されます:
- 検索: ユーザーのクエリは外部の知識源から関連するコンテキストを取得するために使用されます。このために、ユーザーのクエリは埋め込みモデルによってベクトルデータベースの追加コンテキストと同じベクトル空間に埋め込まれます。これにより、類似性検索が実行され、ベクトルデータベースから上位k個の最も近いデータオブジェクトが返されます。
- 拡張: ユーザーのクエリと取得した追加コンテキストはプロンプトテンプレートに挿入されます。
- 生成: 最後に、取得拡張されたプロンプトがLLMに送られます。
LangChainを使用した検索拡張生成の実装
このセクションでは、OpenAIのLLMとWeaviateベクトルデータベース、およびOpenAIの埋め込みモデルを組み合わせて、PythonでRAGパイプラインを実装します。オーケストレーションにはLangChainを使用します。
LangChainまたはWeaviateに慣れていない場合は、次の2つの記事をチェックしてみてください:
LangChain入門: LLMを使用したアプリケーション構築の初心者ガイド
Pythonで大規模な言語モデルを使用した何でも構築するためのLangChainチュートリアル
towardsdatascience.com
Weaviate入門: ベクトルデータベースを使用した検索の初心者ガイド
OpenAIとPythonを使用した意味的検索、質問応答、生成検索のためのベクトルデータベースの使用方法
towardsdatascience.com
前提条件
必要なPythonパッケージがインストールされていることを確認してください:
- オーケストレーションのための
langchain
- 埋め込みモデルとLLMのための
openai
- ベクトルデータベースのための
weaviate-client
#!pip install langchain openai weaviate-client
さらに、.envファイルをルートディレクトリに作成し、関連する環境変数を定義します。OpenAI APIキーを取得するには、OpenAIアカウントが必要であり、その後「APIキー」の下の「新しいシークレットキーを作成」をクリックしてください。
OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"
次に、次のコマンドを実行して関連する環境変数をロードします。
import dotenvdotenv.load_dotenv()
準備
準備の段階として、すべての追加情報を保持する外部の知識源としてのベクトルデータベースを準備する必要があります。このベクトルデータベースは以下の手順に従って作成されます:
- データを収集して読み込む
- ドキュメントをチャンクに分割する
- チャンクを埋め込み、保存する
最初のステップは、データの収集と読み込みです。この例では、2022年のバイデン大統領の国勢調査演説を追加の文脈として使用します。生のテキストドキュメントは、LangChainのGitHubリポジトリで利用可能です。データを読み込むには、LangChainの多くの組み込みDocumentLoader
のいずれかを使用できます。 Document
は、テキストとメタデータを持つ辞書です。テキストを読み込むには、LangChainのTextLoader
を使用します。
import requestsfrom langchain.document_loaders import TextLoaderurl = "https://raw.githubusercontent.com/langchain-ai/langchain/master/docs/docs/modules/state_of_the_union.txt"res = requests.get(url)with open("state_of_the_union.txt", "w") as f: f.write(res.text)loader = TextLoader('./state_of_the_union.txt')documents = loader.load()
次に、ドキュメントをチャンクに分割します。元の状態のDocument
は、LLMのコンテキストウィンドウに収まりきらないほど長いため、小さなピースに分割する必要があります。LangChainには、この目的のための多くの組み込みのテキストスプリッターが付属しています。この単純な例では、CharacterTextSplitter
を使用し、chunk_size
を約500、chunk_overlap
を50に設定してテキストの継続性を確保します。
from langchain.text_splitter import CharacterTextSplittertext_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=50)chunks = text_splitter.split_documents(documents)
最後に、チャンクを埋め込んで保存します。テキストチャンク間の意味的な検索を可能にするために、各チャンクのベクトル埋め込みを生成し、それらと一緒に保存する必要があります。ベクトル埋め込みを生成するには、OpenAIの埋め込みモデルを使用し、保存にはWeaviateのベクトルデータベースを使用できます。 .from_documents()
を呼び出すことで、ベクトルデータベースは自動的にチャンクで埋められます。
from langchain.embeddings import OpenAIEmbeddingsfrom langchain.vectorstores import Weaviateimport weaviatefrom weaviate.embedded import EmbeddedOptionsclient = weaviate.Client( embedded_options = EmbeddedOptions())vectorstore = Weaviate.from_documents( client = client, documents = chunks, embedding = OpenAIEmbeddings(), by_text = False)
ステップ1:検索
ベクトルデータベースが埋められたら、リトリーバコンポーネントとして定義できます。このコンポーネントは、ユーザーのクエリと埋め込まれたチャンクの意味的な類似性に基づいて追加の文脈を取得します。
retriever = vectorstore.as_retriever()
ステップ2:増強
次に、追加の文脈でプロンプトを増強するために、プロンプトテンプレートを準備する必要があります。プロンプトは、以下に示すように、プロンプトテンプレートから簡単にカスタマイズできます。
from langchain.prompts import ChatPromptTemplatetemplate = """質問応答タスクのためのアシスタントです。以下の取得した文脈の断片を使用して質問に答えてください。答えがわからない場合は、わからないと答えてください。最大3文のみ使用し、回答を簡潔にしてください。質問:{question} 文脈:{context} 回答:"""prompt = ChatPromptTemplate.from_template(template)print(prompt)
ステップ3:生成
最後に、RAGパイプライン用のチェーンを構築し、リトリーバ、プロンプトテンプレート、LLMを連結します。RAGチェーンが定義されたら、それを呼び出すことができます。
from langchain.chat_models import ChatOpenAIfrom langchain.schema.runnable import RunnablePassthroughfrom langchain.schema.output_parser import StrOutputParserllm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)rag_chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() )query = "大統領はブレイヤー判事について何と言ったか"rag_chain.invoke(query)
"大統領はブレイヤー判事への奉仕に感謝し、彼の国への奉仕への貢献を認めました。大統領はまた、ジャッジケタンジブラウンジャクソンを後任に指名したことも言及し、ブレイヤー判事の優れた遺産を引き継ぐための後継者としています。"
この具体的な例に対するRAGパイプラインの結果は、以下のように示されています:
概要
この記事では、2020年の論文「知識集約型NLPタスクのための情報検索駆動型生成(Retrieval-Augmented Generation)」[1]で提示されたRAGの概念について説明しました。概念の背後にある理論や動機、問題解決の手法に触れた後、この記事ではPythonでの実装を紹介しました。具体的には、この記事では、OpenAIのLLMとWeaviate
ベクターデータベース、OpenAIの埋め込みモデルを組み合わせてRAGパイプラインを実装しました。LangChainをオーケストレーションに使用しました。
この記事が役に立ちましたか?
新しい記事を公開した際に通知を受け取るには、無料で登録してください。
Leonie Monigattiさんの新しい記事が公開されたらメールを受け取る
Leonie Monigattiさんの新しい記事が公開されたらメールを受け取るには、サインアップしてVoAGIアカウントを作成してください(まだアカウントをお持ちでない場合)…
VoAGI.com
LinkedIn、Twitter、Kaggleでフォローしてください!
免責事項
私はこの記事執筆時点でWeaviateのデベロッパーアドボケイトです。この記事に加えて、同じ例をLangChainドキュメンテーションのWeaviateノートブックに追加しました。または、rag-weaviate
LangChainのテンプレートに従って開始することもできます。
参考文献
文献
[1] Lewis, P., et al. (2020). Retrieval-augmented generation for knowledge-intensive NLP tasks. Advances in Neural Information Processing Systems, 33, 9459–9474.
画像
特に明記されていない限り、すべての画像は著者によって作成されました。
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