最近在尝试用DeepSpeed微调一个7B的LLaMA模型,卡是两张A100 40G。用了ZeRO-3,offload也开了,但每次跑起来没几分钟就报OOM。我看了一些教程说7B模型用ZeRO-3应该能跑,但我设置zero_optimization.stage=3之后,显存占用直接冲到35G以上,训练步数一多就崩。我试过调小per_device_train_batch_size到1,还是不行。是不是我offload_param和offload_optimizer的device没设对?或者ZeRO-3本身对多卡通信有额外显存开销?有没有大佬分享下实际成功跑7B微调的config配置?先谢过了。
用DeepSpeed跑LLaMA微调,ZeRO-3总报显存不足,是我配置有问题吗?
全部回复
共 133 条offload设cpu后记得把 optimizer 和 param 都指过去,另外 ZeRO-3 通信峰值很吃显存,试试 reduce_bucket_size 调小点。
我之前也卡在这过,ZeRO-3不是开了offload就万事大吉,你那个35G其实很多是通信buffer和临时激活值。试试把zero_force_ds_cpu_optimizer设成false,然后offload_optimizer的device用cpu,param用nvme试试,虽然慢点但能跑起来。另外7B模型在40G卡上其实ZeRO-2加offload就够,不一定非上stage3,多卡通信开销反而拖累显存。你设batch size=1还崩的话,检查下model并行相关的配置,或者把stage3_max_live_parameters和stage3_max_reuse_distance调小点。
我之前也遇到过类似情况,7B在双卡A100上用ZeRO-3其实挺吃紧的,关键不光是batch size,那个offload的device如果设成cpu,会有一大块pin memory和通信缓冲占用,建议先看看nvidia-smi里是不是有非模型部分的缓存没释放。另外ZeRO-3的分区参数会在前向反向时频繁做all-gather,这本身就会额外吃掉不少显存,你可以试试把zero_force_ds_cpu_optimizer设为false,或者干脆换ZeRO-2加offload,说不定反而更稳。我之前用单卡A100 40G跑7B,纯ZeRO-2加offload,batch size设1,能跑完整个epoch不崩。
7B用ZeRO-3两张40G按理说够了,但35G打底确实偏高了。我怀疑是offload没真正生效,你检查下offload_param和offload_optimizer里都写了device: cpu没,光开stage 3不写device是不会自动offload的。另外stage3_gather_16bit_weights_on_model_save和sub_group_size也调一下,前者训练时最好关掉。还有别忘了开activation_checkpointing,7B不挂这个显存很容易炸。
两张A100 40G跑7B还开ZeRO-3确实有点吃力,尤其你offload开了之后显存反而涨,大概率是stage3把参数切太碎导致通信buffer占了不少。我之前类似配置是把offload_param设成cpu、offload_optimizer也丢cpu,同时开stage3_gather_16bit_weights_on_model_save,再把gradient_accumulation拉高、batch压到1,才勉强稳住。你可以先试试把zero3的reduce_bucket_size和stage3_prefetch_bucket_size调小点,这两个默认值在40G卡上很容易爆。另外检查下是不是用了flash attention但没开upcast,有时也会偷偷多占显存。
试试把stage3_gather_16bit_weights_on_model_save打开,再查下offload是nvme还是cpu,我这边7B双卡40G跑ZeRO-2更稳。
两张A100 40G跑7B按理说用ZeRO-3不该这么容易OOM,35G的占用看着更像是参数、梯度、优化器状态都堆在卡上了,而不是真正把该offload的都挪走了。你重点检查一下offload_param和offload_optimizer的device是不是都写成了cpu,还有pin_memory有没有开,这俩写错的话基本等于没offload。另外stage3的通信开销确实会额外吃显存,尤其你如果开了stage3_gather_16bit_weights_on_model_save或者训练中频繁gather参数,峰值会顶上去。per_device_train_batch_size调到1还崩的话,八成不是batch的问题,而是模型加载方式或者gradient_accumulation跟zero的交互没弄对。我建议先把offload全开、stage设3、把sub_group_size调小一点试试,同时确认下transformers版本和deepspeed版本兼容,有时候是版本坑。能贴一下完整config和启动命令会更清楚,光看描述很难定位到具体哪一项。
试试把stage3的offload设成cpu,另外7B单卡40G开zero3其实有点吃力,bs=1都崩可能是gradient_accumulation没配好。
两张A100跑7B还OOM,八成是offload_param设成cpu但stage3的临时buffer没降下来,试试把reduce_bucket_size调小点。
试试把stage降到2,7B微调ZeRO-2加offload基本够用,3的开销确实大。
两张40G跑7B还OOM确实离谱,先查下offload的device是不是写成了cpu,nvme和cpu差别挺大的。
两张A100 40G跑7B还用ZeRO-3,通信开销确实会吃掉不少显存,尤其你offload开了但stage3的param分区在forward时还要all-gather,峰值很容易冲上去。建议先确认offload_param和offload_optimizer的device都是nvme或cpu,别设成cuda;另外把stage3_gather_16bit_weights_on_model_save关掉,再试试sub_group_size调小。其实7B微调用ZeRO-2加gradient checkpointing更稳,不一定非得上stage3。
检查下stage3_gather_16bit_weights_on_model_save和optimizer的offload设成cpu了没,我之前也是这俩没配对一直炸。