You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用单SBATCH脚本动态调节点数测试分布式算法可扩展性

分布式算法可扩展性测试的SBATCH脚本问题

我需要测试分布式算法的可扩展性,在选定集群上运行测试时,希望通过单个SBATCH脚本动态设置节点数量,同时避免以下情况:

  • 申请N个节点但仅使用n<N个节点运行部分测试(浪费计算时长)
  • 存在多个重叠的SBATCH请求
  • 仅用单个SBATCH脚本完成所有测试

我拟提交如下脚本:

#!/bin/bash
#SBATCH -p <req_partition>       # Partition name
#SBATCH --gres=gpu:<no_gpu>      # No GPUs requested
#SBATCH -N 128                   # Number of nodes
#SBATCH -n 128                   # Total number of tasks
#SBATCH --time=06:00:00          # Time limit
#SBATCH --exclusive              # Exclusive access to nodes
#SBATCH --account=<account name> # Account name

/run_tests.sh 128                # run the test suite on 128 node

#SBATCH -N 64                    # Number of nodes
#SBATCH -n 64                    # Total number of tasks

/run_tests.sh 64                 # run the test suite on 64 node

#SBATCH -N 32                    # Number of nodes
#SBATCH -n 32                    # Total number of tasks

/run_tests.sh 32                 # run the test suite on 32 node

#SBATCH -N 16                    # Number of nodes
#SBATCH -n 16                    # Total number of tasks

/run_tests.sh 16                 # run the test suite on 16 node

除了该脚本的可行性之外,我还存在疑问:减少节点数量的操作是否会造成阻塞?即能否确保释放部分节点后再运行下一轮测试,还是会在测试运行过程中释放节点导致测试结果失效?


解决方案与答疑

脚本可行性分析

你写的这个脚本完全不可行。SBATCH指令只有在脚本提交到Slurm时才会被解析,脚本运行过程中后续的#SBATCH注释根本不会生效。也就是说,整个脚本只会用最开头申请的128节点、128任务配置跑完所有测试,后面的#SBATCH -N 64之类的指令等于白写,会直接造成大量计算资源浪费,完全违背你的初衷。

正确的实现方式

要在单个脚本里按顺序跑不同节点数的测试,同时动态释放节点避免浪费,有两种可靠方案:

方案1:用scontrol动态调整作业资源

如果你的集群支持Slurm的作业资源调整功能,可以直接修改当前作业的节点配置,步骤如下:

#!/bin/bash
#SBATCH -p <req_partition>
#SBATCH --gres=gpu:<no_gpu>
#SBATCH -N 128
#SBATCH -n 128
#SBATCH --time=06:00:00
#SBATCH --exclusive
#SBATCH --account=<account name>

# 先跑128节点测试
/run_tests.sh 128

# 调整作业到64节点,触发Slurm释放多余节点
scontrol update jobid=$SLURM_JOB_ID NumNodes=64 NumTasks=64
# 短暂等待资源调整生效(部分集群需要这个步骤)
sleep 30

# 跑64节点测试
/run_tests.sh 64

# 调整到32节点
scontrol update jobid=$SLURM_JOB_ID NumNodes=32 NumTasks=32
sleep 30

/run_tests.sh 32

# 调整到16节点
scontrol update jobid=$SLURM_JOB_ID NumNodes=16 NumTasks=16
sleep 30

/run_tests.sh 16

注意:

  • 要确认你的集群启用了JobResize功能,且所在分区允许调整节点数;
  • 脚本会先跑完当前测试,再执行资源调整,绝对不会在测试运行中释放节点,不会导致测试失效。

方案2:串行提交子作业

如果集群不支持动态调整资源,你可以用主脚本按顺序提交独立的子作业,通过依赖关系确保前一个测试完成后再启动下一个:

#!/bin/bash
# 主脚本不需要申请资源,仅用于串行提交子任务

# 提交128节点测试,记录作业ID
JOB_ID=$(sbatch --parsable -p <req_partition> --gres=gpu:<no_gpu> -N 128 -n 128 --time=06:00:00 --exclusive --account=<account name> /run_tests.sh 128)

# 提交64节点测试,依赖前一个作业成功完成
JOB_ID=$(sbatch --parsable --dependency=afterok:$JOB_ID -p <req_partition> --gres=gpu:<no_gpu> -N 64 -n 64 --time=06:00:00 --exclusive --account=<account name> /run_tests.sh 64)

# 提交32节点测试
JOB_ID=$(sbatch --parsable --dependency=afterok:$JOB_ID -p <req_partition> --gres=gpu:<no_gpu> -N 32 -n 32 --time=06:00:00 --exclusive --account=<account name> /run_tests.sh 32)

# 提交16节点测试
sbatch --dependency=afterok:$JOB_ID -p <req_partition> --gres=gpu:<no_gpu> -N 16 -n 16 --time=06:00:00 --exclusive --account=<account name> /run_tests.sh 16

这种方式每个子作业独立申请对应数量的节点,前一个完成后才会启动下一个,完全避免资源浪费和重叠请求,也只用单个主脚本完成所有测试。

关于节点释放的疑问

用方案1的scontrol调整时,Slurm会等当前测试完全跑完,再执行节点释放操作,释放完成后才会继续运行下一轮测试。不会出现测试运行中释放节点的情况,也不会导致测试结果失效。scontrol update命令本身会立即返回,但集群后台调整资源需要一点时间,所以加个短sleep是稳妥的,确保节点配置完全生效后再启动下一轮测试。

内容的提问来源于stack exchange,提问作者Saverio Pasqualoni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 03:23:24