最近在跟一个项目,老板让用LLaMA-2-7B做中文客服问答,说必须微调。我按网上教程,用中文alpaca数据集的子集,跑了LoRA(r=8,alpha=16),只冻结原模型、训adapter,大概2万条样本,1张A100,batch size调小到4,训了3个epoch。结果测试时,回复经常答非所问,有时候还带英文混排。反而我用gpt-3.5-turbo配一个简单的few-shot prompt,效果明显更好。难道微调还不如直接调prompt?还是我的数据预处理有问题?比如要不要先做中文分词?或者直接用英文基座模型本身就不适合中文场景?有没有大佬踩过类似的坑,求分享下经验,真的很困惑。
用LoRA微调LLaMA做中文客服,效果还不如prompt工程,求指点
全部回复
共 83 条大概率是数据质量背锅,alpaca子集本身口语化程度就不够,中文客服场景得自己清洗语料。另外LoRA秩和alpha调大点试试,8确实太保守了。
说实话你这个结果挺正常的,LoRA在小数据量下学到的中文语义表征本来就有限,2万条样本对7B模型来说真不够看,而且alpaca那个数据集质量参差不齐,直接拿来用很容易把模型带偏。我个人觉得你老板要的微调可能只是想要个“我们做了”的交代,但实际效果上,纯中文场景下用基座模型加规则兜底都比硬调强。建议你先试试把英文基座换成Chinese-LLaMA或Baichuan这类中文预训练模型,再对比一下,可能差距就没那么大了。另外你检查过tokenizer对中文的分词效果吗?如果词表里中文覆盖不好,LoRA再调也白搭。
这情况太正常了,小模型微调数据不够真不如直接调大模型prompt,别死磕微调。
中文分词倒不是关键,2万条数据对LoRA来说有点少,试试加大rank和epoch看看。
这问题太典型了,2万条LoRA数据量本来就不够,不如直接上qwen或baichuan基座。
微调前先拿中文基座试试,分词那些都是次要的,数据和基座匹配才是关键。
说实话你这个结果我一点都不意外,LLaMA-2-7B本身中文语料占比就低,你拿alpaca中文子集去LoRA,2万条样本其实有点少了,而且r=8的容量可能根本学不动中文的句法和表达习惯。我做过类似的实验,中文任务上微调基座模型前一定要先看看它在中文上的perplexity,如果基础就很差,那adapter只是在硬掰,效果自然不如GPT-3.5这种原生多语模型配few-shot。你提到的英文混排,大概率是分词没处理好,LLaMA的tokenizer对中文是按字节拆的,训练时你最好把中文文本统一加个空格预处理,或者用sentencepiece重新训练个中文分词器,但那样成本就高了。另外我建议你对比一下只用LoRA训最后几层和训全部参数的效果,有时候冻结太多层会让adapter学不到深层语义。还有个思路,可以试试先用中文继续预训练几百步,把词表扩展一下再加LoRA,虽然慢但效果会稳很多。至于老板说必须微调,你可以拿你这组对比数据去说服他,prompt工程在数据量小的时候确实是性价比更高的方案,微调不是万能的。
说实话你这结果真不意外,7B的中文能力本来就一般,LoRA调出来的知识还是从基座里来的,不如直接靠GPT-3.5的上下文理解硬撑。我之前试过用中文指令集微调,效果飘得厉害,后来发现清洗数据比调参重要多了,比如去掉那些带英文标点的样本,分词倒真没太在意。你不如先拿同样的数据跑个量化版的Qwen或者ChatGLM对比下,大概率不是你的问题,是基座选错了。
同感,我拿中文数据集微调llama也踩过这坑,后来发现chinese-llama的增量词表很关键,直接拿原版跑中文等于让模型硬猜字。另外你这r=8可能太小了,我试过r=32效果明显好一些,但数据量2万条对7B来说确实有点少。其实客服场景如果prompt能解决,真没必要硬上微调,老板那边可以拿对比结果说服他,省下来的A100时间干点别的更香。
2万条对7B中文场景真不够,而且alpaca那数据质量太糙,建议先上全量SFT或者换中文基座。
中文alpaca那批数据质量本来就不行,清洗下可能比换模型更有效。
建议先拿你那个prompt结果当baseline,微调后打不过说明数据分布跟真实客服场景偏离太大了。
说实话你这情况太正常了,基座模型本身中文能力就弱,LoRA那点参数量根本掰不过来。建议先试试用中文版或者双语指令微调过的基座,比如Chinese-LLaMA或者Qwen,再在垂直领域数据上做适配。另外2万条样本对客服场景来说可能不够,而且alpaca那种通用指令数据跟你实际业务分布差太远,不如直接收集真实对话去重清洗。你那个batch size和epoch倒还好,但r=8可能欠拟合,试试r=32或者加两层adaptor。
说实话你这个现象挺常见的,LoRA在小数据量下真的不一定打得过精心设计的prompt。我怀疑问题出在数据上,alpaca子集本身是英文指令翻译过来的,中文表达和客服场景差挺远,2万条样本还可能不够适配特定话术。分词倒不是关键,更建议你试试直接用中文基座比如Baichuan或Qwen做LoRA,或者先拿你那套prompt的输出当训练数据,效果可能立竿见影。另外英文混排大概率是tokenizer对中文支持差导致的,换模型比调参划算多了。
说实话这结果不意外,LoRA那套在中文上经常翻车,尤其LLaMA的词表里中文token切得稀碎,你r=8容量又小,2万条样本真不够它学出什么泛化能力。建议先看看是不是数据里混了太多英文模板,预处理别急着分词,先跑个tokenizer对比下中文字符的切分质量。另外你拿微调跟GPT-3.5比本来就不公平,人家预训练数据里中文语料占比高太多,真要追效果不如换个中文基座试试,比如Yi或Qwen,哪怕只做prompt工程都更靠谱。
效果比不过prompt太正常了,LoRA在7B上本来就是个低秩近似,你数据量又不大,学到的可能只是表面格式而不是语义。我怀疑你alpaca子集里中文质量本身就不行,很多是机翻的,模型反而被带偏了。建议先拿几十条人工标注的高质量问答做few-shot对比一下,如果还是不行就检查下是否该用全参数微调或者换更大rank。至于中文分词,完全没必要,BPE对中文效果还行,问题更多出在基座本身对中文的编码上。
我遇到过类似情况,后面发现是学习率和batch size的锅,你3个epoch在2万条上可能过拟合了,试试把学习率降到1
说实话你这个结果我一点都不意外,LoRA在小数据量下微调7B模型做垂直领域,效果翻车太常见了,尤其是中文任务。alpaca那个数据集本身质量就参差不齐,很多回答都是英文思维硬翻译过来的,你拿它微调出来的模型当然会中英混杂。我怀疑问题不在LoRA参数或者训练步骤,而是基座模型选型就错了,LLaMA的词表里中文字符覆盖率很低,你硬训只会让它记住训练集的表面模式,而不是真正理解中文语义。我试过用中文基座比如Baichuan或Qwen做同样的事,哪怕不微调,直接few-shot效果都比LLaMA微调强。另外你说2万条样本训3个epoch,这个量级对LoRA来说其实很尴尬,数据太少模型学不到泛化规律,数据多了又容易过拟合到alpaca的问答风格。你老板说必须微调,可能只是觉得不微调显得没技术含量,但实际业务里prompt工程加一个带检索的few-shot,性价比高太多了。建议你拿几个bad case分析一下,看看是不是训练数据里本身就有答非所问的样本,清洗一遍再做一次,如果还是不行,就换基座模型试试。
说实话你这结果我一点都不意外,LoRA在小样本+中文场景下经常翻车,尤其基座还是英文为主的LLaMA。中文alpaca那数据集本身质量就参差不齐,很多是翻译腔,你拿它微调客服模型,学到的可能不是对话逻辑,而是噪声。分词倒不是关键,LLaMA的tokenizer对中文支持本来就弱,你硬分词反而可能破坏上下文,更别说r=8这种低秩配置在7B模型上表达能力有限,2万条数据训3个epoch大概率欠拟合或过拟合同时发生。我猜你测试时是不是没做few-shot或system prompt?微调模型其实更吃推理时的输入格式,你的prompt结构跟训练数据分布不一致,它当然答非所问。另一个坑可能是数据没做清洗,alpaca里很多指令是“请写一篇作文”这种,跟客服问答根本不搭,你不如自己标注500条真实客服对话试试。至于跟GPT-3.5比,那不公平,人家基座能力摆在那,prompt工程只是把已有能力激活出来,而微调是在教一个英文基座说中文客服话术,难度完全不是一个量级。我建议你先用qlora或全参数微调跑一版对比,或者干脆换中文基座比如Qwen或Yi,再不行就妥协用prompt+检索,老板要的是效果不是技术路线。
说实话你这个结果我一点都不意外,LoRA在小数据量下跑中文任务,尤其是客服这种需要强指令跟随的场景,经常干不过精心设计的prompt。alpaca子集那东西本身质量就参差不齐,很多是翻译腔,你拿它微调出来,模型学到的可能是“怎么把中文说得像英文”,而不是“怎么做好客服”。中文分词倒不是关键,LLaMA的tokenizer对中文其实能对付,但基座模型的中文语料占比低是硬伤,你等于在先天不足的模型上硬教它新技能。我觉得你可以试试先做一步继续预训练,用几十万条中文通用语料把模型“母语”掰过来,再上LoRA做指令微调,效果会差很多。另外你r=8、alpha=16可能也太保守了,客服任务需要学的新模式不少,可以试r=32甚至64,alpha跟着翻倍,学习率稍微调大点。还有个小问题,你2万条样本里有没有做数据清洗?比如去重、过滤掉超长回复和带英文的case,不干净的数据会让模型更混乱。说真的,如果老板只追求效果,你就拿GPT-3.5交差得了,微调这事等有更强基座模型再说,别跟自己的时间过不去。
说实话你这结果真不意外,7B基座本身中文能力就弱,LoRA只是微调偏好,补不了预训练的知识缺口。数据预处理倒是其次,分词那步对BPE影响真不大,问题更可能出在alpaca子集那种指令风格和客服场景差太远。建议先拿你那套few-shot prompt当测试集,用GPT-4标一批高质量客服问答对来训,比硬刷2万条通用数据靠谱。另外英文混排基本是模型输出分布没校准,可以试试在adapter里加几个中文客服的special token或者强制解码时ban掉英文token。
说实话你这个现象挺常见的,LoRA在小数据上很容易被prompt工程干翻,尤其基座还是英文模型。中文客服场景里,alpaca子集那些指令跟真实客服对话分布差太多了,答非所问大概率是数据没对齐业务,先别急着上分词。我建议你拿几十条真实客服对话做few-shot对比一下,如果效果还不行,那真不是微调的锅,是基座语言能力上限的问题。另外你那个英文混排,试试在训练时加几条强制中文输出的样本,或者把r调到16看看,但别抱太大希望。
这问题太典型了,LoRA在小样本下真不一定打得过设计良好的prompt。你说的英文混排大概率是分词器那边对中文支持弱,建议换成中文词表或者直接用BPE重训一下,别手动分词。另外alfpaca数据集本身质量一般,客服场景不如自己攒几百条真实对话丢进去,比两万条通用数据管用。还有r=8可能太小了,可以试着调到16或32,学习率也调低点,我遇到过类似情况是欠拟合。
2万条样本训3个epoch,r=8其实有点猛了,中文客服这种垂直场景本来就容易过拟合,答非所问大概率是灾难性遗忘加数据里指令模板不统一。我建议先别急着上分词,LLaMA的tokenizer对中文本来就一般,混英文很常见。你可以试试把alpaca数据换成真实客服对话重写一遍指令,再降r到4、训1个epoch看看,baseline先跟few-shot对齐再说。
2万条LoRA确实容易欠拟合,中文场景建议先换中文基座或者加分词适配,不然英文混排很难压住。