最近在用Llama3-8B做领域微调,任务是让它更懂中文客服场景。我准备了大概2万条清洗过的对话数据,用的LoRA,rank=32,学习率2e-4,跑了3个epoch。结果验证集上BLEU和ROUGE都掉了,甚至一些原本能答对的基础中文问题现在也开始胡说八道。查了loss曲线,训练时是下降的,但生成效果就是不对。我怀疑是不是数据里中英混杂太多,还是说微调时把基座模型的通用知识给覆盖了?有没有朋友遇到过类似情况?想听听你们是怎么平衡领域能力和通用能力的,或者有没有什么检查数据质量的经验?谢谢了。
微调Llama3中文能力反而变差了,是数据问题还是我哪里搞错了?
全部回复
共 70 条这问题太典型了,八成不是LoRA参数的事,2万条数据对8B模型来说其实挺容易过拟合的,尤其你学习率还开到了2e-4。我建议你先看看训练集里是不是有大量英文模板或者中英混杂的句式,模型可能把“客服语气”和“乱码式中英混合”绑定了。另外可以试试把验证集分开算一下,只看中文纯文本的生成质量,如果还是掉,那就得考虑冻结更多层或者减小rank,给模型留点通用知识的空间。
我之前调类似任务时,把数据清洗到纯中文口语,并且加了10%的通用中文语料混着训练,效果就稳住了。你也可以查一下loss曲线末尾是不是有突然的尖峰,那通常是模型开始死记硬背训练集的信号。
我之前也踩过类似的坑,LoRA rank开到32在8B上其实风险挺大的,尤其你只跑了3个epoch,大概率是过拟合到客服话术的浅层模式上了,而把基座模型里那些常识性的语义关联给冲淡了。我后来把rank降到16,学习率调到1e-4,然后只训练1.5个epoch,效果反而稳住了。另外你提到中英混杂,这个我建议先拿一个小的通用中文测试集(比如CLUE里抽几百条)在微调前和微调后分别跑一下,如果通用分数掉得厉害,那就是灾难性遗忘太严重了,可以考虑在训练loss里加一个通用语料的正则项,或者用那种混合训练策略,每10条领域数据里混1条通用数据。数据质量上,我碰到的更隐蔽的问题是很多“清洗过”的对话其实带了系统级的噪声,比如用户和客服的角色标签混进了文本,模型学的是“怎么模仿格式”而不是“怎么回答问题”。你可以试着对训练数据做个简单的扰动测试,比如把一些实体替换成同义词,看模型输出是不是也跟着变,如果完全不变,那说明它根本没在学语义。还有个土办法,把训练集里loss最低的几百条拿出来人工看一遍,往往能发现是数据里某些高频无意义回复(比如“亲,稍等哦”)把模型带偏了。
同款问题我调ChatGLM的时候也碰到过,后来发现大概率是数据分布跟基座预训练语料差太远导致的。你2万条对话里如果中英混杂比例超过15%,LoRA很容易去拟合那些中英混合的噪声模式,反而把原本干净的中文语义给带偏了。我建议你先做个词频统计,看看高频token里是不是英文占了不小比例,另外用困惑度挑出那些模型本来就很会答的样本,单独跑一遍微调看会不会掉点。还有个坑是学习率2e-4配rank=32对8B来说可能偏激进,LoRA更新矩阵的奇异值如果掉了,基本就是在破坏原有知识结构,你试试降到1e-4或者rank=16,同时加个0.1的权重衰减。生成胡说八道很典型,就是你优化目标跟语言建模目标打架了,可以试着在训练时混入30%的通用指令数据做回放,或者用NEFTune加噪声正则,能保住一部分通用能力。数据清洗的话,建议把英文对话整段删掉而不是翻译,比硬保留强得多。
遇到过类似的,LoRA微调后通用能力退化挺常见的,尤其是中文数据量不算大的时候。你rank=32可能有点高,试试8或者16,学习率再调低点,比如1e-5,epoch减到1-2个,先看生成是否稳定。另外检查下数据里是不是有太多重复模板,或者中英混杂导致模型学乱了,可以把英文比例压到5%以下,或者干脆纯中文。我之前用alpaca格式做客服数据,加了10%的通用中文指令回放,效果比单纯微调好不少,你可以试下。
这情况大概率是数据里中英混杂导致模型学乱了,建议先筛掉英文样本或加翻译对齐再试。
这配置看着挺标准的,问题大概率出在数据上。2万条看起来不少,但要是中英混杂或者客服场景太单一,LoRA很容易把模型带偏,尤其rank=32对8B来说有点激进,学过头就忘了通用知识。建议你先拿原始模型跑一遍这2万条数据,看看loss分布,把那些让模型特别困惑的样本筛出来检查下,很多时候是标签或上下文格式不一致。另外可以试试把学习率降到1e-4,epoch减到1,先看效果再慢慢加,别一上来就想着快速收敛。
2万条数据跑3个epoch对8B来说确实容易灾难性遗忘,试试降到1个epoch加更低学习率,LoRA rank也可以砍到16。
看到你这个loss曲线下降但生成效果崩掉的情况,我第一反应是学习率太高了。2e-4对LoRA来说其实偏激进,尤其数据量才2万条,rank=32很容易让模型在少数领域样本上过拟合,把通用表征给冲掉了。我之前调中文任务时试过把学习率降到5e-5以下,效果立刻稳了不少,你可以先试试这个方向。
另外你说中英混杂,这个真的很关键。Llama3的中文底座本来就不算强,如果数据里英文客服术语或者代码切换太多,模型会学成一种“中英混合模式”,反而把原本干净的中文回答带偏。建议你抽50条训练数据人工看一眼,统计一下纯中文比例,低于80%的话清洗逻辑就得改。
还有个容易忽略的点:你验证集用的BLEU和ROUGE,对客服这种生成式对话其实不太敏感,经常出现语义对但字面不匹配的情况。不如直接找几个人做盲测,或者用LLM-as-judge打分,不然你判断“变差”的标准可能本身就有偏差。
关于通用能力覆盖的问题,我自己的做法是微调时混合10%-20%的通用中文语料,比如百科问答或者日常对话,相当于给模型留个“记忆锚点”。你可以试试在训练集里掺一些基座模型原来擅长的任务样例,epoch降到1.5或者2,用early stopping盯验证loss,别光看训练loss。
最后想问你一下,你用的LoRA是只调了attention层还是也加了FFN?我试过只调attention的话,领域能力学得慢但通用性保得好一点,全调的话容易顾此失彼。这个细节有时候比数据影响还大。
我之前也踩过类似的坑,LoRA rank拉太高加学习率偏大,很容易在少量数据上把基座模型的分布带偏,尤其中文token的表示本来就不如英文稳定。你2万条对话听起来不少,但要是中英混杂比例超过三成,模型很容易把“客服语气”和“英文句式”绑定在一起,反而污染了原本的中文语感。建议先拿几百条纯中文的通用测试集跑一下,看看掉点是不是集中在涉及知识问答的类别上,如果是,基本就是灾难性遗忘。我自己的做法是,在微调数据里混入20%左右的高质量通用中文语料,比如百科问答和新闻,相当于给模型一个“复习”的机会,效果比单纯调参明显。另外你可以试试把学习率降到5e-5以下,epoch减到1,先看生成是否还稳定,再逐步加数据量。数据清洗方面,我一般会做一遍去重和语言检测,把那些夹杂英文客服术语的样本单独抽出来,用翻译或改写统一成中文,不然模型会学会“中英夹杂”这种坏习惯。还有一个偏方,就是微调时冻结前几层transformer,只让后面的层适配任务,能保留更多通用语义。你可以先跑个小实验,对比一下加不加通用语料的效果,损失曲线降不代表生成对,有时候过拟合就是这么来的。
2e-4对LoRA来说确实偏高了,尤其是rank=32参数量不算小,3个epoch很容易把基座模型的输出分布带偏,loss降不代表生成质量在涨,这俩本来就不是一回事。你描述的这种“通用能力被覆盖”的现象,在社区里一般叫灾难性遗忘,中英混杂的数据确实会加剧这个问题,因为模型会学到一些不中不英的表达模式。建议先做个消融实验,把学习率降到5e-5或1e-4,epoch减到1-2,看看验证集是不是就稳住了。另外2万条数据里如果客服话术高度重复,模型很容易过拟合到那几套模板上,基础问答崩掉也就不奇怪了。检查数据时可以抽样看看有多少条是真正需要微调才能答对的,如果基座本来就能答好,这些样本反而在拖后腿。平衡通用能力的话,可以往训练集里掺10%-20%的通用中文指令数据,或者用更小的rank比如8或16试试。