最近想把手上的一个内部工单分类任务做一下,数据大概几千条,用的Qwen2.5-7B。一开始直接用了Lora,跑完一个epoch之后,效果还行,但发现一个很奇怪的问题:模型在推理时几乎不输出“其他”这个类别,哪怕测试集里其他类的占比高达30%。我怀疑是不是数据不平衡导致,尝试过过采样,也把loss改成过focal,但效果还是差不多。现在又试了全参数微调,跑了两天,结果更离谱了,模型开始疯狂输出换行符和重复的“好的,根据您的描述”。请问是学习率太大导致灾难性遗忘,还是说我的数据格式(用的是sharegpt格式)有问题?有类似经验的兄弟能指点一下吗?
微调Qwen2.5-7B之后,模型只会输出了,求大佬们看看哪里不对
全部回复
共 73 条全参数微调两天那个症状我见过,大概率是lr设太高了,7B全参的话建议3e-6往下探,顺便把max_len砍到2048试试。另外你说的“其他”类不输出,我怀疑不光是不平衡,可能你那条“其他”类的样本在模板里的表述跟别的类差太大,模型学了个捷径,建议把这类样本单独拿出来看看tokenizer之后的pattern。还有个骚操作,推理时把temperature调低到0.1,或者直接对“其他”类的logit加个偏置,先验证下是不是解码策略的问题。
我之前也踩过类似的坑,尤其是全参数微调那部分,模型开始疯狂输出重复内容,基本就是学习率太大+数据量不够导致的灾难性遗忘,Qwen本身指令遵循能力很强,你微调的时候把它的原始分布冲得太狠了。建议先把学习率降到1e-5以下试试,另外几千条数据全参数微调确实风险高,LoRA其实更稳。关于“其他”类不输出的问题,我怀疑不光是数据不平衡,可能是你的标签定义在模板里不够清晰,模型学到的是“优先匹配具体类别”的倾向,你可以试试在system prompt里把“其他”类单独强调一下,或者给它几个“其他”类的few-shot例子。还有sharegpt格式本身没问题,但你要确认一下loss是不是只算assistant部分,如果算上了人设和系统提示,模型会把注意力放在复述而不是分类上。focal loss对这类问题帮助有限,我更建议用类别权重,或者直接把“其他”类的样本做生成式增强,比如把其他类的描述改写成不同说法。最后你可以看看推理时的采样参数,temperature调低一点,top_p也别太高,有时候模型不是不会输出,而是采样时概率被压下去了。
遇到过类似情况,全参数微调崩掉大概率是学习率大了,7B模型用全参一般得压到1e-5以下,你试试把lr调到2e-6跑几个epoch看看。至于“其他”类不输出,光靠过采样和focal可能不够,建议检查下标签在prompt里的分布,有时候模型学到的是模板里的位置偏置,可以试试把类别顺序打乱或者给“其他”类多配几个同义描述。另外sharegpt格式本身没问题,但你的system prompt里如果强调了“判断类别”而不是“从给定列表中选择”,模型可能就自由发挥了。
我之前做分类任务也遇到过类似问题,尤其是“其他”这种低频但重要的类别,光靠过采样和focal其实治标不治本,建议试试在loss里对“其他”类单独加权重,或者干脆把这类样本复制几份但加一点噪声扰动。全参微调输出换行符和重复句,大概率是学习率太高了,我之前用5e-5直接崩了,降到1e-5左右才稳定,另外你是不是把回复模板里“好的”这类词也当成训练目标了?那种通用开头语模型学得特别快,容易把其他内容挤掉。
这情况我也踩过坑,多半是数据里“其他”类的样本质量不行,试试把这类样本单独清洗下再训。
全参微调崩成这样大概率是lr太高了,调到1e-5以下再看看。
这个现象我太熟了,之前做意图分类也踩过同样的坑。全参数微调出重复输出基本就是学习率太大,Qwen这种基座模型对lr特别敏感,我一般用1e-5起步,超过2e-5就很容易崩,你可以先降到5e-6看看。至于“其他”类不输出,光靠过采样和focal其实治标不治本,我怀疑是模板问题,sharegpt格式里如果system提示词写得太死,模型会被带偏,建议把“其他”类的样本在system里明确强调一下,或者在instruction里加一个“若无法确定,请输出其他”的引导。另外几千条数据对7B来说确实偏少,Lora的rank可以调大到32试试,但更关键的是看看你的测试集里“其他”类是不是和某些特定文本强绑定,模型可能学到了某种虚假关联。还有个土办法,推理时把temperature调高到0.3以上,或者直接对“其他”类的logit加个偏置,虽然不优雅但很管用。你那个疯狂输出换行符的情况,八成是数据里混了太多空行或特殊字符,清洗一下训练集大概率能缓解。
全参数微调跑两天大概率是lr太高崩了,试试降到1e-5以下,顺便看看tokenizer有没有把换行符当特殊字符处理。
之前跑分类任务也遇到过类似问题,类别不均衡真不是光调loss就能解决的,建议试试在推理的时候直接对“其他”类做阈值控制,或者把这类样本在训练时多重复几次。全参数微调那种疯狂输出换行符的现象,大概率是学习率太高了,降到1e-5以下再试试,顺便把max_length调小点。另外sharegpt格式本身没问题,但分类任务其实用alpaca那种带instruction的格式更稳,你可以对比下效果。
这情况多半是学习率太高了,降到1e-5以下试试,全参微调尤其容易崩。
全参跑两天还崩成这样,八成是lr太高了,试试降到2e-5以下,顺便把“其他”类单独加权看看。
全参数微调跑两天出这个结果,大概率是学习率太高把原始能力冲没了,Qwen对lr挺敏感的,试试降到1e-5以下,或者加个warmup。另外“其他”类占比30%但输出少,也可能是你数据里“其他”类的样本文本特征太分散,模型学不到统一模式,过采样不一定有用,可以看看这类样本的标签质量,是不是有些该归到别的类。
全参数微调两天确实容易崩,建议先把lr降到1e-5试试,另外检查下数据里其他类别的样本是不是被截断了。
全参数微调两天那个现象大概率是lr太高了,Qwen系列对lr特别敏感,试试把lr降到1e-5以下,顺便加个warmup和梯度裁剪。分类任务其实没必要全参,LoRA把rank调大到32或64,target_modules多加几个线性层,效果应该能上来。另外“其他”类输出少不一定是数据问题,你推理时把temperature调低到0.1或者直接greedy decoding看看,有时候采样温度高会把低概率类别彻底丢掉。数据格式倒是没啥大问题,不过建议你检查下模板里有没有把类别标签写进system prompt,让模型明确知道可选范围。
这明显是学习率太大把模型之前的分布冲垮了,建议先降到1e-5试试,另外看看数据里“其他”类的样本是不是标注太模糊了。
全参数微调跑两天出那种重复输出,大概率就是lr太高把原模型权重冲垮了,建议先把lr降到1e-5以下试试。另外几千条数据其实不太建议全参,lora效果不好可能是秩或者target_modules没调对,换下q/k/v/o全加进去看看。至于“其他”类不输出,光靠过采样和focal可能治标不治本,你可以试试在loss里给“其他”类单独加个权重系数,或者干脆把推理时的temperature调低点,有时候是采样随机性把低概率类给吞了。
我之前也踩过类似的坑,全参数微调后模型疯狂复读和输出换行符,大概率不是数据格式的问题,而是学习率太大导致原有能力被冲垮了。Qwen2.5-7B这种量级,全参微调lr设到2e-5以上就很容易崩,建议先降到1e-5甚至5e-6试试,另外把max_grad_norm设小一点。至于“其他”类不输出,我怀疑不光是数据不平衡,可能是这个类别在训练集里文本特征太杂,模型学不到一个紧凑的决策边界,过采样和focal只是缓解了数量问题,没解决表征问题。你试试在数据里给“其他”类的样本增加一些和工单无关的噪声文本,或者干脆把“其他”类的样本复制几份但随机打乱关键词,让模型被迫去学“没有明显关键词就归其他”这个规则。还有个小技巧,推理时把temperature调低到0.1,top_p设0.9,能减少模型瞎编的概率。数据格式的话,sharegpt没问题,但确认下system prompt里有没有暗示模型“必须给出详细回答”,有时候是prompt把模型带偏了。你那个Lora跑一个epoch效果还行,说明基座能力没坏,建议回到Lora调参,别全参折腾了。
全参微调那个输出模式明显是lr太高了,建议先降到1e-5试试,另外“其他”类少可以试试在system里强调一下。
全参数微调跑两天出这种问题,大概率是学习率太大了,Qwen这种模型全参微调lr一般得压到1e-5甚至更低,你试试用cosine衰减加warmup,另外把max_seq_len检查下,别让长文本把梯度撑爆了。
至于“其他”类别输出少,光改loss作用有限,建议看看是不是模板里给“其他”的定义太模糊,模型学不到边界,试着在system prompt里把“其他”换成几个具体负面例子,或者干脆把“其他”类拆成两个相近类别再合并,有时候反而有用。
数据格式sharegpt没问题,但几千条对7B来说确实少了点,lora跑一个epoch能有效果已经不错了,全参反而容易过拟合,建议还是回到lora,把epoch加到3-5个,配合early stopping,比瞎折腾loss靠谱。
我之前也踩过类似的坑,尤其是“其他”类不输出的问题,八成不是单纯数据不平衡,而是模型在微调时把“其他”当成了默认拒绝项,因为这类样本的语义边界太模糊了。你过采样和focal loss都试过,那可以看看是不是标签在模板里位置太靠后,或者“其他”对应的instruction描述和其他类别不够区分,模型学了个捷径。全参数微调跑两天输出换行符,这个太典型了,大概率是学习率在3e-5以上,加上训练步数太长,导致灾难性遗忘,而且Qwen的chat模板对格式特别敏感,如果你用的sharegpt格式里system和user字段顺序不对,或者generation的stop token没设置好,它就会一直自我重复。建议你先用官方推荐的chatml模板跑一个很小的demo,比如100条数据,固定学习率1e-5,只训一个epoch,看看输出是否正常。另外,推理时temperature调低到0.1,repetition_penalty加到1.1,能压住重复输出。如果还是不行,单独把“其他”类的样本权重乘以2-3,但别用focal,直接改loss的class weight试试。我上次处理类似问题,最后发现是数据里“其他”类文本长度普遍太长,模型把长文本和重复输出关联起来了,你检查一下样本长度分布。
输出崩坏大概率是学习率太大,试试降到1e-5以下再加点warmup,另外检查下数据里“其他”类的样本是不是格式和其他类别不一致。