轻松配置分布式TensorFlow
4.5 配置分布式TensorFlow
在大型的数据集上进行神经网络的训练,往往需要更大的运算资源,而且还要花上若干天才能完成运算量。
TensorFlow提供了一个可以分布部署的模式,将一个训练任务拆成多个小任务,分配到不同的计算机上来完成协同运算,这样使用计算机群运算来代替单机计算,可以时训练时间大大变短。
4.5.1 分布式TensorFlow的角色及原理
要想配置TensorFlow为分布训练,需要先了解TensorFlow中关于分布式的角色分配。
● ps:作为分布式训练的服务端,等待各个终端(supervisors)来连接;
● worker:在TensorFlow的代码注释中被称作supervisors,作为分布式训练的运算终端;
● chief supervisors:在众多运算终端中必须选择一个作为主要的运算终端。该终端是在运算终端中最先启动的,它的功能是合并各个终端运算后的学习参数,将其保存或载入。
每个具体的角色的网络标识都是唯一的,即,分布在不同IP的机器上(或者同一个机器,但是不同端口)。
在实际运行中,各个角色的网络构建部分代码必须100%的相同。三者的分工如下:
● 服务端作为一个多方协调者,等待各个运算终端来连接;
● chief supervisors会在启动时统一管理全局的学习参数,进行初始化或从模型载入。
● 其他的运算终端只是负责得到其对应的任务并进行计算,并不会保存检查点,用于TensorBoard可视化中的summary日志等任何参数信息。
整个过程都是通过RPC协议来通信的。
4.5.2 分布部署TensorFlow的具体方法
配置过程中,首先需要建一个server,在server中会将ps及所有worker的IP端口准备好。接着,使用tf.train.Supervisor中的managed_session来管理一个打开的session。Session中只是负责运算,而通信协调的事情就都交给Supervisor来管理了。
4.5.3 实例20:使用TensorFlow实现分布式部署训练
下面就开始实现一个分布式训练的网络模型。本例以“4-8线性回归的TensorBoard可视化.py”为原型,在其中添加代码将其改成分布式。
案例描述
在本机通过3个端口来建立3个终端,分别为一个ps,两个worker,实现TensorFlow的分布式运算。
具体步骤如下:
1.为每个角色添加IP地址和端口,创建server
在一台机器上开3个不同的端口,分别代表ps、chief supervisors 、worker。角色的名称用strjob_name表示。以ps为例,代码如下:

2. 为ps角色添加等待函数
ps角色使用server.join()函数进行线程挂起,开始接收连接消息。
与正常的程序不同,在创建网络结构时,使用tf.device函数将全部的节点都放在当前任务下。
在tf.device中的任务是通过tf.train.replica_device_setter来指定的。
在tf.train.replica_device_setter中使用worker_device来定义具体任务名称;使用cluster的配置来指定角色及对应的IP地址,从而实现管理整个任务下的图节点。
在tf.train.Supervisor中,is_chief表明了是否为chief supervisors角色。这里将task_index=0的worker设置成chief supervisors。
Logdir为检查点文件和summary文件保存的路径。
init_op表示使用初始化变量的函数。
saver需要将保存检查点的saver对象传入,Supervisor就会自动保存检查点文件。如果不想自动保存,可以设为None。
同理,summary_op也是自动保存summary文件。这里设为None,表示不自动保存。
save_model_secs为保存检查点文件的时间间隔。这里设为5,表示每5秒自动保存一次检查点文件。
Session中的内容与以前一样,直接迭代训练即可。由于使用了Supervisor管理session,将使用sv.summary_computed函数来保存summary文件。同样,如想要手动保存检测点文件,也可以使用sv.saver.save。代码如下:

6.建立worker文件
将文件复制2份,分别起名为“4-16 worker.py”与“4-17 worker2.py”,将角色名称修改成worker,并将“4-16 worker2.py”中的task_index设为1。

7.部署运行
(1)在Spyder中先将“4-15ps.py”运行起来,单击菜单“Consoles/Open an IPython console”来新打开一个consoles,如图4-7所示。
图4-8 consoles框
(3)运行“4-17worker2.py”文件。最后按照“4-17worker2.py”启动的方式,再将“4-16worker.py”启动,这时3个窗口显示内容分别如下:

可以看到循环的次数并不是连续的,跳过的步骤被分配到worker2中去运算了。
分析可能是与Supervisor中的同步算法有关。
分布运算目的是为了提高整体运算速度,如果同步epoch的准确度需要以牺牲总体运算速度为代价,自然很不合适。所以更合理的推断是因为单机单次的运算太快迫使算法使用了更宽松的同步机制。
重要的一点是对于指定步数的学习参数b和w是一致的(比如第8040步,学习参数是相同的,都为W= [ 2.01313496] b= [ 0.01954099]),这表明两个终端是在相同的起点上进行运算的。
在大型的数据集上进行神经网络的训练,往往需要更大的运算资源,而且还要花上若干天才能完成运算量。
TensorFlow提供了一个可以分布部署的模式,将一个训练任务拆成多个小任务,分配到不同的计算机上来完成协同运算,这样使用计算机群运算来代替单机计算,可以时训练时间大大变短。
4.5.1 分布式TensorFlow的角色及原理
要想配置TensorFlow为分布训练,需要先了解TensorFlow中关于分布式的角色分配。
● ps:作为分布式训练的服务端,等待各个终端(supervisors)来连接;
● worker:在TensorFlow的代码注释中被称作supervisors,作为分布式训练的运算终端;
● chief supervisors:在众多运算终端中必须选择一个作为主要的运算终端。该终端是在运算终端中最先启动的,它的功能是合并各个终端运算后的学习参数,将其保存或载入。
每个具体的角色的网络标识都是唯一的,即,分布在不同IP的机器上(或者同一个机器,但是不同端口)。
在实际运行中,各个角色的网络构建部分代码必须100%的相同。三者的分工如下:
● 服务端作为一个多方协调者,等待各个运算终端来连接;
● chief supervisors会在启动时统一管理全局的学习参数,进行初始化或从模型载入。
● 其他的运算终端只是负责得到其对应的任务并进行计算,并不会保存检查点,用于TensorBoard可视化中的summary日志等任何参数信息。
整个过程都是通过RPC协议来通信的。
4.5.2 分布部署TensorFlow的具体方法
配置过程中,首先需要建一个server,在server中会将ps及所有worker的IP端口准备好。接着,使用tf.train.Supervisor中的managed_session来管理一个打开的session。Session中只是负责运算,而通信协调的事情就都交给Supervisor来管理了。
4.5.3 实例20:使用TensorFlow实现分布式部署训练
下面就开始实现一个分布式训练的网络模型。本例以“4-8线性回归的TensorBoard可视化.py”为原型,在其中添加代码将其改成分布式。
案例描述
在本机通过3个端口来建立3个终端,分别为一个ps,两个worker,实现TensorFlow的分布式运算。
具体步骤如下:
1.为每个角色添加IP地址和端口,创建server
在一台机器上开3个不同的端口,分别代表ps、chief supervisors 、worker。角色的名称用strjob_name表示。以ps为例,代码如下:
代码4-15 ps
2. 为ps角色添加等待函数
ps角色使用server.join()函数进行线程挂起,开始接收连接消息。
代码4-15 ps(续)
与正常的程序不同,在创建网络结构时,使用tf.device函数将全部的节点都放在当前任务下。
在tf.device中的任务是通过tf.train.replica_device_setter来指定的。
在tf.train.replica_device_setter中使用worker_device来定义具体任务名称;使用cluster的配置来指定角色及对应的IP地址,从而实现管理整个任务下的图节点。
代码4-15 ps(续)
在tf.train.Supervisor中,is_chief表明了是否为chief supervisors角色。这里将task_index=0的worker设置成chief supervisors。
Logdir为检查点文件和summary文件保存的路径。
init_op表示使用初始化变量的函数。
saver需要将保存检查点的saver对象传入,Supervisor就会自动保存检查点文件。如果不想自动保存,可以设为None。
同理,summary_op也是自动保存summary文件。这里设为None,表示不自动保存。
save_model_secs为保存检查点文件的时间间隔。这里设为5,表示每5秒自动保存一次检查点文件。
代码4-15 ps(续)
如上代码,为了让分布运算的效果明显一些,将迭代次数改成了2200,使其运算时间变长。
5.迭代训练Session中的内容与以前一样,直接迭代训练即可。由于使用了Supervisor管理session,将使用sv.summary_computed函数来保存summary文件。同样,如想要手动保存检测点文件,也可以使用sv.saver.save。代码如下:
代码4-15 ps(续)
6.建立worker文件
将文件复制2份,分别起名为“4-16 worker.py”与“4-17 worker2.py”,将角色名称修改成worker,并将“4-16 worker2.py”中的task_index设为1。
代码4-16 worker
代码4-17 worker2
7.部署运行
(1)在Spyder中先将“4-15ps.py”运行起来,单击菜单“Consoles/Open an IPython console”来新打开一个consoles,如图4-7所示。
图4-7 consoles菜单
(2)在面板的右下角出现一个consoles框(consoles2/A),单点击新建的consoles窗口,确保为**状态,如图4-8所示。(3)运行“4-17worker2.py”文件。最后按照“4-17worker2.py”启动的方式,再将“4-16worker.py”启动,这时3个窗口显示内容分别如下:
“4-16worker.py”对应窗口会显示正常的训练信息。
可以看到循环的次数并不是连续的,跳过的步骤被分配到worker2中去运算了。
● “4-17worker2.py”窗口显示的信息。
显示结果中有警告输出,这是因为在构建Supervisor时没有填写local_init_op参数,该参数的意思是在创建worker实例时,初始化本地变量。由于例子中没有填,系统就会自动初始化,并给个警告提示。
从日志中可以看到worker2 与chief supervisors的迭代序号近似互补,为什么没有绝对互补呢?分析可能是与Supervisor中的同步算法有关。
分布运算目的是为了提高整体运算速度,如果同步epoch的准确度需要以牺牲总体运算速度为代价,自然很不合适。所以更合理的推断是因为单机单次的运算太快迫使算法使用了更宽松的同步机制。
重要的一点是对于指定步数的学习参数b和w是一致的(比如第8040步,学习参数是相同的,都为W= [ 2.01313496] b= [ 0.01954099]),这表明两个终端是在相同的起点上进行运算的。
● 对于“4-15ps.py”窗口则是一直静默着只显示打印的那句wait,因为它只负责连接不参与运算。
更多章节请购买《深入学习之 TensorFlow 入门、原理与进阶实战》全本