【知识检索架构】LLM的知识检索架构(2023)
视频号
微信公众号
知识星球
在大型语言模型的研究和应用方面,他是一个令人着迷的时代。每天都有新的进展!
在本指南中,我将分享我对基于数据的语言模型应用程序的当前体系结构最佳实践的分析。即使以大型语言模型的标准来看,这个特定的子学科也正经历着惊人的研究兴趣——在本指南中,我引用了8篇研究论文和4个软件项目,平均首次发表日期为2022年11月22日。
概述
在几乎所有大型语言模型(LLM)的实际应用中,在某些情况下,您希望语言模型基于特定数据生成答案,而不是基于模型的训练集提供通用答案。例如,公司聊天机器人应该能够参考公司网站上的特定文章,律师的分析工具应该能够参考同一案件以前的文件。引入这些外部数据的方式是一个关键的设计问题。
在高层次上,有两种主要方法来引用特定数据:
- 在模型提示中插入数据作为上下文,并指示响应使用该信息
- 通过提供数百或数千个提示<>完成对来微调模型
现有LLM知识检索的不足
这两种方法都有各自的显著缺点。
对于基于上下文的方法:
- 模型的上下文大小有限,最新的“davinci-003”模型在一个请求中只能处理多达4000个令牌。许多文件不适合这种情况。
- 处理更多的令牌相当于处理时间更长。在面向客户的场景中,这会损害用户体验。
- 处理更多令牌意味着更高的API成本,如果上下文中的信息没有针对性,则可能不会导致更准确的响应。
对于微调方法:
- 生成提示<>完成对既耗时又可能昂贵。
- 许多要从中引用信息的存储库都相当大。例如,如果你的申请是为参加美国MLE的医学生提供的学习援助,那么一个综合模型必须提供多个学科的培训示例。
- 一些外部数据源变化很快。例如,基于每天或每周移交的未结案例队列来重新培训客户支持模型并不是最佳的。
- 围绕微调的最佳实践仍在制定中。LLM本身可以用来帮助生成训练数据,但这可能需要一些复杂度才能有效。
解决方案,简化
上面的设计有各种各样的名字,最常见的是“检索增强生成”或“RETRO”。链接和相关概念:
- RAG(Retrieval-Augmented Generation):知识密集型NLP任务的检索增强生成
- RETRO:通过从数万亿个令牌中检索来改进语言模型
- REALM(Retrieval-Augmented Language Model Pre-Training):检索增强语言模型预训练
检索增强生成(RAG)
a)从语言模型(非参数)外部检索相关数据,以及b)在LLM的提示中使用上下文来增强数据。该体系结构干净地绕过了微调和仅上下文方法的大多数限制。
检索
相关信息的检索值得进一步解释。正如您所看到的,数据可能来自多个来源,具体取决于用例。为了使数据有用,数据的大小必须足够小,以便多个部分能够适应上下文,并且必须有某种方法来识别相关性。因此,一个典型的先决条件是将文本拆分为多个部分(例如,通过LangChain包中的实用程序),然后计算这些块上的嵌入。
语言模型嵌入是文本中概念的数字表示,似乎有着无尽的用途。以下是它们的工作原理:嵌入模型将文本转换为一个大的、有分数的向量,可以有效地与其他有分数的矢量进行比较,以帮助执行推荐、分类和搜索(+更多)任务。我们将这个计算的结果存储到我通常称之为搜索索引和实体存储的地方——下面将对此进行更深入的讨论。
回到流程——当用户提交问题时,LLM会以多种方式处理消息,但关键步骤是计算另一个嵌入——这次是用户文本的嵌入。现在,我们可以通过将新的嵌入向量与预先计算的完整向量集进行比较来从语义上搜索搜索索引和实体存储。这种语义搜索基于语言模型的“习得”概念,并不局限于搜索关键词。根据这次搜索的结果,我们可以定量地识别一个或多个相关的文本块,这些文本块可以帮助告知用户的问题。
增强
使用相关的文本块构建提示非常简单。提示以一些基本的提示工程开始,指示模型避免“产生幻觉”,即编造一个虚假但听起来合理的答案。如果适用,我们指导模型以特定的格式回答问题,例如“高”、“中”或“低”的顺序排名。最后,我们提供了相关信息,语言模型可以使用特定的数据来回答这些信息。在最简单的形式中,我们只需附加(“文档1:”+文本块1+“\n文档2:”+文本组块2+…),直到上下文被填充。
最后,将组合提示发送到大型语言模型。完成后会解析出一个答案,并将其传递给用户。
就是这样!虽然这是一个简单的设计版本,但它价格低廉、准确,非常适合许多轻量级用例。我已经在一个行业原型中使用了这种设置,并取得了巨大的成功。这种方法的即插即用版本可以在openai食谱库中找到,这是一个方便的起点。
高级设计
我想花点时间讨论一下可能进入检索增强生成体系结构的几个研究进展。我相信,应用LLM产品将在6到9个月内实现这些功能中的大部分。
生成然后读取管道
这类方法包括在检索相关数据之前用LLM处理用户输入。
基本上,用户的问题缺乏信息性答案所显示的一些相关性模式。例如,“Python中列表理解的语法是什么?”与代码库中的示例有很大不同,例如代码段“newlist=[x For x in tables if“customer”in x]”。一种提出的方法使用“假设的文档嵌入”来生成假设的上下文文档,该文档可能包含虚假的细节,但模仿真实的答案。嵌入此文档并在数据存储中搜索相关的(真实的)示例会检索到更相关的结果;相关结果用于生成用户看到的实际答案。
类似的方法名为generate-then-read(GenRead),它通过在多个上下文文档生成上实现集群算法来建立在实践的基础上。实际上,它生成了多个示例上下文,并确保它们以有意义的方式有所不同。这种方法使语言模型倾向于返回更多样的假设上下文文档建议,这种建议(嵌入后)从数据存储中返回更多不同的结果,并导致更高的完成机会,包括准确的答案。
用于LLM索引和响应合成的改进数据结构
GPT索引项目非常出色,值得一读。它利用了一组由langauge模型创建并针对其进行了优化的数据结构。GPT索引支持以下更详细描述的多种类型的索引。基本的响应合成是“选择前k个相关文档并将其附加到上下文中”,但有多种策略可以实现这一点。
- 列表索引-每个节点表示一个文本块,否则未更改。在默认设置中,所有节点都被组合到上下文中(响应合成步骤)。
- 矢量存储索引-这相当于我在上一节中解释的简单设计。每个文本块都与嵌入一起存储;将查询嵌入与文档嵌入进行比较,将返回k个最相似的文档以提供给上下文。
- 关键字索引-这支持对特定字符串进行快速高效的词汇搜索。
- 树索引-当数据被组织到层次结构中时,这非常有用。考虑临床文档应用程序:您可能希望文本既包括高级说明(“以下是改善心脏健康的一般方法”),也包括低级说明(参考副作用和特定降压药物方案的说明)。有几种不同的方法可以遍历树来生成响应,其中两种方法如下所示。
- GPT索引提供了索引的可组合性,这意味着您可以在其他索引的基础上构建索引。例如,在代码助理场景中,您可以在内部GitHub存储库上建立一个树索引,在维基百科上建立另一个树指数。然后,在树索引上叠加一个关键字索引。
扩展上下文大小
这篇文章中概述的一些方法听起来很“技巧”,因为它们涉及到当前模型中相对较小的上下文大小的变通方法。有大量的研究工作旨在扩大这一限制。
- GPT-4预计将在未来1-3个月内完成。据传它有更大的上下文大小。
- 这篇来自谷歌人工智能公司的论文对工程权衡进行了一些探索。其中一种配置允许上下文长度高达43000个令牌。
- 一种新的状态空间模型体系结构随着上下文大小线性扩展,而不是像在变换器模型中那样呈二次方扩展。虽然该模型在其他领域的性能落后,但它表明,大量的研究工作都是针对改善模型考虑因素,如上下文大小。
在我看来,上下文大小的进步将随着对更多数据检索的需求而扩展;换言之,可以放心地假设,即使在某些配置不断发展的情况下,仍然需要进行文本拆分和细化。
持续状态(例如会话历史记录)
当LLM以对话的形式呈现给用户时,一个主要的挑战是在上下文中维护对话历史。
对相关战略的概述超出了本员额的范围;有关最近涉及渐进式摘要和知识检索的代码演示示例,请参阅此LangChain示例。
资源和进一步阅读
- GPT Index
- Haystack library for semantic search and other NLP applications
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
- LangChain
- How to implement Q&A against your documentation with GPT3, embeddings and Datasette
- FAISS for vector similarity calculations
- Generate rather than Retrieve: Large Language Models are Strong Context Generators
- Implementation Code
- 380 次浏览