10,000 ワードの詳細な説明。RAG+LangChain を使用して chatpdf を実装します。

chatgpt のような大規模言語モデル (LLM) は、さまざまな種類の質問に答えることができますが、LLM のみに依存すると、学習されたコンテンツのみが認識され、個人データ (社内でインターネットに接続されていない企業文書など) は認識されません。会社、または LLM トレーニング完了後に新しく生成されたデータ。 (最新の GPT-4 Turbo であっても、トレーニング データ セットは 2023 年 4 月までしか更新されません) したがって、独自のドキュメントと対話できるチャットボットを開発し、LLM がドキュメントの情報に基づいて質問に回答できるようにすると、非常に便利になります。意味のあること。

今回はLangChainを利用して、RAGの原理に基づいたPDF文書との対話を実装してみます。

今回使用したドキュメントは、次の docs ディレクトリにあります:https://github.com/fireshort/langchain-chat-with-your-data 今回は、Andrew Ng 教授の CS229 (スタンフォード大学の機械学習コース) の PDF を例に取り上げます。

RAGとは何ですか?

RAG は Retrieval-augmented Generation の略称で、検索と生成の機能を組み合わせ、追加の外部知識 (通常はプライベート データまたはリアルタイム データ) をテキスト シーケンス生成タスクに導入します。つまり、外部情報を使用して LLM の知識を強化します。 。 RAG は、従来の言語生成モデルと大規模な外部知識ベースを組み合わせて、応答またはテキストを生成するときにモデルがこれらの知識ベースから関連情報を動的に取得できるようにします。この組み合わせアプローチは、モデルの生成機能を強化するように設計されており、特に特定の詳細や外部の事実の裏付けが必要な場合に、より豊富で正確な証拠に基づいたコンテンツを生成できるようになります。

RAG は通常、次のステップに分かれています。

検索: 特定の入力 (質問) に対して、モデルはまず検索システムを使用して、大規模な文書コレクションから関連する文書または文章を見つけます。この検索システムは通常、高密度ベクトル検索に基づいています。

コンテキストエンコーディング: 関連する文書または段落を見つけた後、モデルはそれらを元の入力 (質問) とともにプロンプ​​トに挿入します。

生成: エンコードされたコンテキスト情報を使用して、モデルは出力 (回答) を生成します。これは通常、大きなモデルで行われます。

ここに画像の説明を挿入します

RAGの原理

LangChainを使用して実装

RAG はまだ比較的抽象的なように思えますが、次に LangChain を使用して実装します。これは次の 5 つのステップに分けることができます。

ここに画像の説明を挿入します

  1. ドキュメントの読み込み: ドキュメント ローダーは、LangChain が読み取れる形式にドキュメントを読み込みます。
  2. 分割: テキスト スプリッターは、ドキュメントを、一般に「ドキュメント ブロック」または「ドキュメント片」と呼ばれる、意味的に意味のある指定サイズのチャンクに分割します。
  3. 保存:前ステップで分割した「文書ブロック」を「埋め込み」の形でベクトルデータベース(Vector DB)に格納し、「埋め込みスライス」を一つずつ形成します。
  4. 取得: アプリケーションは、セグメント化されたドキュメントをストレージから取得します (たとえば、コサイン類似度を比較して、入力された質問に類似した埋め込みを見つけることによって)。
  5. 出力: 質問と同様のドキュメント チャンクを言語モデル (LLM) に渡し、質問と取得したドキュメント チャンクを含むヒントを使用して回答を生成します。

openai ライブラリの最新バージョンは現在の LangChain と互換性がないため、openai ライブラリのバージョン 0.28.1 をインストールする必要があることに注意してください。

!pip install openai==0.28.1

まず .env ファイルを使用して環境変数を初期化する必要があります。

.env ファイルを使用して環境変数と LangChain を初期化する方法に関する入門チュートリアルについては、コラム「LangChain に基づく LLM アプリケーション開発<」を読むことをお勧めします。 a i=2>": https://juejin.cn/column/7290751135904038953

from langchain.document_loaders import PyPDFLoader
from langchain.memory import ConversationBufferMemory
from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chat_models import AzureChatOpenAI
from langchain.chains import ConversationalRetrievalChain

# 用.env文件初始化环境变量
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())  # read local .env file

ドキュメントの読み込み

PDF ドキュメントと通信するアプリケーションを作成するには、まず PDF ドキュメントを LangChain が使用できる形式にロードする必要があります。 LangChain はこれを実現するドキュメント ローダーを提供します。 LangChain には 80 種類を超えるドキュメント ローダーがあります。

ドキュメント ローダーは、さまざまなソースからのデータ形式を標準化された形式に変換します。 page_content (ドキュメント コンテンツ) および関連するメタデータ (メタデータ、PDF の場合、ソースとページ番号を含む) を含むドキュメント クラス {'source': 'docs /cs229_lectures /MachineLearning-Lecture01.pdf', 'page': 0}); Notion などの他のドキュメント タイプの場合、ページ番号はありません)

最初に pypdf ライブラリをインストールする必要があります。! pip install pypdf

# 加载文档
pdffiles = [
    "docs/cs229_lectures/MachineLearning-Lecture01.pdf",
    "docs/cs229_lectures/MachineLearning-Lecture01.pdf",  # 故意重复以模拟杂乱数据
    "docs/cs229_lectures/MachineLearning-Lecture02.pdf",
    "docs/cs229_lectures/MachineLearning-Lecture03.pdf"
]
docs = []
for file_path in pdffiles:
    loader=PyPDFLoader(file_path)
    docs.extend(loader.load())

print(f"The number of docs:{len(docs)}")
# print(docs[0])

ここでは、重複データの処理方法を示すために、第 1 章の PDF を意図的に繰り返しロードしています。実際のプロジェクトでは、データをクリーンアップした後でも、データの重複を避けることが困難なことがよくあります。

文書の分割

ドキュメントはロードされていますが、これらのドキュメントはまだ非常に大きいため、埋め込みとベクトル ストレージのためにロードされたテキストを小さなチャンクに分割する必要があります。ドキュメントを取得するときは、最も関連性の高いコンテンツのみを取得すればよいため、このステップは重要です。巨大なドキュメント全体をロードする必要はありません。一般に、トピックに関連する段落または文を取得するだけで十分です。

この手順は簡単そうに見えますが、実際の実装では

おすすめ

転載: blog.csdn.net/fireshort/article/details/134646058