paint-brush
600 万の Wikipedia ページで RAG のナレッジ グラフを構築して 7 万ドルを節約する方法@datastax
816 測定値
816 測定値

600 万の Wikipedia ページで RAG のナレッジ グラフを構築して 7 万ドルを節約する方法

DataStax4m2024/10/15
Read on Terminal Reader

長すぎる; 読むには

私たちは、コンテンツ中心のナレッジ グラフ (チャンク間のリンクを可能にするベクトル ストア) は、RAG の結果を改善するための、より使いやすく効率的なアプローチであると主張してきました。ここでは、それをテストします。
featured image - 600 万の Wikipedia ページで RAG のナレッジ グラフを構築して 7 万ドルを節約する方法
DataStax HackerNoon profile picture
0-item



ナレッジ グラフを使用して検索拡張生成 (RAG) アプリケーションの結果を改善することは、ホットな話題になっています。ほとんどの例では、比較的少数のドキュメントを使用してナレッジ グラフを構築する方法を示しています。これは、一般的なアプローチ (きめ細かなエンティティ中心の情報の抽出) が拡張できないためである可能性があります。各ドキュメントをモデルに通してエンティティ (ノード) と関係 (エッジ) を抽出すると、大規模なデータセットで実行するには時間がかかりすぎます (コストもかかりすぎます)。


私たちはこう主張してきましたコンテンツ中心のナレッジグラフチャンク間のリンクを可能にするベクトルストアは、使いやすく効率的なアプローチです。ここでは、それをテストします。Wikipediaの記事のサブセットを読み込み、 2ウィキマルチホップ両方の手法を使用してデータセットをロードし、これがデータセット全体をロードする場合に何を意味するかを説明します。ロードしたデータに対するいくつかの質問の結果を示します。また、データセット全体(約600万のドキュメント)をコンテンツ中心のデータベースにロードします。 グラフベクターストア

エンティティ中心: LLMGraphTransformer

Neo4jのようなエンティティ中心のグラフストアにドキュメントをロードするには、LangChainのLLMGraphTransformerを使用しました。コードはLangChainの「ナレッジグラフを構築する方法」

 from langchain_core.documents import Document from langchain_experimental.graph_transformers import LLMGraphTransformer from langchain_openai import ChatOpenAI llm = ChatOpenAI(temperature=0, model_name="gpt-4-turbo") llm_transformer = LLMGraphTransformer(llm=llm) from time import perf_counter start = perf_counter() documents_to_load = [Document(page_content=line) for line in lines_to_load] graph_documents = llm_transformer.convert_to_graph_documents(documents_to_load) end = perf_counter() print(f"Loaded (but NOT written) {NUM_LINES_TO_LOAD} in {end - start:0.2f}s")

コンテンツ中心: GraphVectorStore

GraphVectorStore にデータをロードすることは、ベクター ストアにデータをロードすることとほぼ同じです。唯一の追加点は、各ページが他のページにどのようにリンクしているかを示すメタデータを計算することです。


 import json from langchain_core.graph_vectorstores.links import METADATA_LINKS_KEY, Link def parse_document(line: str) -> Document:    para = json.loads(line)    id = para["id"]    links = {        Link.outgoing(kind="href", tag=id)        for m in para["mentions"]        if m["ref_ids"] is not None        for id in m["ref_ids"]    }    links.add(Link.incoming(kind="href", tag=id))    return Document(        id = id,        page_content = " ".join(para["sentences"]),        metadata = {            "content_id": para["id"],            METADATA_LINKS_KEY: list(links)        },    )


これは、ノード間に独自のリンクを追加する方法の良い例でもあります。


 from langchain_openai import OpenAIEmbeddings from langchain_community.graph_vectorstores.cassandra import CassandraGraphVectorStore import cassio cassio.init(auto=True) TABLE_NAME = "wiki_load" store = CassandraGraphVectorStore( embedding = OpenAIEmbeddings(), node_table=TABLE_NAME, insert_timeout = 1000.0, ) from time import perf_counter start = perf_counter() from datasets.wikimultihop.load import parse_document kg_documents = [parse_document(line) for line in lines_to_load] store.add_documents(kg_documents) end = perf_counter() print(f"Loaded (and written) {NUM_LINES_TO_LOAD} in {end - start:0.2f}s")

ベンチマークの読み込み

100 行で実行すると、GPT-4o を使用したエンティティ中心のアプローチでは、GraphDocuments の抽出に 405.93 秒、Neo4j への書き込みに 10.99 秒かかりましたが、コンテンツ中心のアプローチでは 1.43 秒かかりました。推定すると、エンティティ中心のアプローチを使用して 5,989,847 ページすべてをロードするには 41 週間かかり、コンテンツ中心のアプローチを使用すると約 24 時間かかります。しかし、並列処理のおかげで、コンテンツ中心のアプローチはわずか 2.5 時間で実行されます。同じ並列処理の利点があると仮定すると、エンティティ中心のアプローチを使用してすべてをロードするには、依然として 4 週間以上かかります。すべてが最初からうまくいったと仮定すると、推定コストが 58,700 ドルになるため、試しませんでした。



結論: LLM を使用してコンテンツからナレッジ グラフを抽出するエンティティ中心のアプローチは、規模が大きくなると時間とコストの両方がかかりすぎます。一方、GraphVectorStore を使用すると、高速かつ低コストで済みます。

回答例

このセクションでは、読み込まれたドキュメントのサブセットから抽出されたいくつかの質問に対して、回答の品質を評価します。


エンティティ中心では、基本的に役に立たない回答を生成するために 7324 個のプロンプト トークンを使用し、コストは 0.03 ドルでした。一方、コンテンツ中心では、質問に直接答える簡潔な回答を生成するために 450 個のプロンプト トークンを使用し、コストは 0.002 ドルでした。


きめ細かい Neo4j グラフが役に立たない回答を返すのは驚くかもしれません。チェーンからのログを見ると、なぜこれが起こるのかがわかります。


 > Entering new GraphCypherQAChain chain... Generated Cypher: cypher MATCH (a:Album {id: 'The Circle'})-[:RELEASED_BY]->(r:Record_label) RETURN a.id, r.id Full Context: [{'a.id': 'The Circle', 'r.id': 'Restless'}] > Finished chain. {'query': "When was 'The Circle' released?", 'result': "I don't know the answer."}


つまり、きめ細かいスキーマはレコード レーベルに関する情報のみを返しました。取得した情報に基づいて LLM が質問に答えることができなかったのは当然です。

結論

きめ細かなエンティティ固有のナレッジ グラフを抽出するには、大規模な場合、時間とコストがかかりすぎます。ロードされたデータのサブセットについて質問すると、粒度が増すと (およびきめ細かなグラフをロードするための追加コスト)、プロンプトを含むトークンがさらに返されますが、役に立たない回答が生成されます。


GraphVectorStore は、粗粒度のコンテンツ中心のアプローチを採用しており、ナレッジ グラフを迅速かつ簡単に構築できます。LangChain を使用して VectorStore にデータを取り込む既存のコードから開始し、チャンク間にリンク (エッジ) を追加して、取得プロセスを改善できます。


Graph RAGは、生成AI RAGアプリケーションがより深く関連性の高いコンテキストを取得できるようにするための便利なツールです。しかし、きめ細かなエンティティ中心のアプローチでは、実稼働のニーズに応えられません。RAGアプリケーションにナレッジグラフ機能を追加したい場合は、 グラフベクターストア


ベン・チェンバース、DataStax