我是分布式操作系统的新手。而且我需要训练有关超级计算机的多种机器学习模型。我需要多次运行相同的训练脚本,并且每次运行都使用不同的命令行参数传递脚本。我可以通过使用mpiexec来实现此目的,以便可以并行训练具有不同输入的多个模型吗?
我发现了mpi的单程序多数据模型,但是我不知道相应的命令。
我想在集群中的计算节点之间并行运行以下行。
python train.py arg > log.out # arg is the argument that differs for each node
但是,如果我使用的是:
mpiexec train.py arg >log.out
它将仅使用相同的命令行参数:arg并行运行train.py。
有人可以指出正确的方法吗?谢谢!
答案 0 :(得分:0)
一种实现所需目标的方法是使用mpi4py创建一个顶级脚本mpi_train.py
。在MPI作业中,每个进程都具有唯一的等级,并且所有进程都运行相同的代码,因此运行
from mpi4py import MPI
comm = MPI.COMM_WORLD
print("Hello! I'm rank " + str(comm.rank))
与
mpiexec -n 4 python mpi_train.py
会给予
Hello! I'm rank 0
Hello! I'm rank 1
Hello! I'm rank 3
Hello! I'm rank 2
然后可以使用不同的等级来读取指定args的单独文件。所以你会有类似的东西,
#All code in train should be in functions or __name__ == "__main__"
import train
from mpi4py import MPI
def get_command_args_from_rank(rank):
#Some code here to get args from unique rank no.
comm = MPI.COMM_WORLD
args = get_command_args_from_rank(comm.rank)
#Assuming the args can be passed to a run function
out = train.run(args)
请注意,您应该使用类似以下内容来明确指定每个进程的输出
with open("log.out"+str(comm.rank)) as f:
f.write(out)
否则,由于无法保证各种处理的顺序,所有打印品都会进入标准输出并变得混乱。
答案 1 :(得分:0)
感谢所有评论和回答。这是我为最终解决方案所做的:
首先,我有一个bash脚本以作业数组的形式将作业提交到集群,其中$ PBS_ARRAYID将不同的命令行参数传递给每个作业:
#PBS -N ondemand/sys/myjobs/default
#PBS -l walltime=24:10:00
#PBS -l file=1gb
#PBS -l nodes=1:ppn=1:gpus=1:default
#PBS -l mem=40MB
#PBS -j oe
#PBS -A PAS0108
#PBS -o Job_array.out
# Move to the directory where the job was submitted
# run the following cmd in shell to submit the job in an array
# qsub -t 1-6 myjob.sh
cd $PBS_O_WORKDIR
cd $TMPDIR
# $PBS_ARRAYID can be used as a variable
# copy data to local storage of the node
cp ~/code/2018_9_28_training_node_6_OSC/* $TMPDIR
cp -r ~/Datasets_1/Processed/PascalContext/ResNet_Output/ $TMPDIR
cp -r ~/Datasets_1/Processed/PascalContext/Truth/ $TMPDIR
cp -r ~/Datasets_1/Processed/PascalContext/Decision_Tree/ $TMPDIR
# currently in $TMPDIR, load modules
module load python/3.6 cuda
# using $PBS_ARRAYID as a variable to pass the corresponding node ID
python train_decision_tree_node.py $PBS_ARRAYID $TMPDIR > training_log_${PBS_ARRAYID}
# saving logs
cp training_log ${HOME}/logs/${PBS_ARRAYID}_node_log/
cp my_results $PBS_O_WORKDIR
我通过命令行提交以上脚本:
qsub -t 1-6 myjob.sh
但是,我从集群中收到了一个错误消息,当我运行脚本时,集群中的实际节点无法以某种方式识别本地目录$TMPDIR
。
最后,我所做的是,我使用了一个顶级bash脚本在while循环中使用不同的命令行参数提交了每个作业,并且效果很好:
run_multiple_jobs.tcsh:
#!/usr/bin/env tcsh
set n = 1
while ( $n <= 5 )
echo "Submitting job for concept node $n"
qsub -v NODE=$n job.pbs
@ n++
end
jobs.pbs:
#PBS -A PAS0108
#PBS -N node_${NODE}
#PBS -l walltime=160:00:00
#PBS -l nodes=1:ppn=1:gpus=1
#PBS -l mem=5GB
#PBS -m ae
#PBS -j oe
# copy data
cp -r ~/Datasets/Processed/PascalContext/Decision_Tree $TMPDIR
cp -r ~/Datasets/Processed/PascalContext/Truth $TMPDIR
cp -r ~/Datasets/Processed/PascalContext/ResNet_Output $TMPDIR
# move to working directory
cd $PBS_O_WORKDIR
# run program
module load python/3.6 cuda/8.0.44
python train_decision_tree_node.py ${NODE} $TMPDIR $HOME
# run with run_multiple_jobs.tcsh script