使用Slurm调度含Multiprocessing的Python脚本并行运行问题
问题分析与解决方案
你的核心需求是在16核节点上,让每个依赖multiprocessing的Python脚本实例独占4核(匹配内部4个子进程),同时运行4个实例,剩余2个实例等前序任务释放资源后自动启动。当前脚本的问题在于:
- 用
-n 1仅申请1核,但脚本内部开4个进程,会抢占其他任务的核资源,导致6个实例同时启动引发资源竞争; - 移除
--exclusive后,Slurm无法保证任务的核独占性,多个任务挤在有限核上,出现串行运行的假象。
修正后的Slurm批处理脚本
直接调整每个srun的核分配参数,让每个脚本实例绑定4核并独占使用:
#!/bin/bash #SBATCH -N 1 #SBATCH -n 16 #SBATCH --time=10:00:00 module purge > /dev/null 2>&1 eval "$(conda shell.bash hook)" conda activate my_environment # 限制OpenMP线程数为1,避免与multiprocessing进程竞争资源 export OMP_NUM_THREADS=1 # 每个srun申请4核并独占,刚好匹配脚本内部的4个并行进程 srun --exclusive -n 4 python script.py 0.95 1 1 0 1 0 > nohup1.out 2>&1 & srun --exclusive -n 4 python script.py 0.955 1 1 0 1 0 > nohup2.out 2>&1 & srun --exclusive -n 4 python script.py 0.96 1 1 0 1 0 > nohup3.out 2>&1 & srun --exclusive -n 4 python script.py 0.965 1 1 0 1 0 > nohup4.out 2>&1 & srun --exclusive -n 4 python script.py 0.97 1 1 0 1 0 > nohup5.out 2>&1 & srun --exclusive -n 4 python script.py 0.975 1 1 0 1 0 > nohup6.out 2>&1 & wait
优化说明
- 核分配匹配:每个
srun用-n 4申请4核,加上--exclusive确保这4核仅给当前脚本实例使用,完美匹配内部4个multiprocessing子进程,避免跨任务资源抢占。 - 自动分批并行:16核节点刚好容纳4个4核任务,剩余2个任务会自动进入Slurm内部队列,当任意前序任务完成释放4核后,后续任务立即启动。
- 避免线程冲突:设置
OMP_NUM_THREADS=1,防止Python依赖的OpenMP库额外创建线程,与multiprocessing进程争夺CPU资源。
可选优雅方案(用GNU Parallel)
如果参数较多,可借助GNU Parallel简化脚本,自动管理并发数:
#!/bin/bash #SBATCH -N 1 #SBATCH -n 16 #SBATCH --time=10:00:00 module purge > /dev/null 2>&1 eval "$(conda shell.bash hook)" conda activate my_environment export OMP_NUM_THREADS=1 # 定义所有参数组合 params=( "0.95 1 1 0 1 0" "0.955 1 1 0 1 0" "0.96 1 1 0 1 0" "0.965 1 1 0 1 0" "0.97 1 1 0 1 0" "0.975 1 1 0 1 0" ) # 最多同时运行4个任务(16核/4核每任务),自动分配核资源 parallel --jobs 4 "srun --exclusive -n 4 python script.py {} > nohup{#}.out 2>&1" ::: "${params[@]}"
内容的提问来源于stack exchange,提问作者dsqubitdo
相关产品推荐
相关产品推荐

