LLMCompiler:大模型的并行工具调用 原创
大型语言模型(LLM)有一些固有限制,如知识截断、较差的算术能力或无法访问私有数据等。为了克服这些限制,研究人员使用了诸如检索增强生成(Retrieval Augmented Generation,RAG)的技术,该技术通过查询向量或结构化数据库,在提示中添加相关上下文的结果。
像Toolformer和ReAct这样的创新提高了LLM的性能,使其能够使用外部函数进行复杂问题的解决。LLM整合各种工具和函数调用的能力可能会导致在开发基于LLM的软件时发生根本性的转变。当前方法(特别是ReAct)存在一些挑战:
- 准确性:连接中间观察结果可能会影响LLM的执行流程,从而降低准确性。
- 串行执行:无法并行运行多个工具。
- 可靠性:中间结果可能会影响LLM跟踪任务的能力。
- 可测试性:很难为代码的特定路径创建单元测试。
- 长期规划:当前的LLM在长期规划方面表现不佳。
- 调试:需要手动阅读中间思考/观察,并推理LLM为什么得出错误的结果。
- 容错性:很难从LLM的错误决策中恢复(无重新规划)。
💡 如果我们能将问题分解为更易处理的函数调用,会怎样?
这与熟练的程序员在大规模代码中所做的类似,将代码分解成较小、易于推理、调试和测试的部分。编写正确调用这些部分的控制逻辑,并使用try/except进行错误处理。
这正是LLMCompiler想要解决的问题!
LLMCompiler是第一个优化LLM函数调用编排的框架,它不仅可以提高响应时间和成本,还可以通过减少中间函数调用的干扰来提高准确性,并优化LLM的并行函数调用性能。
从高层次上看,这是通过引入三个关键组件来实现的:
- LLM计划器:用于识别执行流程的LLM计划器;
- 任务获取单元:根据贪婪策略,将任务并行地发送给执行器;
- 执行器:使用关联函数执行任务的执行器。
LLMCompiler概述
LLM计划器:LLM计划器生成一个任务序列及其依赖关系,形成一个有向无环图。它利用LLMs的推理能力,识别任务、输入和相互依赖关系。如果一个任务依赖于之前的任务,它将使用占位符变量,在稍后用该任务的实际输出替换该变量。
计划器利用LLMs的推理能力,通过预定义的提示将自然语言输入分解为任务,并指导它如何创建依赖图并确保正确的语法格式。
任务获取单元:任务获取单元根据贪婪策略,一旦任务准备就绪(并行执行),就将任务发送给执行器。它将变量替换为计划器最初设置的占位符的实际输出。在上面的示例中,Task Fetching Unit会在搜索任务完成后,将任务
中的变量1和$2替换为Microsoft和Apple的实际市值。
执行器:执行器以异步和并发的方式执行从任务获取单元获取的任务。执行器配备了用户提供的工具,并将任务委托给关联的工具。这些工具可以是简单的函数,如计算器、维基百科搜索或API调用,甚至可以是针对特定任务定制的LLM代理。每个任务都有专用的内存来存储其中间结果,类似于典型的顺序框架在将观察结果聚合为单个提示时所做的操作。任务完成后,最终结果将作为输入转发给依赖于它们的其他任务。
动态重新规划:执行图可能需要根据先前未知的中间结果进行调整。在程序中,类似的情况是分支,执行路径只在运行时确定,取决于满足哪些分支条件。在LLM函数调用中也可能出现这种动态执行模式。在重新规划中,执行器将中间结果发送回LLM计划器。根据此结果,计划器生成一组新的任务及其关联的依赖关系,并将它们发送给任务获取单元,然后再发送给执行器。此过程重复执行,直到获得最终结果。
如何使用?
在LLMCompiler中,用户只需要提供以下内容:
工具定义:工具的名称、类型和参数,与其他框架(如ReAct、OpenAI函数调用等)类似。
计划器的上下文示例:说明计划器应该如何工作的示例,这有助于LLM计划器以正确的格式生成适当的依赖图。
性能结果
LLMCompiler的延迟改进:LLMCompiler通过避免顺序推理和函数调用显著减少延迟,在各种数据集上相对于ReAct的加速比可达到1.8倍和3.7倍。
值得注意的是,LLMCompiler在并行函数调用方面甚至超过了OpenAI,提高了高达35%的性能。这种改进可能源于在幕后减少验证函数名称和参数的开销。
LLMCompiler的准确性改进:LLMCompiler在准确性方面优于ReAct。通过预先规划的执行和最小化每个推理-操作循环中间结果的干扰,LLMCompiler减轻了ReAct的冗余函数调用和过早终止等缺点。
LLMCompiler与OpenAI的并行函数调用的准确性相匹配。
结论
LLMCompiler框架代表了在更有效的问题解决中利用大型语言模型(LLM)的一项变革性进展,解决了知识截断、算术限制和数据访问限制等固有挑战。通过优化LLM函数调用以提高响应时间、成本和准确性,LLMCompiler引入了一种新颖的方法,类似于熟练的编程实践——将复杂任务分解为可管理的单元,并采用动态重新规划。它不仅在实际应用中显著增强了LLM的效用,而且为人工智能和机器学习技术的未来开辟了新的视野,为开发更强大、适应性更强、能够应对复杂挑战的系统带来了希望。
译自(有删改):https://www.anup.io/p/llmcompiler-towards-parallel-function
本文转载自公众号AIGC最前线