📢 转载信息
原文链接:http://bair.berkeley.edu/blog/2024/05/29/tiny-agent/
原文作者:Lutfi Eren Erdogan, Nicholas Lee, Siddharth Jha, Sehoon Kim, Ryan Tabrizi, Suhong Moon, Coleman Hooper, Gopala Anumanchipalli, Kurt Keutzer, Amir Gholami
TinyAgent:边缘侧实现函数调用,小模型也能媲美 GPT-4 性能!
大型语言模型(LLM)通过自然语言执行命令(例如英语)的能力,催生了能够通过编排一系列工具(例如 ToolFormer, Gorilla)来完成用户查询的智能体系统。这,连同最近 GPT-4o 或 Gemini-1.5 等多模态模型的进展,极大地扩展了 AI 智能体的可能性边界。尽管前景令人兴奋,但这些模型的巨大尺寸和高计算要求通常意味着它们的推理必须在云端进行。这给其广泛应用带来了几个挑战。首先,将视频、音频或文本文档等数据上传到第三方云供应商可能会引发隐私问题。其次,这需要稳定的云/Wi-Fi 连接,而这种连接并非总能保证。例如,部署在现实世界中的机器人可能无法始终保持稳定连接。此外,延迟也是一个问题,上传大量数据到云端并等待响应可能会减慢响应时间,导致无法接受的“解决时间”。如果能在边缘设备上本地部署 LLM 模型,这些挑战就可以迎刃而解。
然而,当前的 LLM,如 GPT-4o 或 Gemini-1.5,对于本地部署来说太大了。一个因素是,模型尺寸的很大一部分用于将其关于世界的通用信息“记忆”到其参数化内存中,而这些信息对于特定的下游应用来说可能并不需要。例如,如果你向这些模型提出一个通用的事实性问题,如历史事件或著名人物,它们可以在没有额外上下文的情况下,仅依靠其参数化内存来生成结果。然而,数据隐式地记忆到参数化内存中的现象,似乎与 LLM 中的“涌现”现象(如上下文学习和复杂推理)相关,这也是模型规模不断扩大的驱动力。
实现这一点将大大减少智能体系统的计算足迹,从而实现高效、保护隐私的边缘部署。我们的研究表明,通过使用专门的、高质量的数据进行训练(这些数据不需要回忆通用的世界知识),小型语言模型也可以实现这一点。
这样的系统在语义系统中特别有用,在这些系统中,AI 智能体的作用是理解自然语言的用户查询,然后不是像 ChatGPT 那样回答问题,而是编排正确的工具和 API 集合来完成用户的命令。例如,在一个类似 Siri 的应用中,用户可能会要求语言模型创建一个带有特定与会者的日历邀请。如果已经为创建日历项定义了预设脚本,LLM 只需要学会如何调用此脚本并提供正确的输入参数(如与会者的电子邮件地址、事件标题和时间)。这个过程不需要回忆/记忆维基百科等来源的世界知识,而需要推理和学习如何调用正确的函数并正确地编排它们。
我们的目标是开发能够进行复杂推理的小型语言模型(SLM),以便能够安全、私密地在边缘部署。在这里,我们将讨论我们正在为此目标而进行的研究方向。首先,我们讨论如何使小型开源模型能够执行准确的函数调用,这是智能体系统的关键组成部分。结果表明,现成的(off-the-shelf)小型模型具有非常低的函数调用能力。我们讨论了如何通过系统地策划高质量的函数调用数据来解决这个问题,并以一个专门的 Mac 助手智能体作为我们的驱动应用。然后我们展示,在这些高质量策划数据集上进行微调,可以让 SLM 的函数调用性能甚至超过 GPT-4-Turbo。接着,我们展示了如何通过一种新的工具 RAG 方法进一步改进和提高效率。最后,我们展示了如何将最终模型高效地部署到边缘设备上,实现实时响应。
TinyAgent-1B 连同 Whisper-v3 在 Macbook M3 Pro 上本地部署的演示。该框架已开源,可在 https://github.com/SqueezeAILab/TinyAgent 获取
教 LLM 进行函数调用
图 1:LLMCompiler 函数调用规划器概述。规划器理解用户查询并生成一系列带有相互依赖关系的(Task)任务。然后,LLMCompiler 框架会将这些任务分派出去以完成用户命令。在这个例子中,任务 $1 和 $2 一起被获取,以分别检索 Sid 和 Lutfi 的电子邮件地址。在每个任务执行后,结果被转发到任务 $3,该任务创建日历事件。在执行任务 $3 之前,LLMCompiler 会用实际值替换占位符变量(例如变量 $1 和 $2)。
如上所述,我们的主要兴趣在于 AI 智能体将用户查询转换为一系列函数调用来完成任务的应用程序。在这些应用程序中,模型不需要自己编写函数定义,因为函数(或 API)大多是预定义的并已可用的。因此,模型需要做的是根据函数调用之间的相互依赖性,确定 (i) 要调用哪些函数,(ii) 相应的输入参数,以及 (iii) 调用这些函数的正确顺序(即函数编排)。
第一个问题是如何找到一种有效的方法来使 SLM 具备函数调用能力。像 GPT-4 这样的大模型可以执行函数调用,但如何用开源模型来实现呢?LLMCompiler 是我们小组最近提出的一个框架,它通过指示 LLM 输出一个函数调用计划来实现这一点,该计划包括它需要调用的函数集以及输入参数和它们的依赖关系(参见图 1 中的示例)。一旦生成了这个函数调用计划,我们就可以对其进行解析,并根据依赖关系调用每个函数。
这里的关键部分是教会模型以正确的语法和依赖关系创建此函数调用计划。最初的 LLMCompiler 论文只考虑了大型模型,如 LLaMA-2 70B,这些模型在提供足够的提示指令时,具有复杂的推理能力来创建计划。然而,是否可以用相同的方式提示小型模型以输出正确的函数调用计划呢?不幸的是,我们的实验表明,现成的(off-the-shelf)小型模型,如 TinyLLaMA-1.1B(甚至是更大的 Wizard-2-7B 模型),无法输出正确的计划。错误包括使用错误的函数集、虚构的名称、错误的依赖关系、不一致的语法等。
这其实是意料之中的,因为这些小型模型是在通用数据集上训练的,主要目标是在通用基准测试中取得良好的准确性,而这些基准测试大多测试模型的世界知识、通用推理或基本的指令遵循能力。为了解决这个问题,我们探索了是否可以通过针对函数调用和规划专门策划的高质量数据集对这些模型进行微调,来提高小型语言模型在目标任务上的准确性,并可能超越大型模型。接下来,我们首先讨论如何生成这样的数据集,然后讨论微调方法。
数据集生成
图 2:TinyAgent 是一个可以与各种 MacOS 应用程序交互以协助用户的助手。命令可以通过文本(通过聚光灯输入)或语音下达给它。
作为驱动应用程序,我们考虑了一个用于苹果 Macbook 的本地智能体系统,用于解决用户的日常任务,如图 2 所示。特别是,该智能体配备了 16 种不同的函数,可以与 Mac 上的不同应用程序交互,包括:
- 电子邮件:撰写新邮件或回复/转发邮件
- 联系人:从联系人数据库中检索电话号码或电子邮件地址
- 短信:向联系人发送文本消息
- 日历:创建包含标题、时间、与会者等详细信息的日历事件
- 备忘录:在各种文件夹中创建、打开或追加内容到备忘录
- 提醒:为各种活动和任务设置提醒
- 文件管理:打开、读取或总结各种文件路径中的文档
- Zoom 会议:安排和组织 Zoom 会议
每个函数/工具都存在预定义的 Apple 脚本,模型需要做的就是利用这些预定义 API 并确定正确的函数调用计划来完成给定任务,如图 1 所示。但正如前面讨论的,我们需要一些数据来评估和训练小型语言模型,因为它们现成的函数调用能力不佳。
创建具有多样化函数调用计划的手工数据既具有挑战性又缺乏可扩展性。然而,我们可以使用 GPT-4-Turbo 等 LLM 来策划合成数据。这种方法正成为一种常见的方法,其中会指示一个能力强的 LLM 根据给定的一组示例或模板生成类似的数据(参见 LLM2LLM 和 Self-Instruct)。在我们的工作中,我们采用了类似的方法,但不是向 LLM 提供通用用户查询作为模板,而是向它提供各种函数集,并指示它生成需要那些函数来完成任务的真实用户查询,以及相关的函数调用计划和输入参数,就像图 1 中所示的示例。为了验证生成数据的有效性,我们对函数调用计划进行了健全性检查,以确保它们形成一个可行的图,并且函数名称和输入参数类型是正确的。通过这种方法,我们只花费了约 500 美元的总成本,创建了 80K 训练数据、1K 验证数据和 1K 测试数据。
微调以改进函数调用推理
图 3:图同构成功率。仅当模型生成的计划的 DAG 与地面真相计划的 DAG 同构时,模型才得分为 1;否则为 0。在上面的例子中,虽然 get_email_address 调用的顺序与地面真相计划不同(地面真相计划先获取 Lutfi 的电子邮件地址,然后是 Sid,而生成的计划先获取 Sid 的电子邮件地址,然后是 Lutfi),但由于两个 DAG 相互同构,因此计划获得 1 的成功率。在下面的案例中,由于预测的 DAG 包含一个错误的节点,对应于错误的函数调用,因此计划获得 0 的成功率。
有了我们的数据集,我们现在可以着手对现成的 SLM 进行微调,以增强其函数调用能力。我们从两个基础小型模型开始:TinyLlama-1.1B(instruct-32k 版本)和 Wizard-2-7B。对于这些模型的微调,我们首先需要定义一个指标来评估它们的性能。我们的目标是让这些模型准确地生成正确的计划,这不仅包括选择正确的函数集,还包括以正确的顺序正确地编排它们。因此,我们定义了一个成功率指标,如果满足这两个标准,则得分为 1,否则为 0。检查模型是否选择了正确的函数调用集是直接的。为了进一步确保函数编排的正确性,我们根据依赖关系构建了一个函数调用的有向无环图(DAG),如图 3 所示,其中每个节点代表一个函数调用,节点 A 到 B 的有向边代表它们的相互依赖性(即函数 B 只能在函数 A 执行后执行)。然后,我们检查这个 DAG 是否与地面真相计划的 DAG 相同,以验证依赖关系的准确性。
在定义了评估指标后,我们使用 LoRA 对模型进行了 3 个 epoch 的微调,学习率为 7e-5,使用了 80K 训练样本,并根据验证性能选择了最佳检查点。在微调时,我们的提示不仅包括地面真相函数(即地面真相计划中使用的函数)的描述,还包括其他不相关的函数作为负样本。我们发现负样本对于教会模型如何为给定查询选择合适的工具特别有效,从而提高了训练后的性能。此外,我们还包含了一些上下文示例,演示了查询如何转换为函数调用计划。这些上下文示例是通过检索增强生成(RAG)过程,根据训练数据中的用户查询选择的。
使用上述设置,我们对 TinyLlama-1.1B/Wizard-2-7B 模型进行了微调。微调后,1.1B 模型的成功率从 12.71% 提高到 78.89%,7B 模型的性能从 41.25% 提高到 83.09%,比 GPT-4-Turbo 高出约 4%。
使用工具 RAG 实现高效推理
图 4:基于用户输入的有效工具选择。并非所有用户输入都需要所有可用的工具;因此,选择正确的工具集以最小化提示大小并提高性能至关重要。在这种情况下,LLM 只需要获取电子邮件地址和创建日历事件的函数即可完成其任务。
我们的主要目标是在 Macbook 等边缘设备上本地部署 TinyAgent 模型,与部署 GPT 等闭源模型的 GPU 相比,这些设备的计算和内存资源有限。为了实现高效的低延迟性能,我们需要确保不仅模型尺寸小,而且输入提示尽可能简洁。后者是延迟和计算资源消耗的一个重要因素,因为注意力机制对序列长度呈二次方复杂度。
前面讨论的微调后的 TinyAgent 模型是在其提示中包含了所有可用工具的描述的情况下进行微调的。然而,这效率很低。通过仅根据用户查询包含相关工具的描述,我们可以显著减小提示大小。例如,考虑上图 4 所示的示例,用户要求创建带有两人的日历邀请。在这种情况下,LLM 只需要获取电子邮件地址和创建日历事件的函数即可在提示中使用。
利用这一观察结果,我们需要确定完成用户命令所需的函数,我们称之为工具 RAG,因为它与检索增强生成(RAG)的工作方式相似。然而,有一个重要的细微差别。如果我们使用一种基本的 RAG 方法,即计算用户查询的嵌入并使用该嵌入来检索相关工具,我们会得到非常低的性能。这是因为完成用户查询通常需要使用几个辅助工具,如果辅助工具的嵌入与用户查询不相似,则简单的 RAG 方法可能会遗漏这些工具。例如,图 4 所示的示例需要调用 get_email_address 函数,即使用户查询只是询问创建日历邀请。
这可以通过将问题视为需要哪些工具的分类问题来解决。为此,我们使用训练数据对 DeBERTa-v3-small 模型进行了微调,以执行如图 5 所示的 16 路分类。将用户查询作为输入提供给该模型,然后我们将末尾的 CLS token 传递给一个简单的全连接层(大小为 768x16),将其转换为一个 16 维向量(即我们工具的总大小)。该层的输出通过 Sigmoid 层产生选择每个工具的概率。在推理时,我们选择概率高于 50% 的工具,如果是这样,我们就将它们的描述包含在提示中。平均而言,我们注意到平均仅检索到 3.97 个工具,召回率为 0.998,而基本的 RAG 需要使用前 6 个工具才能达到 0.968 的工具召回率。
图 5:我们的工具 RAG 方案概述。我们将工具检索表述为一个多标签分类问题。用户查询作为输入提供给微调后的 DeBERTa-v3-small 模型,该模型输出一个 16 维向量,指示工具的概率。概率高于 50% 的工具被选中,平均每个查询检索到 3.97 个工具,而基本 RAG 为 6 个工具。
我们评估了结合工具 RAG 后的模型性能。结果如下面的表 1 所示,我们报告了简单 RAG 系统以及微调后的 DeBERTa 方法的性能。正如所见,基于 DeBERTa 的工具 RAG 方法实现了近乎完美的召回性能,提高了基线准确性,同时将提示大小减少了约 2 倍的 token。
表 1:TinyAgent 性能与 DeBERTa 与基本 RAG 和无 RAG 设置的比较。
工具 RAG 方法 | 工具召回率 | 提示大小 (Tokens) | TinyAgent 1.1B 成功率 (%) | TinyAgent 7B 成功率 (%) |
---|---|---|---|---|
无 RAG(所有工具都在提示中) | 1 | 2762 | 78.89 | 83.09 |
基本 RAG | 0.949 (前 3 个) | 1674 | 74.88 | 78.50 |
微调 DeBERTa-v3-small (我们) | 0.998 (概率 >50% 的工具) | 1397 | 80.06 | 84.95 |
量化实现快速边缘部署
即使对于 O(1B) 参数的小模型,在边缘设备(如消费级 Macbook)上部署模型仍然具有挑战性,因为加载模型参数可能会消耗大部分可用内存。解决这些问题的方法是量化,它允许我们以降低的比特精度存储模型。量化不仅减少了存储需求和模型占用空间,还减少了将模型权重加载到内存所需的时间和资源,从而降低了整体推理延迟(有关量化的更多信息,请参阅此处)。
为了更高效地部署模型,我们将模型量化为 4 位,组大小为 32,这得到了 llama.cpp 框架通过量化感知训练的支持。如表 2 所示,4 位模型在延迟方面提高了 30%,同时模型大小减少了 4 倍。我们还注意到准确性略有提高,这是由于进行了模拟量化的额外微调。
表 2:TinyAgent 模型在量化前后的延迟、大小和成功率比较。延迟是函数调用规划器的端到端延迟,包括提示处理时间和生成时间。
模型 | 权重精度 | 延迟 (秒) | 模型大小 (GB) | 成功率 (%) |
---|---|---|---|---|
GPT-3.5 | 未知 | 3.2 | 未知 | 65.04 |
GPT-4-Turbo | 未知 | 3.9 | 未知 | 79.08 |
TinyAgent-1.1B | 16 | 3.9 | 2.2 | 80.06 |
TinyAgent-1.1B | 4 | 2.9 | 0.68 | 80.35 |
TinyAgent-7B | 16 | 19.5 | 14.5 | 84.95 |
TinyAgent-7B | 4 | 13.1 | 4.37 | 85.14 |
整合所有成果
下面是在 Macbook Pro M3 上部署的最终 TinyAgent-1.1B 模型的演示,您实际上可以下载并安装在您的 Mac 上进行测试。它不仅在您的计算机上本地运行所有模型推理,还允许您通过音频提供命令。我们还使用 OpenAI 的 Whisper-v3 模型在本地处理音频,该模型使用 whisper.cpp 框架本地部署。我们最大的惊喜是 1.1B 模型的准确性超过了 GPT-4-Turbo,并且在本地和私密设备上部署时速度明显更快。
总而言之,我们介绍了 TinyAgent,并表明训练小型语言模型并利用它来驱动处理用户查询的语义系统确实是可行的。特别是,我们考虑了一个类似 Siri 的 Mac 助手作为驱动应用。实现它的关键组成部分是 (i) 通过 LLMCompiler 框架教会现成的 SLM 执行函数调用,(ii) 为手头的任务策划高质量的函数调用数据,(iii) 在生成的数据上微调现成的模型,以及 (iv) 通过一种称为 ToolRAG 的方法仅根据用户查询检索必要的工具来优化提示大小,以及量化模型部署以减少推理资源消耗,从而实现高效部署。在完成这些步骤后,我们的最终模型在 TinyAgent1.1.B 和 7B 模型上分别达到了 80.06% 和 84.95% 的成功率,超过了 GPT-4-Turbo 在此任务上的 79.08% 成功率。
致谢
我们要感谢苹果公司对该项目的赞助,以及 NVIDIA 和微软通过加速基础模型研究计划提供的支持。我们还要感谢 Sunjin Choi 关于本地和云部署相关的能耗成本的真知灼见。我们的结论不一定反映我们赞助商的立场或政策,不应推断出任何官方认可。
本文的 BibTex 信息:
@misc{tiny-agent, title={TinyAgent: Function Calling at the Edge}, author={Erdogan, Lutfi Eren and Lee, Nicholas and Jha, Siddharth and Kim, Sehoon and Tabrizi, Ryan and Moon, Suhong and Hooper, Coleman and Anumanchipalli, Gopala and Keutzer, Kurt and Gholami, Amir}, howpublished={\url{https://bair.berkeley.edu/blog/2024/05/29/tiny-agent/}}, year={2024} }
🚀 想要体验更好更全面的AI调用?
欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,小白也可以简单操作。
青云聚合API官网https://api.qingyuntop.top
支持全球最新300+模型:https://api.qingyuntop.top/pricing
详细的调用教程及文档:https://api.qingyuntop.top/about
评论区