Slurm HPC 作业调度

FreeGuideOnline 最新 2026-07-13

bash sinfo

输出简例:

PARTITION AVAIL TIMELIMIT NODES STATE NODELIST debug* up infinite 4 idle node[01-04] gpu up 2:00:00 2 idle node[05-06]

`STATE` 为 `idle` 表示节点空闲可用,`alloc` 表示已被占用,`drain` 表示维护中。带有 `*` 的是默认分区。

### 查看节点详细信息
```bash
scontrol show node node01

编写你的第一个作业脚本

Slurm 通过 作业脚本(Job Script) 来描述资源和运行命令。脚本通常是 Bash 脚本,顶部以 #SBATCH 开头的行是 Slurm 指令。

创建一个文件 myjob.sh

#!/bin/bash
#SBATCH --job-name=hello_slurm     # 作业名称
#SBATCH --output=hello_%j.out      # 标准输出文件,%j 会替换为作业 ID
#SBATCH --error=hello_%j.err       # 错误输出文件
#SBATCH --time=00:05:00            # 最大运行时间 (D-HH:MM:SS)
#SBATCH --partition=debug          # 分区名
#SBATCH --nodes=1                  # 节点数
#SBATCH --ntasks=1                 # 任务数(进程数)
#SBATCH --cpus-per-task=1          # 每个任务使用的 CPU 核数
#SBATCH --mem=1G                   # 每个节点分配的内存

echo "Hello from $(hostname)"
sleep 30
echo "Job finished at $(date)"

提交作业

sbatch myjob.sh

提交后返回作业 ID,例如 Submitted batch job 1234

监控作业状态

squeue -u $USER          # 查看自己的作业
squeue --start           # 显示预计开始时间
squeue -j 1234           # 查看特定作业详情

输出列说明:

  • ST:状态。R 运行中,PD 排队等待,CG 正在完成。
  • TIME:已运行时间。
  • NODELIST(REASON):被分配到的节点,或排队原因(如 PriorityResources)。

查看作业详细信息

scontrol show job 1234

常用资源申请配置详解

控制并行任务

  • --ntasks=16:启动 16 个进程(MPI 应用常用)。
  • --cpus-per-task=4:每个进程使用 4 个 OpenMP 线程。设置 OMP_NUM_THREADS=4 与之配合。
  • --nodes=2 --ntasks-per-node=8:在两个节点上各起 8 个任务,总任务数 16。

内存与时间限制

#SBATCH --mem=16G           # 每个节点的总内存
#SBATCH --mem-per-cpu=2G    # 每个 CPU 核的内存(另一种方式)
#SBATCH --time=2-12:00:00   # 两天十二小时

务必预留合理的时间和内存,超时或内存溢出会直接 kill 作业。

输出文件控制

#SBATCH --output=result_%A_%a.out  # %A 主作业 ID,%a 数组作业索引
#SBATCH --error=result_%j.err
#SBATCH --open-mode=append         # 追加而非覆盖

调试分区与交互式作业

salloc --partition=debug --nodes=1 --ntasks=4 --time=01:00:00

salloc 会为你分配资源并开启一个新的 shell,可以在其中直接运行命令或启动交互式程序,完成后 exit 释放资源。

数组作业(Array Job)

适合参数扫描或相同的程序跑不同输入文件。

#SBATCH --array=1-100         # 数组索引从 1 到 100
#SBATCH --output=job_%A_%a.out

在脚本中通过环境变量 $SLURM_ARRAY_TASK_ID 获取当前索引,例如:

INPUTFILE="input_${SLURM_ARRAY_TASK_ID}.dat"
./myprogram $INPUTFILE

可以限制同时运行的任务数:#SBATCH --array=1-100%20(最多 20 个同时运行)。

作业依赖与工作流

# 提交第一个作业
JOBID1=$(sbatch --parsable step1.sh)

# 作业2依赖作业1成功完成
sbatch --dependency=afterok:$JOBID1 step2.sh
# 作业3在作业2开始后运行
sbatch --dependency=after:$JOBID2 step3.sh

其他依赖类型:afternotokafteranysingleton

使用 GPU 资源

#SBATCH --partition=gpu
#SBATCH --gres=gpu:2           # 请求 2 块 GPU(通用型)
#SBATCH --gres=gpu:tesla:1     # 请求特定型号

在作业脚本中,CUDA 程序会自动看到 CUDA_VISIBLE_DEVICES 被限制为分配的 GPU。

环境变量速查

Slurm 在作业运行时设置大量环境变量,常用:

  • $SLURM_JOB_ID:作业 ID
  • $SLURM_SUBMIT_DIR:提交作业时所在目录
  • $SLURM_NTASKS:总任务数
  • $SLURM_NPROCS:总 CPU 核数
  • $SLURM_CPUS_PER_TASK:每个任务的 CPU 核数
  • $SLURM_GPUS:分配的 GPU 数量

利用它们可以编写更灵活的脚本。

作业管理技巧

取消作业

scancel 1234             # 取消单个作业
scancel -u $USER         # 取消自己所有作业
scancel --state=PENDING -u $USER  # 只取消排队中的作业

挂起与恢复(谨慎使用)

scontrol hold 1234       # 挂起
scontrol release 1234    # 释放

修改已提交作业

scontrol update JobID=1234 TimeLimit=02:00:00  # 仅部分参数可修改(受集群策略限制)

效率与最佳实践

  1. 预先测试:先用交互式作业或小规模数据确认程序无误。
  2. 合理申请资源:不要过度申请 CPU 或内存,否则排队时间更长。可使用 sacct -j 1234 --format=CPUTime,MaxRSS 查看历史使用量。
  3. 清理环境:作业脚本开头建议 set -e 让脚本遇错即停,避免浪费资源。
  4. 模块系统配合:大多数集群用 module load 管理软件环境,务必在脚本中加载所需模块。
  5. 善用 --mail-type 通知#SBATCH --mail-type=END,FAIL --mail-user=your@email.com 作业结束时发邮件提醒。

常见错误与解决

错误信息 原因 解决方案
sbatch: error: Batch job submission failed: Invalid account or account/partition combination specified 未指定账户或分区选择错误 加上 #SBATCH --account=xxx 或检查分区名称
slurmstepd: error: Job 1234 exceeded memory limit 内存不足被 kill 增加 --mem 值,或分析程序内存使用
DUE TO TIME LIMIT 作业超时 提高 --time 或优化程序
Nodes required for job are DOWN, DRAINED or reserved 所需节点状态异常 换分区或等节点恢复
QOSMaxCpuPerUserLimit 超出用户 CPU 核使用限制 减少同时提交的作业总数或用 --array 限制并发

进阶命令速查

sacct -j 1234 --format=JobID,Start,End,Elapsed,State  # 查看已完成作业历史
sinfo -O "Partition:12,NodeList:20,Available:8,Time:10"  # 自定义格式
sstat -j 1234.batch          # 正在运行作业的瞬时资源统计
sprio -j 1234                 # 查看作业优先级