微软OneNote客户预览版学习工具下载(暂未上线):教学好帮手
809
2022-05-30
MoXing没有对运行参数定义特殊API,用户可根据自己的习惯定义运行参数。建议使用TensorFlow的flags组件来定义。
1、使用tf.flags定义运行参数(TensorFlow-1.4)
flags是由TensorFlow-1.4提供的一种定义运行参数组件。从TensorFlow-1.5开始,TensorFlow将flags替换成了absl。
如果代码中出现如下错误信息,很有可能是在使用MoXing-TensorFlow-1.4的情况下,TensorFlow的版本不是1.4。
AttributeError: 'module' object has no attribute '_FlagValues'
通过以下命令查看TensorFlow版本:
pip list | grep tensorflow
或者在python中输入:
import tensorflow as tf
tf.__version__
使用tf.flags定义一个运行参数如下:
tf.flags.DEFINE_string(name='data_url', default='./', help='Data directory.')
flags = tf.flags.FLAGS
print(flags.data_url)
flag_name: 运行参数名,例如外部命令行运行时添加参数--data_url=xxx
default_value: 当外部命令行参数不传入该参数时使用的缺省值
docstring: 命令行帮助文档信息
在TensorFlow-1.4中,tf.flags提供了以下4种数据类型:
tf.flags.DEFINE_string
tf.flags.DEFINE_integer
tf.flags.DEFINE_float
tf.flags.DEFINE_boolean
如果本来的脚本中定义的运行参数中有list,但是tf.flags不支持list怎么办?
用string表达list,然后在代码中解析出来,比如:
tf.flags.DEFINE_string(name='int_list', default='0,1,2', help=None)
flags = tf.flags.FLAGS
int_list = [int(int_item) for int_item in flags.int_list.split(',')]
2、MoXing定义的默认运行参数
MoXing本身会定义一些默认的运行参数,这些参数不需要在用户脚本中额外定义,当用户使用如下导入代码时即生效,直接可以在外部命令行或DLS服务的运行参数中传入。
import moxing.tensorflow as mox
以下列举几个重要的参数:
--num_gpus: 使用GPU的数量,如果使用的是CPU,这项参数不要填写,或者给1,缺省值为1。
以下四个参数是TensorFlow推荐的分布式运行参数,具体可参考TensorFlow官方文档。
--job_name: ps或worker
--task_index: ps或worker进程的序号,一般情况下task_index为0的worker为chief worker (也可以认为是master节点,master节点在物理上并不存在,是一个逻辑节点)
--ps_hosts: ps的ip和端口,多个节点以“,”分割。
--worker_hosts: worker的ip和端口,多个节点以“,”分割。
例如,启动一个2个节点的训练作业,每个节点使用4个GPU,参数配置如下:
# 节点0启动ps进程参数(对应IP地址为192.168.1.100)
--job_name=ps
--task_index=0
--ps_hosts=192.168.1.100:2222,192.168.1.101:2222
--worker_hosts=192.168.1.100:2223,192.168.1.101:2223
# 节点0启动worker进程参数(对应IP地址为192.168.1.100)
--job_name=worker
--task_index=0
--ps_hosts=192.168.1.100:2222,192.168.1.101:2222
--worker_hosts=192.168.1.100:2223,192.168.1.101:2223
--num_gpus=4
# 节点1启动ps进程参数(对应IP地址为192.168.1.101)
--job_name=ps
--task_index=1
--ps_hosts=192.168.1.100:2222,192.168.1.101:2222
--worker_hosts=192.168.1.100:2223,192.168.1.101:2223
# 节点1启动ps进程参数(对应IP地址为192.168.1.101)
--job_name=worker
--task_index=1
--ps_hosts=192.168.1.100:2222,192.168.1.101:2222
--worker_hosts=192.168.1.100:2223,192.168.1.101:2223
--num_gpus=4
MoXing内部定义运行参数的相关API:mox.get_flag,mox.set_flag
所有分布式进程都启动后,worker进程不断在打印如下信息,没有开始训练。
2018-04-13 14:01:47.653259: I tensorflow/core/distributed_runtime/master.cc:221] CreateSession still waiting for response from worker: /job:ps/replica:0/task:0
2018-04-13 14:01:47.653308: I tensorflow/core/distributed_runtime/master.cc:221] CreateSession still waiting for response from worker: /job:ps/replica:0/task:1
2018-04-13 14:01:47.653315: I tensorflow/core/distributed_runtime/master.cc:221] CreateSession still waiting for response from worker: /job:worker/replica:0/task:1
解决办法:
首先保证job_name,task_index,ps_hosts,worker_hosts这四个参数都是正确的,考虑以下这种情况是不正确的:
在一个IP为192.168.1.100的机器上启动ps或worker进程:
--job_name=worker
--task_index=1
--ps_hosts=192.168.1.100:2222,192.168.1.101:2222
--worker_hosts=192.168.1.100:2223,192.168.1.101:2223
因为该进程启动位置是192.168.1.100,但是运行参数中指定的task_index为1,对应的IP地址是ps_hosts或worker_hosts的第二项(第一项的task_index为0),也就是192.168.1.101,和进程本身所在机器的IP不一致。
另外一种情况也会导致该问题的发生,从TensorFlow-1.4开始,分布式会自动使用环境变量中的代理去连接,如果运行的节点之间不需要代理互连,那么将代理的环境变量移除即可,在脚本的开始位置添加代码:
# 注意这段代码必须写在import tensorflow as tf或者import moxing.tensorflow as mox之前
import os
os.enrivon.pop('http_proxy')
os.enrivon.pop('https_proxy')
3、DLS服务中训练作业的运行参数
DLS服务-创建训练作业的界面
DLS服务中,用户不需要考虑代理问题。如用户使用原生TensorFlow-API脚本进行训练,用户需要定义DLS服务规定的几项参数,说明如下:
⊙ 训练数据集中填写的内容会以运行参数--data_url的形式传入到启动文件指定的脚本中.
⊙ 在选择计算节点规格和计算节点个数时会产生多GPU和分布式相关的5项参数。如,计算节点规格为4*P100,即使用4个P100的GPU,所以--num_gpus=4,计算节点个数为2,则表示分布式运行并使用2个节点,则会使用启动文件指定的脚本启动4个进程,每个进程都会按规范填入job_name,task_index,ps_hosts,worker_hosts,其中的IP地址和端口是由DLS预先分配指定好的,用户直接在脚本中使用即可。
⊙ 如果用户使用基于MoXing的脚本进行训练,则不需要定义多GPU和分布式的参数,也不需要编写多GPU和分布式相关的代码。但用户仍然需要定义--data_url这个运行参数。
用户在训练脚本中想读取一些文件或者写入一些日志文件,发现找不到文件或路径。
如果你想读取OBS上桶名为dls-test中的文件a.txt,而且使用了如下代码:
f=open('/dls-test/a.txt', 'r')
则会出现如下错误:
IOError: [Errno 2] No such file or directory: '/dls-test/a.txt'
在DLS服务中,作业在容器中启动,一般来说对文件的读写都是基于OBS或其他数据服务的,比如打开一个OBS上,桶名为dls-test中的文件a.txt,那么要使用OBS的路径s3://dls-test/a.txt,但是当你发现把代码修改为:
f=open('s3://dls-test/a.txt', 'r')
依然会出现同样找不到文件的错误,那是因为大多数文件读写的API都不支持s3路径,用户如果涉及文件读写的操作,都必须使用支持s3的文件接口,如obs-sdk,obscmd,s3cmd,tf.gfile,mox.file
以下代码利用tf.gfile操作文件:
import tensorflow as tf
f=tf.gfile.Open('s3://dls-test/a.txt', 'r')
在DLS中,用户不需要配置OBS的ak, sk等信息,因为都已经默认配置好了。
建议用户将输入数据集、代码、输出日志这三者的路径提前规划好,不要放在相同的目录下,由于代码目录有10MB的容量大小限制,所以如果输入数据集或者输出日志存放在代码目录中可能会导致不能提交作业。
假设用户将代码结构如下:
project_dir
|- main.py
|- module_dir
|- module_file.py
用户在main.py中有代码:
from module_dir import module_file
发生如下错误:
Traceback (most recent call last):
File "project_dir/main.py", line 1, in
from module_dir import module_file
ImportError: No module named module_dir
这份代码如果在本地运行,需要将project_dir加入到PYTHONPATH或者将整个project_dir安装到site-package中才能运行,但是在DLS中没有办法进行这些操作,所以可以将project_dir加入到sys.path中解决该问题,步骤如下:
首先保证被import的module中有__init__.py存在,创建module_dir的__init__.py,代码结构如下:
project_dir
|- main.py
|- module_dir
|- __init__.py
|- module_file.py
在main.py中将project_dir添加到sys.path中,由于用户不知道project_dir在容器中的位置,所以利用相对路径:
import os
import sys
# __file__为获取当前执行脚本main.py的绝对路径
# os.path.dirname(__file__)获取main.py的父目录,即project_dir的绝对路径
current_path = os.path.dirname(__file__)
sys.path.append(current_path)
# 在sys.path.append执行完毕之后再导入其他模块
from module_dir import module_file
再次提交作业运行即可。
如果在DLS服务中训练数据集的值没有填写,脚本依然会收到--data_url的参数,参数值为空。
在用户脚本中定义了运行参数如下:
tf.flags.DEFINE_string('data_url', default='s3://xxx', help=None)
在DLS中训练数据集项不填写,这种情况下用户可能会认为脚本会取运行参数data_url的默认值default_value,即's3://xxx',但实际情况是,即使训练数据集项不填写,脚本依然会收到--data_url的参数,只是参数的值为空,即:python xxx.py --data_url='',所以默认值无法起作用。
如果是用户自定义的运行参数,考虑以下3种情况:
① 用户添加了一个运行参数: my_flag = xxx,则脚本会收到--my_flag=xxx
② 用户添加了一个运行参数: my_flag,但是没有填入任何的值,则脚本会收到--my_flag=''
③ 用户没有添加运行参数: my_flag,则脚本不会收到--my_flag这个运行参数
所以训练数据集类似这里的第②种情况。
MoXing系列文章下期预告:数据输入教程。
TensorFlow
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。