在超算系统上使用sbatch提交MXNet分布式训练任务
在超算系统上运行MXNet分布式训练任务时,面临着一个IP地址相关的问题。我们在提交MXNet的分布式任务时,需要知道各个GPU节点的IP地址,把这些IP地址放到一个hosts文件中,以供分布式训练使用。因此,一种常用的方式是先使用salloc
或yhalloc
申请若干节点,然后依次登录这些节点,查询它们的IP地址,手动写入到一个hosts文件中,再使用MXNet提供的脚本提交分布式训练任务。显然,这种方法具有很多劣势。首先,当集群资源不足时,我们需要人工守在电脑前,等待有空闲资源时再手动申请节点,费时费力;其次,这种方式需要在.bashrc
文件中修改全局环境变量,导致同一时间段只能有1位同学做实验,不能利用好剩余的资源;最后,在整个任务运行期间,我们也需要守在电脑前,等待任务结束后手动释放资源,否则也会造成机器空转,浪费机时。因此,我们需要寻找其他的方式,每当集群中有空闲资源时,都能够自动申请资源,运行任务,然后释放掉相关资源,而且能够使多为同学一起做实验,互不影响。这样一来,我们就不需要守在电脑屏幕旁边,既方便了自己,又节省了机时,一举两得。
当前,超算集群一般都使用Slurm进行管理。Slurm支持利用sbatch
命令采用批处理方式运行作业,sbatch
在脚本正确传递给作业调度系统后立即退出,同时获取到一个作业号,作业会等待所需资源满足后开始运行。sbatch
会提交一个批处理作业脚本到Slurm,批处理脚本名可以在命令行上通过传递给sbatch,如没有指定文件名,则sbatch从标准输入中获取脚本内容。关于sbatch
命令的详细内容请参考链接1以及链接2。
sbatch
脚本文件的基本格式包括以下几点:
- 第一行以
#!/bin/sh
等指定该脚本的解释程序,/bin/sh
可以变为/bin/bash
、/bin/csh
等。 - 在可执行命令之前的每行
#SBATCH
前缀后跟的参数作为作业调度系统参数。 - 在任何非注释及空白之后的
#SBATCH
将不再作为Slurm参数处理。
例如,下面的脚本申请了4个GPU节点,并在这些节点上运行python test.py
命令。
#!/bin/bash
#SBATCH -N 4
#SBATCH -p gpu_v100
python test.py
看起来,sbatch
命令完美地契合了我们的需求,能够自动运行任务并管理资源,只需要我们写一个脚本,在脚本里放上我们需要运行的分布式训练任务相关的代码,然后使用sbatch
提交就可以了。但是,一个关键的问题是,在通过sbatch
申请到节点资源之前,我们并不能预知所申请到的节点是哪些,也就不知道它们的IP地址;然而,我们写在脚本里的分布式训练命令,又要求我们提供节点的IP地址。一种解决方法是在提供给sbatch
的脚本里,指定要申请的节点列表,根据这个列表可以推算出相应的IP地址。下面的代码表示的就是这种情况,我们在脚本里指定申请gpu1到gpu4这4个节点,然后提前在hosts文件里把这4个节点的IP地址填进去,这样就可以完成自动运行训练任务且释放资源了。
#!/bin/bash
#SBATCH -N 2
#SBATCH -p gpu_v100
#SBATCH -w gpu[1-4]
python ../../tools/launcher.py --launcher ssh -H hosts -n 4 python train_imagenet.py
不幸的是,上面的方法仍然具有很强的局限性。当集群中有空闲节点而我们又没有在申请列表中指定它们时,就会导致我们的任务在等待,不利于我们进行实验。因此,想要完美地发挥出sbatch
命令的优势,就必须能够在脚本中获取所申请节点的IP地址。已知在脚本中,我们可以通过srun -l /bin/hostname
获取到每个节点的主机名,那么问题就变成如何根据主机名获取到对应的IP地址。所幸,我们可以通过getent hosts hostname
来从主机名获取到其对应的IP地址,如下图所示:
那么,我们只要通过一些编程技术,在申请资源后,从主机名获取到对应的IP地址并写入到hosts文件中,然后再运行分布式训练命令,就可以发挥出sbatch
的优势,解放自己的双手~
在sbatch
脚本中,获取到主机名后,通过xargs
向getent hosts
命令传输参数,然后利用awk
命令抽取相应的IP地址并写入到hosts文件中,就达成了我们的目的。关于xargs
和awk
命令,请参考xargs 命令教程和awk 命令教程。完整的脚本文件如下所示,其中环境变量可以根据自己的实验需求进行配置。
#!/bin/bash
#SBATCH -N 4
#SBATCH -p gpu_v100
export PYTHONEPATH=CUSTOM_PYTHON_PATH
export OTHER_ENV_VAR=VALUES
MACHINEFILE="nodes.$SLURM_JOB_ID"
srun -l /bin/hostname | sort -n | awk '{print $2}' | xargs -L 1 getent ahosts | awk '{match($0,/([0-9]{1,3}\.){3}[0-9]{1,3}/,a); print a[0]}' > $MACHINEFILE
sort $MACHINEFILE | uniq > hosts
rm $MACHINEFILE
python ../../tools/launcher.py --launcher ssh -H hosts -n 4 python train_imagenet.py
使用以上方式获取IP地址,仍然有两个局限性:第一,只能获取到默认网卡的IP地址,不能获取其他的IP地址。例如在广州V100集群上,获取到的是IB网卡的地址。第二,当只申请一个节点进行训练任务时,上述脚本会失败并挂起。不过一般来说,分布式训练任务都需要多个节点,所以这个问题影响比较小。目前正在解决这两个问题。
在超算系统上使用sbatch提交MXNet分布式训练任务的更多相关文章
- MXNet源码分析 | Gluon接口分布式训练流程
本文主要基于MXNet1.6.0版本,对Gluon接口的分布式训练过程进行简要分析. 众所周知,KVStore负责MXNet分布式训练过程中参数的同步,那么它究竟是如何应用在训练中的呢?下面我们将从G ...
- 数据终端设备与无线通信模块之间串行通信链路复用协议(TS27.010)在嵌入式系统上的开发【转】
转自:http://blog.csdn.net/hellolwl/article/details/6164449 目录(?)[-] 协议介绍 模块协议介绍 1 命令包格式 2 ...
- CentOS 6.5系统上安装SVN服务器端的方法及目录访问权限配置(转总结)
SVN其实就是Subversion,分为服务器端和客户端.之前在网上搜了很多方法,都有各种问题,经过自己搜集整理以及实际尝试,总算有个比较靠谱的方法.本文主要介绍CentOS 6.5系统上安装SVN服 ...
- 如何在一个ubuntu系统上搭建SVN版本控制工具
有话说,由于公司项目部署需要,将Windows工程迁移到Linux,通过调查确定使用Ubuntu的Linux操作系统.那么如何快速搭建和Windows一样快捷方便的开发环境就很重要了.本文讲述如何在一 ...
- 【C# .Net GC】Windows 系统上的大型对象堆
原文链接:https://docs.microsoft.com/zh-cn/dotnet/standard/garbage-collection/large-object-heap NET 垃圾回收器 ...
- 在配有英特尔® Iris™ 显卡的系统上通过优化对 Just Cause 3 进行增强
高端 PC 继续通过高性能显卡驱动桌面游戏. 一流的"梦想机器"基于第六代智能 英特尔® 酷睿™ 处理器i7-6700K等 CPU,通常与高端独立显卡配合使用以运行要求最严苛的游戏 ...
- 基于英特尔® 至强™ 处理器 E5 产品家族的多节点分布式内存系统上的 Caffe* 培训
原文链接 深度神经网络 (DNN) 培训属于计算密集型项目,需要在现代计算平台上花费数日或数周的时间方可完成. 在最近的一篇文章<基于英特尔® 至强™ E5 产品家族的单节点 Caffe 评分和 ...
- win10调用局域网内xp系统上的打印机
首先在xp系统上配置允许远程连接,然后设置账户密码,最后配置打印机,允许共享. 打开自己win10 ,win+R ,输入\\目标电脑ip\打印机名,确定,输入账户,密码. win+X - P-进入控制 ...
- 64位的Ubuntu系统上使用汇编nasm和C语言
64位的Ubuntu系统上使用汇编nasm和C语言 $ nasm -f elf foo.asm -o foo.o$ gcc -c bar.c -o bar.o$ ld -s foo.o bar.o ...
随机推荐
- 深入理解Java虚拟机之自己编译JDK
题外话 最近在阅读<深入理解Java虚拟机>,其中有一小节实战是自己编译JDK,实际操作下来后遇到问题不少,为此特地记录,也希望可以给大家带来一些参考! 前置准备 平台及工具:Window ...
- phpAdmin写webshell的方法
一.常规导入shell的操作 创建数据表导出shell CREATE TABLE `mysql`.`shadow9` (`content` TEXT NOT NULL ); INSE ...
- T-SQL创建数据库常用方法2020年10月29日20:12:04网课笔记
2.接口的作用 第一.方便框架的设计.利于团队的开发. 第二.方便项目拓展.高内聚.低耦合. 3.反射 [1]反射的理解:通过读取程序集的信息,找到相关的类型和类型的成员,也可以得到相关的对象.而这种 ...
- promise到底怎么理解
Promise的含义promise是异步编程的一种解决方法.所谓promise,简单说是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,从语法上说,promise是一个对象,从 ...
- [STM32F10x] 使用printf函数进行串口调试问题
硬件:STM32F103C8T6 平台:Keil ARM-MDk V5.11 利用printf函数通过串口(USART)进行调试时遇到的一个问题: printf("Hello, Mini-M ...
- CMake语法—普通变量与包含、宏(Normal Variable And Include、Macro)
目录 CMake语法-普通变量与包含.宏(Normal Variable And Include.Macro) 1 CMake普通变量与包含.宏示例 1.1 代码目录结构 1.2 根目录CMakeLi ...
- T-SQL的存储过程
1.简介 存储过程可以说是一个记录集,它是由一些T-SQL语句组成的代码块,这些T-SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删改查),然后再给这个代码块取一个名字,在用到这个功能的时 ...
- pytest文档5-参数化parametrize
pytest.mark.parametrize装饰器可以实现测试用例参数化. parametrizing 1.这里是一个实现检查一定的输入和期望输出测试功能的典型例子 # content of tes ...
- Linux下Makefile的编写及四个特殊符号的意义@、$@、$^、$
转自:https://blog.csdn.net/runfarther/article/details/50036115# 我们先看三段C++程序: 一.line1的源码 line1.h #ifnde ...
- golang中匿名函数的应用-回调函数-闭包
package main import ( "fmt" "strconv" ) type funcType func(int, int) int // 自定义函 ...