最近在试着用LoRA微调Qwen2.5-7B,用的是单张4090(24G),按理说显存应该很充裕。但我发现训练速度只有大概5-6 steps/s,batch size=1,序列长度也就512。看日志loss在降,但心里没底——这速度正常吗?我看网上有人说用同样的卡能跑到十几steps/s,他们是不是用了什么加速技巧?还是说7B模型本来就这样?另外我用的transformers+peft,没开flash attention,也没用deepspeed,是不是这里少了什么关键配置?希望有经验的朋友指点一下,先谢过了。
用LoRA微调7B模型,显存够但训练速度极慢正常吗?
全部回复
共 13 条正常,7B不开flash attention就这速度,开一下能翻倍,deepspeed倒不是必须的。
5-6 steps/s对7B单卡来说其实算正常范围,网上那些十几的要么开了flash attention要么序列更短,我自己的经验是装上flash-attn之后能提升30%左右,你试试看。另外batch size=1确实亏吞吐,可以试试gradient accumulation配合稍微大点的batch,或者检查下是不是数据加载成了瓶颈。deepspeed倒不是必须的,但offload优化器状态能省点显存,对速度帮助不大。
5-6 steps/s对7B+LoRA来说其实不算离谱,特别是没开flash attention的情况下,瓶颈多半在attention计算和内存带宽上。网上那些十几steps/s的,大概率是开了flash attention2+bf16混合精度,甚至可能用了8bit的基座模型,你这配置把这几项加上应该能明显提一截。另外可以看看是不是CPU在跑数据加载,把num_workers调高试试,有时候这个卡脖子比GPU还狠。我自己的经验是7B单卡能稳定在10左右就算正常,不用太焦虑,loss在降就说明方向没问题。
5-6 steps/s对7B来说确实偏慢,但也没到离谱的程度。你提到的flash attention和deepspeed都是关键,尤其flash attention在长序列下能快不少,但512长度影响有限。我怀疑瓶颈在数据加载或梯度累积设置上,可以试试把num_workers调高、pin_memory打开,或者用torch.compile试试。另外网上说十几steps/s的,很多是用了量化或者更短的序列,别全信。
另外你检查过GPU利用率吗?如果没跑满,八成是CPU或数据管道拖后腿了。我自己的经验是,开bf16混合精度能明显提速,显存也还有富余。还有个小技巧,把LoRA的r值调小一点,比如8或4,虽然不影响速度,但能减少显存碎片,间接提升效率。先看看nvidia-smi的利用率,再对症下药吧。
5-6 steps/s对7B来说其实算正常范围了,网上那些十几steps/s多半开了flash attention或者用了8bit/4bit量化,甚至可能跑的是6B以下模型。你缺的那几个关键配置里flash attention提升最明显,建议先装上试试,速度能涨一截。另外deepspeed单卡其实没必要,但可以看看是不是数据加载或CPU瓶颈,把num_workers调高点也有用。loss在降就说明方向对,别太焦虑。
flash attention不开确实亏,开完起码翻倍,另外你试试torch.compile,5-6步确实偏低了。
正常,7B单卡4090这速度差不多,flash attention一开能提不少,再挂个deepspeed stage2试试。
5-6 steps/s对于7B模型单卡4090来说其实算正常范围,网上那些十几steps/s大概率是开了flash attention加bf16混合精度,甚至可能用了更短的序列长度或者梯度累积来刷数据。你提到没开flash attention,这确实是个关键点,Qwen2.5的GQA结构在长序列下收益特别明显,建议先把这个加上,光这一步可能就能提到8-10步。另外deepspeed不是必须的,单卡跑LoRA反而会引入额外通信开销,不如把注意力放在优化上,比如检查一下是不是默认用了fp32训练,改成bf16能快不少。还有一个容易被忽略的点,你的tokenizer和dataloader的预处理是否成了瓶颈,有时候数据加载比计算还慢,试试把num_workers调高或者用流式读取。最后想确认下你用的peft版本,最近几个版本对Qwen的target_modules有优化,旧版可能把不必要的层也纳入了训练,导致计算量虚高。速度这事只要loss在稳定下降就不用太焦虑,7B模型本身计算密度就摆在那,单卡4090的算力上限也就这么多了。
5-6 steps/s对7B来说不算离谱,但确实有优化空间。关键是你没开flash attention,这玩意儿在长序列下能省不少显存带宽,速度提升挺明显的。另外建议试试unsloth或者给peft加个gradient checkpointing,batch size=1的时候这个很管用。deepspeed倒不是必须,单卡用不上,但如果你连transformers的trainer都没用,纯手写训练循环的话,建议检查下数据加载是不是成了瓶颈。我跑类似配置大概能到8-10,你可以从这几个方向去排查下。
5-6 steps/s对7B来说不算离谱,但确实有优化空间。你提到没开flash attention,这基本就是最大瓶颈,建议先加上,一般能提升30%-50%。另外transformers+peft默认走的是慢速路径,可以试试unsloth或者torch.compile,很多人说的十几steps/s多半是开了这些。还有个小细节,检查下是不是把pad token设了,不然计算量会虚高。我自己的经验是4090上7B+LoRA,序列512,正常优化后能到10左右,你再试试看。
说实话5-6 steps/s对7B+LoRA来说不算离谱,但确实有优化空间。你提到没开flash attention,这很关键,开了之后显存占用和速度都能改善不少,4090上应该能明显提上去。另外可以试试把梯度检查点打开,虽然会慢一点但能省显存,或者调大batch size看吞吐是否上去。至于网上说的十几steps/s,很多是用了bitsandbytes的4bit量化加载模型,再配合flash attention,速度差距就出来了。你现在的配置其实挺正常的,先试试换这几个选项,跑个几十步对比下再判断吧。
5-6 steps/s对7B来说其实算正常范围,网上十几steps/s的多数开了flash attention或者用了更短的序列长度,另外他们可能还开了bf16混合精度。你试试在peft里加个torch_dtype=torch.bfloat16,再把attention实现换成sdpa或flash_attention_2,速度能提不少。deepspeed这种单卡其实没必要上,但如果你愿意折腾,zero2也能压点显存换速度。还有个冷门小技巧,把pad token设成eos,能省点计算。
5-6 steps/s对于7B模型单卡4090来说确实偏慢,但也没到离谱的程度。你提到的关键点其实自己已经猜到了——没开flash attention和deepspeed确实是两个大坑,尤其flash attention对长序列的加速非常明显,开了之后速度能提升30%以上。另外你用的transformers+peft默认是不走torch.compile的,加上compile之后推理和训练都会有额外收益,不过要注意和peft的兼容性。还有一个容易忽略的点是数据加载,检查下dataloader的num_workers是不是0,有时候瓶颈根本不在GPU而在CPU预处理。网上说的十几steps/s大概率是用了bf16混合精度加上flash attention,甚至可能序列长度更短。最后建议你装一下最新的flash-attn库,配合transformers的attn_implementation="flash_attention_2"参数,速度会立竿见影。至于deepspeed,单卡其实没必要上,但可以试试zero stage 2配合offload,对显存冗余有帮助,不过速度提升有限。总之先把flash attention开了,再对比下loss下降曲线,如果依然慢再考虑其他优化。