最近在做一个内部知识库的Agent,用Llama-3-8B做底座,拿几千条工具调用的对话数据做了LoRA微调。单轮工具选择准确率还行,但一旦涉及多轮对话,模型经常把上一个tool的结果当参数传给下一个tool,或者干脆自己编一个不存在的工具名。我确认过数据格式和system prompt都没问题,推理时temperature也降到0.1了。想问下各位大佬,这种多轮工具调用的“记忆混乱”一般是微调数据里缺少了某些负样本,还是说LoRA的rank和alpha设置得不合适?或者跟基座模型本身的多轮能力关系更大?求指点,孩子已经被这个搞了快两周了。
微调后的模型做Agent工具调用总跑偏,是数据问题还是训练参数没调对?
全部回复
共 26 条多轮跑偏大概率是负样本不够,得专门塞点“错误调用”让模型学会拒绝,参数倒不是主因。
八成是负样本太少了,多轮里得塞点故意传错参数的例子让模型学会拒绝。
这种问题我调RAG agent时也遇到过,后来发现纯粹是LoRA rank调太高(比如64)导致灾难性遗忘,把基座的多轮能力冲掉了。你试试rank降到8-16,alpha跟着减半,同时把训练数据里故意混入一些“错误调用后纠正”的负样本,让模型学会看到异常结果就停手。另外8B基座本身对复杂状态跟踪就弱,如果数据量不大,不如换个Qwen-2.5-7B或14B的base再试,实测多轮稳定性好不少。
说实话你这个现象我太熟了,之前用7B模型做类似任务也卡了大半个月。我个人感觉大概率不是LoRA参数的问题,rank和alpha只要不是特别离谱(比如rank=1或者alpha=64),对多轮行为的影响远没有数据分布来得大。你单轮准但多轮崩,典型的“上下文漂移”症状——模型在微调时见过的多轮样本里,可能工具返回结果和下一轮用户问题之间的关联模式太单一了,它没学会“工具结果要经过推理再决定怎么用”,只是死记硬背了“上轮输出接本轮输入”这个表面规律。
建议你先把训练数据里的多轮轨迹单独拎出来看,是不是有很大比例都是工具结果直接作为参数传入下一个工具,而缺少了那种“工具返回后需要先总结、再结合用户意图决定是否调用”的中间步骤。另外负样本很关键,我那时候加了大概10%的“错误调用但最后被纠正”的对话,以及一些“工具不存在时应该拒绝”的样本,效果提升特别明显。你还可以试试在推理时把system prompt里明确加上“只能用列表中的工具,如果工具名不在列表就回答不知道”,这能压掉一部分编造工具名的行为。
最后说句实话,Llama-3-8B本身的多轮跟随能力就一般,尤其是工具结果比较长的时候,注意力很容易被带偏。如果数据清洗过、负样本也加了还是不行,建议换Qwen2.5-7B或者干脆用同参数量的带工具调用预训练的模型,省很多事。两周时间不算长,别太灰心,这问题很常见。
我之前也踩过类似的坑,后来发现多轮跑偏大概率不是单一原因。你提到缺负样本这点很关键,LoRA微调数据里如果全是正例,模型很容易把“记忆上一个结果”学成默认行为,建议专门造一些工具返回异常或空值的样本进去。另外rank可以试试16到32之间,alpha跟着调大一点,有时候低rank会让模型对上下文敏感度不够。不过说实话,Llama-3-8B本身多轮指令跟随就偏弱,如果数据清洗没问题,可能真得考虑换更擅长对话的基座,或者加一层显式的状态管理缓存来兜底。
我之前做类似项目也踩过这个坑,多轮对话里工具结果串场的问题,大概率不是LoRA参数的事。你想想,单轮准确率高说明模型已经学会了工具选择的基本模式,但多轮调用涉及的是“状态跟踪”能力,这恰恰是8B模型比较薄弱的地方。我后来试过在数据里刻意加入一些“上一个tool返回了错误格式”或者“工具结果为空”的样本,让模型学会在这种情况下怎么处理,效果改善很明显。另外你可以检查下是不是训练数据里多轮对话的轮次太短,如果平均只有2-3轮,模型很难学到长上下文的依赖关系。还有一个偏门但有用的技巧,就是把工具描述改成更口语化的指令,比如“如果上个结果里没有xxx字段,就调用查询接口”,这样模型更容易理解边界条件。至于rank和alpha,我一般用16和32起步,但如果数据量才几千条,调高了反而容易过拟合,建议先固定住,重点折腾数据构造。最后想说,如果实在不行,可以试试在推理时给模型加一个“显式记忆”的prompt,把最近两轮的工具结果用结构化文本放在对话历史里,比让模型自己隐式记住靠谱多了。