赞
踩
微软近日开源了新一代RAG框架GraphRAG[1],以解决当前RAG在大型语料库上全局理解问题。当前RAG主要聚焦于局部检索能力,即根据查询语句在向量库中匹配部分知识,然后通过大型语言模型合成这些检索到的信息,生成一个自然流畅的回答。相信大部分同学看过《仙逆》这部小说,如果你问王林这一生有几个相好?如果让RAG来回答,它能回答出来吗?而GraphRAG通过两个阶段构建基于图的文本索引:首先从源文档中推导出实体知识图谱,然后为所有紧密相关的实体群体生成社区摘要。给定一个问题,每个社区摘要用于生成部分回应,然后将所有部分回应总结为最终用户的回答。通过这样的方法,那么我们再问王林这一生有多少女人,是不是会容易的多了呢?下图来自百度百科-王林词条[2]。本文将先首先概述RAG和GraphRAG,然后介绍如何安装、如何使用GraphRAG对《仙逆》进行索引和回答测试。
索引整本小说耗资太过巨大,时间也较长,本文只采用前面10章作为案例用以说明。下一篇,我们将使用LlamaIndex测试同样问题进行对比全局理解能力。
大语言模型(LLM)是在大量数据上训练,但他们并不是在我们私有数据上训练,因此要想让LLM能够回答我们私有数据集上的问题,我们就得使用一种叫做检索增强生成(RAG)的技术。它的基本原理是加载我们的文档,然后将每个文档按照一定的规则,比如Token数量、字符数量、语义和层次分割等,将每个文档拆分为一个一个小片段(chunk)。然后使用嵌入技术对这些chunk生成embeding,存储到高维向量数据库中,生成索引Index。在用户查询的时候,将查询语句转换为embeding,然后向高维向量数据库寻找和查询embeding最相似的Top K个embeding,将其对应的文本以及对应的上下文发送给LLM,从而利用LLM合成自然流畅地回答返回给用户,如下图所示。
但是像**数据集中的核心主题是什么?**这类问题需要查询聚焦摘要(Query focused summary)而不是像我们上述RAG系统那样显式检索,现有的QFS方法无法扩展到RAG系统索引的文本量。而GraphRAG结合知识图谱,RAG和QFS这些方法的优势,它可以根据用户问题的普遍性和要索引的源文本量进行扩展。该方法使用LLM构建基于图的文本索引,包括从源文档派生实体知识图谱,然后为所有密切相关的实体组生成社区摘要。给定一个问题后,每个社区摘要用于生成部分回答,然后所有部分回答再次汇总为最终回答。具体步骤和流程图如下:
源文档到文本块:一个基本的设计决策是决定从源文档中提取的输入文本应以何种粒度分割成文本块进行处理。
文本块到元素实例:这一步骤的基本要求是识别并提取每个文本块中的图节点和边的实例。使用一个多部分的LLM提示来首先识别文本中的所有实体,包括它们的名称、类型和描述,然后识别所有明确相关实体之间的关系,包括源实体和目标实体以及它们关系的描述。
元素实例到元素摘要:使用LLM将实例级摘要转换为每个图元素的描述性文本块。使用LLM“提取”源文中表示的实体、关系和声明的描述已经是一种抽象摘要的形式,依赖于LLM创建独立有意义的摘要,这些摘要可能是文本本身暗示但没有明确陈述的概念(例如,暗示关系的存在)。要将所有这些实例级摘要转换为每个图元素(即实体节点、关系边和声明协变量)的单一描述性文本块,需要进一步通过匹配实例组进行LLM摘要。
元素摘要到图社区:使用社区检测算法将图划分为模块化社区。前一步创建的索引可以被建模为一个同质无向加权图,其中实体节点通过关系边连接,边权重表示检测到的关系实例的归一化计数。给定这样的图,可以使用各种社区检测算法将图划分为节点之间相互连接的社区。在流程中使用Leiden算法,因为它能够高效地恢复大规模图的层次社区结构。这个层次结构的每个级别都提供了一个社区划分,以相互独立、集体穷尽的方式覆盖图中的节点,使得分而治之的全局摘要成为可能。
图社区到社区摘要:为Leiden层次结构中的每个社区创建报告式摘要。这一步是使用旨在扩展到非常大的数据集的方法为Leiden层次结构中的每个社区创建报告式摘要。这些摘要本身是有用的,因为它们是理解数据集的全局结构和语义的一种方式,并且它们自己可以用来在没有问题的情况下理解语料库。
社区摘要到社区回答再到全局回答:使用社区摘要生成最终答案的多阶段过程。准备社区摘要,社区摘要被随机打乱并分成预指定token大小的块。这确保了相关信息分散在各个块中,而不是集中在一个上下文窗口中(可能丢失)。映射社区回答,并行生成中间答案,每个块一个。LLM也被要求生成一个0-100之间的分数,以指示生成的答案在回答目标问题方面的有用程度。得分为0的答案被过滤掉。汇总为全局答案,按有用性得分降序排列的中间社区答案被迭代地添加到新的上下文窗口中,直到达到token限制。这个最终上下文被用来生成返回给用户的全局答案。
由于GraphRAG刚开源,部署起来还有很多问题,所以本次采用源码安装测试,方便调试修改代码。
git clone https://github.com/microsoft/graphrag.git
安装poetry,然后安装依赖poetry install
。当所有依赖安装好之后,我们cd到graphrag目录,在当前目录准备初始化:
poetry run poe index --init --root .
它会在当前目录创建input、output、prompts、cache目录,以及.env文件和settings.yaml配置文件。
input目录,存放需要索引的文件,默认配置只支持txt,当然也可以修改settings.yaml
output目录,存储生成的图、以及总结、日志等信息。
prompts目录,存储默认的4个提示词文件:claim_extraction.txt、community_report.txt、entity_extraction.txt、summarize_descriptions.txt。
cache目录,用于缓存提取实体和摘要等,能够减少LLM调用
.env文件中只包含一个字幕GRAPHRAG_API_KEY,用于设置你的LLM API_KEY。
settings.yaml 文件较为复杂,配置项目也较多,运行本项目只需要修改两个。
将想要索引的文件放入input文件夹。准备配置settings.yaml和.env文件,我没有OpenAI的key,所以只能使用非Open AI LLM,如果你经费充足可以直接使用OpenAI的LLM,但是github上有人测试一次花了他46美刀。可以使用免费LLM且兼容OpenAI SDK的,有通义千问、月之暗面还有Groq。
使用通义千问作为LLM时候,问题较多,兼容性有点差,但是速度没什么限制,基本上能够用到100RPM,TPM没限制。
top_p 必须设置0-1之间,要小于1,比如0.99这样。
max_tokens 必须设置为2000,超过会报错。
还有其他未知的错误,不要使用qwen-long,好像输入过长就会报错,让你走文件上传,建议使用qwen-turbo。
使用Groq,Groq上的模型除了Mistral的上下文窗口是32K,其他的诸如llama3 70B、Gemma等都是8192。对于GraphRAG,由于它在总结时候,一个Prompt就超过8K,所以上下文窗口小的模型基本可以忽略,即使速度很快。但是Mistral的8x7B的模型,在免费用户上的限制也较大,虽说可以达到30每分钟请求,但是每分钟Token输出最多5000,这个非常限制速度,根据我的观察,有时候一次返回就超过2000了,意味着你每分钟只能请求一次。
月之暗面的免费用户可以使用所有的模型,moonshot-v1-32k作为目标模型,它的速率限制是每分钟3次请求,每分钟32000 Token限制。所以几项比较下来,还是通义千问速度快点。
其实,在实体提取的时候,可以使用Groq的Llama3 7B模型,速度较快,而且TPM和RPM都很大。等到实体提取结束后,报context window时候,再切换回通义千问,速度上相对能接受一点。
那么在.env中配置你的API KEY,然后打开settings.yaml,找到llm这一项,修改model、api_base等信息。其中max_tokens是指响应的最大Tokens数量而不是输入。另外要注意的时候tokens_per_minute
和request_per_minute
在你本地是不生效的,你应该使用它的缩写tpm和rpm,我已经提了PR尝试去修复了。这两个值一定要根据你的模型提供方去设置,不然日志中会有很多报错。
PS:已经被修复了,其他人早我4小时提的
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/848977
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。