Paper

论文速读:DualTune 把工具调用拆成两半,让端侧小模型也会用工具

5 min read ·

💡 一句话总结:DualTune 把「工具调用」这件事拆成「选工具」和「填参数」两个子任务,各训一个专门的 LoRA、推理时分阶段切换。一个简单的解耦,就让端侧小模型的工具调用准确率从不可用拉到了可用区间,而且和 4-bit 量化兼容。

一、问题:端侧 agent 卡在工具调用这道坎上

把 agent 跑在本地,是 2026 年最热的工程方向之一——隐私不出端、零 API 成本、低延迟。但凡真动手做过的人都会撞到同一堵墙:本地小模型的工具调用太不靠谱

DualTune 这篇论文把这堵墙拆开看,发现失败集中在两个地方:

  1. 工具选择错误:agent 挂着一长串工具(几十甚至上百个),小模型从工具描述列表里选不准。相似的工具尤其容易混——search_websearch_docsget_userget_user_profile,小模型经常选错那个。

  2. 参数生成错误:就算选对了工具,按它的 schema 填参数又是另一道坎。复杂的嵌套结构、严格的类型约束、必填字段缺失、JSON 格式非法——这些都是小模型的高发错误。

前沿大模型(GPT、Claude 这个级别)靠模型规模硬把这两件事一起做好了,但端侧根本跑不起那么大的模型。于是端侧 agent 陷入两难:用小模型,工具调用不可用;用大模型,端侧跑不动。

二、洞察:工具调用是两个不同的任务

DualTune 的核心洞察很简洁:工具调用不是一个任务,是两个

这两种能力的「脑回路」不一样。把它们塞进同一个模型、用同一套权重一起学,训练时两个子任务的梯度会互相干扰——优化选工具的能力可能损害填参数的能力,反之亦然。结果是两个子任务都学得半吊子。

这就是为什么单纯对小模型做整体微调,提升有限。相关数据点也印证了这一点:传统微调能把工具调用准确率从十几个百分点提到三十几个百分点,有改善但远不够用——天花板就卡在「一个模型同时学两件事」上。

三、方法:解耦微调(Decoupled Fine-Tuning)

DualTune 的解法顺理成章——既然是两个任务,就分开训、分开用

训练阶段,把工具调用数据拆成两路:

两个 LoRA 共享同一个冻结的基座模型,各自只在自己的子任务上优化,互不干扰。

推理阶段,串成一个两阶段管线:

用户请求


[阶段一] 加载「工具选择 LoRA」
  → 从工具列表中选出目标工具


[阶段二] 加载「参数生成 LoRA」
  → 针对选中工具的 schema 生成参数


执行工具调用

关键在于:基座模型只加载一份,两个 LoRA 按阶段热插拔。LoRA adapter 本身很轻(几 MB 到几十 MB),切换开销远小于重载整个模型。

💡 提示:这套结构天然适配 vLLM 的 multi-LoRA 能力——基座常驻显存,多个 adapter 动态挂载。工程上不需要起两个模型实例。

四、为什么解耦有效:各司其职

解耦带来的提升来自三个层面:

第一,消除子任务间的梯度干扰。每个 LoRA 只优化一个目标,不再被另一个任务的梯度拉扯,于是各自都能学到更优的解。

第二,缩小每个子任务的输入复杂度。工具选择阶段不用操心参数格式,参数生成阶段不用从一长串工具里挑——每个阶段面对的问题都更聚焦,小模型更容易学好。

第三,与量化正交。论文强调一个对端侧极其重要的点:LoRA 的低秩适配在 4-bit 量化的基座上依然有效。量化压缩基座权重、LoRA 在低秩空间补回任务能力,两者不冲突。这意味着你可以把基座量化到能塞进边缘设备的体积,再叠两个轻量 LoRA,得到一个「小 + 会用工具」的 agent。

按论文给出的消融,从「不微调」到「传统微调」再到「解耦微调」,准确率是台阶式上升的——解耦微调相比传统整体微调有明显的额外增益,这部分增益正是「分开学」省下来的、原本被任务干扰浪费掉的能力。

五、工程意义:端侧 agent 的一条务实路径

抛开论文,DualTune 给端侧 agent 落地提供了一套可直接抄的方法论:

六、局限与思考

DualTune 不是银弹,几个值得留意的点:

但瑕不掩瑜。DualTune 最大的价值是给了一个清晰且可复制的认知:当一个任务用单模型学不好时,先问问它是不是其实是两个任务。这个「解耦」的思路,远不止能用在工具调用上。

Frequently asked questions

为什么本地小模型用不好工具,非要前沿大模型不可?
核心难点有两个。第一是工具选择:真实 agent 往往挂着几十上百个工具,小模型要从一长串工具描述里精准选出对的那个,这考验的是长上下文里的判别能力,小模型容易被相似工具带偏。第二是参数生成:选对工具后还要按它的 schema 填参数,复杂嵌套结构、类型约束、必填项,小模型经常生成不合法的 JSON 或填错字段。前沿大模型靠规模硬扛过去,小模型扛不住,所以 DualTune 才要拆开各个击破。
「解耦微调」到底解耦了什么?和普通微调差在哪?
普通微调是用一个模型(或一个 LoRA)同时学「选工具 + 填参数」整件事,两个子任务的梯度信号混在一起互相拉扯。DualTune 解耦的是这两个子任务:训练阶段为工具选择训练一个专门的 LoRA,为参数生成训练另一个专门的 LoRA,各自只优化自己的目标。推理阶段分两步走——先加载工具选择 LoRA 选出工具,再加载参数生成 LoRA 针对选中的工具填参数。每个 adapter 只干一件事,自然干得更好。
推理时要切换两个 LoRA,会不会拖慢速度、吃更多显存?
影响可控。LoRA adapter 本身很小(通常几 MB 到几十 MB),热插拔的开销远小于重新加载整个模型。显存上,基座模型只加载一份,两个 LoRA 叠加的额外占用很有限。代价主要是推理变成两阶段(选工具→填参数),多一次前向,但换来的是准确率的大幅提升。对端侧场景而言,宁可慢一点也要调用成功,否则一次失败的工具调用要重试,反而更慢更耗电。
这套方法和 4-bit 量化兼容吗?端侧部署最关心这个。
兼容,而且这正是论文强调的工程价值。相关实验表明,LoRA 的低秩适配即使在激进的 4-bit 量化基座上依然能学到有效的工具调用能力——量化压缩了基座权重,LoRA 在低秩空间里补回任务特化的能力,两者不冲突。这意味着你可以把基座模型量化到能塞进手机/边缘设备的体积,再叠加两个轻量 LoRA,得到一个既小又会用工具的端侧 agent。
我现在就想用这个思路,工程上怎么落地?
不必等官方代码,思路本身就能复刻。第一步,把你的工具调用训练数据拆成两份:一份是「query → 选中的工具名」(分类标签),一份是「query + 选中工具的 schema → 参数 JSON」。第二步,用 PEFT/LoRA 分别在这两份数据上训两个 adapter。第三步,推理时串成两阶段管线,用支持 LoRA 热插拔的推理框架(如 vLLM 的 multi-LoRA)切换。难点在数据构造——参数生成那份数据要覆盖足够多的 schema 变体,否则泛化不到新工具。
// next.txt ›

Some outbound links in this post are affiliate links — see disclosure.