If you have great ideas,
Let's talk!

blog

llamaindex Implementation of GraphRAG[1-工具选择]

llm相关export

以下文字从https://docs.llamaindex.ai/en/stable/examples/cookbooks/GraphRAG_v1/中粘贴性总结 总结性粘贴

后续还会更新

Approximate implementation of GraphRAG

两步:

  1. Graph Generation - Creates Graph, builds communities and its summaries over the given document.

    1. Source Documents to Text Chunks: Source documents are divided into smaller text chunks for easier processing. —> SentenceSplitter with a chunk size of 1024 and chunk overlap of 20 tokens

    2. Text Chunks to Element Instances: Each text chunk is analyzed to identify and extract entities and relationships, resulting in a list of tuples that represent these elements.( 建立triples) (how local? 这里看了一眼 用的是openai 正在找用本地ollma 方式 )

    3. Element Instances to Element Summaries: The extracted entities and relationships are summarized into descriptive text blocks for each element using the LLM. —> GraphRAGExtractor

    4. Element Summaries to Graph Communities: These entities, relationships and summaries form a graph, which is subsequently partitioned into communities using algorithms using Heirarchical Leiden(关系网上关系检测 ,社区聚类,递归收敛 类似k-means ) to establish a hierarchical structure.

    5. Graph Communities to Community Summaries: The LLM generates summaries for each community, providing insights into the dataset’s overall topical structure and semantics.

      —> GraphRAGStore

  2. Answer to the Query - Use summaries of the communities created from step-1 to answer the query.

    Community Summaries to Global Answers: The summaries of the communities are utilized to respond to user queries. This involves generating intermediate answers, which are then consolidated into a comprehensive global answer. —> GraphQueryEngine

以下流程先假设有openai api

  1. load csv [’title’ ‘date’ ‘text’] —>
documents = [
llama_index.core.Document(text=f"{row['title']}: {row['text']}")
for i, row in news.iterrows()
]
  1. Extraction Process:

For each input node (chunk of text):

  1. It sends the text to the LLM along with the extraction prompt.
  2. The LLM’s response is parsed to extract entities, relationships, descriptions for entities and relations.
  3. Entities are converted into EntityNode objects. Entity description is stored in metadata(暂时还未implement 现在只有Relationship description)
  4. Relationships are converted into Relation objects. Relationship description is stored in metadata.
  5. These are added to the node’s metadata under KG_NODES_KEY and KG_RELATIONS_KEY.
from llama_index.core.schema import TransformComponent, BaseNode
class GraphRAGExtractor(TransformComponent):
    """Extract triples from a graph.

    Uses an LLM and a simple prompt + output parsing to extract paths (i.e. triples) and entity, relation descriptions from text.

    Args:
        llm (LLM):
            The language model to use.
        extract_prompt (Union[str, PromptTemplate]):
            The prompt to use for extracting triples.
        parse_fn (callable):
            A function to parse the output of the language model.
        num_workers (int):
            The number of workers to use for parallel processing.
        max_paths_per_chunk (int):
            The maximum number of paths to extract per chunk.
    """

    llm: LLM
    extract_prompt: PromptTemplate
    parse_fn: Callable
    num_workers: int
    max_paths_per_chunk: int

def __init__(
        self,
        llm: Optional[LLM]=None,
        extract_prompt: Optional[Union[str, PromptTemplate]]=None,
        parse_fn: Callable= default_parse_triplets_fn,
        max_paths_per_chunk: int= 10,
        num_workers: int= 4,
    )->None:
        """Init params."""
from llama_index.coreimport Settings

if isinstance(extract_prompt, str):
            extract_prompt= PromptTemplate(extract_prompt)
				
				#TransformComponent
        super().__init__( 
            llm=llm or Settings.llm,
            extract_prompt=extract_prompt or DEFAULT_KG_TRIPLET_EXTRACT_PROMPT,
            parse_fn=parse_fn,
            num_workers=num_workers,
            max_paths_per_chunk=max_paths_per_chunk,
        )

    @classmethod
def class_name(cls)-> str:
return "GraphExtractor"

def __call__(
        self, nodes: List[BaseNode], show_progress: bool=False,**kwargs: Any
    )-> List[BaseNode]:
        """Extract triples from nodes."""
return asyncio.run(
            self.acall(nodes, show_progress=show_progress,**kwargs)
        )

asyncdef _aextract(self, node: BaseNode)-> BaseNode:
        """Extract triples from a node."""  
assert hasattr(node, "text")

        text= node.get_content(metadata_mode="llm")
try:
            llm_response=await self.llm.apredict(
                self.extract_prompt,
                text=text,
                max_knowledge_triplets=self.max_paths_per_chunk,
            )
            entities, entities_relationship= self.parse_fn(llm_response)
except ValueError:
            entities= []
            entities_relationship= []

        existing_nodes= node.metadata.pop(KG_NODES_KEY, [])
        existing_relations= node.metadata.pop(KG_RELATIONS_KEY, [])
        metadata= node.metadata.copy()
for entity, entity_type, descriptionin entities:
            metadata[
                "entity_description"
            ]= description# Not used in the current implementation. But will be useful in future work.
            entity_node= EntityNode(
                name=entity, label=entity_type, properties=metadata
            )
            existing_nodes.append(entity_node)

        metadata= node.metadata.copy()
for triplein entities_relationship:
            subj, rel, obj, description= triple
            subj_node= EntityNode(name=subj, properties=metadata)
            obj_node= EntityNode(name=obj, properties=metadata)
            metadata["relationship_description"]= description
            rel_node= Relation(
                label=rel,
                source_id=subj_node.id,
                target_id=obj_node.id,
                properties=metadata,
            )

            existing_nodes.extend([subj_node, obj_node])
            existing_relations.append(rel_node)

        node.metadata[KG_NODES_KEY]= existing_nodes
        node.metadata[KG_RELATIONS_KEY]= existing_relations
return node

asyncdef acall(
        self, nodes: List[BaseNode], show_progress: bool=False,**kwargs: Any
    )-> List[BaseNode]:
        """Extract triples from nodes async."""
        jobs= []
for nodein nodes:
            jobs.append(self._aextract(node))

returnawait run_jobs(
            jobs,
            workers=self.num_workers,
            show_progress=show_progress,
            desc="Extracting paths from text",
        )

后续还有完整的实现… 这里就不放了 原网页上有

OK 没有openai api的话 那么现在开始看一下 Triplex + R2R + neo4j + llamaindex??

https://www.sciphi.ai/blog/triplex → 模型介绍

https://ollama.com/sciphi/triplex → ollama

“A high quality dedicated model for triples extraction is a significant step towards making it possible to build a knowledge graph locally - as I have personally seen that right now even frontier models struggle with the task of triples extraction.” — https://www.reddit.com/r/LocalLLaMA/comments/1e77yqy/build_a_knowledge_graph_from_your_laptop/

image.png

image.png

The triple extraction model achieves results comparable to GPT-4, but at a fraction of the cost. This significant cost reduction is made possible by Triplex’s smaller model size and its ability to operate without the need for few-shot context.

Building upon the SFT model, we generated additional preference-based dataset using majority voting and topological sorting to further train Triplex using DPO and KTO. These additional training steps yielded substantial improvements in model performance.

leverages proprietary datasets generated from authoritative sources such as DBPedia and Wikidata, as well as web-based text sources and synthetically generated datasets

image.png

https://neo4j.com/labs/genai-ecosystem/llamaindex/

image.png

OK那么先从R2R开始看起 https://github.com/SciPhi-AI/R2R?tab=readme-ov-file

这个支持的太全面了呀 甚至前端dashboard都有

https://mychen76.medium.com/automatic-knowledge-rag-with-r2r-0e9841714d5b

https://freedium.cfd/https://mychen76.medium.com/automatic-knowledge-rag-with-r2r-0e9841714d5b

分享首歌

https://www.bilibili.com/video/BV1Rs4y1A7xJ/?spm_id_from=333.337.search-card.all.click&vd_source=143a2ef0cd4b513f15da9430a5ab01fc

Well I do