最近在调一个7B的LoRA微调,单卡A100(80G)能跑,但想上8卡做全参数微调。试了PyTorch自带的DDP,结果每张卡要复制一份完整模型+优化器状态,直接爆显存。换成FSDP之后虽然能塞下,但通信开销特别大,训练速度比DDP慢了快一倍,而且sharding策略(full_shard vs shard_grad_op)看得头大,文档里写得很抽象。有没有老哥实际对比过这两种方案在7B规模下的吞吐和显存表现?另外,如果我不想把模型改成HuggingFace的Accelerate写法(工程改动太大),有没有什么黑科技能硬上DDP+梯度检查点/offload?目前用的是transformers+peft,模型是llama2-7b,batch size已经压到1了,但还是卡在优化器状态上。求指点,感谢!
训练7B模型用FSDP还是DDP?显存不够但不想改代码怎么办?
全部回复
共 12 条8卡全参数微调7B,FSDP通信慢一半其实挺正常的,尤其你如果没调好reduce散播策略的话。我试过7B在8卡A100上,full_shard配activation checkpointing,吞吐大概能到DDP的80%左右,但显存能省一半多。黑科技的话,你可以试试torch.distributed的zero冗余优化器,自己包一层,不用改模型代码,但得手动管梯度同步。另外你提到transformers+,如果用的是peft,其实可以直接开accelerate的fsdp插件,改动比自己写DDP小很多,值得看一眼。
FSDP这玩意儿在小规模集群上通信开销确实离谱,尤其7B这种不上不下的尺寸,shard_grad_op比full_shard强点但吞吐还是不如DDP。你要是不想动Accelerate,试试deepspeed的zero-1?反正也就是改个config的事,比FSDP省心。另外全参微调真没必要硬刚,LoRA在7B上效果差不了多少,还能省一堆调参功夫。
7B全参微调DDP肯定爆,优化器状态就占一大块,8卡也扛不住。FSDP慢主要是默认full_shard通信太频繁,试试shard_grad_op加混合精度,速度能拉回来不少。不想改代码的话,可以看下accelerate的config直接套,或者用deepspeed zero2,改动比想象中小。
7B全参微调8卡A100用DDP基本没戏,模型+优化器+梯度加起来每卡要一百多G,爆是必然的。FSDP慢主要卡在all-gather通信上,试试把sharding策略换成shard_grad_op加mixed precision,通信量能降不少,速度会好一些。不想改代码的话可以看下accelerate的config直接套,其实不用大改模型结构,或者用deepspeed zero2,它对transformers兼容挺好,改个json配置就行。
7B全参微调想用DDP硬扛8卡确实不太现实,模型参数+梯度+Adam状态加起来光静态内存就奔着100G+去了,80G单卡能跑LoRA不代表全参能跑,这俩显存需求差着量级呢。你FSDP慢一倍这个事,我猜大概率是sharding策略没调对,full_shard对7B这个规模来说通信量确实偏大,可以试试hybrid_shard或者把shard_grad_op和full_shard混着用,另外务必开mixed precision加上transformer auto wrap policy,不然FSDP的all-gather会把整个模型层拉回来,通信直接炸。不想改Accelerate写法的话,其实FSDP也能套在原生transformers Trainer上,只要在TrainingArguments里配fsdp参数就行,工程改动比想象中小,不用手写accelerate那套。至于DDP+gradient checkpointing+CPU offload,DeepSpeed的ZeRO-2/3其实是更成熟的路子,offload优化器状态到CPU能省不少显存,但PCIe带宽会拖后腿,吞吐未必比FSDP好看。真要说黑科技,bitsandbytes的8bit optimizer配合DDP能压一压优化器状态,但7B全参还是够呛,建议还是老老实实调FSDP的wrap策略和sharding,把通信藏到计算后面,速度能追回来不少。
7B全参微调8卡DDP基本没戏,优化器状态加梯度每卡至少得百来G,不offload根本塞不下。FSDP慢主要是默认full_shard通信量太大,试试hybrid_shard或者把shard_grad_op和gradient checkpointing叠着用,吞吐能拉回来不少。不想改Accelerate的话,可以看下torch.distributed.fsdp.wrap的auto_wrap_policy直接包transformers层,改动其实比想象中小。真硬上DDP就只能上ZeRO-Offload那套,但那就不是纯DDP了。
8卡全参微调7B还想硬上DDP基本不现实,优化器状态一分片就得分片,不然80G也扛不住。FSDP慢一倍多半是没开mixed precision或者sharding策略没用对,shard_grad_op在小规模下通信确实比full_shard轻不少,可以试试。实在不想动代码,看看accelerate的config直接套,改动其实没想象中大。
7B全参微调DDP基本没戏,优化器状态就得占掉一大块,8卡也扛不住。FSDP慢主要是通信没和计算重叠好,试试把sharding strategy设成shard_grad_op加混合精度,速度能拉回来不少。不想改Accelerate的话可以用torchrun直接包FSDP的auto_wrap_policy,transformers的Trainer其实支持传fsdp参数,不用重写训练逻辑。梯度检查点能省激活但省不了优化器状态,offload到CPU更慢,不如老老实实调FSDP配置。
7B全参微调8卡DDP肯定爆,除非上ZeRO-2/3,但那不就是FSDP换皮嘛。我之前试过DDP+gradient checkpointing+Adam offload到CPU,能跑但慢得离谱,吞吐直接砍到单卡水平。FSDP shard_grad_op在7B上比full_shard快不少,通信量小,你可以先试这个策略调调。不想改代码的话看看accelerate的config,其实只加几行wrapper,比手搓FSDP省心。
这个思路不错,收藏了。
有没有更详细的教程推荐?
这个思路不错,收藏了。