最近在试着用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跑llama3-8B的LoRA,5万条数据max len 2048,bs2+ga8大概一个epoch六小时左右,你这10小时有点离谱。先检查下是不是数据加载成了瓶颈,比如dataloader的num_workers没调,或者预处理没做tokenized缓存,这些经常被忽略但影响巨大。另外flash-attention在3090上老版本可能有兼容问题,建议更新到最新版再试,deepspeed stage2对这种规模反而可能增加通信开销,不如直接关掉跑原生。QLoRA应该会快一些,因为4bit量化后计算量下降明显,但如果你显存还有余量,我建议先查下是不是CPU在拼命做tokenize,把数据预处理提前做好存成二进制格式,往往比换框架提升更直接。
5万条数据、2048长度,10小时一个epoch其实真不算离谱,3090跑7B这数据量本来就得这时间。你试试把max length砍到1024,速度能翻倍,很多任务根本用不到那么长上下文。QLoRA快是快在省显存,但你这显存又没瓶颈,不如直接调低batch size换更小gradient accumulation试试能不能提点速。另外看看是不是数据加载那块卡IO了,开个num_workers=8能省不少时间。
说实话你这个速度确实偏慢了,我拿3090跑8B LoRA,同样5万条数据,max length撑死1500,一个epoch也就6小时左右。你check一下是不是dataloader的num_workers设成0了,或者pin_memory没开,这种IO瓶颈经常被忽略。QLoRA的话4bit量化后显存能省不少,但速度提升有限,主要看瓶颈在计算还是数据加载,建议先开个profiler看看GPU利用率是不是一直满的。另外你试试把max length降到1024,很多任务没必要2048,速度能快近一倍。
这个速度确实偏慢了,我拿3090跑7B LoRA,5万条数据max length 2048大概也就6小时左右。你试试把batch size直接提到4,gradient accumulation降到4,吞吐量往往比小batch+大累积高不少;另外确认下是不是没开torch.compile,这个对训练速度影响挺大的。QLoRA的话显存占用会低一些,但速度基本和LoRA持平,不会有质的飞跃,瓶颈还是在计算量上。你可以先跑个100条数据的小样本看下每秒处理多少token,再算算是不是真达到了3090的预期上限。
说实话这个速度确实偏慢了,我拿3090跑7B的LoRA,5万条数据max length 1024大概一个epoch三四个小时,你2048长度本身计算量就翻倍了。建议先确认下是不是tokenizer把padding都算进attention了,另外flash-attention版本和CUDA不匹配也会导致没生效,用nvidia-smi看下GPU利用率是不是一直满载。QLoRA的话4bit量化能省不少显存,但速度提升有限,主要看你瓶颈是不是在显存带宽上,如果GPU利用率已经很高,那换成QLoRA也就快个10-20%。
单卡3090跑5万条2048长度,10小时算正常,别被网上晒的截图骗了,QLoRA能快20%但质量会掉点。
试试把max length砍到1024,数据清洗下无效样本,速度能翻倍,你这配置瓶颈在数据量不在显存。
你这速度确实偏慢了,我拿3090跑7B LoRA,5万条数据max length 2048大概6小时一个epoch,flash-attention开了但deepspeed其实收益不大。QLoRA会快一些,主要是4bit下计算量变小,但如果你显存还够用,不如试试把batch size调大减少梯度累积步数,或者检查下是不是数据加载成了瓶颈。另外你确认下是不是真的在训练而不是卡在验证集上,有时候eval频率设置太高也会拖慢整体节奏。
说实话你这个速度确实偏慢,但问题大概率不在显存上,而是max length 2048配合5万条数据,单条样本的token数可能远超你想象,实际计算量被放大了好几倍。我建议你先用个小工具统计下数据集的平均token长度,如果大部分都超过1500,那这个时长就合理了。QLoRA不会更快,反而因为量化反量化会多出额外开销,但你可以试试把batch size提到4或者8,配合gradient accumulation调小,有时候吞吐反而能上来。另外检查下是不是CPU在跑数据预处理或者tokenizer成了瓶颈,把num_workers和prefetch_factor调大点可能立竿见影。
说实话你这个速度确实偏慢了,但问题大概率不在显存上。我怀疑你max length设2048是个大坑,5万条数据全塞到2048,很多样本其实没那么多token,白白计算了padding部分。建议先统计一下数据集的真实长度分布,把max length砍到128或256试试,速度可能直接翻倍。另外你说用了flash-attention但提升不明显,确认下是不是真的生效了,有时候版本不匹配会静默回退到普通attention。
至于QLoRA,理论上会快一些因为4bit量化后计算量更小,但前提是你瓶颈在显存带宽而不是计算本身。你3090跑8B,显存才用16G,说明计算可能已经饱和了,这时候换QLoRA提升不会太大。反而可以试试gradient checkpointing,虽然会慢一点点但能让你把batch size翻倍,吞吐量说不定更高。
还有个容易忽略的点,你的数据加载和预处理是不是成了瓶颈?如果每次step都在CPU上做tokenize,那GPU其实一直在等数据。建议把数据集提前tokenize好存成二进制格式,或者用dataloader的num_workers多开几个进程。另外deepspeed stage2对LoRA来说其实有点杀鸡用牛刀,offload optimizer state反而可能增加通信开销,不如直接关掉,纯靠LoRA的低rank特性省显存。
最后说下速度预期,8B模型在3090上,如果真实序列长度平均500左右,一个step大概也就1-2秒,你算算50000条数据除以batch size 2再乘8梯度累积,理论上应该几小时能跑完。所以你这个10小时肯定有优化空间,先从max length和数据管线下手吧。
你这速度确实偏慢,我3070跑7B LoRA一个epoch也就6小时,试试把max length降到1024或者换4bit量化,能快不少。
说实话这个速度有点离谱了,我之前用3090跑llama3-8B的LoRA,5万条数据max length 1024大概一个epoch也就3小时左右。你2048的长度确实会慢不少,但10小时还是偏高了,建议查一下是不是数据加载那边有瓶颈,比如tokenize没提前缓存。QLoRA的话速度提升有限,主要是省显存,除非你量化后能加大batch,否则对训练时间帮助不大。可以试试unsloth这个库,我换过去之后训练速度直接翻倍了,而且显存占用还更低。
还有个小细节,gradient accumulation设8的话,实际batch size才16,如果显存还有余量,不如直接调大batch size减少accumulation步数,省掉不少同步开销。另外检查下是不是开了--gradient_checkpointing,这个虽然省显存但也会拖慢速度,你显存才用16G,其实没必要开。
5万条数据量放在这儿,10个小时真不算离谱,尤其max length拉到2048,序列长计算量是线性往上翻的,13B那个对比可能数据集小或者长度短。QLoRA不会更快,4bit量化反而可能略慢,只是省显存,你这显存根本没瓶颈,瓶颈在算力上。建议先把max length砍到1024试试,速度直接翻倍,或者用packing把短样本拼起来,比调deepspeed那些有用多了。另外检查下是不是开了gradient checkpointing,不开的话反向传播显存会爆,但开了又会拖慢速度,这玩意儿得权衡着来。
这速度正常,5万条2048长度单卡3090跑10小时真不慢,QLoRA能快但别指望质变。
说实话你这个速度不太正常,5万条2048长度单卡3090跑8B LoRA,我估计正常也就3-4小时一个epoch,10小时确实离谱。先查下是不是数据加载成了瓶颈,试试把num_workers调高或者用 StreamingDataset 预加载;另外确认下是不是真的用上了flash-attention,有些版本要手动改模型配置才生效。QLoRA主要是省显存,对速度帮助不大,反而可能因为4bit反量化更慢,你显存够用就别折腾了。建议先跑个小数据集看看单步耗时,再对比下别人开源的训练日志,定位是前向还是反向慢。
5万条数据、2048长度,单卡3090跑10小时一个epoch其实不算离谱,毕竟llama3-8B的attention计算量在那儿摆着。你试试把max length砍到1024或者512,速度能翻倍,很多任务其实用不到那么长的上下文。QLoRA用4bit量化后显存占用会更低,但速度提升有限,主要省的是显存而不是算力。另外检查下是不是CPU在跑数据预处理,把num_workers调高、用pin_memory能榨出不少性能。
你这个数据集规模和max length确实是大头,5万条2048长度,单条序列的forward+backward计算量本身就很大,10小时一个epoch不算离谱。建议先看下实际吞吐量,比如每秒处理多少token,如果低于1000那肯定还有优化空间。QLoRA因为把基座模型量化到4bit,能省不少显存和带宽,但训练速度不一定更快,反而可能因为反量化开销略慢,除非你batch size能因此翻倍。我建议试试把max length降到1024,或者用gradient checkpointing再配合flash-attention,看看能不能把吞吐提上来。另外确认下是不是数据加载瓶颈,比如dataloader的num_workers没调够,有时候这个问题比计算还致命。
说实话这速度不太正常,我拿3090跑llama3-8B的LoRA,5万条数据max length 2048大概一epoch两三个小时就完了。你试试把batch size调成1,然后gradient accumulation拉高到16或32,有时候小batch反而能触发更高效的内核计算。另外你确认一下是不是数据加载成了瓶颈,比如dataloader的num_workers设了多少,还有tokenize是不是在每次训练时重复做的,建议预处理一次性缓存好。QLoRA的话会快一些,但主要省的是显存,你这显存本来就不紧张,不如把注意力放在优化数据管线和attention计算上,比如试试torch.compile或者换成unsloth的kernel。
你这速度确实不对,我怀疑是序列长度虚高导致attention计算量爆炸,很多样本实际没到2048但pad到满长度了。你统计一下平均序列长度,如果大部分在500以内,那建议动态padding或者用packing策略,能快好几倍。另外deepseed stage2对单卡LoRA其实没啥帮助,反而可能引入额外开销,关掉试试。QLoRA在3090上大概率不会更快,因为4bit反量化也有计算成本,除非你同时把模型换小一点。建议先用profiler看一下时间花在哪,大概率是attention或者数据加载,别急着怪LoRA本身。
5万条2048长度这速度其实正常,flash-attention瓶颈在数据处理,试试packing或减小max length。
QLoRA快不了多少,瓶颈在数据读取和计算,先查下GPU利用率是不是跑满了。
5万条2048长度这速度正常,3090跑8B就这样,想快换4bit量化加unsloth能翻倍。
这速度确实偏慢,但大概率不是配置问题,而是数据长度和batch size的锅。2048的max length对8B模型来说计算量翻倍,5万条数据相当于每步要处理大量token,建议先试试把max length砍到1024或者512,速度可能直接翻倍。QLoRA的话显存占用会更低,但速度不会快太多,毕竟瓶颈主要在计算量上,除非你同时降精度到4bit的nf4格式顺便开flash-attention2。另外检查下是不是没关掉梯度检查点或者没开torch.compile,这两个对3090提升挺明显的。我跑13B用类似配置也就比你慢个20%,你这数据量换我可能直接换7B的量化版本加packing策略了。