GoT:用大语言模型解决复杂的问题
摘要
本文介绍了一种思维图(GoT),这是一个框架,将大语言模型中的提示能力提升到思维链或思维树等范式之外。GoT的关键思想和主要优点是能够将大语言模型生成的信息生成建模为任意图,其中信息单位(“LLM thoughts”)是顶点,边对应这些顶点之间的依赖关系。这种方法能够将任意大语言模型的思想组合协同输出,或使用反馈循环增强思想。我们说明了GoT在不同任务上比现有技术具有的优势。确保GoT可以通过新的思想转换进行进行扩展,因此可以用于引导新的提示方案。这项工作使LLM推理更接近人类的大脑机制和思维,如循环,形成了复杂的网络。
介绍
大语言模型正在接管AI世界。近年来,主要基于解码器的Transformer变体的模型得到了飞速发展,如GPT、PaLM、LLaMA。
提示工程是一种资源高效的方法,用于解决不同的大语言模型的任务。简而言之,在发送给大语言模型的输入中包括任务描述。如果该描述被适当地公式化,则大语言模型使用其基于自回归令牌的机制来生成文本,从而解决任务。此类提示可能包含具有解决方案的实例任务(少样本,也称为上下文学习(ICL)),甚至根本没有实例任务(零样本)。近年来的研究表明,这种机制可以用于解决一系列设计数学、常识或符号推理的任务。
CoT是一种提示方法,其中包括在提示中重新排序的中间步骤(中间“thoughts”),而不是任务输入/输出。CoT被证明可以显著提高LLM解决问题的能力,而无需对任何模型更新进行重新排序。一个主要的用来提升CoT的方法是CoT-SC(自我一致性方法),是一种生成多个CoT,然后选择最佳CoT作为结果的方案。最近,CoT和CoT-SC用了思维树(ToT)进行了扩展,该树用树对大语言模型推理过程进行建模。该方法使用不同的思想路径,并提供了一些新颖的功能,如从没有希望的结果中回溯。不幸的是,ToT方法任然通过在思维过程中加强刚性的树结构,在一定程度上限制了推理能力。
在这项工作中,我们认为,通过使用LLM思想形成任意的图结构,可以从根本上实现更强大的提示。这是由人类推理、大脑结构或算法执行等复杂现象驱动的。当研究一个新的想法时,人类不仅会遵循一个思维链或尝试不同独立思想(如思维树),而且实际上会形成一个更复杂的思想网络。例如,一个人可以探索某个推理链,回溯并开始一个新的推理链,然后意识到前一个推理链中的某个想法可以与当前探索的想法相结合,并将它们合并为一个新的解决方案,利用它们的优势,消除它们的弱点。类似地大脑形成了复杂的网络,具有类似图形的模式,如复现。执行算法也暴露了网络模式,通常由无向循环图表示。对应的 **图启用转换(graph-enabled transformation)**在应用于大语言模型思想时带来了更强大的提示。但它们不能自然地用COT或ToT表示。
我们观察到,当将大语言模型的重组过程建模为图时,这些思想转化可以自然地实现。为此我们提出了思维图,这是一种通过削弱推理增强大语言模型能力的方法。在GoT中,大语言模型思想被建模为顶点,而边是这些思想之间的依赖关系。使用GoT,可以通过构造具有多个进入边的顶点来聚合任意思想。总的来说,GoT无缝地使用的图抽象将CoT和ToT概括为更复杂的思维模式,而不需要任何模型更新。
然而,将GoT付诸实践需要解决几个设计挑战,例如,不同任务的最佳图形结构是什么?为了回答这些问题,我们仔细设计了一个用于实现GoT的模块化架构,并结合了两个设计亮点。首先,我们能够对单独的思想进行精细的控制。这使得我们能够完全控制与LLM正在进行的对话,并应用先进的思想转换,例如将正在进行的推理中最具有破坏性的思想组合成新的思想。其次,我们确保我们的架构可以通过新的思维转换、推理模型(即思维图)和大语言模型无缝扩展。这使得我们能在GoT上快速原型化新的提示思想,同时尝试不同的模型。
我们展示了GoT的几个用例(排序、摘要的关键字计数、集合操作、文档合并),并详细介绍了如何使用基于图的范式实现它们。我们评估了GoT并展示了它相对现有技术的优势。总的来说,我们观察到GoT特别适合于可以自然分解为更小子任务的任务,这些子任务可以单独解决,然后合并为最终解决方案。在这里,GoT优于其他方案,例如,就分拣质量而言,比ToT降低了大于31%的成本。GoT是唯一一个能够在提示中实现基于任意图的思想转换的方案,例如聚合,包括之前提到的所有方案。
最后我们提出了一个新的指标来评估策略,即 思维容量(volume of a thought) 。通过这个指标,我们旨在更好地理解提示方案之间的差异。对于给定的思维 v v v, v v v的体积是大语言模型中思维的数量,从中可以使用有向边到达 v v v。直观地说,这些都是大语言模型有潜力为 v v v做出贡献的思想。我们表明,GoT通过结合聚合等思想转换,使思想比其他方案有根本上的大容量。
背景和符号表示
语言模型和上下文学习
与LLM对话包括用户消息(提示)和LLM回复(想法)。我们遵循已建立的符号(notation),并且,我们将带有参数 θ θ θ的一个预训练的语言模型表示为 p θ p~θ~ p θ ,小写字母如 x , y , z , . . . x,y,z,... x,y,z,...表示LLM的思想。我们故意不规定什么是单一的“thought”,而是使其特定于用例。因此,一个想法可以是一个段落(例如在文章的摘要中)、一个文档(例如,在文档生成中)、代码块(例如,在代码调试或操作中)等。
下面描述具体提示的方法。
Input-Output(IO)
IO提示是一种直接的方式,我们使用大语言模型将输入序列x直接转换为输出y,而不需要任何中间思想。
Chain of thought(CoT)
在CoT中,介绍了在x到y生成过程中的中间思想。该策略被证明在简单的IO基线上显著提高了各种语言模型任务,例如数学难题或一般数学推理。
Multiple CoT
可以通过独立地生成k个CoT,并转换为具有最佳输出的CoT(根据某个规定的评分指标),将CoT推广为多个CoT。被称为CoT自我一致性的方法增强了CoT,因为它提供了探索推理路径的机会。然而,它不提供路径内的“局部探索”,例如回溯。
Tree of thoughts(ToT)
最后,思维树的方法在一定程度上被其他方案隐含地使用,如思想分解。它通过将过程或推理建模为思维树来增强CoT-SC。单个树节点表示部分解决方案。思维生成器基于一个给定的节点构造一个给定数量的新节点。然后,状态评估器为每个这样的新节点生成分数。根据使用情况,评估可以使用大语言模型本身进行,也可以使用人工评分。最后,扩展树的时间由所使用的搜索算法(如BFS或DFS)决定。
GoT框架
这一节详细介绍了GoT框架并与其他提示策略进行比较。
形式上,GoT可以建模为元组 ( G , T , E , R ) (G,T,E,R) (G,T,E,R),其中G是LLM推理的过程(即上下文中的所有LLM思维及其关系),T是可能的思维变换,E是用于获得思维分数的评估器函数,R是用于选择最相关思维的排序函数。
推理过程
这里,推理过程被建模为一个有向图G=(V , E),其中V是一组顶点,E ⊆ V×V是一组边。G是有向的,因此边是有序顶点对E ⊆ V×V的子集。一个顶点包含对当前问题的一个解答,不管这个问题是最初的问题,还是中间的问题,或最后的问题,这种思维的具体形式取决于用例;其可能是一个段落(在写作任务中)、一个数值排序(在排序任务中)。一个有向边(t1,t2)表示思维t2的构建方式是将t1用作“直接输入”,即通过明确指示LLM使用t1来生成t2。
在某些用例中,图节点属于不同类别,举个例子,在写作任务中,一些顶点建模写出一段文本的计划,其他节点则建模实际的文本段。在这种情况下,GoT采用异构图G=(V,E,c)来建模大语言模型推理,其中c将顶点V映射到各自的类C(上述案例中,C={plan,par}),这样一来,任何顶点 v v v都可以建模推理的不同方面。
于是G就与LLM推理过程联系起来。为了推进这一过程,我们将思想转换应用于G。这种转变一个例子是将得分最高的想法合并到一个新的想法中。另一个例子是对一个思想进行循环,以增强它。注意,这些转换严格扩展了CoT、CoT-SC、ToT中可用的转换集合。
思维变换
GoT可以实现全新的思维变换(得益于将基于图的模型用于推理),我们称之为图使能的变换(graph-enable transformation)。比如,在写作任务中可以将多篇输入文章组合成一篇连贯一致的摘要。在排序时,可以将多个已排序的数值子数组合并为一个最终已排序数组。
形式上将,每个这样的变换都可以建模成T(G,pθ),其中 G = (V, E) 是反映推理当前状态的图,pθ 是所使用的 LLM。T 修改 G 的方式通常是通过添加新顶点及其传入边。于是有 G′ = T (G, pθ) = (V′, E′),其中 V′ = (V ∪ {V+}) \ {V−} 且 E′ = (E ∪ {E+}) \ {E−}。V+ 和 E+ 是注入到 G 中的新顶点和边,它们分别建模的是新的思维和它们的依赖关系。
为了最大化 GoT 的表达能力,用户还可以删除思维,做法是指定要删除的相应顶点和边(分别为 V− 和 E−)。在这里,确保集合 V+、E+、V− 和 E− 有一致的变换是用户的责任(举个例子,用户不会尝试删除不存在的顶点)。这使得 prompt 方案能无缝整合,其中用户可以为了节省上下文中的空间而移除无法带来提升的推理部分。
T 的具体形式及其影响 G 的方式取决于具体的变换。下面首先详细介绍主要几个图使能的思维变换,然后会描述 GoT 何以囊括之前方案的变换。除非另有说明,V− = E− = ∅。
聚合变换:
用户可以使用 GoT 将任意思维聚合成新思维,实现取长补短。这里看看只创建一个新顶点的基础形式:V+ = {v+} 且 E+ = {(v1, v+), …,(vk, v+)},其中 v1, …, vk 是被融合的 k 个思维。更一般而言,这能实现对推理路径的聚合,即更长的思维链,而不只是单个思维。使用图模型,可以轻松实现聚合变换:通过添加来自建模了几条链中最后思维的顶点 v1, …, vk 的传出边,使之指向组合这些链的单个思维 v+。
细化变换:
另一种思维变换是通过修改内容对当前思维 v 进行细化:V+ = {} 和 E+ = {(v, v)}。图中的这个循环表示与原始思维有同样连接的迭代版思维。
生成变换:
最后,用户还可以基于已有的单个思维 v 生成一个或多个新思维。这一类别中包含 ToT 或 CoT-SC 等更早期方案中的类似推理步骤。在形式上:
思维的分类和排序
对思维评分的目的是为了理解当前的解答是否足够好。分数被建模为一个一般函数 E (v, G, pθ),其中 v 是所要评估的思维。为了尽可能让 E 更普适通用,E 中还使用了推理的整个过程 (G),因为在某些评估场景中,分数可能与其它思维相关。
GoT 也能排名。研究者使用了函数 R (G, pθ, h) 来建模,其中 h 指定了要被 R 返回的 G 中排名最高的思维的数量。虽然 R 的具体形式取决于用例,但最常使用一个简单而有效的方法是返回分数最高的 h 个思维,即 v1, …, vh = R (G, pθ, h)。
E 和 R 的具体形式取决于用例。
系统构架和扩展
GoT 由一组交互式模块构成,见下图(蓝色部分)。这些模块是 Prompter(准备用于 LLM 的消息)、Parser(解析器,提取 LLM 答复中的信息)、评分模块(验证 LLM 答复并评分)、Controller(控制器,协调整个推理过程,并决定如何推进推理)。Controller 中包含另外两个重要组件:操作图(GoO)和图推理状态(GRS)。GoO 是一个静态结构,其指定了对给定任务的图分解,即它规定了应用于 LLM 思维的变换及其顺序和依赖关系。GRS 是一个动态结构,其维持着正在进行的 LLM 推理过程的状态(其思维及其状态的历史)。
Prompter(提示器)
Prompter准备发送给LLM的提示。该模块负责在提示中编码图结构的具体细节。GoT架构允许用户通过提供对图结构的完全访问,来实现对特定于用例的图形编码。
Parser(解析器)
解析器从LLM的思想中提取信息。对于每一个LLM思想,解析器构建了思维状态,其中包括这些提取的信息。思维 状态随后用于相应地更新GRS。
得分和验证
在此验证给定LLM的思想是否满足潜在的正确性条件,然后给它分配一个分数。根据分数的推导方式,模块可能会查阅LLM。此外,根据用例的不同,内核也可能由人分配。最后,使用简单的本地排序函数进行排序。
控制器(Controller)
控制器执行一个特定的策略来从其GRS结构中选择思想。它还选择应该对哪些思想应用哪些变换(聚合变换、细化变换、生成变换),然后将这些信息传递给提示器。它还决定了整个过程是否应该被最终确定,或者是否应该启动与LLM的下一轮互动。在目前的设计中,这是由GoO中指定的执行计划决定的。
GoO和GRS
用户构造一个GoO实例,该实例规定了思维操作的执行计划。GoO是一个静态结构,在执行开始之前构造一次。每个操作对象都知道其前一个操作和后一个操作。然后,在执行过程中,GoO的一个实例维护关于LLM推理过程的不断更新的信息。这包括到目前为止执行了哪些操作,它们的有效性和分数,以及任何其他相关信息。
上述元素提供了可扩展的API,包括不同提示方案的直接实现。API在图3的绿色部分中进行了概述,并在文档中进行了详细说明。我们还在图3的红色部分提供了这些操作使用的提示实例和响应的GRS。
实验用例
排序
详细介绍一个排序的用例。我们专注于它的分解和操作图,这是实现和执行GoT中任何工作负载的核心。我们用双复数对数字0-9进行排序。由于 重复计数不匹配,大语言模型不能对某一长度的数字进行正确的排序。
重复计数的结果与实际的重复元素数量不匹配
在GoT中,我们使用基于合并的排序:首先,将输入的数字序列分解为子数组。然后,对这些子数组进行单独排序,然后将它们分别合并为最终方案。这里,LLM的思想是一个排序的数字序列。
为了对结果进行评分,用[a1,a2,…,an]代表一个输入序列,[b1,b2,…,bm]代表一个输出序列。我们使用下列分数作为错误的范围。
X指明有多少连续的数字对被错误地排序了。如果两个数字
i
i
i和
i
+
1
i+1
i+1排序错了(例如
b
i
>
b
i
b_i>b_i
bi>bi+1),那么求和中的表达式返回1,将错误的分数增加一。当两个数字正确的排序时,求和中的表达式返回0。然后,Y确定了给定输出序列在多大程度上保持输出数字的频率。对于每一个被考虑的数字x(x∈{0,…,9}),我们获得等于x的输入元素的计数与等于x的输出元素的计数之间的差。对于完全保持输出频率为2的输出序列,这将等于0。该计数中的任何一个“偏差”都会使“误差范围”增大。我们然后将其与所有考虑的值x相加。在绘制该分数时,为了提高绘图的清晰度,我们还应用了clipping min(error-scope, n),因为一些基线(IO,CoT)会导致大量具有高误差范围的异常值。最后,要使用“正分数”来描述“正确排序的范围”元素,可以使用max(n — error-scope,0)
对min(error-scope, n)进行剪裁。
剪裁是一种常见的数学操作,用于限制一个值的范围在指定的上下限之间。
在这种情况下,"min(error-scope, n)"返回"error-scope"和"n"中的较小值,而剪裁操作会确保这个结果不会超过某个上限或低于某个下限。
集合运算
此外,我呢还考虑了集合运算,重点讨论了集合交集。它们在从基因组或者文档比较 到模式匹配的问题中的众多应用(特别是集合交集)。两个集合的集合交集与排序类似。第二个输入集合被划分成子集,并借助LLM确定这些子集与第一个输入的集合的交集。在这之后,这个交集集合被聚合成最终的结果。为了评估,我们使用了32,64,128个元素的不同集合大小,并且我们将两个集合中的元素数量都在变到25%到75%之间。
我们的分数表示最终交叉点中缺失或正确包含的元素的总和。具体来说,用A=[a1,a2,…,an]和B=[b1,b2,…,bn]表示两个输入集合,C=[c1,c2,…,cn]表示输出集合。所以,
其中X1=| C \ (A∩B) |是C中的不应该在这的元素的数量,X2=| (A∩B) \ C|是C中缺失的元素数量,Xd是C中的重复数量(因为大语言模型在自然语言中将集合表示为列表)。最后,可以使用max(n — error-scope, 0) 来使用“正得分”描述“正确计算的范围”元素。
关键字计数
关键字计数找到在输入文本中的一个给出类别的频率(在示例中为:国家)。GoT将输入文本划分成多个段落,统计每个段落的关键字,并对子结果进行聚类。段落的数量是可配置的,也可以留给LLM,从而可以将每个句子视为单独的段落。在这里,为了给一个想法打分,我们首先(对于每个关键词)推导出计算计数和正确计数之间差的绝对值。然后,我们将所有这些差值相加,得到最终的分数。
文档合并
最后,也提供了文档合并。目标是基于多个在内容上部分重叠的输入文件产生一个新的保密协议(NDA)文档。这个目标是确保尽量减少重复,同时最大限度地保留信息。文档合并广泛适用,如法律程序,即必须将多个信息源合并为一个文档或文章。为了对解决方案进行评分,我们查询LLM中的两个值(每个值3次,取平均值)。第一个值对应于解决方案的冗余(10表示没有冗余,0表示至少一半信息冗余),第二个值表示信息的保留(10代表保留了所有信息,0表示没有保留)。我们计算这些值的调和平均值。
延迟和量之间的权衡
GoT在延迟(GoT中达到给定最终思维的次数)和量之间的权衡方面改进了以前的提示方案。我们将给定思维 t 的体积定义为先前LLM思想的数量。形式上,t的体积是GoT中存在通向t的路径的思想的数量。我们假设输出单个思想花费O(1)时间,并将每个提示方案的总成本固定为Θ(n)。
这些方案的结构如下。CoT-SC由源自单一启动思想的k个独立链组成。ToT是一个完整的k元树。最后,在GoT中,一颗完整的k元树在其叶子处与一颗大小相同但边缘颠倒的镜像k元树相连。
CoT提供高达N的大容量,但以N的高延迟为代价。CoT-SC将延长减少了k被(对应于其分支),但同时也将容量减少了k。ToT提供了logkN的延迟,但体积很小。GoT是唯一一个同时具有logkN的延迟和高容量N的方案。这是因为GoT利用了思路的聚合,使得从图分解中的任何其他中间思想中得出最终思想成为可能。
评估
展现GoT相对于现有技术的优势,重点与ToT进行了比较,因为ToT明显优于其他方案。尽管如此,为例进行比较,还对IO、CoT、CoT-SC进行了实验。由于分析结果在很大的评估空间中,作者给出了具有代表性的结果,并省略了不会带来相关影响的数据(如CoT-SC)。
本文为每个任务使用100个输入样本,并比较基线。将温度设置为1.0,除非另有说明,否则我们使用4k的上下文。对于每个实验,作者们在各个方案中固定了思想的数量,以在每个实验中实现相似的成本。
参数
对分支因子k和水平数量L进行了广泛的实验,以确保将GoT与具有成本效益和优势的组合进行比较。绘制了ToT的两个变体:一个具有较高的k(分支因子)和较低的深度(ToT),另一个具有较低的k但较高的L(水平数量)(ToT2)。通常的目标是在稀疏生成轮数(较低的k)与更多论述(较大的L)之间的权衡中实现最佳点。通常,每轮更多的回复更为昂贵(例如,图7的总回复为80比60,但成本为6美元比3美元)。我们还尝试了不同的问题大小P(例如,在排序中,P表示要排序的数字数量)。使用LLM
由于预算限制,我们将重点放在GPT-3.5上,使用GPT-4。我们还用Llama-2进行了实验,但它通常比GPT-3.5更差,也更慢,因此无法获得足够的样本。
GoT的优势
分析的结果:图5(排序)、图6(交集集合)、图7(关键字统计)、图8(文档合并)。
GoT vs. ToT
GoT与ToT相比,在所有考虑的问题实例中,GoT完善了ToT和ToT2。ToT的质量往往略高于ToT2,但同时成本也高得多。GoT的成本总是低于ToT,并且与ToT2相当(在某些情况下更低,在另一些情况下更高)。
GoT vs. IO and CoT
已解决问题的复杂性日益增大
关于任务分解的讨论
当将任务分解为子任务,然后求解这些子任务时,响应和输入(以令牌表示)的大小会随着任务分解的程度而成比例减少。然而,提示的“静态”部分(即少样本提示)可能会成为一个巨大的开销(见图7中的GoT4到GoT8)。在这里,我们观察到,这些少样本的示例 通常也可以缩小大小(例如,用于演示关键字计数的通道也可以缩小,并且仍然可以指示实际输入大小),从而努力降低成本(例如,见图7中GoT8和GoTx之间的差异)。
进行图分解时的总体目标是将任务分解到这样一个点,即LLM可以使用单个提示(或通过一些额外的改进步骤)在最长的时间内正确求解。这显著降低了在图探索的后期阶段所需的改进/细化步骤的数量。此外,正如我们的结果所表明的,组合或合并子结果通常比从头开始解决大型任务实例更容易。因此,LLM在聚合最终解决方案时通常是成功的。