ホームページ  >  記事  >  テクノロジー周辺機器  >  FAISS ベクトル空間を視覚化し、RAG パラメータを調整して結果の精度を向上させます

FAISS ベクトル空間を視覚化し、RAG パラメータを調整して結果の精度を向上させます

PHPz
PHPz転載
2024-03-01 21:16:15563ブラウズ

オープンソースの大規模言語モデルのパフォーマンスが向上し続けるにつれて、コード、推奨事項、テキストの要約、質問と回答 (QA) のペアの作成と分析のパフォーマンスが大幅に向上しました。しかし、QA に関しては、LLM はトレーニングされていないデータに関連する問題に対応していないことが多く、多くの内部文書はコンプライアンス、企業秘密、またはプライバシーを確​​保するために社内に保管されています。これらの文書がクエリされると、LLM は幻覚を起こし、無関係なコンテンツ、捏造されたコンテンツ、または矛盾したコンテンツを生成する可能性があります。

FAISS ベクトル空間を視覚化し、RAG パラメータを調整して結果の精度を向上させます

#この課題に対処するために考えられる手法の 1 つは、検索拡張生成 (RAG) です。これには、生成の品質と精度を向上させるために、トレーニング データ ソースを超えた信頼できるナレッジ ベースを参照して応答を強化するプロセスが含まれます。 RAG システムは、コーパスから関連する文書フラグメントを取得する検索システムと、取得したフラグメントをコンテキストとして利用して応答を生成する LLM モデルで構成されます。したがって、コーパスの品質とベクトル空間に埋め込まれた表現は、RAG のパフォーマンスにとって非常に重要です。

この記事では、視覚化ライブラリ renumics-spotlight を使用して、FAISS ベクトル空間の多次元埋め込みを 2 次元で視覚化し、特定の主要なベクトル化パラメーターを変更することで改善を模索します。 RAG 応答精度の可能性。私たちが選択した LLM には、Llama 2 と同じアーキテクチャを持つコンパクトなモデルである TinyLlama 1.1B Chat を使用します。精度が比例して低下することなく、リソース フットプリントが小さくなり、実行時間が短縮されるという利点があり、迅速な実験に最適です。

システム設計

QA システムには、図に示すように 2 つのモジュールがあります。

FAISS ベクトル空間を視覚化し、RAG パラメータを調整して結果の精度を向上させます

LoadFVectorize モジュールは、PDF または Web ドキュメントをロードし、予備テストと視覚化を実行するために使用されます。別のモジュールは、LLM のロードと FAISS サーチャーのインスタンス化を担当し、LLM、サーチャー、カスタム クエリ プロンプトを含む検索チェーンを構築します。最後に、ベクトル空間を視覚化します。

コードの実装

1. 必要なライブラリをインストールします

renomics-spotlight ライブラリも同様のものを採用していますUmap の視覚化手法は、主要な属性を維持しながら、高次元の埋め込みを管理可能な 2D 視覚化に削減します。以前に umap の使い方を簡単に紹介しましたが、基本的な機能のみでした。今回はシステム設計の一環として実際のプロジェクトに組み込みました。まず、必要なライブラリをインストールする必要があります。

pip install langchain faiss-cpu sentence-transformers flask-sqlalchemy psutil unstructured pdf2image unstructured_inference pillow_heif opencv-python pikepdf pypdf pip install renumics-spotlight CMAKE_ARGS="-DLLAMA_METAL=on" FORCE_CMAKE=1 pip install --upgrade --force-reinstall llama-cpp-python --no-cache-dir

上の最後の行は、Metal サポートを備えた llama-pcp-python ライブラリをインストールすることであり、これは llama-pcp-python ライブラリをロードするために使用されます。 M1 プロセッサーでの Metal サポートにより、ハードウェアでアクセラレートされた TinyLlama。

2. LoadFVectorize モジュール

このモジュールには 3 つの関数が含まれています:

load_doc はオンライン PDF を処理します文書が読み込まれ、各ブロックが 512 文字に分割され、100 文字ずつ重ねられて文書リストが返されます。

vectorize は、上記の関数load_doc を呼び出してドキュメントのブロック リストを取得し、埋め込みを作成してローカル ディレクトリ opdf_index に保存し、FAISS インスタンスを返します。

load_db は、FAISS ライブラリがディスク上のディレクトリ opdf_index にあるかどうかを確認し、ロードを試み、最終的に FAISS オブジェクトを返します。

#このモジュール コードの完全なコードは次のとおりです:

# LoadFVectorize.py  from langchain_community.embeddings import HuggingFaceEmbeddings from langchain_community.document_loaders import OnlinePDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.vectorstores import FAISS  # access an online pdf def load_doc() -> 'List[Document]':loader = OnlinePDFLoader("https://support.riverbed.com/bin/support/download?did=7q6behe7hotvnpqd9a03h1dji&versinotallow=9.15.0")documents = loader.load()text_splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=100)docs = text_splitter.split_documents(documents)return docs  # vectorize and commit to disk def vectorize(embeddings_model) -> 'FAISS':docs = load_doc()db = FAISS.from_documents(docs, embeddings_model)db.save_local("./opdf_index")return db  # attempts to load vectorstore from disk def load_db() -> 'FAISS':embeddings_model = HuggingFaceEmbeddings()try:db = FAISS.load_local("./opdf_index", embeddings_model)except Exception as e:print(f'Exception: {e}\nNo index on disk, creating new...')db = vectorize(embeddings_model)return db

3. メイン モジュール

メイン モジュールは、最初に次のテンプレートの TinyLlama プロンプト テンプレートを定義します。

{context}{question}

また、TheBloke の TinyLlama の量子化バージョンを使用します。メモリを大幅に削減するために、量子化 LLM を GGUF 形式でロードすることを選択します。

次に、LoadFVectorize モジュールから返された FAISS オブジェクトを使用して FAISS リトリーバーを作成し、RetrievalQA をインスタンス化し、それをクエリに使用します。

# main.py from langchain.chains import RetrievalQA from langchain.prompts import PromptTemplate from langchain_community.llms import LlamaCpp from langchain_community.embeddings import HuggingFaceEmbeddings import LoadFVectorize from renumics import spotlight import pandas as pd import numpy as np  # Prompt template  qa_template = """ You are a friendly chatbot who always responds in a precise manner. If answer is  unknown to you, you will politely say so. Use the following context to answer the question below: {context}  {question}  """  # Create a prompt instance  QA_PROMPT = PromptTemplate.from_template(qa_template) # load LLM llm = LlamaCpp(model_path="./models/tinyllama_gguf/tinyllama-1.1b-chat-v1.0.Q5_K_M.gguf",temperature=0.01,max_tokens=2000,top_p=1,verbose=False,n_ctx=2048 ) # vectorize and create a retriever db = LoadFVectorize.load_db() faiss_retriever = db.as_retriever(search_type="mmr", search_kwargs={'fetch_k': 3}, max_tokens_limit=1000) # Define a QA chain  qa_chain = RetrievalQA.from_chain_type(llm,retriever=faiss_retriever,chain_type_kwargs={"prompt": QA_PROMPT} )  query = 'What versions of TLS supported by Client Accelerator 6.3.0?'  result = qa_chain({"query": query}) print(f'--------------\nQ: {query}\nA: {result["result"]}')  visualize_distance(db,query,result["result"])

ベクトル空間の視覚化自体は、上記のコードの Visualize_ distance の最後の行で処理されます:

visualize_ distance access FAISS オブジェクトの属性 __dict__、index_to_docstore_id 自体は値 docstore-ids のキー インデックス ディクショナリであり、ベクトル化に使用されるドキュメントの総数はインデックス オブジェクトの属性 ntotal で表されます。 #

vs = db.__dict__.get("docstore")index_list = db.__dict__.get("index_to_docstore_id").values()doc_cnt = db.index.ntotal
#オブジェクト インデックスのメソッド再構築_n を呼び出すと、ベクトル空間の近似的な再構築が実現できます

#

embeddings_vec = db.index.reconstruct_n()
docstore-id リストをindex_list として使用すると、関連するドキュメント オブジェクトを検索し、それを使用して、docstore-id、ドキュメント メタデータ、ドキュメント コンテンツ、およびすべての ID のベクトル空間への埋め込みを含むリストを作成できます。 :

doc_list = list() for i,doc-id in enumerate(index_list):a_doc = vs.search(doc-id)doc_list.append([doc-id,a_doc.metadata.get("source"),a_doc.page_content,embeddings_vec[i]])
次に、リストを使用して列ヘッダーを含む DF を作成します。最後に、この DF を視覚化に使用します

df = pd.DataFrame(doc_list,columns=['id','metadata','document','embedding'])

在继续进行可视化之前,还需要将问题和答案结合起来,我们创建一个单独的问题以及答案的DF,然后与上面的df进行合并,这样能够显示问题和答案出现的地方,在可视化时我们可以高亮显示:

# add rows for question and answerembeddings_model = HuggingFaceEmbeddings()question_df = pd.DataFrame({"id": "question","question": question,"embedding": [embeddings_model.embed_query(question)],})answer_df = pd.DataFrame({"id": "answer","answer": answer,"embedding": [embeddings_model.embed_query(answer)],})df = pd.concat([question_df, answer_df, df])

这里使用使用np.linalg.norm在文件和问题嵌入上的进行距离大小的计算:

question_embedding = embeddings_model.embed_query(question)# add column for vector distancedf["dist"] = df.apply( lambda row: np.linalg.norm(np.array(row["embedding"]) - question_embedding),axis=1,)

因为spotlight可以对df进行可视化,所有我们直接调用即可

spotlight.show(df)

このステップでは、ブラウザ ウィンドウで Spotlight が起動します。

テストを実行します

1. 基本テスト

以下はサンプル質問です。選択済み:

Client Accelerator 6.3.0 でサポートされている TLS のバージョンは何ですか?

正解は:

Client Accelerator 6.3.0 は TLS 1.1 または 1.2 をサポートします。

次の追加情報が応答に含まれる場合があります。 。

クライアント アクセラレータで次の CLI コマンドを使用して、この機能を有効にする必要があります:(config) #policy id ssl backend client-tls-1.2Evenこのコマンドの構文では TLS 1.1 については言及されていませんが、このコマンドを使用すると、TLS 1.1 と 1.2 の両方のサポートが自動的に有効になります。

次に、次に対する TinyLlama の応答を見てみましょう。上記の問題 回答:

Client Accelerator 6.3.0 は、Client Accelerator でサポートされるデフォルトの TLS バージョンとして TLS 1.1 または 1.2 をサポートします。次の CLI コマンドを使用してこの機能を有効にする必要があります。クライアント アクセラレータ:```(config) # ポリシー ID ssl backend client -tlss1.2```このコマンドは TLS 1.1 または TLS 1.2 にのみ適用されることに注意してください。古いバージョンをサポートする必要がある場合は、 TLS バージョンでは、代わりに client-tlss1.0 または client-tlss1.1 オプション を指定して ssl バックエンド コマンドを使用できます。

は実際の答えと非常に似ています。 、ただし、これらの TLS バージョンはデフォルトではないため、完全に正しいわけではありません。

それでは、彼が答えを見つけた文章を見てみましょう。

FAISS ベクトル空間を視覚化し、RAG パラメータを調整して結果の精度を向上させます

#スポットライトに表示されているボタンを使用して、表示される列を制御します。テーブルを「dist」で並べ替えて、質問、回答、および最も関連性の高いドキュメントのスニペットを上部に表示します。ドキュメントの埋め込みを見ると、ドキュメントのほぼすべてのチャンクが単一のクラスターとして記述されています。これは合理的です。なぜなら、当社のオリジナルの PDF は特定の製品の導入ガイドであるため、クラスターとみなされても問題ありません。

[類似性マップ] タブのフィルター アイコンをクリックすると、密にクラスター化された選択したドキュメント リストのみが強調表示され、以下に示すように残りはグレー表示になります。

FAISS ベクトル空間を視覚化し、RAG パラメータを調整して結果の精度を向上させます

2. ブロック サイズとオーバーラップ パラメーターのテスト

取得者は RAG に影響を与える鍵であるため、パフォーマンス要因、埋め込み空間に影響を与えるいくつかのパラメーターを見てみましょう。 TextSplitter のチャンク サイズ (1000、2000) および/またはオーバーラップ (100、200) パラメーターは、ドキュメントの分割中に異なります。

FAISS ベクトル空間を視覚化し、RAG パラメータを調整して結果の精度を向上させます

#出力はすべての組み合わせで同様に見えますが、正しい答えと各答えを注意深く比較すると、正確な答えは (1000,200) になります。 。他の回答における不正確な詳細は赤色で強調表示されています。視覚的な埋め込みを使用してこの動作を説明してみましょう:

FAISS ベクトル空間を視覚化し、RAG パラメータを調整して結果の精度を向上させます

左から右に見ると、ブロック サイズが増加するにつれて、ベクトル空間は次のようになります。スパースであり、ブロックは小さくなります。下から上に向かって、ベクトル空間の特性に大きな変化はなく、オーバーラップが徐々に増加します。これらすべてのマッピングでは、セット全体が多かれ少なかれ単一のクラスターとして見えますが、外れ値はわずかしか存在しません。生成された応答はすべて非常に似ているため、これは生成された応答で確認できます。

如果查询位于簇中心等位置时由于最近邻可能不同,在这些参数发生变化时响应很可能会发生显著变化。如果RAG应用程序无法提供预期答案给某些问题,则可以通过生成类似上述可视化图表并结合这些问题进行分析,可能找到最佳划分语料库以提高整体性能方面优化方法。

为了进一步说明,我们将两个来自不相关领域(Grammy Awards和JWST telescope)的维基百科文档的向量空间进行可视化展示。

def load_doc():loader = WebBaseLoader(['https://en.wikipedia.org/wiki/66th_Annual_Grammy_Awards','https://en.wikipedia.org/wiki/James_Webb_Space_Telescope'])documents = loader.load()...

只修改了上面代码其余的代码保持不变。运行修改后的代码,我们得到下图所示的向量空间可视化。

FAISS ベクトル空間を視覚化し、RAG パラメータを調整して結果の精度を向上させます

这里有两个不同的不重叠的簇。如果我们要在任何一个簇之外提出一个问题,那么从检索器获得上下文不仅不会对LLM有帮助,而且还很可能是有害的。提出之前提出的同样的问题,看看我们LLM产生什么样的“幻觉”

Client Accelerator 6.3.0 supports the following versions of Transport Layer Security (TLS):

  1. TLS 1.2\2. TLS 1.3\3. TLS 1.2 with Extended Validation (EV) certificates\4. TLS 1.3 with EV certificates\5. TLS 1.3 with SHA-256 and SHA-384 hash algorithms

这里我们使用FAISS用于向量存储。如果你正在使用ChromaDB并想知道如何执行类似的可视化,renumics-spotlight也是支持的。

总结

检索增强生成(RAG)允许我们利用大型语言模型的能力,即使LLM没有对内部文档进行训练也能得到很好的结果。RAG涉及从矢量库中检索许多相关文档块,然后LLM将其用作生成的上下文。因此嵌入的质量将在RAG性能中发挥重要作用。

在本文中,我们演示并可视化了几个关键矢量化参数对LLM整体性能的影响。并使用renumics-spotlight,展示了如何表示整个FAISS向量空间,然后将嵌入可视化。Spotlight直观的用户界面可以帮助我们根据问题探索向量空间,从而更好地理解LLM的反应。通过调整某些矢量化参数,我们能够影响其生成行为以提高精度。

以上がFAISS ベクトル空間を視覚化し、RAG パラメータを調整して結果の精度を向上させますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事は51cto.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。