当前位置: 首页 > article >正文

【论文解读】Toolformer: 语言模型自学使用工具

1st author: ‪Timo Schick‬ - ‪Google Scholar‬

paper: Toolformer: Language Models Can Teach Themselves to Use Tools | OpenReview NeurIPS 2023 oral

code: lucidrains/toolformer-pytorch: Implementation of Toolformer, Language Models That Can Use Tools, by MetaAI


5. 总结 (结果先行)

Toolformer 提出了一种自监督框架,使语言模型能够学会自主使用外部工具。通过以“降低未来词元预测损失”为目标来过滤和学习 API 调用,Toolformer 在不牺牲核心语言能力的前提下,显著增强了模型在知识获取、数学计算、实时信息处理等方面的零样本能力,甚至能让较小模型匹敌数倍于其参数量的更大模型。

前瞻与思考:

  • 工具链的挑战: 目前的 Toolformer 独立采样每个 API 调用,尚不支持将一个工具的输出作为另一个工具的输入(工具链)。这是未来一个重要的扩展方向。
  • 交互式工具使用: 对于搜索引擎这类可能返回大量结果的工具,允许模型进行多轮交互(如 уточнение запроса)将是关键。
  • API 调用成本: 当前模型未考虑调用不同 API 的计算或经济成本。
  • 鲁棒性与泛化: 模型对提示词的敏感性以及如何更好地泛化到未见过的工具或组合值得进一步研究。
  • 更深层次的“理解”: Toolformer 通过降低预测损失来学习,这是否等同于对工具功能和适用场景的深层理解,仍是一个开放问题。

1. 思想

语言模型(LMs)在文本生成和理解上已展现惊人能力,但其固有缺陷——如知识局限于训练数据、易产生事实幻觉、数学推理薄弱、缺乏对动态世界的实时感知——限制了其在更复杂和真实场景中的应用。

Toolformer 的核心思想是:让语言模型通过自监督学习,自主学会调用外部工具(APIs)来弥补自身能力的不足 ——既保留 LMs 的强大语言能力,又获得工具的精确性和实时性。 让 LM 自己决定何时(when)、为何(what arguments)、以及如何(how to incorporate results)使用何种工具。

其本质是探索一种让 LMs 从“封闭世界”走向“开放世界”,与外部环境交互并从中学习的有效路径。

2. 方法

Figure 2

Toolformer 的方法论体现了巧妙的自监督设计,主要包含以下 3 个步骤,针对每个工具独立进行:

  1. API 调用采样 (Sampling API Calls):

    • 目的: 对于数据集 C \mathcal{C} C 中的每个文本 x x x,识别潜在有益的 API 调用位置和内容。
    • 过程:
      • 给定一个纯文本数据集 C = { x ( 1 ) , x ( 2 ) , … , x ( N ) } \mathcal{C} = \{x^{(1)}, x^{(2)}, \dots, x^{(N)}\} C={x(1),x(2),,x(N)},其中每个 x x x 是一个文本序列,例如 x = ( x 1 , x 2 , … , x n ) x = (x_1, x_2, \dots, x_n) x=(x1,x2,,xn) x j x_j xj 代表第 j j j 个词元 (token)。和一些特定的 API(例如,计算器API、问答API)。
      • 通过少量人工编写的 few-shot 示例,构建一个提示 (prompt),引导一个预训练的 LM 在文本的潜在位置 i i i 生成候选的 API 调用。例如,在文本 “… 1400名参与者中,400人…” 处,LM 可能会被引导生成 [Calculator(400/1400)] 这样的调用。
      • LM 会为文本中每个位置 i i i 生成一个代表特殊 token (<API>) 的概率 P M ( <API> ∣ P ( x ) , x 1 : i − 1 ) P_M(\text{<API>} | P(x), x_{1:i-1}) PM(<API>P(x),x1:i1),并以超过某个阈值的位置 i i i 多作为候选的 API 调用起始位置。
      • 在每个选定的位置 i i i,让模型 M M M P api ( x ) , x 1 : i − 1 , <API> P_{\text{api}}(x), x_{1:i-1}, \text{<API>} Papi(x),x1:i1,<API> 为前缀,继续生成 API 调用的具体内容(即 API 名称和输入参数),直到生成 API 调用的结束标记 </API> \text{</API>} </API> (如论文中实际使用的 ])。这样,我们就得到了一系列候选的 API 调用 c 1 , c 2 , … , c m c_1, c_2, \dots, c_m c1,c2,,cm。每个调用 c c c 可以看作是一个包含 API 名称 a c a_c ac 和输入 i c i_c ic 的元组 ( a c , i c ) (a_c, i_c) (ac,ic)
  2. API 调用执行 (Executing API Calls):

    • 目的: 执行上一步采样的所有 API 调用 c j c_j cj,获得相应的文本结果 r j r_j rj
    • 过程:
      • 对每个采样到的 API 调用 c j = ( a c , i c ) c_j = (a_c, i_c) cj=(ac,ic),我们执行它。例如,如果 c j c_j cj 是一个计算器调用 Calculator("400/1400"),我们就实际计算 400 / 1400 400/1400 400/1400
      • 执行后得到文本形式的返回结果 r j r_j rj。例如,对于 Calculator("400/1400"),结果 r j r_j rj 可能是 “0.29”。
  3. API 调用过滤 (Filtering API Calls):

    • 目的: 只保留那些能够显著帮助模型 M M M 预测原始文本 x x x 中后续词元的 API 调用。(这是自监督学习的核心)

    • 过程:

      • 我们将一个 API 调用 c c c(包含其输入 i c i_c ic)及其返回结果 r r r 线性化为文本序列。我们定义两种形式:

        • e ( c ) = <API> a c ( i c ) </API> e(c) = \text{<API>} a_c(i_c) \text{</API>} e(c)=<API>ac(ic)</API>:仅包含 API 调用本身。
        • e ( c , r ) = <API> a c ( i c ) → r </API> e(c,r) = \text{<API>} a_c(i_c) \rightarrow r \text{</API>} e(c,r)=<API>ac(ic)r</API>:包含 API 调用及其结果 r r r。“ → \rightarrow ”是一个特殊的分隔符。
      • 对于在文本 x x x 的位置 i i i 插入的 API 调用 c c c 及其结果 r r r,我们计算模型 M M M 在给定前缀 z z z 的情况下,对后续文本 x i : n = ( x i , x i + 1 , … , x n ) x_{i:n} = (x_i, x_{i+1}, \dots, x_n) xi:n=(xi,xi+1,,xn) 的加权交叉熵损失 L i ( z ) L_i(z) Li(z):
        L i ( z ) = − ∑ j = i n w j − i log ⁡ P M ( x j ∣ z , x 1 : j − 1 ) L_i(z) = -\sum_{j=i}^{n} w_{j-i} \log P_M(x_j | z, x_{1:j-1}) Li(z)=j=inwjilogPM(xjz,x1:j1)

        • 符号解释:
          • z z z: 代表插入到 x 1 : i − 1 x_{1:i-1} x1:i1 x i : n x_{i:n} xi:n 之间的前缀序列。它可以是 e ( c , r ) e(c,r) e(c,r)(调用+结果), e ( c , ϵ ) e(c, \epsilon) e(c,ϵ)(调用+空结果),或者 ϵ \epsilon ϵ(完全没有调用)。
          • ϵ \epsilon ϵ: 代表空序列。
          • w j − i w_{j-i} wji: 是一个权重,通常随着 j − i j-i ji (即词元 x j x_j xj 与 API 调用位置 i i i 的距离) 的增大而减小。这意味着模型更关注紧随 API 调用之后的词元的预测。
      • 我们比较以下两种损失:

        • L i + = L i ( e ( c , r ) ) L_i^+ = L_i(e(c,r)) Li+=Li(e(c,r)): 在位置 i i i 提供了完整的 API 调用及其结果 r r r 时的损失。
        • L i − = min ⁡ ( L i ( ϵ ) , L i ( e ( c , ϵ ) ) ) L_i^- = \min(L_i(\epsilon), L_i(e(c, \epsilon))) Li=min(Li(ϵ),Li(e(c,ϵ))): 不进行任何 API 调用 (损失为 L i ( ϵ ) L_i(\epsilon) Li(ϵ)),或者进行了 API 调用但没有提供结果 (损失为 L i ( e ( c , ϵ ) ) L_i(e(c, \epsilon)) Li(e(c,ϵ))) 时的最小损失。
      • 只有当提供完整的 API 调用和结果能显著降低损失时,即 L i − − L i + ≥ τ f L_i^- - L_i^+ \ge \tau_f LiLi+τf (其中 τ f \tau_f τf 是一个预设的过滤阈值),我们才认为这个 API 调用 c c c 在位置 i i i 是有用的,并将其保留。

Figure 1

模型微调 (Model Finetuning):

  • 将所有通过过滤的、有用的 API 调用及其结果整合回原始文本,形成一个增强的数据集 C ∗ \mathcal{C}^* C
  • C ∗ \mathcal{C}^* C 上微调原始的 LM。

推理阶段: 当微调后的 Toolformer 生成文本时,如果它预测出特殊序列 “ → \rightarrow ”,表示它期望一个 API 的返回结果。此时,解码过程暂停,系统执行相应的 API 调用,并将返回结果插入文本流,然后继续解码。

3. 优势

Toolformer 的设计带来了几个显著优势:

  • 自监督学习: 无需大规模人工标注 API 调用数据,极大降低了数据获取成本,并使得模型能从其认为“有用”的角度学习,而非人类预设的“有用”。
  • 通用性与自主性: 模型自主决定何时、何地、如何使用何种工具,而非针对特定任务硬编码工具使用逻辑。这使得 Toolformer 具备更广泛的适用性。
  • 性能提升: 在多种下游任务上,尤其是在需要事实查找、计算或最新信息的场景中,Toolformer(基于 GPT-J 6.7B)的零样本性能显著优于同等规模甚至远大于其的 LMs(如 GPT-3 175B 的部分任务)。
  • 保持核心语言能力: 由于微调数据是在原始文本基础上增加 API 调用,模型在学习使用工具的同时,其核心的语言建模能力(如 PPL)并未受到损害。
  • 工具多样性: 该框架可集成多种类型的工具,如问答系统、计算器、搜索引擎、翻译系统和日历。

4. 实验

论文进行了一系列详尽的实验,以验证 Toolformer 的有效性:

  • 基础模型: 主要使用 GPT-J (6.7B 参数) 作为基础 LM。
  • 数据集: 使用 CCNet 的子集进行 API 调用采样和微调。
  • 评估任务:
    • LAMA (事实知识探测): Toolformer (使用 QA 工具) 在 SQuAD, Google-RE, T-REx 子集上显著优于 GPT-J,并与 GPT-3 (175B) 表现相当或更好。
    • 数学推理 (ASDiv, SVAMP, MAWPS): Toolformer (使用计算器) 性能远超所有基线,包括 GPT-3 (175B)。
    • 问答 (WebQS, NQ, TriviaQA): Toolformer (使用维基百科搜索) 表现优于同尺寸模型,但不及 GPT-3,可能受限于搜索工具的简单性和交互性。
    • 多语言问答 (MLQA): Toolformer (使用翻译工具) 在所有语言上均有提升,但由于 CCNet 微调可能引入分布漂移,其表现并非总是优于原始 GPT-J。
    • 时序数据集 (TEMPLAMA, DATESET): Toolformer (主要使用维基搜索和QA工具处理 TEMPLAMA,使用日历工具处理 DATESET) 均优于基线。
  • 语言模型能力: 在 WikiText 和 CCNet 验证集上评估困惑度 (PPL),Toolformer (禁用 API 调用时) 的 PPL 与在纯 CCNet 上微调的 GPT-J 相当,表明其语言能力未受损。
  • 模型规模扩展性 (Scaling Laws): 实验表明,模型利用工具的能力大约在 775M 参数规模时开始显现,并随模型增大而增强。

相关文章:

【论文解读】Toolformer: 语言模型自学使用工具

1st author: ‪Timo Schick‬ - ‪Google Scholar‬ paper: Toolformer: Language Models Can Teach Themselves to Use Tools | OpenReview NeurIPS 2023 oral code: lucidrains/toolformer-pytorch: Implementation of Toolformer, Language Models That Can Use Tools, by…...

408第一季 - 数据结构 - 线性表II

链表 头节点始终指向第一个 头节点的好处&#xff1a; 第一个好处 这里L是头节点 可以发现&#xff0c;删除第一个也可以统一了 第二个好处 这是无头节点&#xff0c;空和非空指向的不一样 然后有头节点就可以统一了&#xff01; 双链表 插入 第一步要在第四步之前&…...

网络通讯知识——通讯分层介绍,gRPC,RabbitMQ分层

网络通讯分层 网络通讯分层是为了将复杂的网络通信问题分解为多个独立、可管理的层次&#xff0c;每个层次专注于特定功能。目前主流的分层模型包括OSI七层模型和TCP/IP四层&#xff08;或五层&#xff09;模型&#xff0c;以下是详细解析&#xff1a; 一、OSI七层模型&#…...

Linux与Windows切换使用Obsidian,出现 unexplained changes 问题的解决

如果你的Obsidian文档在Linux与Windows间来回切换&#xff0c;可能会涉及到文件的保存换行符问题&#xff0c;但这样的话就容易导致一个问题&#xff0c;那就是内容无差异&#xff0c;Obsidian却提示unexplained changes&#xff0c;Windows系统下的解决方法如下&#xff0c;找…...

基于VMD-LSTM融合方法的F10.7指数预报

F10.7 Daily Forecast Using LSTM Combined With VMD Method ​​F10.7​​ solar radiation flux is a well-known parameter that is closely linked to ​​solar activity​​, serving as a key index for measuring the level of solar activity. In this study, the ​​…...

35 C 语言字符串转数值函数详解:strtof、strtod、strtold(含 errno 处理、ERANGE 错误)

1 strtof() 函数 1.1 函数原型 #include <stdlib.h> // 必须包含这个头文件才能使用 strtof() #include <errno.h> // 包含 errno 和 ERANGE #include <float.h> // 包含 FlOAT_MAX 和 FLOAT_MIN #include <math.h> // 包含 HUGE_VALF(inf)float…...

解决 idea提示`SQL dialect is not configured` 问题

前言 在 Java 开发中&#xff0c;尤其是使用 IntelliJ IDEA 或 MyBatis 等框架时&#xff0c;开发者常会遇到 SQL dialect is not configured 的警告或错误。这一问题不仅影响代码的高亮和智能提示功能&#xff0c;还可能导致表结构解析失败、语法校验失效等问题。 一、问题分…...

springboot的test模块使用Autowired注入失败

springboot的test模块使用Autowired注入失败的原因&#xff1a; 注入失败的原因可能是用了junit4的包的Test注解 import org.junit.Test;解决方法&#xff1a;再加上RunWith(SpringRunner.class)注解即可 或者把Test由junit4改成junit5的注解&#xff0c;就不用加上RunWith&…...

日志收集工具-Filebeat

提示&#xff1a;windows 环境下 Filebeat 的安装与使用 文章目录 前言一、安装二、配置部署三、启动测试 前言 Filebeat 一般用于日志采集&#xff0c;由两部分组成 &#xff1a;Harvesters 和 prospector Harvesters采集器&#xff1a;逐行读取单个文件的内容&#xff0c;并…...

【PCIe总线】 -- PCI、PCIe相关实现

PCI、PCIe相关概念和知识点 【PCIe总线】-- PCI、PCIe基础知识点整理 【PCIe】非常适合初学的pcie博客(PCIe知识整理) PCIe具体实现 【PCIe】如何获取PCIe的BAR空间大小&#xff1f;...

Vue3学习(4)- computed的使用

1. 简述与使用 作用&#xff1a;computed 用于基于响应式数据派生出新值&#xff0c;其值会自动缓存并在依赖变化时更新。 ​缓存机制​&#xff1a;依赖未变化时直接返回缓存值&#xff0c;避免重复计算&#xff08;通过 _dirty 标志位实现&#xff09;。​响应式更新​&…...

手机上网可以固定ip地址吗?详细解析

在移动互联网时代&#xff0c;手机已成为人们日常上网的主要设备之一。无论是工作、学习还是娱乐&#xff0c;稳定的网络连接都至关重要。许多用户对IP地址的概念有所了解&#xff0c;尤其是固定IP地址的需求。那么&#xff0c;手机上网能否固定IP地址&#xff1f;又该如何实现…...

电脑同时连接内网和外网的方法,附外网连接局域网的操作设置

对于工作一般都设置在内网网段中&#xff0c;而同时由于需求需要连接外网&#xff0c;一般只能通过内网和外网的不断切换进行设置&#xff0c;如果可以同时连接内网和外网会更加便利&#xff0c;同时连接内网和外网方法具体如下。 一、电脑怎么弄可以同时连接内网和外网&#…...

如何在Unity中实现点击一个按钮跳转到哔哩哔哩

1.创建一个按钮 2.编写一个脚本&#xff08;你可以把链接改成你想要跳转的网站&#xff09; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class JumpToBilibili : MonoBehaviour {void Start(){gameObject.…...

DHCP 动态主机配置协议(Dynamic host configuration protocol)逐层封装过程: DHCP --> UDP --> IP

&#x1f4e6; DHCP 报文逐层封装结构&#xff08;自上而下&#xff09; 应用层&#xff08;DHCP 报文&#xff09; ↓ 传输层&#xff08;UDP 首部&#xff09; ↓ 网络层&#xff08;IP 首部&#xff09; ↓ 数据链路层&#xff08;以太网帧头&#xff09; ↓ 物理层&#x…...

PySide6 GUI 学习笔记——常用类及控件使用方法(单行文本控件QLineEdit)

文章目录 QLineEdit 介绍常用方法QLineEdit.EchoMode 取值光标相关方法文本选择方法输入格式化字符&#xff08;Input Mask&#xff09;常用信号QLineEdit 实例 QLineEdit 介绍 QLineEdit 是 PySide6&#xff08;Qt for Python&#xff09;中用于单行文本输入的控件。它支持文本…...

【数据结构】6. 时间与空间复杂度

文章目录 一、算法效率1、算法的复杂度 二、时间复杂度1、时间复杂度的概念2、大O的渐进表示法3、常见时间复杂度计算1&#xff09;实例12&#xff09;实例23&#xff09;实例34&#xff09;实例45&#xff09;实例56&#xff09;实例67&#xff09;实例78&#xff09;实例8 三…...

Python 函数全攻略:函数进阶(生成器、闭包、内置函数、装饰器、推导式)

一、默认参数中的易错点 问题: 当函数的默认参数是可变类型(如 list, dict)时,存在“坑”。 现象: def func(a2=[]): # a2 默认是一个空列表a2.append(2)print(a2)func() # 第一次调用,a2 默认为 [],输出 [2] func([]) # 传入新列表,输出 [2] func([1]) # 传入带元素的…...

基于springboot的藏文古籍系统

博主介绍&#xff1a;高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实实在…...

重构城市应急指挥布控策略 ——无人机智能视频监控的破局之道

在突发事件、高空巡查、边远区域布控中&#xff0c;传统摄像头常常“看不到、跟不上、调不动”。无人机智能视频监控系统&#xff0c;打破地面视角局限&#xff0c;以“高空布控 AI分析 实时响应”赋能政企单位智能化管理。在城市应急指挥中心的大屏上&#xff0c;一场暴雨正…...

声音信号的基频检测(python版本)

import math import wave import array import functools from abc import ABC, abstractmethod import matplotlib import matplotlib.pyplot as plt from matplotlib.gridspec import GridSpec import os import sys# 设计模式部分 class PreprocessStrategy(ABC):"&q…...

STM32 控制12VRGB灯带颜色亮度调节,TFTLCD显示

接了一个同学的小项目&#xff0c;要实现控制一个实体&#xff0c;控制灯带的亮度为红/绿/蓝/白/黄以及亮度的叠加。 时间要的比较急&#xff0c;要两天实现&#xff0c;因此不能打板&#xff0c;只能采用现有模块拼接。 一. 实施方案 一开始觉得很简单&#xff0c;就是使用五…...

Hive开窗函数的进阶SQL案例

​一、开窗函数基础​ 1. ​定义与作用​ 开窗函数&#xff08;Window Functions&#xff09;在保留原始行数据的同时&#xff0c;对分组内的行进行聚合或排序分析&#xff0c;常用于累计计算、排名、移动平均等场景。与普通聚合函数&#xff08;如SUM、AVG&#xff09;的区别…...

【JJ斗地主-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …...

《绩效管理》要点总结与分享

目录 绩效管理与目标设定 绩效管理的循环&#xff1a;PDCA 绩效目标的设定要点 绩效设定的工具&#xff1a;SMART法则 绩效跟踪与评估 刻板印象&#xff1a;STAR法 晕轮效应&#xff1a;对比评价法 近因效应&#xff1a;关键事项评估表 绩效面谈 面谈前准备工作 汉堡…...

Microsoft前后端不分离编程新风向:cshtml

文章目录 什么是CSHTML&#xff1f;基础语法内联表达式代码块控制结构 布局页面_ViewStart.cshtml_Layout.cshtml使用布局 模型绑定强类型视图模型集合 HTML辅助方法基本表单验证 局部视图创建局部视图使用局部视图 高级特性视图组件依赖注入Tag Helpers 性能优化缓存捆绑和压缩…...

【评测】用Flux的图片文本修改的PS效果

【评测】Flux的图片文本修改的PS效果 1. 百度图库找一张有英文的图片 2. 打开https://playground.bfl.ai/image/edit上传图片 3. 输入提示词 “change brarfant to goodbeer” 图片的文字被修改了...

青少年编程与数学 01-011 系统软件简介 01 MS-DOS操作系统

青少年编程与数学 01-011 系统软件简介 01 MS-DOS操作系统 1. MS-DOS的历史背景1.1 诞生背景1.2 发展历程1.3 与Windows的关系 2. MS-DOS的技术细节2.1 系统架构2.2 启动过程2.3 内存管理2.4 设备驱动程序 3. MS-DOS的用户界面3.1 命令行界面3.2 配置文件 4. MS-DOS的应用程序与…...

数据库管理-第334期 Oracle Database 23ai测试版RAC部署文档(20250607)

数据库管理334期 2024-06-07 数据库管理-第334期 Oracle Database 23ai测试版RAC部署文档&#xff08;20240607&#xff09;1 环境与安装介质2 操作标准系统配置2.1 关闭防火墙2.2 关闭SELinux2.3 关闭avahi-daemon2.4 时间同步配置 3 存储服务器配置3.1 配置本地yum源3.2 安装…...

springCloud2025+springBoot3.5.0+Nacos集成redis从nacos拉配置起服务

文章目录 前言一、网关gateway选型1. 响应式编程模型2. 网关的特定需求3. 技术栈一致性4. 性能对比5. 实际应用场景优势 二、redis的集成1.引入库2.配置类A、自定义配置类RedisAfterNacosAutoConfigurationB、自定义配置类RedisConfig 总结 前言 最近在搭建最新的springCloud …...