SLURM多节点单GPU单任务调度报错原因咨询
问题描述
我尝试在两个各配备4块GPU的节点上调度8个任务,每个任务分配一块GPU。原本用于单节点4GPU环境的SLURM脚本可正常运行,但修改为2节点配置后执行脚本,反复出现警告:srun: Warning: can't run 1 processes on 2 nodes, setting nnodes to 1,希望了解配置错误之处。
原单节点SLURM脚本:
#!/bin/bash # #SBATCH --time 24:00:00 #SBATCH --partition=X #SBATCH --mem=96G # RAM per node #SBATCH --cpus-per-task=12 # number of CPUs per process #SBATCH --nodes=1 #SBATCH --gres=gpu:4 srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=4 Job.worker_id=1 & srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=4 Job.worker_id=2 & srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=4 Job.worker_id=3 & srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=4 Job.worker_id=4 & echo "Start!" wait echo "Done!"
修改后的多节点脚本:
#!/bin/bash # #SBATCH --mail-type=ALL #SBATCH --time 24:00:00 #SBATCH --partition=X #SBATCH --mem=96G # RAM per node #SBATCH --cpus-per-task=12 # number of CPUs per process #SBATCH --nodes=2 #SBATCH --gres=gpu:4 srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=8 Job.worker_id=1 & srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=8 Job.worker_id=2 & srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=8 Job.worker_id=3 & srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=8 Job.worker_id=4 & srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=8 Job.worker_id=5 & srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=8 Job.worker_id=6 & srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=8 Job.worker_id=7 & srun --gres=gpu:1 --ntasks=1 --exclusive p.py Job.num_workers=8 Job.worker_id=8 & echo "Start!" wait echo "Done!"
问题原因
- 每个
srun指定--ntasks=1后,默认会尝试在所有申请到的2个节点上分配任务,但单个任务无法跨节点运行,SLURM因此自动将节点数设为1,导致所有任务挤在同一个节点。 --exclusive参数会让单个任务独占整个节点,完全违背“单任务占1块GPU”的需求,同时浪费另一节点的资源。
修正方案
以下两种方案任选其一即可:
方案一:单srun批量启动任务
通过SBATCH参数声明总任务数和单任务资源,让SLURM自动分配到两个节点:
#!/bin/bash # #SBATCH --mail-type=ALL #SBATCH --time 24:00:00 #SBATCH --partition=X #SBATCH --nodes=2 #SBATCH --ntasks=8 # 总任务数匹配GPU总数 #SBATCH --gres=gpu:1 # 每个任务分配1块GPU #SBATCH --mem=12G # 单任务内存(按节点总内存/任务数计算,按需调整) #SBATCH --cpus-per-task=12 # 每个任务的CPU数 # 用%s自动传递1-8的任务ID srun --nodes=2 --ntasks=8 p.py Job.num_workers=8 Job.worker_id=%s echo "Start!" wait echo "Done!"
方案二:保留多srun写法,明确单任务节点限制
给每个srun添加--nodes=1,限制单任务仅在一个节点运行,同时去掉--exclusive:
#!/bin/bash # #SBATCH --mail-type=ALL #SBATCH --time 24:00:00 #SBATCH --partition=X #SBATCH --nodes=2 #SBATCH --gres=gpu:4 # 每个节点分配4块GPU,总8块 #SBATCH --mem=96G # 单节点总内存 #SBATCH --cpus-per-task=12 # 每个任务的CPU数 srun --nodes=1 --gres=gpu:1 --ntasks=1 p.py Job.num_workers=8 Job.worker_id=1 & srun --nodes=1 --gres=gpu:1 --ntasks=1 p.py Job.num_workers=8 Job.worker_id=2 & srun --nodes=1 --gres=gpu:1 --ntasks=1 p.py Job.num_workers=8 Job.worker_id=3 & srun --nodes=1 --gres=gpu:1 --ntasks=1 p.py Job.num_workers=8 Job.worker_id=4 & srun --nodes=1 --gres=gpu:1 --ntasks=1 p.py Job.num_workers=8 Job.worker_id=5 & srun --nodes=1 --gres=gpu:1 --ntasks=1 p.py Job.num_workers=8 Job.worker_id=6 & srun --nodes=1 --gres=gpu:1 --ntasks=1 p.py Job.num_workers=8 Job.worker_id=7 & srun --nodes=1 --gres=gpu:1 --ntasks=1 p.py Job.num_workers=8 Job.worker_id=8 & echo "Start!" wait echo "Done!"
关键注意点
- SBATCH中的
--gres=gpu:N是每个节点的GPU数量,nodes=2+gres=gpu:4的配置是正确的,会申请到8块GPU。 - 单个
srun任务默认会使用所有申请节点,必须用--nodes=1限制单任务在单个节点运行,否则触发警告。 --exclusive会独占节点,完全不符合单任务单GPU的需求,必须移除。
内容的提问来源于stack exchange,提问作者Gianluca De Stefano
相关产品推荐
相关产品推荐

