如何让两个Slurm作业同时获取资源启动运行PyTorch DPP任务
Slurm跨节点双作业同步启动配置方案
核心逻辑是依托Slurm原生的资源预留机制实现同步,不需要提前探测空闲资源,不依赖多节点作业申请权限,也不用仅支持完成态校验的常规依赖参数,完全规避你提到的三类局限。
操作步骤
- 提交两个作业时默认设置为用户持有(hold)状态,让Slurm按正常队列优先级为两个作业调度资源,但调度到资源后不会直接启动,避免单个作业先跑起来空等、资源被抢占的问题。
- 待第一个作业完成节点分配后,动态给第二个作业配置节点排除规则,保证两个作业落在不同节点,各占4块GPU。
- 持续轮询两个作业的状态,当两个作业都进入
CONFIGURING状态时,说明Slurm已经为两个作业锁死了对应节点的GPU资源,此时其他排队作业无论优先级高低都无法抢占这部分资源,再同时释放两个作业的持有状态,让两个作业同步启动。
可直接复用的提交流程脚本
#!/bin/bash # 替换为你使用的Slurm分区名 PARTITION_NAME="your_partition" # 替换为你自己的两个作业脚本路径 JOB_A_SCRIPT="./ddp_node0.sh" JOB_B_SCRIPT="./ddp_node1.sh" # 提交两个持有状态的单节点4GPU作业,--parsable参数直接返回纯数字作业ID JOB_A_ID=$(sbatch --parsable --hold -N1 --gres=gpu:4 -p $PARTITION_NAME $JOB_A_SCRIPT) JOB_B_ID=$(sbatch --parsable --hold -N1 --gres=gpu:4 -p $PARTITION_NAME $JOB_B_SCRIPT) echo "已提交持有状态作业,A节点作业ID: $JOB_A_ID,B节点作业ID: $JOB_B_ID" # 等待作业A完成节点分配 while true; do NODE_A=$(scontrol show job $JOB_A_ID | grep -oP 'NodeList=\K\S+') if [ -n "$NODE_A" ] && [ "$NODE_A" != "(null)" ]; then break fi sleep 10 done echo "作业A已分配节点: $NODE_A,配置作业B排除该节点保证跨节点部署" scontrol update job $JOB_B_ID ExcludeNodes=$NODE_A # 等待两个作业都完成资源预留进入CONFIGURING状态 while true; do STATE_A=$(scontrol show job $JOB_A_ID | grep -oP 'JobState=\K\S+') STATE_B=$(scontrol show job $JOB_B_ID | grep -oP 'JobState=\K\S+') if [ "$STATE_A" = "CONFIGURING" ] && [ "$STATE_B" = "CONFIGURING" ]; then break fi sleep 5 done echo "两个作业均已锁定所需资源,同步放行启动" scontrol release $JOB_A_ID $JOB_B_ID
配套注意事项
- PyTorch DDP初始化时,将
torch.distributed.init_process_group的timeout参数设置为120秒以上,覆盖两个作业启动的数秒时差,避免个别进程提前超时退出。 - DDP所需的组网环境变量可以通过共享存储传递:作业A启动后将自身节点的IP写入两个节点都能访问的共享目录文件,固定通信端口(如29500),设置
WORLD_SIZE=8;作业B启动时从共享文件读取MASTER_ADDR地址即可完成组网。 - 该方案完全适配你提到的环境限制:两个作业均为单节点4GPU申请,不需要分区支持2节点作业提交权限;资源分配全程由Slurm按队列规则调度,不存在手动探测空闲资源被高优作业抢占的可靠性问题;没有使用仅支持完成态校验的
--dependency参数,真正实现双作业拿到资源后再同步启动。
内容的提问来源于stack exchange,提问作者GIONII
相关产品推荐
相关产品推荐

