最近在跑一个法律文书摘要的微调实验,基座是LLaMA-2-7B,用的peft库里的LoRA。训练loss能降到0.8左右,但推理时生成的内容完全不是正常中文,夹杂着大量重复的“^”和“?”符号,偶尔蹦出几个英文单词。我检查过数据预处理,分词器用的是llama官方tokenizer,padding和truncation都设了128。调过学习率(从2e-4降到1e-5)和LoRA的rank(8到64),情况稍微好转但依然乱码。看网上说可能是tokenizer的special token没加,但我用base模型直接生成是正常的,只有微调后才崩。有没有大佬遇到过类似情况?是应该检查attention mask还是需要重新对齐label?求指点一下排查方向,谢谢!
用LoRA微调LLaMA模型后推理结果全是乱码,是学习率问题还是分词器没对齐?
全部回复
共 69 条base模型正常但微调后崩,基本能排除分词器本身的问题,更可能是训练时label没对齐或者padding token参与了loss计算。你检查下数据预处理里labels是不是把padding部分设成了-100,不然模型会学着生成一堆填充符。另外LoRA的target_modules如果只挂了q和v,法律这种长文本任务可能欠拟合,试试把k、o和gate也加上。我上次遇到类似乱码,最后发现是gradient accumulation和batch size配比不对,导致实际学习率被放大了好几倍。
检查下推理时是不是没把LoRA权重merge进去,base正常但微调后崩,八成是加载方式不对。
base模型正常说明tokenizer没问题,乱码大概率是LoRA权重在推理时没正确合并或加载。你试过用merge_and_unload()把适配器融进基座再推理吗?另外训练loss降到0.8但输出崩,很可能是target_modules只选了q_proj和v_proj,法律领域这种长文本任务建议把k_proj、o_proj也加上,不然注意力层学偏了。还有检查下推理时的prompt格式跟训练时是否完全一致,少个空格或换行都可能让LoRA输出跑飞。
是不是只训了LoRA权重但推理时没merge或者加载错了?base正常说明分词器没问题,大概率是权重对不上。
试试先合并LoRA权重再推理,peft直接加载有时会出错,我之前也踩过这坑。
训练loss降到0.8但推理乱码,这基本说明模型在过拟合或者学崩了,不是单纯的分词器问题。我之前用LLaMA-2跑中文LoRA也踩过类似的坑,后来发现是target_modules只设了q_proj和v_proj,中文任务这样容易把语义空间搞乱,建议把k_proj和o_proj也加上试试。另外你用的法律文书数据量是不是不大?数据少加上rank开太大,模型很容易记住噪声然后生成时彻底失控。还有一个隐蔽的点是LLaMA-2的pad_token默认等于unk_token,训练时attention mask可能没正确处理padding位置,这个也会让推理输出飘掉。
loss能降到0.8但推理乱码,感觉更像是target modules没设对,你LoRA是只挂了q_proj和v_proj吗?法律摘要这种任务建议把k_proj、o_proj还有gate/up/down全加上试试,不然容量不够模型会往奇怪的方向漂。另外训练时prompt模板和推理时不一致也很容易崩,尤其是special token的位置。我之前遇到过类似的,最后发现是保存adapter时没合并好,你试试load完adapter后打印几个生成的token id看看是不是正常的中文编码。
base模型正常、微调后才崩,基本可以排除tokenizer本身的问题,更像是训练目标或者生成配置上出了岔子。loss能到0.8其实挺可疑的,法律文书摘要这种任务不太可能压这么低,除非你的标签里混进了大量padding或者重复文本,模型在学怎么复读。那堆“^”和“?”很像是模型在贪心解码时反复吐出低概率的碎片token,越滚越偏。建议先别动学习率,把生成参数固定成do_sample=False、repetition_penalty=1.0,再看输出是不是还乱,这样能区分是训练坏了还是解码坏了。另外确认一下训练时是不是把labels里的pad token也算了loss,peft默认不帮你屏蔽,这个坑我踩过,loss会假性下降,实际学了个寂寞。还有个容易忽略的点,LLaMA-2的tokenizer在中文上本来就比较碎,如果你训练数据里中英混排严重,LoRA只学了几个attention层,很容易把中文嵌入空间带偏。你可以试试只对q_proj和v_proj加LoRA,别把mlp也挂上,rank给16就够了,先跑个200步看看生成是不是还带“^”。
生成参数是不是默认没改,temperature调低点试试,乱码经常是采样炸了。