From a14eeb56dd310e80c81a7940573461177380436c Mon Sep 17 00:00:00 2001
From: Appointat
Date: Fri, 29 Nov 2024 20:51:58 +0800
Subject: [PATCH] feat(GraphRAG): Support concurrent community summarization
(#2160)
---
.env.template | 1 +
dbgpt/rag/transformer/graph_extractor.py | 19 +-
.../community/community_store.py | 33 +-
.../community/tugraph_store_adapter.py | 44 +-
.../knowledge_graph/community_summary.py | 20 +-
.../cookbook/rag/graph_rag_app_develop.md | 27 +-
.../graph_rag/doc_structure_graph_demo.png | Bin 0 -> 1350950 bytes
examples/test_files/dbgpt.md | 185 ---
.../{osgraph.md => graphrag-test.md} | 1395 +++++++++++++----
examples/test_files/tugraph.md | 286 ----
10 files changed, 1226 insertions(+), 784 deletions(-)
create mode 100644 docs/static/img/chat_knowledge/graph_rag/doc_structure_graph_demo.png
delete mode 100644 examples/test_files/dbgpt.md
rename examples/test_files/{osgraph.md => graphrag-test.md} (59%)
delete mode 100644 examples/test_files/tugraph.md
diff --git a/.env.template b/.env.template
index 8da450bf6..cb96c9dcb 100644
--- a/.env.template
+++ b/.env.template
@@ -168,6 +168,7 @@ DOCUMENT_GRAPH_ENABLED=True # enable the graph search for documents and chunks
KNOWLEDGE_GRAPH_CHUNK_SEARCH_TOP_SIZE=5 # the top size of knowledge graph search for chunks
KNOWLEDGE_GRAPH_EXTRACTION_BATCH_SIZE=20 # the batch size of triplet extraction from the text
+COMMUNITY_SUMMARY_BATCH_SIZE=20 # the batch size of parallel community summary process
### Chroma vector db config
#CHROMA_PERSIST_PATH=/root/DB-GPT/pilot/data
diff --git a/dbgpt/rag/transformer/graph_extractor.py b/dbgpt/rag/transformer/graph_extractor.py
index 7a02f74d1..c8b2794f0 100644
--- a/dbgpt/rag/transformer/graph_extractor.py
+++ b/dbgpt/rag/transformer/graph_extractor.py
@@ -73,7 +73,7 @@ class GraphExtractor(LLMExtractor):
texts: List[str],
batch_size: int = 1,
limit: Optional[int] = None,
- ) -> List[List[Graph]]:
+ ) -> Optional[List[List[Graph]]]:
"""Extract graphs from chunks in batches.
Returns list of graphs in same order as input texts (text <-> graphs).
@@ -86,11 +86,12 @@ class GraphExtractor(LLMExtractor):
# Pre-allocate results list to maintain order
graphs_list: List[List[Graph]] = [None] * len(texts)
- total_batches = (len(texts) + batch_size - 1) // batch_size
- for batch_idx in range(total_batches):
- start_idx = batch_idx * batch_size
- end_idx = min((batch_idx + 1) * batch_size, len(texts))
+ n_texts = len(texts)
+
+ for batch_idx in range(0, n_texts, batch_size):
+ start_idx = batch_idx
+ end_idx = min(start_idx + batch_size, n_texts)
batch_texts = texts[start_idx:end_idx]
# 2. Create tasks with their original indices
@@ -104,11 +105,17 @@ class GraphExtractor(LLMExtractor):
# 3. Process extraction in parallel while keeping track of indices
batch_results = await asyncio.gather(
- *(task for _, task in extraction_tasks)
+ *(task for _, task in extraction_tasks), return_exceptions=True
)
# 4. Place results in the correct positions
for (idx, _), graphs in zip(extraction_tasks, batch_results):
+ if isinstance(graphs, Exception):
+ raise RuntimeError(f"Failed to extract graph: {graphs}")
+ if not isinstance(graphs, list) or not all(
+ isinstance(g, Graph) for g in graphs
+ ):
+ raise RuntimeError(f"Invalid graph extraction result: {graphs}")
graphs_list[idx] = graphs
assert all(x is not None for x in graphs_list), "All positions should be filled"
diff --git a/dbgpt/storage/knowledge_graph/community/community_store.py b/dbgpt/storage/knowledge_graph/community/community_store.py
index 3a5eb2474..34a415c41 100644
--- a/dbgpt/storage/knowledge_graph/community/community_store.py
+++ b/dbgpt/storage/knowledge_graph/community/community_store.py
@@ -1,7 +1,8 @@
"""Define the CommunityStore class."""
+import asyncio
import logging
-from typing import List
+from typing import List, Optional
from dbgpt.rag.transformer.community_summarizer import CommunitySummarizer
from dbgpt.storage.knowledge_graph.community.base import Community, GraphStoreAdapter
@@ -27,28 +28,38 @@ class CommunityStore:
self._community_summarizer = community_summarizer
self._meta_store = BuiltinCommunityMetastore(vector_store)
- async def build_communities(self):
+ async def build_communities(self, batch_size: int = 1):
"""Discover communities."""
community_ids = await self._graph_store_adapter.discover_communities()
# summarize communities
communities = []
- for community_id in community_ids:
- community = await self._graph_store_adapter.get_community(community_id)
- graph = community.data.format()
- if not graph:
- break
+ n_communities = len(community_ids)
- community.summary = await self._community_summarizer.summarize(graph=graph)
- communities.append(community)
- logger.info(
- f"Summarize community {community_id}: " f"{community.summary[:50]}..."
+ for i in range(0, n_communities, batch_size):
+ batch_ids = community_ids[i : i + batch_size]
+ batch_results = await asyncio.gather(
+ *[self._summary_community(cid) for cid in batch_ids]
)
+ # filter out None returns
+ communities.extend([c for c in batch_results if c is not None])
# truncate then save new summaries
await self._meta_store.truncate()
await self._meta_store.save(communities)
+ async def _summary_community(self, community_id: str) -> Optional[Community]:
+ """Summarize single community."""
+ community = await self._graph_store_adapter.get_community(community_id)
+ if community is None or community.data is None:
+ logger.warning(f"Community {community_id} is empty")
+ return None
+
+ graph = community.data.format()
+ community.summary = await self._community_summarizer.summarize(graph=graph)
+ logger.info(f"Summarize community {community_id}: {community.summary[:50]}...")
+ return community
+
async def search_communities(self, query: str) -> List[Community]:
"""Search communities."""
return await self._meta_store.search(query)
diff --git a/dbgpt/storage/knowledge_graph/community/tugraph_store_adapter.py b/dbgpt/storage/knowledge_graph/community/tugraph_store_adapter.py
index fa107a28b..3a2d96ae5 100644
--- a/dbgpt/storage/knowledge_graph/community/tugraph_store_adapter.py
+++ b/dbgpt/storage/knowledge_graph/community/tugraph_store_adapter.py
@@ -356,7 +356,7 @@ class TuGraphStoreAdapter(GraphStoreAdapter):
return
# Create the graph schema
- def _format_graph_propertity_schema(
+ def _format_graph_property_schema(
name: str,
type: str = "STRING",
optional: bool = False,
@@ -390,9 +390,9 @@ class TuGraphStoreAdapter(GraphStoreAdapter):
# Create the graph label for document vertex
document_proerties: List[Dict[str, Union[str, bool]]] = [
- _format_graph_propertity_schema("id", "STRING", False),
- _format_graph_propertity_schema("name", "STRING", False),
- _format_graph_propertity_schema("_community_id", "STRING", True, True),
+ _format_graph_property_schema("id", "STRING", False),
+ _format_graph_property_schema("name", "STRING", False),
+ _format_graph_property_schema("_community_id", "STRING", True, True),
]
self.create_graph_label(
graph_elem_type=GraphElemType.DOCUMENT, graph_properties=document_proerties
@@ -400,10 +400,10 @@ class TuGraphStoreAdapter(GraphStoreAdapter):
# Create the graph label for chunk vertex
chunk_proerties: List[Dict[str, Union[str, bool]]] = [
- _format_graph_propertity_schema("id", "STRING", False),
- _format_graph_propertity_schema("name", "STRING", False),
- _format_graph_propertity_schema("_community_id", "STRING", True, True),
- _format_graph_propertity_schema("content", "STRING", True, True),
+ _format_graph_property_schema("id", "STRING", False),
+ _format_graph_property_schema("name", "STRING", False),
+ _format_graph_property_schema("_community_id", "STRING", True, True),
+ _format_graph_property_schema("content", "STRING", True, True),
]
self.create_graph_label(
graph_elem_type=GraphElemType.CHUNK, graph_properties=chunk_proerties
@@ -411,10 +411,10 @@ class TuGraphStoreAdapter(GraphStoreAdapter):
# Create the graph label for entity vertex
vertex_proerties: List[Dict[str, Union[str, bool]]] = [
- _format_graph_propertity_schema("id", "STRING", False),
- _format_graph_propertity_schema("name", "STRING", False),
- _format_graph_propertity_schema("_community_id", "STRING", True, True),
- _format_graph_propertity_schema("description", "STRING", True, True),
+ _format_graph_property_schema("id", "STRING", False),
+ _format_graph_property_schema("name", "STRING", False),
+ _format_graph_property_schema("_community_id", "STRING", True, True),
+ _format_graph_property_schema("description", "STRING", True, True),
]
self.create_graph_label(
graph_elem_type=GraphElemType.ENTITY, graph_properties=vertex_proerties
@@ -422,10 +422,10 @@ class TuGraphStoreAdapter(GraphStoreAdapter):
# Create the graph label for relation edge
edge_proerties: List[Dict[str, Union[str, bool]]] = [
- _format_graph_propertity_schema("id", "STRING", False),
- _format_graph_propertity_schema("name", "STRING", False),
- _format_graph_propertity_schema("_chunk_id", "STRING", True, True),
- _format_graph_propertity_schema("description", "STRING", True, True),
+ _format_graph_property_schema("id", "STRING", False),
+ _format_graph_property_schema("name", "STRING", False),
+ _format_graph_property_schema("_chunk_id", "STRING", True, True),
+ _format_graph_property_schema("description", "STRING", True, True),
]
self.create_graph_label(
graph_elem_type=GraphElemType.RELATION, graph_properties=edge_proerties
@@ -433,9 +433,9 @@ class TuGraphStoreAdapter(GraphStoreAdapter):
# Create the graph label for include edge
include_proerties: List[Dict[str, Union[str, bool]]] = [
- _format_graph_propertity_schema("id", "STRING", False),
- _format_graph_propertity_schema("name", "STRING", False),
- _format_graph_propertity_schema("description", "STRING", True),
+ _format_graph_property_schema("id", "STRING", False),
+ _format_graph_property_schema("name", "STRING", False),
+ _format_graph_property_schema("description", "STRING", True),
]
self.create_graph_label(
graph_elem_type=GraphElemType.INCLUDE, graph_properties=include_proerties
@@ -443,9 +443,9 @@ class TuGraphStoreAdapter(GraphStoreAdapter):
# Create the graph label for next edge
next_proerties: List[Dict[str, Union[str, bool]]] = [
- _format_graph_propertity_schema("id", "STRING", False),
- _format_graph_propertity_schema("name", "STRING", False),
- _format_graph_propertity_schema("description", "STRING", True),
+ _format_graph_property_schema("id", "STRING", False),
+ _format_graph_property_schema("name", "STRING", False),
+ _format_graph_property_schema("description", "STRING", True),
]
self.create_graph_label(
graph_elem_type=GraphElemType.NEXT, graph_properties=next_proerties
diff --git a/dbgpt/storage/knowledge_graph/community_summary.py b/dbgpt/storage/knowledge_graph/community_summary.py
index 62e3e4c13..1815c26be 100644
--- a/dbgpt/storage/knowledge_graph/community_summary.py
+++ b/dbgpt/storage/knowledge_graph/community_summary.py
@@ -38,8 +38,7 @@ class CommunitySummaryKnowledgeGraphConfig(BuiltinKnowledgeGraphConfig):
password: Optional[str] = Field(
default=None,
description=(
- "The password of vector store, "
- "if not set, will use the default password."
+ "The password of vector store, if not set, will use the default password."
),
)
extract_topk: int = Field(
@@ -75,6 +74,10 @@ class CommunitySummaryKnowledgeGraphConfig(BuiltinKnowledgeGraphConfig):
default=20,
description="Batch size of triplets extraction from the text",
)
+ community_summary_batch_size: int = Field(
+ default=20,
+ description="Batch size of parallel community building process",
+ )
class CommunitySummaryKnowledgeGraph(BuiltinKnowledgeGraph):
@@ -130,6 +133,12 @@ class CommunitySummaryKnowledgeGraph(BuiltinKnowledgeGraph):
config.knowledge_graph_extraction_batch_size,
)
)
+ self._community_summary_batch_size = int(
+ os.getenv(
+ "COMMUNITY_SUMMARY_BATCH_SIZE",
+ config.community_summary_batch_size,
+ )
+ )
def extractor_configure(name: str, cfg: VectorStoreConfig):
cfg.name = name
@@ -177,9 +186,12 @@ class CommunitySummaryKnowledgeGraph(BuiltinKnowledgeGraph):
async def aload_document(self, chunks: List[Chunk]) -> List[str]:
"""Extract and persist graph from the document file."""
+
await self._aload_document_graph(chunks)
await self._aload_triplet_graph(chunks)
- await self._community_store.build_communities()
+ await self._community_store.build_communities(
+ batch_size=self._community_summary_batch_size
+ )
return [chunk.chunk_id for chunk in chunks]
@@ -230,6 +242,8 @@ class CommunitySummaryKnowledgeGraph(BuiltinKnowledgeGraph):
[chunk.content for chunk in chunks],
batch_size=self._triplet_extraction_batch_size,
)
+ if not graphs_list:
+ raise ValueError("No graphs extracted from the chunks")
# Upsert the graphs into the graph store
for idx, graphs in enumerate(graphs_list):
diff --git a/docs/docs/cookbook/rag/graph_rag_app_develop.md b/docs/docs/cookbook/rag/graph_rag_app_develop.md
index 0cdca75d4..46c328bd5 100644
--- a/docs/docs/cookbook/rag/graph_rag_app_develop.md
+++ b/docs/docs/cookbook/rag/graph_rag_app_develop.md
@@ -117,6 +117,7 @@ TRIPLET_GRAPH_ENABLED=True # enable the graph search for the triplets
DOCUMENT_GRAPH_ENABLED=True # enable the graph search for documents and chunks
KNOWLEDGE_GRAPH_CHUNK_SEARCH_TOP_SIZE=5 # the number of the searched triplets in a retrieval
KNOWLEDGE_GRAPH_EXTRACTION_BATCH_SIZE=20 # the batch size of triplet extraction from the text
+COMMUNITY_SUMMARY_BATCH_SIZE=20 # the batch size of parallel community summary process
```
@@ -233,7 +234,8 @@ First, create a knowledge base using the `Knowledge Graph` type.
-Then, upload the documents ([tugraph.md](https://github.com/eosphoros-ai/DB-GPT/blob/main/examples/test_files/tugraph.md), [osgraph.md](https://github.com/eosphoros-ai/DB-GPT/blob/main/examples/test_files/osgraph.md), [dbgpt.md](https://github.com/eosphoros-ai/DB-GPT/blob/main/examples/test_files/dbgpt.md)) and process them automatically (markdown header by default).
+Then, upload the documents ([graphrag-test.md](https://github.com/eosphoros-ai/DB-GPT/blob/main/examples/test_files/graphrag-test.md)) and process them automatically (markdown header by default).
+
@@ -254,14 +256,15 @@ Performance testing is based on the `gpt-4o-mini` model.
#### Indexing Performance
-| | DB-GPT | GraphRAG(microsoft) |
-| ----------------- | --------------------- | -------------------- |
-| Document Tokens | 42631 | 42631 |
-| Graph Size | 808 nodes, 1170 edges | 779 nodes, 967 edges |
-| Prompt Tokens | 452614 | 744990 |
-| Completion Tokens | 48325 | 227230 |
-| Total Tokens | 500939 | 972220 |
-
+| | DB-GPT | GraphRAG(microsoft) |
+| ------------------- | --------------------- | -------------------- |
+| Doc Tokens | 42631 | 42631 |
+| Triplets Graph | 734 nodes, 1064 edges | 779 nodes, 967 edges |
+| Doc Structure Graph | 76 nodes, 1090 edges | N/A |
+| Prompt Tokens | 375768 | 744990 |
+| Completion Tokens | 41797 | 227230 |
+| Total Tokens | **417565** | 972220 |
+| Indexing Time | **170s** | 210s |
#### Querying Performance
@@ -371,6 +374,12 @@ Knowledge Graph = Triplets Graph + Document Structure Graph
+Thanks to the Document Structure Graph, GraphRAG now can provide references to the original text when answering:
+
+
+
+
+
How?
We decompose standard format files (currently best support for Markdown files) into a directed graph based on their hierarchy and layout information, and store it in a graph database. In this graph:
diff --git a/docs/static/img/chat_knowledge/graph_rag/doc_structure_graph_demo.png b/docs/static/img/chat_knowledge/graph_rag/doc_structure_graph_demo.png
new file mode 100644
index 0000000000000000000000000000000000000000..f3ab4b7931cb0230dcb09557ca9aa145d224b835
GIT binary patch
literal 1350950
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 jR9bI3D$aesHuzwOWf{FRQA?)E-U
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