使用SRUN代替SBATCH,能否在后台运行SLURM作业?

15

我试图使用srun在后台运行slurm作业。不幸的是,由于我现在必须通过Docker运行事物,因此使用sbatch有点麻烦,因此我正在尝试找出是否可以完全避免使用它。

根据我的观察,每当我运行srun时,比如说:

srun docker image my_job_script.py

关闭我正在运行命令的窗口(以避免接收所有打印语句),打开另一个终端窗口以查看命令是否仍在运行,似乎我的运行脚本由于某种原因被取消了。由于它不是通过sbatch运行的,所以它不会向我发送带有错误日志的文件(据我所知),所以我不知道它为什么关闭。

我还尝试过:

srun docker image my_job_script.py &

我希望在终端中重新获得控制权。不幸的是,如果我这样做,它仍然会将东西打印到我的终端屏幕上,而我正试图避免这种情况。

基本上,我通过ssh登录到远程计算机,然后执行srun命令,但似乎如果我终止ssh连接的通信,则srun命令会自动停止运行。有没有办法阻止这种情况发生?

理想情况下,我想要发送脚本运行,除非我通过scancel取消它,否则不会因任何原因被取消,并且不应该打印到我的屏幕上。因此,我的理想解决方案是:

  1. 即使我退出ssh会话,也要继续运行srun脚本
  2. 即使我关闭发送命令的窗口,也要继续运行我的srun脚本
  3. 让我的srun脚本继续运行并让我离开srun会话,而不会打印到我的屏幕上(即实际上在后台运行)

这将是我理想的解决方案。


对于想了解sbatch问题的好奇人群,我想能够执行以下操作(这是理想的解决方案):

sbatch docker image my_job_script.py

然而,正如人们所知道的那样,它不起作用,因为sbatch接收到的命令是docker,它不是一个"batch"脚本。基本上,一个简单的解决方案(对于我的情况实际上并不起作用)是将docker命令包装在批处理脚本中:

#!/usr/bin/sh
docker image my_job_script.py

不幸的是,我实际上正在使用批处理脚本来编码大量信息(类似于配置文件)以运行任务。因此这样做可能会影响我的工作,因为它们的基础文件正在更改。通过直接将作业发送到sbatch来避免这种情况,因为它本质上创建了批处理脚本的副本(如在这个问题中所述:在slurm中运行时更改发送给sbatch的bash脚本是个坏主意吗?)。因此,解决我的问题的真正方法是使我的批处理脚本包含所有我的脚本需要的信息,然后以某种方式在Python中调用docker并同时传递所有信息。不幸的是,其中一些信息是函数指针和对象,因此我甚至不清楚如何将这样的东西传递给在Python中运行的docker命令。


或者,直接在sbatch中运行docker而不是使用批处理脚本也可以解决问题。


1
使用 & 并使用 -o 重定向输出?我不确定,但如果 srun docker image my_job_script.py & 对您有效,除了输出之外,那么如何尝试:srun -o output.txt docker image my_job_script.py &。您还可以使用 -e 重定向 _stderr_。 - Bub Espinja
@SergioIserte 看起来到目前为止已经起作用了...现在唯一的警告是我拥有的 slurm 设置每 6 小时会杀掉我的任务。因此,如果 6 小时后它再次尝试运行它,我想知道它是否只会调用我的原始命令。只是好奇,因为也许最好将“-o”参数的参数设置为绝对路径(或者可能会发生任何其他意外的警告)。 - Charlie Parker
3个回答

9
-o stdout-e选项可以重定向输出到标准输出和标准错误流。

因此,作业可以在后台启动,并将输出重定向:

$ srun -o file.out -e file.errr docker image my_job_script.py &

2
这太搞笑了,sbatch是这样实现的吗?还是有什么区别。我知道sbatch会复制批处理脚本。那这个会不会也复制我的my_job_script.py呢? - Charlie Parker

2
另一种方法是使用终端复用器,例如tmuxscreen
例如,创建一个新的tmux窗口,输入tmux。在该窗口中,使用srun运行您的脚本。然后,您可以分离tmux窗口,返回到主shell,以便进行其他操作,或者您可以完全注销。当您想要检查脚本时,只需重新附加到tmux窗口。有关如何在您的操作系统上分离和重新附加,请参见文档tmux -h
使用此技术仍然可以重定向任何输出(使用-o-e),并且您可以在不同的tmux窗口中同时运行多个srun命令。我发现这种方法对于运行并发流水线(例如基因组学)非常有用。

1
我也在想这个问题,因为sbatchsrun之间的区别并没有很清楚地解释或解释动机。我查看了代码,发现以下内容:

sbatch

sbatch基本上只是将一个shell脚本发送到控制器,告诉它运行该脚本,然后退出。它不需要在作业进行时继续运行。它有一个--wait选项,可保持运行状态,直到作业完成,但它只是每2秒轮询控制器以请求。 sbatch不能跨多个节点运行作业-代码根本不在sbatch.c中。sbatch没有按照srun实现,它是完全不同的东西。
此外,它的参数必须是一个shell脚本。有点奇怪的限制,但它确实有一个--wrap选项,以便可以自动为您在shell脚本中包装一个真正的程序。祝你好运,希望你能正确地进行所有转义!

srun

srun更像是MPI运行器。它直接在许多节点上启动任务(默认情况下每个节点一个任务,但您可以使用--ntasks覆盖它)。它旨在用于MPI,因此所有作业都将同时运行。在所有节点都有空闲插槽之前,它不会启动任何作业。
它必须在作业进行时继续运行。您可以使用&将其发送到后台,但这与sbatch仍然不同。如果您需要启动一百万个srun,您将遇到问题。一百万个sbatch应该(理论上)可以正常工作。
sbatch不同,没有办法让srun退出并使作业仍然运行。srun本身充当作业中所有节点的协调器,更新作业状态等,因此它需要在整个过程中运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接