本文档介绍如何创建TensorFlow服务器集群,以及如何在该集群中分发计算图。我们假设您熟悉编写TensorFlow程序的基本概念。
开始
要查看一个简单的TensorFlow集群,请执行以下操作:
# Start a TensorFlow server as a single-process "cluster".
$ python
>>> import tensorflow as tf
>>> c = tf.constant("Hello, distributed TensorFlow!")
>>> server = tf.train.Server.create_local_server()
>>> sess = tf.Session(server.target) # Create a session on the server.
>>> sess.run(c)
'Hello, distributed TensorFlow!'
该tf.train.Server.create_local_server
方法创建具有进程内服务器的单进程集群。
创建一个集群
<iframe width="412" height="232" src="https://www.youtube.com/embed/la_M6bCV91M?ecver=1" frameborder="0" allowfullscreen></iframe>
TensorFlow“集群”是参与TensorFlow图形的分布式执行的一组“任务”。每个任务与TensorFlow“服务器”相关联,该服务器包含可用于创建会话的“主”,以及在图中执行操作的“工作者”。群集还可以分为一个或多个“作业”,其中每个作业包含一个或多个任务。
要创建集群,请在集群中为每个任务启动一个TensorFlow服务器。每个任务通常在不同的机器上运行,但您可以在同一台机器上运行多个任务(例如控制不同的GPU设备)。在每个任务中,执行以下操作:
-
创建一个
tf.train.ClusterSpec
描述集群中所有任务的内容。这对每个任务应该是一样的。 -
创建一个
tf.train.Server
,传递tf.train.ClusterSpec
给构造函数,并使用作业名和任务索引识别本地任务。
创建一个tf.train.ClusterSpec
描述集群
群集规范字典将作业名称映射到网络地址列表。将此字典传递给tf.train.ClusterSpec
构造函数。例如:
|
Available tasks |
---|---|
tf.train.ClusterSpec({"local": ["localhost:2222", "localhost:2223"]}) |
/job:local/task:0 |
tf.train.ClusterSpec({ "worker": [ "worker0.example.com:2222", "worker1.example.com:2222", "worker2.example.com:2222" ], "ps": [ "ps0.example.com:2222", "ps1.example.com:2222" ]}) |
/job:worker/task:0 /job:worker/task:1 /job:worker/task:2 /job:ps/task:0 /job:ps/task:1 |
tf.train.Server
在每个任务中创建一个实例
一个tf.train.Server
对象包含了一组本地设备,一组到其他任务的连接 tf.train.ClusterSpec
,并且 tf.Session
能够使用这些来进行分布式计算。每个服务器是特定命名作业的成员,并且在该作业中具有任务索引。服务器可以与群集中的任何其他服务器进行通信。
例如,推出了集群两台服务器上运行localhost:2222
,并localhost:2223
在本地机器上的两个不同的进程运行下面的代码片段:
|
注意:手动指定这些集群规范可能很乏味,特别是对于大型集群。我们正在开发以编程方式启动任务的工具,例如使用像Kubernetes这样的集群管理器 。如果您想要查看支持的特定集群管理器,请提出一个 GitHub问题。
在模型中指定分布式设备
要对特定进程进行操作,您可以使用与tf.device
用于指定运行在CPU或GPU上的操作相同的 功能。例如:
|
在上述示例中,在作业中的两个任务上创建变量ps
,并且在作业中创建模型的计算密集型部分worker
。TensorFlow将插入作业之间的适当的数据传输(从ps
到worker
用于直传,以及从worker
到ps
用于施加梯度)。
复印训练
一种称为“数据并行性”的常见培训配置涉及到worker
在不同小批量数据上对同一模型进行职业培训的多个任务,更新托管在ps
作业中的一个或多个任务中的共享参数。所有任务通常在不同的机器上运行。有很多方法可以在TensorFlow中指定此结构,并且我们正在构建库,以简化指定复制模型的工作。可能的方法包括:
-
图形内复制。在这种方法中,客户端构建一个
tf.Graph
包含一组参数(在tf.Variable
固定到节点中/job:ps
)的参数; 和模型的计算密集型部分的多个副本,每个副本都固定在不同的任务中/job:worker
。 -
图形间复制。在这种方法中,每个
/job:worker
任务都有一个单独的客户端,通常与worker任务相同。每个客户端构建一个包含参数的类似图(固定为/job:ps
使用前tf.train.replica_device_setter
将其确定性地映射到相同的任务); 和模型的计算密集型部分的单个副本,固定到本地任务/job:worker
。 -
异步训练 在这种方法中,图的每个副本都有一个独立的训练循环,无需协调地执行。它与上述两种复制形式兼容。
-
同步训练 在这种方法中,所有的副本都会读取当前参数的相同值,并行计算梯度,然后将它们应用在一起。它与图形内复制(例如使用CIFAR-10多GPU培训师中的梯度平均 )和图形间复制(例如使用
tf.train.SyncReplicasOptimizer
)兼容 。
把它们放在一起:示例教练程序
以下代码显示了分布式教练程序的框架,实现了图形间复制和异步训练。它包括参数服务器和工作任务的代码。
|
要启动具有两个参数服务器和两个工作人员的培训师,请使用以下命令行(假设调用脚本trainer.py
):
|
词汇表
Client
客户端通常是一个构建TensorFlow图并构建一个 tensorflow::Session
与集群进行交互的程序。客户端通常用Python或C ++编写。单个客户端进程可以直接与多个TensorFlow服务器进行交互(请参见上面的“复制培训”),单个服务器可以为多个客户端提供服务。
Cluster
TensorFlow集群包括一个或多个“作业”,每个“作业”分为一个或多个“任务”的列表。集群通常专用于特定的高级目标,例如训练神经网络,并行使用许多机器。集群由tf.train.ClusterSpec
对象定义。
Job
一份工作包括一份通常用于共同目的的“任务”清单。例如,名为ps
(对于“参数服务器”)的作业通常会托管存储和更新变量的节点; 而名为“ worker
job” 的作业通常会承载执行计算密集型任务的无状态节点。作业中的任务通常在不同的机器上运行。一组工作角色是灵活的:例如,a worker
可能会保持一些状态。
Master service
提供远程访问一组分布式设备并充当会话目标的RPC服务。主服务实现 tensorflow::Session
接口,负责协调一个或多个“工作服务”的工作。所有TensorFlow服务器都实现主服务。
Task
任务对应于特定的TensorFlow服务器,通常对应于单个进程。任务属于特定的“作业”,并由该作业的任务列表中的索引识别。
TensorFlow服务器运行tf.train.Server
实例的进程,该实例是集群的成员,并导出“主服务”和“工作服务”。
Worker service
使用本地设备执行TensorFlow图形的一部分的RPC服务。worker服务实现了worker_service.proto。所有TensorFlow服务器都实现了工作服务。