最近在尝试用DeepSpeed微调一个7B的LLM,显卡是两张3090(24G)。参考了几个开源项目的配置,把ZeRO Stage调到了2,offload_optimizer也开了,但跑起来大概十几个step之后就报CUDA OOM。
我看nvidia-smi,显存占用并没有满,但就是报错。后来试了把train_batch_size降到1,gradient_accumulation设成8,还是不行。
有点迷茫:是ZeRO的partition策略没生效,还是我的模型本身太大,两张卡真的带不动?
或者是不是我漏了offload_param?看网上有人说Stage 2要配合offload_param才能稳,但那样速度会不会太慢?
求有经验的老哥指点一下,这种配置到底该怎么调,或者说7B微调最低需要多少显存?谢谢!
用DeepSpeed微调7B模型总是OOM,是ZeRO配置问题还是我显存真不够?
全部回复
共 83 条说实话看到你说显存没满但报OOM,我第一反应是碎片化问题,PyTorch的缓存分配器有时候会预留显存不释放,看着nvidia-smi有空余,实际可用的连续块不够。你可以试试在训练脚本里加torch.cuda.empty_cache(),或者设PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128,这招我救急用过好几次。
但7B模型两张24G卡,ZeRO Stage 2理论上勉强够,关键是你开没开activation checkpointing?这个才是吃显存的大头,尤其是序列长度一上来,激活值能占掉好几个G。你光调batch size和offload optimizer,没提gradient checkpointing,我怀疑是这块爆了。
另外你确认下offload_optimizer是真正生效了吗?有时候配置文件里写了,但DeepSpeed版本不一样,参数名或者stage没对齐,会静默回退到Stage 1。可以打印一下deepspeed config的最终值看看。
至于offload_param,Stage 2其实不需要,那是Stage 3才强制配的。但如果你把optimizer offload到CPU,参数还在GPU上,那显存大头还是模型权重加梯度,7B全精度光权重就14G,再加梯度和Adam状态,两张卡确实紧。
我个人经验是,3090的24G跑7B微调,ZeRO Stage 2配offload optimizer加上activation checkpointing,batch size 1是能跑的,但得把序列长度压到1024以下。你如果任务允许,试试把max_seq_len砍半,可能比折腾offload更直接。
最后问一句,你用的是LoRA还是全参数微调?如果是全参数,那两张卡带7B基本是极限,建议换LoRA或者QLoRA,显存占用能降一半还不止,效果差不了太多。
offload_param也加上试试,3090跑7B全参微调确实紧巴,两张卡stage2理论够但得把能offload的都offload掉。
我遇到过类似情况,offload_param真得开,不然ZeRO2白配。两张24G跑7B勉强,把batch再调小试试。
把offload_optimizer改成offload_param试试,我之前就是这么救回来的,7B全参数微调两张卡确实紧巴巴的。