使LLM善假于物: Toolformer
大模型可以仅凭指令或几个示例就能解决各种新任务,但在一些看似简单的算术或搜索任务上却表现欠佳。俗话说得好,人和动物的区别就是人可以更好地使用工具。于是,Meta
AI提出了Toolformer
,让LLM善假于物
,通过自学使用外部工具。
Toolformer
可以决定调用什么API、何时调用它们、传递什么参数及如何将API返回值融合。Toolformer
以自监督方式训练,每个API仅需要几个示例。它在各种下游任务中显著提升了零样本性能,而不牺牲其核心语言模型能力。
# Toolformer: Language Models Can Teach Themselves to Use Tools
简介
众所周知,大模型存在一些天然缺陷:无法获取最新事件信息,虚构事实,低资源语言理解能力弱,缺乏精确计算能力,不知道系统时间等。虽然通过扩大模型规模可以一定程度上减少这些问题,但却不能根除。解决这些问题的简单方案就是让LLM可以自行使用工具,之前的方案要么依赖大量的人工标注,要么仅适用于某些特定任务,不够通用。
Toolformer
基于in-context learning
的方法从零开始生成整个数据集。通过少量人工编写的示例,让语言模型对可能需要API调用的大数据集进行标注。然后,使用自监督损失函数来确定哪些API调用有用。最后,用这些有用的数据对模型微调,下图是Toolformer
使用问答系统、计算器、翻译系统和wiki搜索的示例:
方法
为了让LLM可以使用不同的API,需要将每个API的输入输出表示为文本序列。这样可以无缝地将API调用插入任意文本,用特殊标记符来标记调用的开始和结束。
每个API调用表示为一个tuple: \(c=(a_c, i_c)\),其中\(a_c\)是API名字,\(i_c\)是输入。API调用\(c\)的返回值记为\(r\),那么带有返回值和不带返回值的API调用可分别表示为:
\[e(c) = <API> a_c(i_c) </API>\]
\[e(c,r) = <API> a_c(i_c) \rightarrow r</API>\]
其中<API>
,</API>
,\(\rightarrow\) 为特殊标记符。
Toolformer
构建训练数据集的方式如上图,给定输入文本x,先采样一个位置i和k个API调用的候选\(c_i^1,c_i^2 \ldots
c_i^k\),然后执行这些API调用并过滤,留下加上API调用结果后让语言模型损失更小(生成更好结果)的样本,构成新数据集。下面具体看下这三步操作如何实现。
采样API调用
给定已有语言模型\(M\),对每个API,写一个prompt \(P(x)\) 扩展数据样例\(x=x_1,x_2 \ldots
x_n\),对所有可能的采样位置\(i \in
\{1,2 \ldots n \}\),计算其生成特殊字符 <API>
的语言模型概率(可参考这里):
\[p_i=p_M(<API>|P(x), x_{1:i-1})\]
保留的采样位置集合,语言模型概率需要大于采样阈值\(\tau_s\):\(I=\{ i|p_i > \tau_s \}\),仅保留概率最大的前\(k\)个。此采样方法的目的是筛选出最需要使用API调用的位置。使用的prompt样例:
对每个采样后的位置,用\(P(x), x_1, \ldots
x_n, <API>\) 作为输入前缀,以</API>
作为输出结束符,获取最多\(m\)个API调用结果:\(c_i^1, c_i^2 \ldots
c_i^m\)。若模型未输出结束符</API>
则丢弃该样本。
所以经过本步后,会得到不多于\(m\)个API调用。
执行API
没什么好说的,执行上步得到的\(m\)个API调用并得到返回文本序列\(r\)。
过滤API调用
扩展数据集的关键问题:扩展而得的API调用是否必要? 因此,进一步过滤这些生成的API调用就非常关键。这里的过滤标准:与不用API或用了API但不包含其结果相比,是否更有利于语言模型生成之后的文本了?
引入对token \(x_i, \ldots x_n\)按位置计算的加权交叉熵损失,\(z\)是模型输入前缀:
\[L_i(z)=-\sum_{j=i}^n{w_{j-i}} \cdot \log p_M(x_j|z, x_{1:j-1})\]
定义两种情况:
- 不用API: \[L_i^+=L_i(e(c_i,r_i)\]
- 用了API但不包含其结果: \[L_i^-=\min(L_i(\epsilon),L_i(e(c_i,\epsilon))\]
其中\(\epsilon\)表示空序列。过滤条件为:
\[L_i^- - L_i^+ \geq \tau_f\]
即加上API调用与结果后,语言模型的损失至少降低了 \(\tau_f\),留下这样的样本。
微调模型
数据集中的样本由\(x=x_1, \ldots x_n\)变为了\(x=x_{1:i-1},e(c_i,r_i),x_{i:n}\)。使用新数据集微调模型M。重要的一点:新构造的数据集必须包含原始数据集。
推理
微调模型后,在推理阶段,当解码时遇到\(\rightarrow\)时,就中断解码过程,调用API得到结果,加入</API>
结束符后再继续解码过程。
工具
限制工具使用的条件:1. 它的输入和输出都可以表示为文本序列 2. 可以写出一些示例。Toolformer使用了以下五个工具:问答系统,维基百科搜索引擎,计算器,日历和机器翻译系统。
结果
实验思路是在多个下游任务上查看Toolformer
在零样本条件下是否有性能提升,同时也要确保语言模型本身的能力没有损失。
论文用GPT-J
模型进行实验,数据集选择了CCNet
的子集。
使用贪心解码策略进行解码,但加入了些许改动(来增加工具使用的召回率):不仅在<API>
是最可能出现的token时执行API,只要它的出现概率是top-k的情况即执行API。同时,每个输入最多调用一次API,避免模型死锁在调用API而不产生输出。
在LAMA数据集上的结果见上图第一表格,所有未使用工具的GPT-J
模型性能都相似。Toolformer
明显优于这些基准模型,分别比最佳基准模型提高了11.7、5.2和18.6个点。尽管OPT
(66B)和GPT-3
(175B)这两个模型更大,Toolformer
也超过了它们。原因在于几乎所有情况下(98.1%),模型都使用了问答工具获取所需信息,只有极少数情况下(0.7%)使用其他工具,或者根本不使用工具(1.2%)。
数学推理数据集上的结果在上图第二表格,GPT-J
和GPT-J + CC
的表现差不多,但即使禁用API调用,Toolformer
的结果也明显更好。作者推测这是因为模型在许多API调用及其结果的示例上进行了微调,提高了其自身的数学能力。尽管如此,允许模型进行API调用可以使所有任务的性能提高一倍以上,并且明显优于更大的OPT和GPT-3模型。这是因为在所有基准测试中,对于97.9%的所有示例,模型都使用了计算器工具。
作者验证了在WikiText数据集和1000个随机采样的CCNet样本上,PPL没有明显下降,说明Toolformer
没有损失语言模型的能力。
此外,作者验证了同样的方案在4个更小的GPT-2模型上的效果。发现使用工具的能力只有在模型规模在775M参数以上才涌现。
更多实验结果可见原文,不再赘述。
结论
Toolformer
的想法符合直觉,尤其是从有利语言模型继续生成的角度出发,进行API调用过滤的思路不错。这种思路本质上有后验指导先验的作用:如果使用工具得到的结果与后续生成的内容一致,则使用工具有效,应该调用API。
Toolformer
也还存在一些缺陷,比如:
- 不能使用工具链,因为API调用都是独立生成的
- 不可迭代使用,尤其是像搜索引擎这样返回大量不同结果的工具
- 模型决定是否调用API时,对输入词敏感