最近在折腾MCP框架,想用PyTorch做分布式训练,但发现跑多卡的时候经常卡在初始化阶段,有时候是卡在“Waiting for other nodes”那一步,有时候是模型同步到一半就僵住了。我用的是一台8卡4090的机器,后端设的是NCCL,但即使是跑最简单的ResNet-50也卡。日志里也没报错,就是一直不动。有没有大佬遇到过类似情况?是MCP和PyTorch的DDP兼容性有问题,还是我哪里配置错了?求指点,卡了好几天了。
MCP框架在PyTorch里做分布式训练时总是卡住,有人遇到过吗?
全部回复
共 168 条我之前也碰到过类似情况,卡在Waiting for other nodes八成是端口或者网卡通信没配对,你可以先试试设个NCCL_SOCKET_IFNAME指定具体网卡,别让它自己瞎选。还有就是MCP如果自己包了一层init_process_group,可能跟DDP的初始化冲突了,检查下是不是重复初始化。最简单的验证方法就是先用纯DDP跑一遍ResNet-50,如果纯DDP没问题那基本就是MCP那边的锅。
检查下MCP的通信超时设置,DDP默认半小时,MCP可能更短,我之前卡同步就是改这个好的。
卡在“Waiting for other nodes”而且没报错,大概率是NCCL在建立通信环的时候超时了,但默认的watchdog又没触发打印。你可以先试试设NCCL_DEBUG=INFO,看看它到底卡在哪个rank的bootstrap上,很多时候是某张卡的P2P或者NVLink没起来。八卡4090的话,检查一下是不是所有卡都在同一个PCIe switch下,跨NUMA的拓扑有时候会让NCCL选错路径。另外MCP这层封装如果自己维护了进程组,可能和PyTorch DDP的init_process_group有冲突,比如重复初始化或者group没对齐。我之前遇到过类似的情况,最后发现是MCP的launcher把MASTER_PORT给占用了,换一个端口就好了。你也可以先用torchrun直接跑一个最小DDP例子,排除掉MCP看看是不是框架本身的问题。如果torchrun正常,那基本就是MCP和DDP的握手逻辑有坑了。
我之前也踩过类似的坑,MCP的进程组初始化和PyTorch DDP的默认超时时间不太对付,卡在“Waiting for other nodes”往往是某个rank还没进来。建议先把NCCL_DEBUG=INFO打开看看到底停在哪一步,顺便确认下有没有哪个卡的显存被其他进程占着。另外MCP自己那层通信封装有时候会和DDP的allreduce抢资源,试试只跑单机8卡、把MCP的分布式开关先关掉对比一下,能快速定位是框架问题还是配置问题。
建议先试下设NCCL_IB_DISABLE=1,4090机器上经常是IB网卡在捣乱,我上次也卡在同步那步。
你描述的这个卡在“Waiting for other nodes”的情况我也踩过,特别是在MCP这种套了一层封装的框架里。先别急着怀疑DDP兼容性,八成是NCCL初始化时网络接口选错了,8卡4090机器如果有多张网卡(比如docker虚拟网卡和物理网卡混在一起),NCCL经常挑到那个不通的。你可以在启动脚本里加上NCCL_SOCKET_IFNAME=eth0或者你实际物理网卡名,再设一下NCCL_DEBUG=INFO看看日志到底卡在哪一步。另外MCP如果内部自己做了梯度压缩或者异步同步,跟DDP的allreduce叠在一起很容易死锁,建议先把MCP的分布式特性全关掉,只用它最基础的模块跑一遍纯DDP的ResNet-50,确认底层没问题再往上加。还有个小坑是4090不支持P2P直接访问,如果你没设NCCL_P2P_DISABLE=1,有些拓扑下会卡在初始化握手。我之前也是卡了好几天,最后发现就是网卡名写错了一个字母,你可以先用torch.distributed的默认启动器跑个mnist测试脚本,排除掉MCP的干扰。
我之前也遇到过类似问题,后来换了方案。
这个思路不错,收藏了。