最近在跑一个中文客服意图分类的微调任务,用的LLaMA-7B,LoRA方式,单卡A100 40G。数据大概2万条,每条也就几十个字。问题是batch size设2就OOM,设1又怕不收敛。尝试了梯度累积设4,但loss曲线震荡得很厉害,而且训练速度慢得离谱,一天才跑几千步。我看教程里都说小batch加梯度累积能模拟大batch,但实际效果很差。有没有大佬实际调过这类的?是不是LoRA的rank也要跟着改?还是说数据集太杂、需要先清洗一遍?求实战经验,顺便问下你们训练时一般多久看一次验证集loss?
微调LLaMA模型做中文客服,显存总爆掉,求指点batch size和梯度累积怎么设?
全部回复
共 24 条A100 40G跑7B LoRA按理说bs=2不该爆,你看看是不是max_length设太长了,客服短文本512完全够用,设2048纯属浪费显存。梯度累积loss震荡一般是累积步数太多、等效batch过大导致学习率不匹配,把lr调小点或者累积设2试试。LoRA rank对显存影响不大,r=8和r=16差不了多少,别在这上面纠结。验证集我一般500步看一次,太频繁反而干扰判断,2万条数据其实一两个epoch就差不多了,先确认下数据标签有没有问题。
2万条几十个字的中文数据,A100 40G跑LoRA按理说不至于batch size 2就OOM,我第一反应是你max_seq_length是不是开太大了?很多人直接按默认512甚至1024来截,但客服意图分类这种短文本任务,256甚至128基本就够用了,光这一项显存就能省一大截。另外你梯度累积设4之后loss震荡,未必是累积本身的问题,更可能是学习率没跟着放大——累积等效batch变大,学习率还按batch size 1的来,优化轨迹就会很怪,建议先把accumulation steps和lr一起调。还有个容易被忽略的点,LoRA的rank默认8通常够用,但target_modules如果只挂了q_proj和v_proj,表达力确实会偏弱,可以试试把k_proj、o_proj也加进去,比单纯堆rank更划算。训练慢到一天几千步这个不正常,建议开gradient_checkpointing再把dataloader的num_workers调大,A100上7B LoRA一个epoch跑2万条不该这么慢。验证集我一般每500到1000步看一次,太频繁纯属浪费,但你这种loss震得厉害的情况,前200步密一点盯着,能早点发现问题。数据清洗我觉得优先级反而没那么高,意图分类2万条只要标签不是乱标的,先解决显存和收敛再回头洗也不迟。
LoRA rank不用跟着batch size调,但40G跑7B按理说bs=2不该爆,你先看看是不是max_length设太大了,客服语料几十个字的话截到128就够了,能省不少显存。loss震荡厉害可能跟梯度累积时没做loss平均有关,有些框架默认是求和不是求均值,你确认下。验证集我一般两三百步看一次,太频繁反而干扰判断。
A100 40G跑LLaMA-7B的LoRA,batch size只能到2确实有点不正常,正常来说7B做LoRA微调,序列长度控制在256-512,40G显存跑个batch 8到16都没啥问题。你每条数据才几十个字,如果padding没有做动态处理、直接按最大长度补齐,那显存浪费会非常严重,建议先检查下tokenizer的padding策略,用DataCollatorWithPadding按batch内最长样本动态补齐,能省一大截。梯度累积4导致loss震荡,很多时候不是累积本身的锅,而是累积期间用了错误的BN或者学习率没跟着放大,LoRA虽然没BN但学习率确实要随有效batch调整,不然优化轨迹会很怪。训练慢到一天几千步,先看看是不是dataloader的num_workers设成0了,或者每步都在做全量验证,这种隐形开销比显存问题更常见。LoRA的rank一般8到16就够做意图分类这种任务了,rank调大反而容易过拟合,先别急着动它。数据集两万条做意图分类不算杂,但如果标注噪声大,loss震荡也可能是标签本身的问题,建议先抽一两百条人工过一遍看看。验证集我一般500到1000步看一次就够了,太频繁看既拖速度又容易让你被噪声带偏,意图分类这种任务看f1比看loss靠谱得多。