跳转至

作业管理

sbatch (提交作业)

sbatch 命令用于向 Slurm 作业调度系统提交一个作业脚本,以便在计算节点上执行。用户需将计算任务和资源申请需求编写在脚本文件中,然后通过 sbatch 提交。

为什么需要通过 sbatch 命令提交作业?

高性能计算集群是由众多服务器组成的分布式系统。当您登录集群时,您所在的是登录节点。登录节点资源有限,仅用于文件管理、代码编辑和作业提交等轻量级任务。严禁在登录节点上直接运行计算程序。您必须通过 sbatch 等命令向作业调度系统申请计算资源(如 CPU 核心、内存、GPU 等),由系统将您的任务分配到合适的计算节点上运行。

使用示例

  1. 单节点 CPU 作业

    申请一个计算节点中的多个 CPU 核心来加速执行任务。

    示例提交作业脚本:job.sh

    #!/bin/bash
    #SBATCH -J myMultiCoreJob      # 作业名称
    #SBATCH -o job.%j.out          # 标准输出文件 (%j 会替换为作业号)
    #SBATCH -p L40                 # 提交到 L40 分区
    #SBATCH -N 1                   # 申请 1 个节点
    #SBATCH -n 1                   # 启动 1 个任务 (Task)
    #SBATCH -c 4                   # 每个任务分配 4 个 CPU 核心
    #SBATCH -t 1-00:00:00          # 最长运行 1 天
    
    # 打印当前节点的主机名
    hostname
    echo "Job finished!"
    

    脚本参数解析:

    • -J myFirstJob: 定义作业在调度系统中的名称为 myFirstJob
    • -o job.%j.out: 脚本的标准输出将被重定向到 job.%j.out 文件中,%j 会被系统自动替换为作业 ID。
    • -p L40: 指定作业提交到名为 L40 的分区。
    • -N 1--nodes=1: 申请 1 个计算节点。对于非并行(如 MPI)作业,此值通常为 1。
    • -n 1--ntasks=1: 启动 1 个任务(通常对应 1 个主程序进程)。
    • -c 4--cpus-per-task=4: 为每一个任务分配 4 个 CPU 核心。
    • -t 1-00:00:00:设置作业最长运行时间为 1 天。

    通过以下命令提交作业:

    sbatch job.sh
    
  2. 如何查看可用的分区和 QOS?

    • 查看可用分区 (Partition):

      sinfo -o "%P %G %m %c"
      
  3. 单节点 GPU 作业

    如果您的程序需要使用 GPU,必须在脚本中明确申请 GPU 资源。

    示例提交作业脚本:gpu_job.sh

    #!/bin/bash
    #SBATCH -J myGPUJob
    #SBATCH -o gpu_job.%j.out
    #SBATCH -p L40               # 选择分区:A100 / L40 / RTX4090 / A800
    #SBATCH -N 1                 # 当前系统仅支持单节点作业
    #SBATCH -n 1                 # 1 个任务
    #SBATCH -c 4                 # 为该任务分配 4 个 CPU 核心
    #SBATCH --gres=gpu:1         # 申请 1 张 GPU
    #SBATCH -t 00:05:00          # 最长运行 5 分钟
    
    hostname
    nvidia-smi
    echo "GPU Job finished!"
    

    关键参数说明:

    • --gres=gpu:1: gres (Generic RESource) 用于申请通用资源。gpu:1 表示申请 1 块 GPU 卡。如果需要 2 块,则使用 --gres=gpu:2

常用参数

参数 (Parameter) 简写 说明
--job-name=<jobname> -J 指定作业的名称。
--output=<filename> -o 指定标准输出文件。%j 代表作业 ID, %N 代表节点名。
--error=<filename> -e 指定标准错误文件。
--partition=<name> -p 提交到指定分区。
--qos=<name> -q 指定服务质量 (QOS)。
--nodes=<count> -N 申请的节点数量。
--ntasks=<count> -n 申请的总任务数(核心数)。
--ntasks-per-node=<count> 指定每个节点上运行的任务数。
--cpus-per-task=<count> -c 为每个任务分配的 CPU 核心数(用于多线程程序)。
--gres=<list> 申请通用资源,如 GPU (--gres=gpu:2)。
--time=<time> -t 作业运行的最大时间限制,格式为 D-HH:MM:SS
--chdir=<directory> -D 指定作业的工作目录。
--mail-user=<email> 发送通知邮件的地址。
--mail-type=<type> 邮件通知类型,如 BEGIN, END, FAIL, ALL
--account=<account> -A 指定计费账户(通常无需设置)。
--nodelist=<nodes> -w 指定在哪些节点上运行。
--exclude=<nodes> -x 指定排除哪些节点。

salloc 和 srun (创建交互式作业)

salloc 命令用于实时申请计算资源,并为您创建一个交互式的会话。这允许您直接登录到计算节点上进行调试、软件测试或执行需要实时交互的命令。

sallocsbatch 的核心区别

  • sbatch非交互式。您将所有指令写入一个脚本,提交后由系统在后台自动执行,您只需等待结果。适用于成熟的、无需干预的计算任务。

  • salloc交互式。您申请资源后,会得到一个在计算节点上的命令行 Shell。您可以像在本地终端一样逐条输入命令并立即看到反馈。适用于程序调试、环境配置和短时间测试。

使用示例

在大多数 Slurm 配置中,交互式作业建议遵循“先申请,再进入”的标准流程:

  1. 申请单节点多核心

    假设您需要 6 个 CPU 核心,最长需要 2 小时。

    # 申请资源
    salloc -p L40 -N 1 -n 6 -t 02:00:00 bash
    
    # 第二步:进入计算节点
    # 此时无需重复参数,srun 会自动继承 salloc 申请到的资源
    srun --pty bash
    
    # 现在您可以执行您的调试任务了
    ./my_program
    
    # 调试完成后,退出 shell 即可释放资源
    exit
    
  2. 申请 GPU 资源

    如果您需要调试一个 GPU 程序,可以申请一块 GPU 卡和相应的 CPU 核心。

    # 申请 1 个节点、4 个核心和 1 块 L40 显卡
    salloc -p L40 -N 1 -n 4 --gres=gpu:1 -t 2:00:00
    
    # 进入节点并检查显卡状态
    srun --pty bash
    nvidia-smi
    
    # 运行任务
    python train.py
    
    # 退出并释放资源
    exit
    

注意事项

  • “两步走”逻辑:执行 salloc 成功后,其实还停留在登录节点,只是获得了一个“特权 Shell”。必须配合 srun --pty bash 才能真正跳转到计算节点的物理机器上。
  • 环境变量残留:如果 salloc 任务意外中断或超时,环境变量 $SLURM_JOB_ID 可能会残留在当前窗口,导致下次申请报错。若遇到 Job has expired 错误,请运行 unset SLURM_JOB_ID 或开启新终端。
  • 限时自动释放:交互式作业受 -t (Time Limit) 严格限制。一旦到达预设时间,系统会强制终止节点内所有进程并把用户踢回登录节点。请确保在时间耗尽前保存调试进度。
  • 资源占用风险:只要还在交互式 Shell 中,申请的资源就会被一直占用并计费。任务执行完毕请务必两次 exit 或执行 scancel

进阶技巧

可以直接使用 srun 代替 salloc

srun -p L40 -N 1 -n 6 --gres=gpu:1 -t 01:00:00 --pty bash

该命令会直接排队并在资源就绪时将您“弹”入计算节点,退出时自动释放所有资源,是目前最推荐的交互式调试方案。

sinfo (查看集群状态)

sinfo 命令用于实时查询集群中各个分区(Partition)和节点(Node)的状态信息。

使用示例

  1. 查看集群整体状态

    直接运行 sinfo 可以快速了解整个集群的概览。

    sinfo
    

    输出结果中 STATE 列显示了节点的状态,常见的状态有:

    • idle: 节点完全空闲,所有资源可用。

    • mix: 节点部分被占用,仍有空闲核心可供使用。

    • alloc / allocated: 节点资源已被完全占用。

    • down: 节点故障或已关闭,不可用。

    • drain: 节点正在排空,不再接受新作业,等待现有作业完成后下线维护。

  2. 查看指定分区的状态

    如果您只关心特定的几个分区,可以使用 -p 参数。

    # 查看单个分区
    sinfo -p L40
    
    # 查看多个分区,用逗号隔开
    sinfo -p L40,A100
    
  3. 查看分区详细资源配置

    列出每个分区的资源情况,如 GPU、CPU 核心数和内存。

    sinfo -o "%P %G %c %m"
    
    • %P: 分区名称
    • %G: GPU 类型及数量
    • %c: 每个节点的 CPU 核心数
    • %m: 每个节点的内存大小 (MB)

常用参数

参数 (Parameter) 简写 说明
--help 显示 sinfo 命令的帮助信息。
--Node -N 以节点为单位,每行列出一个节点,信息更详细。
--partition=<name> -p 显示指定分区的信息,多个分区用逗号分隔。
--nodelist=<list> -n 显示指定节点的信息,多个节点用逗号分隔。
--responding -r 只显示当前响应正常的节点。
--dead -d 只显示当前没有响应的节点。
--list-reasons -R 显示节点离线或不正常工作的原因。
--iterate=<secs> -i 每隔指定秒数自动刷新并显示信息,按 Ctrl+C 退出。

自定义格式化输出

sinfo 提供了强大的格式化输出功能,通过 -o <format_string>--format=<format_string> 参数,您可以精确控制需要显示的内容。

格式化字符串由 % 加上特定字符组成,例如 %.15P 表示显示分区名,左对齐,宽度为 15 个字符。

常用格式符列表:

格式符 说明
%P 分区名 (默认分区会带 * 后缀)。
%N 节点列表。
%t 节点状态 (紧凑形式,如 mix, idle)。
%T 节点状态 (完整形式,如 mixed, idle)。
%c 每个节点的 CPU 核心数。
%C 核心数统计 (allocated/idle/other/total)。
%D 分区中的节点总数。
%m 每个节点的内存大小 (MB)。
%G 节点的通用资源信息 (常用于显示 GPU 类型和数量)。
%l 分区允许的最大作业运行时长。
%a 分区是否可用 (up/down)。
%E 节点不可用的原因。
%O 节点的 CPU 负载。

格式化输出示例:

以下命令将以自定义的格式显示分区名、可用状态、时间限制、节点数、节点状态和节点列表。

sinfo -o "%.15P %.5a %.10l %.6D %.6t %N"

这将生成一个非常清晰、对齐的表格,便于快速掌握集群资源状况。

squeue (查看作业状态)

squeue 命令用于监控作业队列。在本集群中,用户默认只能查看到自己提交的作业。

使用示例

  1. 查看自己的作业列表

    直接运行 squeue。由于限制,其输出通常等同于 squeue -u $USER

    squeue
    

    默认输出包含以下列:

    • JOBID: 唯一的作业 ID。
    • PARTITION: 作业所在的分区。
    • NAME: 作业的名称。
    • USER: 提交该作业的用户名。
    • ST: 作业状态(R 表示正在运行,PD 表示正在排队)。
    • TIME: 作业已经运行的时间。
    • NODES: 作业占用的节点数。
    • NODELIST(REASON):
      • 对于 正在运行 的作业,显示其所在的节点列表。
      • 对于 正在排队 的作业,显示其等待的原因(如 Resources, Priority 等)。
  2. 只查看自己的作业

    虽然默认已过滤,但使用 -u 参数是标准的筛选方式。

    # 使用环境变量 $USER 自动填充
    squeue -u $USER
    

常用参数

参数 (Parameter) 简写 说明
--user=<user_list> -u 显示指定用户的作业,多个用户用逗号分隔。
--jobs=<job_id_list> -j 显示指定作业 ID 的信息,多个 ID 用逗号分隔。
--states=<state_list> -t 显示处于特定状态的作业,如 PENDING, RUNNING
--partition=<name> -p 显示指定分区的作业。
--nodelist=<list> -w 显示在指定节点上运行的作业。
--account=<list> -A 显示指定计费账户下的作业。
--iterate=<secs> -i 每隔指定秒数自动刷新并显示信息,按 Ctrl+C 退出。
--help 显示 squeue 命令的帮助信息。

自定义格式化输出

通过 -o <format_string>--format=<format_string> 参数,您可以完全自定义 squeue 的输出内容和格式。

常用格式符列表:

格式符 说明
%i 作业 ID (Job ID)。
%P 分区 (Partition)。
%j 作业名称 (Job Name)。
%u 用户名 (User)。
%T 作业状态 (State),如 RUNNING, PENDING
%M 已运行时间 (Time Used)。
%l 作业总运行时限 (Time Limit)。
%D 节点数 (Nodes)。
%C 请求的 CPU 核心数 (CPUs)。
%q 作业的服务质量或优先级 (QOS/Priority)。
%R 节点列表或排队原因 (Node List / Reason)。
%a 计费账户 (Account)。

格式化输出示例:

下面的命令会以一个清晰、对齐的表格形式显示作业的详细信息。

squeue -o "%.18i %.9P %.12j %.12u %.8T %.10M %.16l %.6D %R"

scontrol (查看作业详情与排错)

提交作业后,如果作业处于排队状态(Pending)或正在运行(Running),可以使用 scontrol 工具获取该作业极其详尽的实时快照。这是调试提交脚本、确认资源分配是否符合预期的首选工具。

  • scontrol show job提供正在运行刚结束作业的实时、详尽快照。是调试问题的首选。

查看作业详情

scontrol show job <job_id> 命令可以显示一个作业极其全面的配置和状态信息,但其数据具有时效性,通常只能查询正在运行或在系统缓存中的近期作业。

使用示例:

# 查看作业 ID 为 7454119 的详细信息
scontrol show job 7454119

能从中获取的关键信息包括:

  • JobState: 作业当前状态。
  • WorkDir: 作业的工作目录。
  • SubmitTime, StartTime, RunTime: 提交、开始及已运行时间。
  • NodeList: 正在使用的节点。
  • NumCPUs, NumNodes: 申请的 CPU 核心数和节点数。
  • Command: 提交的命令。

注意 此命令直接从 Slurm 控制器的内存中读取数据,因此无法查询很久以前的历史作业。

scancel (取消作业)

scancel 命令用于取消您已经提交到队列中的作业,无论是正在排队的(Pending)还是正在运行的(Running)。

您只能取消属于您自己账户下的作业。

使用示例

  1. 取消单个作业

    只需提供要取消的作业 ID。

    # 取消作业 ID 为 123 的作业
    scancel 123
    
  2. 取消自己的所有作业

    这是一个危险操作,请在执行前务必确认无误!

    下面的命令会取消提交的所有作业,包括正在运行和排队的。

    # 使用环境变量 $USER 自动填充当前用户名
    scancel -u $USER
    
  3. 按状态取消作业

    此命令会取消所有处于 PENDING(排队中)状态的作业,而不会影响正在运行的作业。

    scancel -t PENDING -u $USER
    

    同理,也可以使用 -t RUNNING 来取消所有正在运行的作业。

常用参数

参数 (Parameter) 简写 说明
--user=<user_name> -u 取消指定用户的作业。
--state=<state_name> -t 取消处于特定状态的作业,如 PENDING, RUNNING
--name=<job_name> -n 取消指定作业名称的作业。
--partition=<name> -p 取消提交到指定分区的作业。
--qos=<qos> -q 取消属于指定 QOS 的作业。
--account=<account> -A 取消指定计费账户下的作业。
--help 显示 scancel 命令的帮助信息。