LlamaIndex:PDF文档的知识图谱构建之旅

866 阅读5分钟

在数字化时代,信息的海洋浩瀚无垠,而知识图谱则是导航这片海洋的灯塔。想象一下,如果我们能够将散布在PDF文档中的知识碎片,通过一种智能的方式,编织成一张张互联互通的网络,那将会怎样?这不仅是对信息的重新组织,更是对知识深度挖掘的一次革新。本文将带您走进一个由LlamaIndex驱动的奇妙世界,探索如何将静态的PDF文档转化为动态的知识图谱,让数据不仅仅是数据,而是能够讲述故事、揭示联系的活生生的实体。

介绍

检索增强生成(RAG)是向大语言模型(LLM)提供来自外部知识源(如 PDF 文档、CSV 文件等)的补充信息的概念。这使它们能够生成更准确和语境相关的响应。然而,RAG 在处理广泛的异构信息方面存在困难。RAG 利用向量数据库,根据它们的高维向量表示来衡量不同实体(如单词或短语)之间的相似性或相关性。它忽略了实体的结构和关系。例如,在向量表示中,“员工” 这个词可能与 “雇主” 更相关,而不是 “信息”,因为它在向量空间中更接近。

这可以通过引入知识图谱来管理,它是一种将数据组织为节点和边的数据结构,增强了检索信息的上下文性。知识图谱由主语-谓语-宾语三元组组成,其中主语/宾语由节点表示,谓语/关系由边表示。例如,在这个三元组中,“employer — submit — claim”,“submit” 是谓语,表示 “employer” 和 “claim” 之间的关系。通过三元组表示,知识图谱数据库可以使复杂数据搜索更准确和高效。

image.png

步骤

安装依赖

!pip install -q pypdf  
!pip install -q python-dotenv  
!pip install -q pyvis  
!pip install -q transformers einops accelerate langchain bitsandbytes sentence_transformers langchain-community langchain-core  
!pip install -q llama-index  
!pip install -q llama-index-llms-huggingface  
!pip install -q llama-index-embeddings-langchain  
!pip install -q llama-index-embeddings-huggingface

前置工作

开启日志

日志可以第一时间观察到运行情况。

import os, logging, sys  
  
logging.basicConfig(stream=sys.stdout, level=logging.INFO)  
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))

连接 Huggingface API

from huggingface_hub import login  
  
os.environ["HF_KEY"] = "Your Hugging Face access token goes here"  
login(token=os.environ.get('HF_KEY'),add_to_git_credential=True)

加载 PDF

from llama_index.core import SimpleDirectoryReader  
  
documents = SimpleDirectoryReader(input_dir="/content/", required_exts=".pdf").load_data()

构建知识图谱索引

使用 HuggingFace 创建本地嵌入

HuggingFaceEmbeddings 是 LangChain 库中的一个类,它为 Hugging Face 的句子转换模型提供了一个包装器,用于生成文本嵌入。它允许您使用 Hugging Face 上可用的任何句子嵌入模型来执行语义搜索、文档聚类和问答等任务。本练习中使用了 HF 句子转换模型 multi-qa-MiniLM-L6-cos-v1。

from llama_index.embeddings.huggingface import HuggingFaceEmbedding  
  
EMBEDDING_MODEL_NAME = "sentence-transformers/multi-qa-MiniLM-L6-cos-v1"  
  
embed_model = HuggingFaceEmbedding(model_name=EMBEDDING_MODEL_NAME, embed_batch_size=10)

LlamaIndex 配置

从LlamaIndex v0.10.0 起,有一个新的全局设置对象,旨在取代旧的 ServiceContext 配置。新的 Settings 对象是一个全局设置,其参数是延迟实例化的。像 LLM 或嵌入模型这样的属性只有在底层模块实际需要时才会加载。

当文档被摄入索引时,它们被分成具有一定重叠量的块。这称为“分块”。默认块大小为 1024,而默认块重叠为 20。这里将块大小设置为 256,重叠设置为 50,因为文档长度较短。

更多分块策略可以参考: docs.llamaindex.ai/en/stable/o…

from llama_index.core import Settings  
  
Settings.embed_model = embed_model  
Settings.chunk_size = 256  
Settings.chunk_overlap = 50

定义 Prompt 及准备 LLM

import torch  
from llama_index.core import PromptTemplate  
from llama_index.llms.huggingface import HuggingFaceLLM  
  
system_prompt = """<|SYSTEM|># You are an AI-enabled admin assistant.  
Your goal is to answer questions accurately using only the context provided.  
"""  
query_wrapper_prompt = PromptTemplate("<|USER|>{query_str}<|ASSISTANT|>")  
LLM_MODEL_NAME = "meta-llama/Llama-2-7b-chat-hf"


llm = HuggingFaceLLM(  
context_window=4096,  
max_new_tokens=512,  
generate_kwargs={"temperature": 0.1, "do_sample": False},  
system_prompt=system_prompt,  
query_wrapper_prompt=query_wrapper_prompt,  
tokenizer_name=LLM_MODEL_NAME,  
model_name=LLM_MODEL_NAME,  
device_map="auto",  
model_kwargs={"torch_dtype": torch.float16 , "load_in_8bit":True}  
)  
  
Settings.llm = llm

构建知识图谱索引

from llama_index.core.storage.storage_context import StorageContext  
from llama_index.core import SimpleDirectoryReader, KnowledgeGraphIndex  
from llama_index.core.graph_stores import SimpleGraphStore  
  
#setup the storage context  
graph_store = SimpleGraphStore()  
storage_context = StorageContext.from_defaults(graph_store=graph_store)  
  
index = KnowledgeGraphIndex.from_documents(documents=documents,  
max_triplets_per_chunk=3,  
storage_context=storage_context,  
embed_model=embed_model,  
include_embeddings=True)
  • max_triplets_per_chunk:从文本每个块中提取的三元组的最大数量。减少此数字可以加快处理速度,因为需要处理的三元组更少。
  • include_embeddings:控制是否在索引中包含嵌入。默认为 False,因为生成嵌入可能会消耗大量计算资源。

可视化知识图谱

from pyvis.network import Network  
g = index.get_networkx_graph()  
net = Network(notebook=True, cdn_resources="in_line", directed=True)  
net.from_nx(g)  
net.save_graph("rag_graph.html")  
from IPython.display import HTML, display  
HTML(filename="rag_graph.html")

image.png

实现查询

query_engine = index.as_query_engine(llm=llm, similarity_top_k=5)  
  
done = False  
while not done:  
print("*"*30)  
question = input("Enter your question: ")  
response = query_engine.query(question)  
print(response)  
done = input("End the chat? (y/n): ") == "y"

image.png

传统的基于向量的 RAG 和 Graph-RAG 在存储和展示数据的方式上有所不同。向量数据库适合基于相似性比较事物。它们使用数字来衡量事物之间的距离。而知识图谱则用于展示复杂的连接以及事物之间的依赖关系。它们使用节点和边来进行语义分析和高级推理,不过每种方法都有适用的用例。

结语

随着本文的深入,我们见证了LlamaIndex如何巧妙地将PDF文档中沉睡的知识唤醒,构建出一个层次丰富、关系紧密的知识图谱。这个过程不仅仅是技术的展示,更是对知识管理和信息检索方式的一次深刻反思。在这个信息爆炸的时代,我们比以往任何时候都更需要这样的工具来帮助我们理解复杂的世界。LlamaIndex不仅仅是一个构建知识图谱的工具,它更是一种思考方式,一种将孤立信息转化为有价值知识的途径。让我们带着这份启示,继续在知识的海洋中航行,探索未知,发现可能。