TensorFlow的节点分配
- 一个硬件设备时,计算图会按依赖关系被顺序执行。
一个节点的所有上游依赖都被执行完时(依赖数为0),此节点加入ready queue,同时下游节点依赖数减1。 - 多个设备时:
(1)每一个节点该让什么硬件设备执行
(2)如何管理节点间的数据通信
问题一,TensorFlow设计了一套节点分配设备的策略(贪婪策略,不能确保找到最优解)。
首先,策略需要计算一个代价模型,估算每一个节点的输入、输出tensor的大小,以及所需时间。代价模型一部分由人工经验制定的启发式规则得到,另一部分则由对一小部分数据进行实际运算而测量得到。
接下来,分配策略会模拟执行整个计算图:
首先,从起点开始,按拓扑序执行。在模拟执行一个节点时,把每一个能执行这个节点的设备都测试一遍,测试会考虑到:
1、 代价模型对这个节点的计算时间的估算
2、数据传到这个设备所需要的通信时间
3、1的时间加上2的时间,选择一个综合时间最短的设备作为运算该节点的设备
除了时间,也会考虑内存的最高使用峰值。
节点分配策略仍在不断研发、优化,将来可能会使用一个强化学习(reinforcement learning)的神经网络来辅助策略。
此外,允许用户对节点的分配设置限制条件。TensorFlow会使用并查集(union-find)算法找到必须使用同一个设备的节点。
此时,问题一即节点分配设备的方案被确定后,这个计算图就会被划分为许多子图,使用同一个设备并且相邻的节点 会被划分到同一个子图。
计算图中,从x到y的边,会被取代为一个发送端的发送节点(send node)、一个接收端的接收节点(receive node)以及从发送节点到接收节点的边。
数据通信问题就转变为发送节点和接收节点的实现问题,用户不需要为不同的硬件环境实现通信方法。
同时,两个子图之间可能会有多个接收点,如果这些接收节点接收的都是同一个tensor,那么所有这些接收节点会被自动合并为一个,避免数据反复传输或重复占用设备内存。
- 总结:
TensorFlow的通信机制很优秀,发送节点和接收节点的设计简化了底层的通信模式,用户无须设计节点之间的通信流程,可以让同一套代码,自动扩展到不同硬件环境并处理复杂的通信流程。
- (分布式)TensorFlow的容错
故障会在两种情况下检测出来:
(1)信息从发送节点传输到接收节点失败时
(2)周期性的worker心跳检测失败
当一个故障被检测到,这个计算图会终止并重启。其中Variable node可以被持久化,TensorFlow支持检查点(check point)的保存和恢复,每一个Variable node都连接一个Save node 和一个Restore node,每隔几次迭代就会保存一次数据到持久化的储存系统,每次重启时会调用Restore node恢复数据。所以发生故障重启后,模型参数得以保留,训练将从上一次checkpoint恢复而不需要完全从头再来。