能否在单GPU上运行多个Slurm作业步?求可行方案
在Slurm单GPU作业中运行多个作业步的问题
我尝试用Slurm在单个GPU上运行多个作业步,确认内存足够,但测试里只有第一个作业步能跑。查过不同作业共享GPU的方案,但没找到同一作业内多作业步的相关内容。
带GPU请求的测试代码
#!/bin/bash #SBATCH --qos bham #SBATCH -t 0-4:0:0 #SBATCH --ntasks=3 #SBATCH --nodes=1 #SBATCH --gres gpu:1 #SBATCH --cpus-per-task=1 #SBATCH --mem-per-cpu=10G module purge module load baskerville srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive bash -c "nvidia-smi ; sleep 60" & srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive bash -c "nvidia-smi ; sleep 60" & srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive bash -c "nvidia-smi ; sleep 60" & wait
对应sacct输出
sacct --jobs 517334 --format jobid,ntasks,elapsed,state,alloctres%35,NCPUS,maxrss JobID NTasks Elapsed State AllocTRES NCPUS MaxRSS ------------ -------- ---------- ---------- ----------------------------------- ---------- ---------- 517334 00:00:42 RUNNING billing=4,cpu=4,gres/gpu=1,mem=40G+ 4 517334.batch 1 00:00:42 RUNNING cpu=4,gres/gpu=1,mem=40G,node=1 4 517334.exte+ 1 00:00:42 RUNNING billing=4,cpu=4,gres/gpu=1,mem=40G+ 4 517334.0 1 00:00:37 RUNNING cpu=1,gres/gpu=1,mem=10G,node=1 1
无GPU请求的预期效果(参考)
测试代码
#!/bin/bash #SBATCH --qos bham #SBATCH -t 0-4:0:0 #SBATCH --ntasks=5 #SBATCH --nodes=1 #SBATCH --cpus-per-task=1 #SBATCH --mem-per-cpu=10G module purge module load baskerville srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive bash -c "echo hello; sleep 60" & srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive bash -c "echo hello; sleep 60" & srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive bash -c "echo hello; sleep 60" & wait
对应sacct输出
sacct --jobs 517343 --format jobid,ntasks,elapsed,state,alloctres%35,NCPUS,maxrss JobID NTasks Elapsed State AllocTRES NCPUS MaxRSS ------------ -------- ---------- ---------- ----------------------------------- ---------- ---------- 517343 00:00:24 RUNNING billing=6,cpu=6,mem=60G,node=1 6 517343.batch 1 00:00:24 RUNNING cpu=6,mem=60G,node=1 6 517343.exte+ 1 00:00:24 RUNNING billing=6,cpu=6,mem=60G,node=1 6 517343.0 1 00:00:19 RUNNING cpu=1,mem=10G,node=1 1 517343.1 1 00:00:19 RUNNING cpu=1,mem=10G,node=1 1 517343.2 1 00:00:19 RUNNING cpu=1,mem=10G,node=1 1
核心疑问
是否可以在单GPU上运行多个作业步?若不可行,推荐的替代方案是什么?
解答
可行性结论
可以在单GPU上运行多个Slurm作业步,你遇到的问题是因为Slurm默认将作业的GPU资源绑定到第一个srun任务,后续srun无法获取GPU权限。
直接解决方法
1. 全局设置GPU可见性
在脚本开头导出环境变量,让所有子任务共享同一GPU:
#!/bin/bash #SBATCH --qos bham #SBATCH -t 0-4:0:0 #SBATCH --ntasks=3 #SBATCH --nodes=1 #SBATCH --gres gpu:1 #SBATCH --cpus-per-task=1 #SBATCH --mem-per-cpu=10G module purge module load baskerville # 绑定作业分配的GPU到所有子任务 export CUDA_VISIBLE_DEVICES=$SLURM_JOB_GPUS srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive bash -c "nvidia-smi ; sleep 60" & srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive bash -c "nvidia-smi ; sleep 60" & srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive bash -c "nvidia-smi ; sleep 60" & wait
2. 给每个srun指定共享GPU
在每个srun中添加--gres gpu:0,明确告知Slurm该子任务共享作业级GPU:
#!/bin/bash #SBATCH --qos bham #SBATCH -t 0-4:0:0 #SBATCH --ntasks=3 #SBATCH --nodes=1 #SBATCH --gres gpu:1 #SBATCH --cpus-per-task=1 #SBATCH --mem-per-cpu=10G module purge module load baskerville srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive --gres gpu:0 bash -c "nvidia-smi ; sleep 60" & srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive --gres gpu:0 bash -c "nvidia-smi ; sleep 60" & srun --ntasks=1 --cpus-per-task=$SLURM_CPUS_PER_TASK --exclusive --gres gpu:0 bash -c "nvidia-smi ; sleep 60" & wait
3. 放弃srun,直接后台启动进程
如果不需要Slurm单独跟踪每个作业步,直接用普通后台进程启动:
#!/bin/bash #SBATCH --qos bham #SBATCH -t 0-4:0:0 #SBATCH --nodes=1 #SBATCH --gres gpu:1 #SBATCH --cpus-per-task=3 #SBATCH --mem-per-cpu=10G module purge module load baskerville bash -c "nvidia-smi ; sleep 60" & bash -c "nvidia-smi ; sleep 60" & bash -c "nvidia-smi ; sleep 60" & wait
替代方案
如果上述方法不适用,可选择:
- 拆分独立作业:将每个任务提交为单独的Slurm作业,集群若支持GPU共享,Slurm会自动调度多个作业共享同一GPU。
- 容器化部署:用Singularity或Docker封装任务,在单个Slurm作业内启动多个容器共享GPU资源。
内容的提问来源于stack exchange,提问作者JBartlett_6
相关产品推荐
相关产品推荐

