最近在试着用LoRA微调llama3-8B,显卡是3090(24G),batch size调到2,gradient accumulation设了8,显存占用大概16G左右。但跑一个epoch要差不多10个小时,感觉不太对劲。我看网上有人用同样配置微调13B都没这么慢。我的数据集大概5万条,max length设了2048,也试过用flash-attention和deepspeed stage2,但速度提升不明显。是不是我哪里配置有问题?还是说这个速度其实是正常的,只是我预期太高了?求有经验的大佬指点一下,或者有什么优化方向可以尝试的?顺便问下,用QLoRA会不会快一些?谢谢!
用LoRA微调7B模型,显存够但训练速度慢得离谱正常吗?
全部回复
共 99 条说实话你这速度确实有点离谱了,我拿3090跑7B LoRA,5万条数据、2048长度,一个epoch大概也就5-6小时。你试试把max length砍到1024看看,很多时候数据里根本没那么多长样本,但计算量直接翻倍。另外flash-attention和deepspeed得配合着开,单独用有时候反而拖慢速度。QLoRA的话理论上能省点显存,但速度提升有限,主要看你瓶颈在计算还是IO,建议先看一眼GPU利用率是不是一直拉满的,如果经常掉到80%以下可能是在等数据加载。
5万条数据跑10小时其实不算离谱,主要瓶颈在max length=2048上,序列越长attention计算量越大。你试试把max length砍到1024或者用packing策略,速度能翻倍。QLoRA用4bit量化确实会快一些,但3090上跑8B本来就不该这么慢,建议检查下是不是没开torch.compile或者数据加载有瓶颈。另外deepspeed stage2对单卡LoRA帮助不大,不如把gradient accumulation调小点直接加大batch size。
5万条2048长度这速度真不算离谱,瓶颈在序列长度上,试试把max length砍到1024能快一倍。
QLoRA能省显存但速度没啥提升,你卡在计算上,建议先查下是不是没开torch.compile。
说实话你这速度确实偏慢了,我拿3090跑7B LoRA,5万条数据max len 2048大概也就6小时左右一个epoch。你试过把batch size提到4然后gradient accumulation降到4吗?有时候小batch反而会触发更多的kernel launch开销,特别是配上flash-attention。另外QLoRA不会更快,4bit量化主要省显存,计算量基本没变,甚至可能因为反量化步骤略慢一点。建议你开一下profiler看看是不是卡在dataloader上,或者试试unsloth这个库,它针对LoRA做了很多底层优化,我换了之后速度直接翻倍。
说实话你这速度确实偏慢了,我拿4090跑同尺寸数据集(5万条、2048长度)大概6小时一轮,3090慢30%左右但也不至于10小时。先检查下是不是CPU吃满了,数据加载和tokenize经常是瓶颈,试试把num_workers调高或者用流式加载。QLoRA不会更快,4bit量化反而可能因为反量化开销变慢,但能省显存让你加batch size,如果卡在显存带宽上可能有点用。另外确认下你的LoRA rank和alpha是不是设太高了,我见过有人设成128导致计算量暴涨的,降到16试试说不定能翻倍。
这速度对3090来说算正常,5万条2048长度本来就不轻松,QLoRA能快个30%但别抱太大期望。
试试把max length砍到1024,数据清洗一下,速度能翻倍。
你这配置跑5万条2048长度,10小时一个epoch其实真不算离谱,网上那些13B快的多半是数据量小或者max length短。flash-attention和deepspeed都上了的话,瓶颈大概率在数据加载和预处理上,试试把dataset预处理成tokenized的arrow文件,能省不少时间。QLoRA的话4bit量化后显存占用更低,但速度提升有限,主要省的是显存不是算力。另外可以看看是不是CPU在疯狂跑tokenizer,把num_workers调高或者用on-the-fly预处理会好很多。
5万条2048长度,10小时真不算慢,13B那是人家数据量小或者卡多。QLoRA能快但效果略降,先查下数据加载是不是瓶颈。
说实话你这个速度确实偏慢了,但也没到离谱的程度。5万条数据、2048长度,单卡3090跑llama3-8B,一个epoch十小时换算下来大概每秒处理1.4条样本,这个吞吐量明显低于正常水平。我怀疑瓶颈不在显存,而在数据加载和预处理上,你试试把dataloader的num_workers调高,或者检查一下是不是tokenize过程在每次迭代时重复计算了。另外flash-attention和deepspeed stage2对LoRA这种小规模训练提升本来就很有限,它们主要优化的是大模型全参数微调的场景。QLoRA确实会快一些,因为4bit量化后显存占用更低,可以加大batch size,但如果你已经用16G显存跑2的batch,量化后也就勉强能上4,速度提升可能不到20%。更值得检查的是你的梯度累积步数,8步累积相当于实际batch size只有16,而3090的算力跑这个模型理论吞吐应该能到每秒5条以上,建议你用nsight或者简单的torch profiler看看是不是CPU在拖后腿。还有个细节,max length 2048如果数据集里很多短样本,等于在浪费算力,可以试试动态padding或者按长度分桶。
说实话你这个速度确实偏慢了,但瓶颈大概率不在显存,而在数据吞吐和计算效率上。5万条、max length 2048,单条序列本身就很长,即便LoRA只更新少量参数,前向反向还是要完整过一遍base model,这跟13B的对比没意义,因为人家可能用的序列长度短、数据集也小。你试了flash-attention和deepspeed stage2但提升不明显,我怀疑你数据加载的num_workers没调好,或者tokenize的预处理没做缓存,导致GPU大部分时间在等CPU喂数据。QLoRA不会让你更快,反而因为4bit反量化会增加额外计算开销,它只是省显存,你是显存够用但算力受限,所以别指望这个方向。建议你先用一个小样本比如500条跑一下,看单步耗时,再算一下理论吞吐量,如果单步就慢,那就是模型配置或环境问题,比如没开torch.compile或者bf16没生效。另外可以试试packing技术把短序列拼到2048,减少padding浪费,或者直接砍到1024看速度变化,很多任务其实不需要那么长上下文。最后检查一下是不是在跑验证集或者日志记录太频繁,这些隐形开销有时候比你想的严重。
说实话你这速度不太正常,我拿4090跑同样规模的LoRA,5万条数据max length 2048大概也就5-6小时一个epoch。你batch size 2加梯度累积8等效batch16,这配置本身没问题,但3090的显存带宽和算力跟4090差距挺大,10小时虽然偏慢但也不算离谱到哪去。建议你先确认下是不是真的在gpu上跑,有时候数据加载或tokenize环节会变成瓶颈,试试把dataloader的num_workers调高,或者用pin_memory。另外flash-attention装了不一定生效,得检查下模型是否真的调用了,有时候版本不匹配会静默回退到普通attention。QLoRA确实能快不少,因为4bit量化后计算量更小,但3090上24G显存跑8B量化后可能只有6-7G占用,你可以把batch size翻倍试试,吞吐量应该能提升30%以上。还有个容易被忽略的点,max length 2048对8B模型来说计算量很大,如果数据集里大部分样本没那么长,可以考虑动态padding或者截断到1024,速度能翻倍。最后检查下是不是CPU在预填充阶段卡住了,用nvidia-smi看下GPU利用率是不是一直满载,如果经常掉到50%以下,那问题多半在数据管道。
你这配置跑5万条2048长度,10小时一个epoch其实不算离谱,llama3的tokenizer和attention机制比老模型吃性能,13B那个对比可能数据集长度或者步数不一样。QLoRA快不了多少,主要省显存,速度瓶颈在计算量,不如试试把max length降到1024,或者用packing把短样本拼起来,吞吐能涨一截。另外检查下是不是没开torch.compile,那个对7B模型提升挺明显的,我这边开了之后大概能快30%。
5万条2048长度这速度真不算离谱,QLoRA能快20%但别指望质变。
你这数据量+2048长度,10小时真不算离谱,试试把max length砍到1024或者换8bit优化器,能快不少。
5万条长文本这速度真不算离谱,4090来也快不了多少。QLoRA能省显存但不会提速,想快直接砍max length或换7B以下模型。
这速度确实偏慢,5万条数据跑10小时不太正常,检查下是不是数据加载或CPU瓶颈了。QLoRA能快些但别指望质变,先看看GPU利用率稳不稳吧。
10小时一个epoch对5万条2048长度来说确实偏慢,但也没到离谱的程度,3090跑8B大概就这水平。你试试把max length降到1024看看,如果速度翻倍那就说明瓶颈在序列长度上。QLoRA主要是省显存,速度提升有限,但4bit量化后计算量小些,可能快个20%左右。另外检查下是不是数据加载在拖后腿,用dataloader的num_workers设高一点,还有尽量别用deepspeed,直接单卡跑说不定更快。
5万条2048长度这速度正常,瓶颈在数据量不在显存,QLoRA快不了多少。
3090跑这个规模就这德行,试试把max length砍到1024,能快两倍以上。
我之前也踩过这坑,LoRA虽然省显存但计算量没降多少,5万条2048长度跑10小时真不算离谱,我是拿A100试过才敢说。你试试把max length砍到1024,速度能翻倍,很多任务其实用不了那么长上下文。QLoRA主要省显存,你24G已经够用了,速度提升有限,不如检查下是不是数据加载和预处理成了瓶颈。另外把batch size提到4或8,配合gradient accumulation调小点,有时候反而更快,因为梯度同步开销变少了。
说实话你这个速度确实偏慢了,我拿3090跑过类似的7B LoRA,5万条数据、2048长度,一个epoch大概6-7小时左右,你10小时肯定有优化空间。但先别急着怀疑配置,我猜你大概率是卡在数据加载和预处理上了,尤其是tokenize那一步,如果没提前做好缓存,每次epoch都在重复分词,那时间全浪费在这上面了。你可以试试把数据集先离线tokenize成二进制存下来,训练时直接load,这个改动通常能省20%-30%时间。另外seq长度2048对8B模型来说attention计算量是平方级增长的,flash-attention虽然有效但如果你用的是旧版本,可能没完全生效,建议确认一下是不是真的跑起来了,或者试试把max length降到1024看看速度变化。QLoRA的话,4bit量化确实能省显存,但训练速度反而可能更慢,因为反量化有额外开销,除非你显存紧张,不然不建议为了速度换。还有个容易忽略的点,就是gradient accumulation设8的话,实际batch size是16,如果3090的带宽被喂满了,那瓶颈可能在数据管线上,你可以开个--dataloader_num_workers提高预取,或者试试把gradient checkpointing关掉,虽然显存会涨但有时反而更快。最后建议你开个profiler看看具体是哪个环节耗时最长,别瞎调,定位问题比盲目优化靠谱。