上一篇介绍了TensorFlow物体检测API通过多进程,完成一个文件启动单机多卡的分布式服务相关流程,本篇首先简单总结一下多机多卡的分布式代码完善;其次分享一下k分布式训练结束后kill所有分布式节点的一个方式,想法比较简单,如果各位有更好的方法,欢迎指正讨论。
多机多卡分布式调用代码改进
上一篇通过python的多进程方式完成物体检测API的分布式多节点的同时启动,这里继续改进代码,使其可以在多机(多服务器)多卡上进行分布式的部署,这里我的想法比较简单,就是添加一个判断,根据当前服务的地址来启动对应服务器上应该部署的节点。具体代码如下:
首先需要得到当前服务器地址:
# 获取当前主机ip
host_ip = socket.gethostbyname(socket.gethostname())
used_ip = '"' + host_ip
第一行即得到主机IP,第二行是为后续进行判断设计的变量,至于为什么是在前边加了 ‘“’,这个是由于本方法设计的过程的历史遗留原因,如果尝试了我的方式,就明白了。
以PS节点部署为例,回顾一下单机多卡获取对应节点和参数的代码段:
for index_ps in range(ps_len):
multiprocessing.Process(target = do_distribute, args = (params, index_ps, 'ps')).start()
多机多卡改进为:
for index_ps in range(ps_len):
current_ip = get_ip(params['ps'], index_ps)
if current_ip == used_ip:
multiprocessing.Process(target = do_distribute, args = (params, index_ps, 'ps')).start()
def get_ip(param, index_ip):
return param[0].split(',')[index_ip].split(':')[0].strip()
即在循环读取参数表中的节点参数的时候,每次判断一下当前参数的IP是否与当前主机一致,如果一致则添加到多进程启动,否则跳过。这样在两台服务器上同时启动修改后的文件,代码自动启动对应服务器上应该配置的节点,多机多卡分布式的启动改进到此完成。
在实际运行过程中,如果个别服务器没有联网设置,或者网络的传输有其他设置,会导致启动ps,worker,master节点之后,多个节点互相等待,但是无法联通,这个时候可以尝试一下这个命令:
os.environ['http_proxy'] = ''
重置一下http的传输协议,这样或许正好解决你的问题,一般情况下除了这一项不会有其他问题。
分布式杀进程处理方式
完成了单机与多机的分布式训练启动优化问题,接下来的问题就是在分布式训练结束之后,一般情况下是worker节点会自动退出,留下ps与master节点还在互相通信,尤其是master节点会占用相对一大部分内存,不想ps节点200兆就足够了,在实际工程中,可以由另外的服务来监督,如果发现该项占用或者其他参照不变,然后进行删除,这里提供一种思路,即在训练结束之后,添加判断自动kill掉启动的所有节点。主要思路分为以下几点:(编号实在不会搞,总是不对,影响各位阅读敬请见谅)
首先,在分布式服务启动的时候,记录各个节点的PID,因为主进程文件调用的分布式文件为train.py,所以在train.py文件构建好FLAGS之后添加记录PID的文件:
pid = os.getpid()
pid_txt = open('pids.txt', 'a')
pid_txt.write(FLAGS.type + ':' + FLAGS.index + 't' + str(pid) + 'n')
pid_txt.close()
对应参数不清楚的,请看上一篇。
记录好PID之后,下一步要做的就是判断何时分布式训练结束了,然后将保存的pids.txt文件的名字改为hahaha.txt:
os.rename('pids.txt', 'hahaha.txt')
这行代码我添加在了learning.py的倒数第二行,即return total_loss的上边,因为到这里已经判训练结束了(如果有错,请指出,谢谢)
修改文件名字的目的,就是为了用来判断训练结束了,那么当然在最开始的时候我们需要有程序来实时监控文件夹里是否有hahaha.txt文件,有则说明训练结束,那我们可以kill所有节点了,没有则一直监控就好了。没错,就是这个思路,源头其实在这里。那我们没有选择另开一个窗口单独去监控文件的变化,根据之前写的多进程启动分布式节点的代码,可以直接在其后边直接添加监控的代码,作为主进程,正好其一直运行到最后,完成kill动作,主进程执行结束,bingo!那么主进程的具体代码如下:
pids_txt = 'hahaha.txt' 之后设计主进程进行监控,并kill节点
kill_distribute(pids_txt)
def kill_distribute(pid_path):
while True:
if os.path.exists(pid_path):
txt = open(pid_path, 'r')
con = txt.readlines()
for i in con:
print("kill process ", i.split('t')[0])
os.system('kill -9 {}'.format(i.split('t')[1]))
break
remove_txt(pid_path)
def remove_txt(txt_path):
if os.path.exists(txt_path):
os.remove(txt_path)
OK,这里应该不用注释了,逻辑就是主进程判断是否有hahaha.txt,有了就读取并kill,最后别忘了 删除hahaha.txt,以免下次运行的时候出问题。 到这里,关于TensorFlow物体检测API的分布式部署与杀进程相关的想法介绍完了,如果各位大神有 更好的方式,或者本文有错误,欢迎批评指正,共同交流。