最近想把手上的一个内部工单分类任务做一下,数据大概几千条,用的Qwen2.5-7B。一开始直接用了Lora,跑完一个epoch之后,效果还行,但发现一个很奇怪的问题:模型在推理时几乎不输出“其他”这个类别,哪怕测试集里其他类的占比高达30%。我怀疑是不是数据不平衡导致,尝试过过采样,也把loss改成过focal,但效果还是差不多。现在又试了全参数微调,跑了两天,结果更离谱了,模型开始疯狂输出换行符和重复的“好的,根据您的描述”。请问是学习率太大导致灾难性遗忘,还是说我的数据格式(用的是sharegpt格式)有问题?有类似经验的兄弟能指点一下吗?
微调Qwen2.5-7B之后,模型只会输出了,求大佬们看看哪里不对
全部回复
共 73 条类别不平衡这块,focal loss其实对生成模型作用有限,建议试试在采样时把“其他”类的权重再调高一点,或者干脆用分类头而不是生成式。全参数微调跑两天出现重复输出,大概率是学习率太高了,降到1e-5左右试试,另外数据格式最好统一成alpaca那种带instruction的,sharegpt对7B来说容易学偏。
之前也踩过类似的坑,全参微调跑到后面疯狂输出重复内容,八成是学习率太大,建议降到1e-5左右试试,或者加个warmup和梯度裁剪。另外几千条数据做全参确实容易过拟合,LoRA其实够用了,重点看看你的模板和标签定义,“其他”类是不是在数据里被模型当成了默认兜底,反而学不到特征。你试过在推理时调高采样温度或者直接对“其他”类做logit调整吗?有时候比改loss更直接。
全参数微调两天出现疯狂输出换行和重复套话,大概率是学习率太高把原始能力冲垮了,建议先降到1e-5以下试试,或者加个warmup。另外“其他”类不输出不一定是数据不平衡,可能你过采样后反而让模型把边界学糊了,focal loss参数调过gamma没?我之前遇到过类似情况,最后是给“其他”类的logit加个偏置才救回来。sharegpt格式本身没问题,但注意system prompt里别给太多指令性描述,会让模型偏向模仿语气而不是分类。你训练时eval的指标是只看acc还是也看了每类的recall?这个现象最好从混淆矩阵入手排查。
全参数微调两天那个现象大概率是lr太高了,7B全参一般得降到2e-5以下,你试试带warmup的cosine调度,另外“其他”类输出少可能跟模板里prompt引导有关,换个更明确的指令让模型先判断是否属于已知类别再输出。数据格式本身sharegpt没问题,但你要确认下system里有没有隐含的偏好设定。
全参数微调跑两天出这个症状大概率是lr太高了,7B全参一般得压到1e-5甚至更低,你试试把lr降到5e-6看看。另外几千条数据全参微调确实容易崩,不如回到LoRA,把“其他”类的样本在loss里手动加权重,比focal直接调参更可控。数据格式倒是没问题,sharegpt做分类任务挺常见的,重点还是看你的system prompt有没有明确限定输出类别。你那个疯狂换行的情况,八成是模型学到的是生成格式而不是分类逻辑,建议把response改成纯标签加简短理由,别让它自由发挥。
这情况我也踩过坑,先查下eval时的模板和训练是不是一致,换行符暴走八成是数据里特殊token没处理好。
我之前也踩过类似的坑,全参数微调那个“好的,根据您的描述”我太熟了,大概率不是灾难性遗忘,是数据格式里系统提示词或者回答模板里带了这句话,模型把它当成了固定输出前缀,你检查下sharegpt格式里是不是有大量重复的回复开头,或者instruction里把任务描述写得太死。至于“其他”类不输出,过采样和focal loss都试过还不行的话,我怀疑是标签定义的问题,你看看是不是“其他”这个类别在数据里本身语义就特别杂,模型学不到一个统一的特征,试着把“其他”拆成几个子类或者干脆换成“无法分类”这种更明确的表述。另外你Lora只跑了一个epoch,效果还行但类别失衡,可以试试把Lora的rank调高一点,或者用rsLoRA那种缩放方式,有时候rank太低模型学不到足够区分度。全参数微调跑两天,学习率如果用的默认5e-5确实可能偏大,但更关键的是你得看看训练loss曲线,如果后期还在震荡,那就不是学习率的事,可能是数据里有噪声样本在反复拉扯。还有个土办法,推理的时候把temperature调低到0.1,然后限制max_tokens,至少能避免疯狂刷换行符,先看看真实输出内容到底长啥样,别被重复文本干扰了判断。哦对,你数据量几千条做全参数微调其实有点勉强,7B模型容易过拟合到训练集的表层模式,建议还是回到LoRA,但多跑几个epoch,配合early stopping,效果可能比你现在折腾全参数要稳。
全参数微调那个症状基本就是lr太高了,7B全参我一般用1e-5甚至更低,你可以先降到5e-6试一下。另外“其他”类不输出不一定是数据不平衡,更像是这个类在loss里被淹没了,试试把其他类的loss权重单独调高,比focal更直接。还有你sharegpt格式里system和user的字段是不是都填对了,之前我遇到过模型把类别名当生成文本学,就是因为instruction里没强调“只能从给定列表选”。
全参数微调那症状大概率是lr太高了,试试降到1e-5以下,另外把“其他”类的采样权重单独调一下。
这情况我也踩过坑,先查下数据里“其他”类的样本是不是标注质量太差,模型学不到特征。
这输出格式崩了大概率是学习率太大,调回1e-5以下试试,另外全参微调数据量不够容易灾难性遗忘。
先查下是不是类别权重没生效,focal loss参数调过没?我之前也遇到过类似,调低学习率到1e-5就好了。
试试把训练轮数降到1个epoch以下,全参微调两天大概率过拟合了,换回lora加个类别平衡采样可能更稳。
我之前也遇到过类似情况,全参数微调输出重复内容大概率是学习率太高了,试试降到1e-5以下或者用带warmup的调度器。不过你说“其他”类死活不输出,这我倒觉得不光是数据不平衡的问题,可能模板里“其他”类别的指令描述太模糊,模型没学会区分边界,你试试在few-shot样本里多塞几个“其他”的例子。另外sharegpt格式本身没问题,但几千条数据做全参微调确实容易过拟合,建议还是回Lora,把epoch数加到3-5个,观察验证集loss变化。