LLM增强

 从公众号转载,关注微信公众号掌握更多技术动态

LLM增强_第1张图片

---------------------------------------------------------------

一、增强语言大模型基础

1.大语言模型存在的不足

  • 存 在 “ 幻 觉 ” , 容 易 一 本 正 经 胡 说 八 道
  • 提 示 直 接 决 定 回 复 质 量 , 经 常 容 易 “ 说 正 确 的 废 话 ”
  • 无 法 理 解 与 更 新 个 性 化 知 识 , 如 无 法 针 对 个 性 需 求 提 供 信 息
  • 无 法 处 理 动 态 、 实 时 问 题 , 如 股 票 价 格 、 天 气 变 化 等
  • 知 识 无 法 更 新 , 不 能 提 供 最 新 信 息
  • 不 擅 长 数 学 计 算 和 逻 辑 推 理 等

2.增强语言大模型的必要性和可能方向

针对当前L LM的不足,研究者们提出了一些改进措施,例如使LM利用外部工具,用LM的权重中不包含的重要缺失信息来增强上下文理解,形成更强大的智能体;这些模型统称为增强语言模型(AL M s)。

  • 推理(Re a son i ng):将复杂任务分解成更简单的子任务,LM可以自己 或使用工具更容易地解决。
  • 工具(Tool):收集外部信息,或者对ALM感知的虚拟或物理世界产生影响。
  • 行为(Ac t):调用一个对虚拟或物理世界有影响的工具并观察其结果,将其纳入ALM的当前上下文。

结合使用:推理和工具可以放在同一个模块里,二者都是通过增强LM的上下文来更好地预测缺失;收集额外信息的工具和对虚拟或物理世界产生影响的工具可以被LM以同样的方式调用

• 翻转字符串 - 如果我们⽤⼀个reverse函数呢?

• 计算乘法 - 如果我们⽤⼀下计算器呢?

二、高级提示工程

1.ReAct

在使用langchain的过程中,大模型给人留下最深刻的印象无疑是Agent功能。大模型会自己分析问题,选择合适的工具,最终解决问题。这个功能背后的原理就是来自ReAct框架。在人类从事一项需要多个步骤的任务时,而步骤和步骤之间,或者说动作和动作之间,往往会有一个推理过程。让LLM把内心独白说出来,然后再根据独白做相应的动作,来提高LLM答案的准确性。

Reasoning and Acting。意思是LLM可以根据逻辑推理(Reason),构建完整系列行动(Act),从而达成期望目标。LLM灵感来源是人类行为和推理之间的协同关系。人类根据这种协同关系学习新知识,做出决策,然后执行。LLM模型在逻辑推理上有着非常优秀的表现,因此有理由相信LLM模型也可以像人类一样进行逻辑推理,学习知识,做出决策,并执行。在实际使用中,LLM会发生幻觉和错误判断的情况。这是因为LLM在训练的时候接触到的知识有限。因此对超出训练过程中使用的数据进行逻辑分析时,LLM就会开始不懂装懂地编造一些理由。因此对于解决这个问题最好的办法是,可以保证LLM模型在做出分析决策时,必须将应该有的知识提供给LLM。

ReAct方式的作用就是协调LLM模型和外部的信息获取,与其他功能交互。如果说LLM模型是大脑,那ReAct框架就是这个大脑的手脚和五官。同时具备帮助LLM模型获取信息、输出内容与执行决策的能力。对于一个指定的任务目标,ReAct框架会自动补齐LLM应该具备的知识和相关信息,然后再让LLM模型做出决策,并执行LLM的决策。

(1)如何运作

①三个概念

Thought:由LLM模型生成,是LLM产生行为和依据。可以根据LLM的思考,来衡量他要采取的行为是否合理。这是一个可用来判断本次决策是否合理的关键依据。相较于人类,thought的存在可以让LLM的决策变得更加有可解释性和可信度。

Act:Act是指LLM判断本次需要执行的具体行为。Act一般由两部分组成:行为和对象。用编程的说法就是API名称和对应的入参。LLM模型最大的优势是,可以根据Thought的判断,选择需要使用的API并生成需要填入API的参数。从而保证了ReAct框架在执行层面的可行性。

Obs:LLM框架对于外界输入的获取。它就像LLM的五官,将外界的反馈信息同步给LLM模型,协助LLM模型进一步的做分析或者决策。

②包含流程

  • 输入目标:任务的起点。可以是用户的手动输入,也可以是依靠触发器(比如系统故障报警)。
  • LOOP:LLM模型开始分析问题需要的步骤(Thought),按步骤执行Act,根据观察到的信息(Obs),循环执行这个过程。直到判断任务目标达成。
  • Finish:任务最终执行成功,返回最终结果。

LLM增强_第2张图片

以下面这个问题为例:

除了Apple遥控器,还有什么其他设备可以控制相关软件?相关软件指的是,Apple遥控器最早可以控制的软件。

说明:

  • Apple遥控器最早只能控制Front Row软件。
  • Front Row软件可以被两种设备控制,Apple遥控器和键盘的功能键。
  • 所以,正确答案是键盘的功能键。

传统方式1,直接问LLM。得到结果:

iPod。

答案错误,显然是在胡言乱语。

传统方法2,思维链。得到结果:

想法:让我们一步一步思考这个问题。Apple遥控器可以控制Apple电视。Apple电视可以被iPhone、iPad和iPod Touch控制。答案:iPhone、iPad和iPod Touch控制。

答案错误,思维链范式,其实也是在胡诌,因为它不知道答案。

ReAct方法,即推理+动作。得到结果:

想法1:我需要搜索Apple遥控器,并找到Apple遥控器最早可以控制的软件。

动作1:搜索【Apple 遥控器】

结果1:Apple遥控器是一种遥控器……最早可以控制“Front Row”……

想法2:Apple遥控器最早可以控制Front Row。我需要搜索Front Row下一步,找出还有什么其他设备可以控制他

动作2:搜索【Front Row】

结果2:无结果,可以试试“Front Row Seat to Earth”和“Front Row软件”

想法3:Front Row没有找到,我可以搜索“Front Row软件”

动作3:搜索【Front Row软件】

结果3:FrontRow是一种过时软件……可以被Apple遥控器和键盘功能键控制。

想法4:现在我知道答案了。

动作4:完成【键盘功能键】

答案正确。通过显式推理,加上动作,LLM Agent自主找到了答案。整个过程感觉就像是个不是特别聪明的孩子,要把想法写出来,然后去综合所有想法和观察,接着再做出相应的动作。但显然这个方法很有效,它最终找到了答案。如果使用ReAct范式,因为他具备了可解释性。我们可以知道Agent是怎么想的,尤其是在需要调试和人工介入的情况下。

此外,还有一种进一步提高ReAct准确率的方法,即微调finetuning,类似人类“内化”知识的过程,将上千条正确的推理动作轨迹输入进LLM进行finetuning,可以显著提高准确率。

(2)ReAct缺点

①LLM模型的通病

LLM的表现来看,更像一个人类。泛用性很强,可以通过自己思考去解决很多问题,但也会因为自身知识,能力上的缺陷无法做到稳定输出。但LLM跟人比,会显得更加盲目自信,对于不了解不理解的问题也会编造一些内容(幻觉)。

LLM增强_第3张图片

②成本

采用ReAct方式,开发者是无法控制输入内容的。因为在任务提交给LLM后,LLM对任务的拆解、循环次数是不可控的。因此存在一个可能性,过于复杂的任务导致Token过量消耗。一个复杂任务一晚上跑掉一栋别墅的钱也不是玩笑话。

③响应时间

比起大部分API接口毫秒级的响应,LLM响应时间是秒级以上。以ChatGPT的API为例,普通一次Completion接口,响应时间都要10秒以上。如果是复杂的任务,达到20秒以上也是可能的。当然,这里不确定是不是OpenAI本身工程能力有限导致的,还是LLM本身就需要这么长的时间。

在ReAct模式下,这个时间变得更加不可控。因为无法确定需要拆分多少步骤,需要访问多少次LLM模型。因此在在秒级接口响应的背景下,做成同步接口显然是不合适的,需要采用异步的方式。而异步方式,又会影响用户体验,对应用场景的选择又造成了限制。

(3)React组成

LLM增强_第4张图片

① Agent

一个调优的专用于推理与动作(reasoning and acting)的大模型,他的核心能力是规划任务和反思\持续完善,需要有强大的推理决策能力。

任务规划:将大型任务分解为更小的可被管理的子目标,这样就可以高效的执行复杂任务。之前分享推理时提到的XoT(CoT、Cot-SC、ToT)都是比较典型的。另外介绍ReWOO,这也是一个基于计划的方案,思路是,当问题被提出时,制定出解决这个问题的各个Plan,并把Plan的结果留空(称为蓝图),Plan作为一个个的Act交由Worker执行,执行的结果被填充到这个蓝图中,最终交由大模型得出结果,与一般方案不同,他不需要按步就班的去执行,这是突出“规划”能力的一个很好的方案。

反思和持续完善:再是反思和持续完善,简单来说就是为大模型提供改进方案,帮助它从之前的错误中去学习,以更好的完成将来的任务。拿ART来说,这是一个需要监督的方案,可以将发生过的推理过程沉淀下来,并在将来召回再使用。过程可以描述为:一个Task Library存放了多种类型任务的CoT,当向ART实例提问时,会从TaskLibrary中找到最适合的Task案例与用户的问题一起向大模型提问,最终结果由人脑评审并修正,结果会持久化到TaskLibrary。而右边提到的Reflexion则将人脑部分换成了语言模型,转换成了由大模型自我学习优化自身行为,通过尝试、错误和自我反思来解决决策、编程和推理任务的架构。在业界中比较优秀的案例有ReAct、BabyAGI等等,而ReAct是当下的事实标准,影响力深远。而OpenAI也在最近公布的Function Call中提供了基于GPT3.5 turbo \ 4.0的调优规划模型(0613版)。

②Memory

memory包括Context和History

Context:语境上下文,类似人脑的STM(Short-term memory 短期记忆),为Agent提供上下文能力,当下大模型的提示词工程化就是基于上下文的。

History:回忆,类似人脑的LTM(Long-term memory 长期记忆),为Agent提供了存储和召回关联数据的能力。像WebGPT一样检索数据就是非常常见的场景,区别于传统的内容检索,我们也有一些通过大模型增强检索的方案,如:RAG、FLARE等。在实践中通常选择支持快速最大内积搜索(MIPS)的近似最近邻 (ANN) 算法数据库与这些方案配套,这块有很多向量数据库可供选择了,

③Tools

一组工具集或者Agent可以利用的所有外部资源,这是Agent可调用、可执行的能力,它既可以是一个函数、api,还可以是其它任何大模型,包括另一个Agent应用等等。

ChatGPT的插件以及OpenAI API Function Calls都是Tools应用范畴的最佳案例。当下适用于互联网的常用思路是提供不同领域的api以及这些api的说明用法文档,由Agent的推理去判断需要使用的api在Tools中是否存在,这是个不断查阅、调用、证实的过程:

API Bank是一个Benchmark工具,在他的论文里为我们提供了一个可行的API调用思路:

  • Step1. 向Agent提供API Manual Agent可以在它各个规划任务中,使用关键词去API Manual中检索并总结出所需API用法,用法说明可以按Prompts Engineering提出的方案,利用Few-Shot或者Zero-Shot CoT去引导Agent。
  • Step2. 向Agent提供API和输入检查器 当Agent已经掌握API的用法后,Agent可以生成API所需参数,并调用API获取结果,这个过程需要不断的检查输入的参数是否正确,以及评估输出的结果是否符合预期。

2.问题拆解

(1)Cot思维链

  • Zero-shot-CoT
  • few-shot-Cot

LLM增强_第5张图片

(2)ToT思维树

①简介

由普林斯顿和谷歌DeepMind联合提出的全新「思维树」框架,让GPT-4可以自己提案、评估和决策,推理能力最高可提升1750%。

2022年,前谷歌大脑华人科学家Jason Wei在一篇思维链的开山之作中首次提出,CoT可以增强LLM的推理能力。但即便有了思维链,LLM有时也会在非常简单的问题上犯错。ToT将当前流行的「思维链」方法泛化到引导语言模型,并通过探索文本(思维)的连贯单元来解决问题的中间步骤。

CoT强调的是任务分解为子任务的过程,而ToT则强调了分解任务就是生成多个思考过程,最终整个ToT会形成一个思维树结构,这样我们可以方便的将复杂问题到结果的思维路径作为Tree这样的经典数据结构,使用广度优先(BFS)或深度优先(DFS)查找来解决一个复杂问题,其中思维路径也就是CoT的每个推论状态则由前面提到的Self-Consistency或者其它等更先进方式去评估。

通过这种方式形成的以大模型自我推理决策的Tree结构是基于AI的场景下钻和逻辑自洽来完成的,简单来说,它替代了之前人类要做的关于理解、分析、执行、验证的整个过程在反复推演直到得出正确结果的整个过程。

②技术原理

「思维树」可以让LLM:

  • 自己给出多条不同的推理路径
  • 分别进行评估后,决定下一步的行动方案
  • 在必要时向前或向后追溯,以便实现进行全局的决策

LLM增强_第6张图片

3.SC自一致

LLM增强_第7张图片

首先可以利用CoT给出几个写了推理过程的示例,然后要求LLM对给定的问题进行推理,如果是CoT,直接输出一个推理过程和答案,整个过程就结束了。“Self-Consistency”则不然,它要求LLM输出多个不同的推理过程和答案,然后采用投票的方式选出最佳答案,思路非常简单直接,但是效果也确实好。“Self-Consistency”其实是教导LLM学会这么一个道理:孔乙己说过茴香豆的“茴”字有四种写法,类似的,一个数学题的正确解法也可以有很多种,每个不同的推导过程都指向最终的答案。

4.其它相关技术

(1)Program-aided Language Model (PAL)

 程序辅助语言模型(PAL)使用LLM来读取问题并生成程序作为中间推理步骤。然而,有时CoT是不够的,因为它只依赖于模型生成的文本。(PAL) 与思维链提示的不同之处在于,它不是使用自由格式的文本来获得解决方案,而是将解决方案步骤变为编程代码运行,提高了结果的准确性。该方法的缺点是需要较长的提示样例,通常也是一些程序代码,这样才能让 LLM 也用代码回答。

LLM增强_第8张图片

(2)Progressive-Hint Prompting(PHP)方法

《Progressive-Hint Prompting Improves Reasoning in Large Language Models》这方法的思想在于,人类的一个突出方面是人类不仅能够思考一次,而且还能重复检查答案。

该工作提出这个过程可以通过依次采用以前的答案在语言模型中进行模拟。换句话说,一个模型可以生成一个答案,然后将其与问题结合起来进行下一轮的思考。如果当前的答案与之前的答案相同,则就可以确信当前的答案是正确的。

LLM增强_第9张图片

①实现方式

渐进式提示方法将生成的答案和问题结合起来,以达到双重检查的目的,该方法分为两个阶段。

在第一阶段,通过向LLM传递当前问题和基本提示(如CoT或Complex CoT)的串联来生成一个基本答案。

在第二阶段,通过相应的渐进式提示产生后续答案,如渐进式提示CoT(PHP-CoT)或渐进式提示复杂CoT(PHP-Complex CoT),用于后续的交互。

当两个连续的答案相同时,互动停止。

LLM增强_第10张图片

如上图所示,紫色方框表示LLM的输入。橙色方框表示LLM的输出,细致的操作方法如下:

  • 给定一个问题,要求LLM提供一个基本答案;
  • 把问题和答案结合起来,重新询问LLM,得到后续答案;
  • 重复(2)中的操作,直到答案收敛,并且保证在最后两个答案中没有变化,也就是说,当两个连续的回答相同时,就达到了PHP中的停止标准,标志着互动交流的结束。

总体来说,PHP遵循一个类似人类的思维过程,在重新评估问题后,利用以前的答案作为提示,得出正确的答案。

②PHP-CoT提示的生成过程

LLM增强_第11张图片

PHP提出了一个两句话的结构,包括一个在问题部分表示答案接近的短语,然后是一个在答案部分排练提示的句子。

例如,为了从CoT提示中创建一个PHP提示,首先在最初的问题后加入 "答案接近A1,...,Ap",其中A1,...,Ap代表可能的答案。

接下来,在潜在答案的开头句中引入提示: "我们知道答案的提示: A1, ..., Ap. 有了答案提示: A1, ..., Ap, 我们将回答这个问题。"。

其中有个很重要的点,即PHP设计原则,在这个提示设计中,会考虑以下两种可能的情况:

  • 提示与正确答案相同:以确保模型在提示正确时仍能得到正确答案;
  • 提示与正确答案不相同:以确保模型能跳出错误的答案。

③实验结论

  • 当LLM更强大时,PHP的效果更好
  • 当提示的效果较优时,PHP的工作效果更好
  • 当模型更强大,但提示没那么有效时,互动数就会减少

(3)Self-ask

Self-ask是一种follow-up的使用范式,仅仅包含follow-up, immediate answer步骤,至于follow-up多少个step,完全由它自己决定,估计这就是Self-ask的名字的由来。如上图,白色背景的是prompt,绿色背景的文本是LM的输出,下划线的是inference-time的问题。Self-ask需要一个或者少量的prompt来演示如何回答的提示问题。我们的提示从这些例子开始,之后我们附加inference-time question,然后在prompt的末尾插入短语“Are follow up questions needed here:",因为我们发现这样做会略微改善结果。然后模型输出一个响应。在大多数情况下,它首先输出“Yes”,这意味着后续行动问题是必要的。然后LM输出第一个follow-up问题,回答它,然后继续询问并回答follow-up问题,直到它决定有足够的信息为止。最终会输出:"So the final answer is:",这使得最终答案可以很容易根据":"解析出来。

LLM增强_第12张图片

(4)Plan-and-execute agents

Plan-and-execute agents这个方法本质上是先计划再执行,即先把用户的问题分解成一个个的子任务,然后再执行各个子任务,最后合并输出得到结果。做法也比较简单,prompt的形式需要改变一下,前面的论文使用的是“Let’s think step by step”,在这里使用新的prompt,“Let’s first understand the problem and devise a plan to solve the problem. Then, let’s carry out the plan and solve the problem step by step”,图a表示的是Zero-shot-Cot Prompting,图b使用的是Plan-and-Solve(PS)prompting,图(c)显示的是answer extracting prompting。Zero-shot-CoT鼓励LLM生成多步骤用“Let’s think step by step”进行推理,当问题复杂时,它仍然可能产生错误的推理步骤。与Zero-shot-CoT不同,PS提示首先要求LLM设计一个计划,通过生成一个步骤来解决问题计划和执行计划以找到答案。

5.函数调用

import openai import json # 定义一个函数,用于获取天气信息 def get_current_weather(location, unit="fahrenheit"): """获取给定城市的天气信息""" weather_info = { "location": location, "temperature": "72", "unit": unit, "forecast": ["晴朗", "温暖"], } return json.dumps(weather_info) # 第一步,向openai发送消息和定义函数信息 def run_conversation(): openai.api_key = "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" openai.proxy = "http://127.0.0.1:10809" response = openai.ChatCompletion.create( model="gpt-3.5-turbo-0613", messages=[{"role": "user", "content": "今天广州的天气怎么样?"}], functions=[ { "name": "get_current_weather", "description": "获取当前地区天气", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "输入城市和地区", }, "unit": {"type": "string", "enum": ["摄氏", "华氏"]}, }, "required": ["location"], }, } ], function_call="auto", ) message = response["choices"][0]["message"] # 第二步,检查模型是否需要调用函数 if message.get("function_call"): function_name = message["function_call"]["name"] # 第三步,调用函数 function_response = get_current_weather( location=message.get("location"), unit=message.get("unit"), ) # 第四步,向模型发送函数调用和函数返回值 second_response = openai.ChatCompletion.create( model="gpt-3.5-turbo-0613", messages=[ {"role": "user", "content": "今天广州的天气怎么样?"}, message, { "role": "function", "name": function_name, "content": function_response, }, ], ) return second_response print(run_conversation()) # 输出了:今天广州的天气是晴朗的,温度为72°F,温暖舒适。

三、检索/知识增强——RAG

LLM增强_第13张图片

1.向量数据库结合LLM流程

向量数据库现在看起来是构建LLM App中很关键的一个组件。首先 LLM 的预训练和微调过程不可能包含我们所期待的私有数据,因此如何将LLM关联到私有数据成为一个很关键的需求。而且LLM的“接口”-自然语言通常不是像Key-Value的映射那样精确地。而且在这一阶段我们希望LLM去理解我们的知识库,而不是简单的在其中搜索相同的字符串,我们希望询问关于我们知识库的细节,并给出一定理解后的答案(以及来源),这样匹配向量这样的搜索方式是一个非常合适且关键的解决方案。还有一个关键点是,LLM在每次调用是按token计费(即文本量),并且目前的接口的上下文有着4096 tokens的限制。,因此面对庞大的数据,我们也不可能将所有的数据一次性传给LLM。因此才有了第一张图那个流程图的结构。本地预先将我们私有的数据转成向量存在Qdrant里,用户问答时,将用户的问题转为向量,然后去Qdrant里进行搜索(相似性匹配)得到Top K个结果,然后将这些结果(注意这里的结果已经是自然语言了)传给LLM进行总结输出。

LLM增强_第14张图片

LLM增强_第15张图片

LLM增强_第16张图片

(1)后端数据处理和存储流程

上图黑色的部分为后端的数据处理流程,主要是将我们的原始数据求解embedding,并和原始数据一起存入到向量数据库ADB-PG中。这里你只需要关注上图的蓝色虚线框部分。黑色的处理模块和ADB-PG向量数据库。

  • Step1:先将原始文档中的文本内容全部提取出来。然后根据语义切块,切成多个chunk,可以理解为可以完整表达一段意思的文本段落。在这个过程中还可以额外做一些元数据抽取,敏感信息检测等行为。
  • Step2:将这些Chunk都丢给embedding模型,来求取这些chunk的embedding。
  • Step3:将embedding和原始chunk一起存入到向量数据库中。

(2)前端问答流程

①问题提炼

这个部分是可选的,之所以存在是因为有些问题是需要依赖于上下文的。因为用户问的新问题可能没办法让LLM理解这个用户的意图。

比如用户的新问题是“它能做什么”。LLM并不知道它指的是谁,需要结合之前的聊天历史,比如“通义千问是什么”来推理出用户需要求解答案的独立问题“通义千问能做什么”。LLM没法正确回答“它有什么用”这样的模糊问题,但是能正确回答“通义千问有什么用”这样的独立问题。如果你的问题本身就是独立的,则不需要这个部分。

得到独立问题后,我们可以基于这个独立问题,来求取这个独立问题的embedding。然后去向量数据库中搜索最相似的向量,找到最相关的内容。这个行为在Part2 Retrieval Plugin的功能中。

②向量检索

独立问题求取embedding这个功能会在text2vec模型中进行。在获得embedding之后就可以通过这个embedding来搜索已经事先存储在向量数据库中的数据了。比如我们已经在ADB-PG中存储了下面内容。我们就可以通过求取的向量来获得最相近的内容或者知识,比如第一条和第三条。通义千问是...,通义千问可以帮助我们xxx。

LLM增强_第17张图片

③推理求解

在获得最相关的知识之后,我们就可以就可以让LLM基于最相关的知识和独立问题来进行求解推理,得到最终的答案了。这里就是结合“通义千问是...”,“通义千问可以帮助我们xxx”等等最有效的信息来回答“通义千问有什么用”这个问题了。最终让GPT的推理求解大致是这样:

LLM增强_第18张图片

(3)问题点

假如你的产品有一套研发阶段效果很好的prompt,交给测试后,可能测试上百条上千条就能看出问题了。由于效果无法保证,真正推出给c端用户会面临很大的挑战。而且没有用微调服务或者model instance的话,如果OpenAI更新了模型,你的生产环境的prompt可能需要全部重新测试一下效果。你的prompt也需要和代码一样按版本来管理,不管有没有prompt变更,每个版本上线前都需要进行回归测试。没有好的自动化评估方案的话,大量的case都需要测试人工来看会耗费非常多的人力。

结合私有数据的LLM应用目前开发起来在工程上已经有很多不错的方案了,很容易跑出效果不错的demo,但还是需要非常谨慎对待这样一种应用。毕竟我们不只是要做一个在社交媒体或者Leader面前演示的项目。提供给用户输入的是一个对话框,自然语言宽泛到即使你测试上万条结果也可能出现意想不到的结果,毕竟像new bing和chatGPT这样的产品也会被Prompt Injection。面对这种不确定性,工程上如何去避免,测试如何去覆盖都是一个成熟产品待解决或者说还有很多工作可以做的问题。

2.RAG

LLM是通过大量的数据进行训练的,可以回答任何问题或完成任务,利用其参数化记忆。这些模型有一个知识截止日期,取决于它们上次训练的时间。被问及超出其知识范围或在知识截止日期之后发生的事件时,模型会产生幻觉高。Meta公司的研究人员发现,通过提供与手头任务相关的信息,模型在完成任务时表现显著改善。例如,如果询问模型关于截止日期之后发生的事件,则提供该事件作为背景信息并随后提问将帮助模型正确回答问题。由于LLM具有有限的上下文窗口长度,在处理当前任务时只能传递最相关的知识。我们添加到上下文中数据质量影响着模型生成响应结果的质量。机器学习从业者在RAG流程不同阶段使用多种技术来改善LLM性能。

(1)RAG 与微调

微调是在特定任务上训练模型的过程,就像在问题解答数据集上微调 GPT-3.5 以提高其在特定数据集上的问题解答性能一样。如果你有一个足够大的数据集来完成手头的任务,而且数据集不会发生变化,那么微调就是一种很好的方法。如果数据集是动态的,我们就需要不断重新训练模型以跟上变化。如果手头的任务没有大型数据集,微调也不是一种好方法。在这种情况下,您可以使用 RAG 来提高 LLM 的性能。同样,您也可以使用 RAG 来提高 LLM 在摘要、翻译等任务上的性能,因为这些任务可能无法进行微调。

(2)RAG如何工作

RAG 架构和管道包括三个主要阶段--数据准备、检索和生成。数据准备阶段包括确定数据源、从数据源中提取数据、清理数据并将其存储到数据库中。检索阶段包括根据手头的任务从数据库中检索相关数据。生成阶段包括利用检索到的数据和手头的任务生成输出结果。输出的质量取决于数据的质量和检索策略

①数据准备

根据LLM将要处理的任务类型,数据准备通常涉及识别数据来源、从来源中提取数据、清洗数据并将其存储在数据库中。用于备数据的步骤可能因使用情况和检索方法而异。例如,如果您正在使用像Weaviate这样的向量存储器,您创建嵌入,并将它们存储在向量存储器中。如果您正在使用像Elasticsearch这样的搜索引擎,则需要在搜索引擎中对数据进行索引。如果您正在使用像Neo4j这样的图形数据库,则需要为数据创建节点和边,并将它们存储在图形数据库中。我们将在下一节讨论不同类型的数据库以及准备数据所涉及的步骤。

②向量存储器

向量存储器适用于存储文本、图像、音频等非结构化数据,并基于语义相似性搜索该类别下的内容。我们使用一个内置模型来生成我们所保存到数据库中的每个片段(chunk)对应ding) 。根据不同类型和用例以及embedding模型, 数据会更小块进行处理, 例如:如果你要保存文本信息,可以按句子或段落划分;如果你要保存代码,则可以按函数或类划分;如果你选择提供与LLM相关上下文范围范围代码片段时 , 可以选择更小块大小. 将原始文件拆解后, 每个部分都会生成相应embedding 并且 存放到vector store 中. 当查询发送给 vector store 时, 查询也会转换为 embedding , 然后 vector store 返回与查询最相似 的 embeddings.

Weaviate 这种 类型 的 向量 数据库 在 存取过程 中 都能够自 嵌入(embeddings) 的生成工作 , 因此 操作者只需关注 数据建模 和 切割策略即可。

③关键词搜索

是一种简单的检索数据的方法,其中数据根据关键词进行索引,并且搜索引擎返回包含这些关键的文档。关键词搜索适用于存储结构化数据(如表格、文档等)并使用关键词对数据进行搜索。

④图数据库

以节点和边的形式存储数据。它们适用于存储结构化数据(如表格、文档等),并通过数据之间的关系进行搜索。例如,如果您正在存储有关人员的数据,可以为每个人创建一个节点,并在彼此认识的人之间建立边缘。当向图数据库查询时节点相连接的节点。这种使用知识图谱进行检索的方式对于问题回答等任务非常有用,其中答案是一个人或实体。

⑤搜索引擎

在RAG架构中,可以从公共搜索引擎(如Google、Bing等)或内部擎(如Elasticsearch、Solr等)中检索RAG管道中的数据。在RAG架构中,在检索阶段查询了搜索引擎并返回最相关的文档。搜索引擎适用于从网络上检索数据并使用关键字对其进行搜索。可以将来自搜索引擎的数据与其他数据库(如向量存储、图数据库等)中获取到 的 数据相结合,以提高输出质量。————tips

结合多种策略(如语义搜索 + 关键字匹配)的混合方法也是可行的,而且众所周知,这种方法在大多数使用案例中都能提供更好的结果。例如,您可以使用矢量存储来存储文本数据,使用图数据库来存储结构化数据,然后将两个数据库的结果结合起来生成输出。

⑥检索

一旦数据被识别和处理以备检索,RAG 管道就会根据所处理的任务(用户提出的问题)检索相关数据,并准备将上下文传递给生成器。检索策略可根据用例而有所不同。它通常涉及将用户的查询或任务传递给数据存储并提取相关结果。例如,如果我们正在使用一个存储相关数据块的矢量数据库构建一个问题解答系统,那么我们可以为用户的查询生成嵌入式数据,在矢量数据库中对嵌入式数据进行相似性搜索,然后检索出最相似的数据块(有些矢量数据库会在检索过程中生成嵌入式数据)。同样,根据不同的使用情况,我们可以在同一向量存储区或多个数据库中进行混合搜索,并将搜索结果作为上下文传递给生成器。

⑦生成

一旦检索到相关数据,就会连同用户的查询或任务一起传递给生成器(LLM)。LLM 使用检索到的数据和用户的查询或任务生成输出。输出结果的质量取决于数据的质量和检索策略。生成输出结果的指令也会对输出结果的质量产生很大影响。

(3)如何提高RAG性能

在生产中提高RAG性能的技术以下是在RAG流程的不同阶段可以用来提高生产中RAG性能的一些技术。

  • 混合搜索:将语义搜索与关键词搜索结合起来,从向量存储中检索相关数据已被证明对大多数用例都能获得更好的结果。
  • 摘要:对块进行摘要并将摘要存储在向量存储中,而不是原始块。例如,如果您的数据包含很多填充词,那么总结块以去除填充词并将摘要存储在向量存储中是一个好主意。这将改善生成质量,因为我们除了帮标记数量外还消除了数据中的干扰叠块:当将数据分割检索的块时,在语义搜索程中可能会选择具有相邻块相关和有用上下文信息的情况。如果没有周围上下文环境就直接传递该块给LLM进行生成,则可能导输出质量较差。为避免这种情况,我们可以将重叠部分传递给LLM进行生成。例如,如果我们将数据分割成100个标记大小的块,则可以通过50个标记大小来使这些块重叠。这样可以确保我们为LLM生成时传递了周围上下文信息。
  • 微调嵌入模型:使用BERT、ada等现成的嵌入模型为数据块生成嵌入可能适用于大多数用例。但是如果您正在处理特定领域,请注意这些模型可能无法很好地表示该领域,在向量空间内导致检索质量较差。在这种情况下,我们可以对该领域内的调并使用一个自定义化后续使用embedding模型以提高检索质量。
  • 元数据:提供关于上下文中传递的块的来源等元数据,将有助于LLM更好地理解上下文,从而产生更好的输出生成。
  • 重新排序:在使用语义搜索时,可能会出现前k个结果相似的情况。在这种情况下,我们应该考虑根据其他因素(如元数据、关键词匹配等)对结果进行重新排序,以涵盖与LLM相关的各种间
  • 丢失问题:观察到LLMs并不给予输入中所有标记相同权重。中间标记似乎比输入开头和结尾处的标记被赋予较低权重。这被称为中间丢失问题。为了避免这种情况,我们可以重新排列上下文片段,使最重要的片段位于输入开头和结尾,并将次要片段放置在中间位置。

你可能感兴趣的:(人工智能,AIGC,chatgpt)