我正在尝试运行python脚本,其中的部分代码将根据一些SLURM环境变量进行并行化。我认为确切的代码并不重要,但是作为参考,我想use this来训练我的网络。
现在,问题是我需要通过srun
运行脚本,但是这会生成我不需要的脚本的多个并行实例。
最基本的例子是这样:
#!/bin/sh
#SBATCH -N 2
#SBATCH --ntasks=2
srun python myscript.py
现在我将有2个节点和2个任务,这意味着当我运行python myscript.py
时,将有2个myscript.py
实例并行运行。
但是,这不是我想要的。我希望只有myscript.py
的一个实例在运行,但是它应该可以访问srun
设置的环境变量,并将其留给python脚本以正确分配资源。设置srun --ntasks=1
不起作用,因为该脚本将仅“看到”节点之一。
是否可以使用srun
运行脚本的单个实例,同时仍然可以“访问” SLURM环境变量?我查看了--exclusive
和--preserve-env
等选项,但在这种情况下它们似乎对我没有帮助。
事实证明,Hristo Iliev在注释中是正确的,要正确使用SlurmClusterResolver,需要并行运行多个作业。这可能会造成一些混乱,因为所有内容将并行打印,因此所有内容将被多次打印,但这是正常的。
但是,我最初的困惑和我必须按照原始问题所述进行的假设来自TensorFlow报告了内存不足错误,每当我尝试使用MultiWorkerMirrored策略时,而我知道如果没有此模型,该模型就完全适合可用内存。
我在代码中调用tf.config.get_visible_devices("GPU")
的某个地方。现在,为了使TensorFlow能够获取GPU,它将分配它们,并且默认情况下会通过填满整个GPU内存来分配它们。但是,由于所有脚本都并行运行,因此每个脚本都将尝试自己执行此操作(因为此操作超出了策略范围),从而导致内存不足(OOM)错误。
删除这段代码后,一切运行正常。
针对将来可能会偶然发现此职位的人的建议:-脚本应该并行运行,您将多次看到相同的输出-确保在strategy.scope()
下完成所有操作,即模型编译,数据生成设置(使用tf.data)-特别注意保存模型;只有“主要”工作人员应将模型保存到实际的保存文件,其他应将其写入临时文件see here
如果出现内存不足错误;确保没有任何代码可以分配示波器之外的所有GPU。这可能是TensorFlow在某个地方发起的,但是如果所有脚本中都存在,则会导致OOM错误。一种方便的测试方法是使用tf.config.experimental.set_memory_growth
,以允许内存增长而不是全部内存分配。
在我的代码中,我使用了get_task_info()
的tf.distribute.cluster_resolver.SlurmClusterResolver
函数,并且仅在任务编号为0时运行主函数的分配内存的函数。
(以上功能和注释均基于TensorFlow 2.2.0和Python 3.7.7)