分布式集群
本目录包括了运行时分布式
Quick start
首先,需要构建一个grpc_tensorflow_server
# CPU-only build.
$ bazel build -c opt //tensorflow/core/distributed_runtime/rpc:grpc_tensorflow_server
# GPU build.
$ bazel build -c opt --config=cuda //tensorflow/core/distributed_runtime/rpc:grpc_tensorflow_server
如果是从最新的源代码创建的
# Start a TensorFlow server as a single-process "cluster".
$ bazel-bin/tensorflow/core/distributed_runtime/rpc/grpc_tensorflow_server \
--cluster_spec='local|localhost:2222' --job_name=local --task_index=0 &
然后启动
$ python
>>> import tensorflow as tf
>>> c = tf.constant("Hello, distributed TensorFlow!")
>>> sess = tf.Session("grpc://localhost:2222")
>>> sess.run(c)
'Hello, distributed TensorFlow!'
集群定义
命令行参数 grpc_tensorflow_server
定义了集群之间的关系--cluster_spec
决定了集群中工作对象的多少--cluster_spec
参数,例子如下
--cluster_spec='...' |
Available tasks |
---|---|
local|localhost:2222 |
/job:local/task:0 |
local|localhost:2222;localhost:2223 |
/job:local/task:0``/job:local/task:1 |
worker|worker0:2222;worker1:2222;worker2:2222,``ps|ps0:2222;ps1:2222 |
/job:worker/task:0``/job:worker/task:1``/job:worker/task:2``/job:ps/task:0``/job:ps/task:1 |
还有 --job_name
与 --task_index
标志位指明了哪些任务会运行在当前处理过程上。具体而言--job_name=local --task_index=0
意思就是该过程会被标志为
/job:local/task:0
N.B. 手动来指明这些运行参数可能是非常冗长的,特别是对一个大型集群而言。我们正在研发可以程式化启动的工具,譬如使用一些类似于Kubernetes集群管理器。如果有啥集群管理工具你觉得挺好的希望加入进来,可以在GitHub issue上提出你的建议。
标注模型中的分布式设备
为了将某个操作放在某个特殊的处理过程上tf.device()
函数,之前是用来指明是放在
with tf.device("/job:ps/task:0"):
weights_1 = tf.Variable(...)
biases_1 = tf.Variable(...)
with tf.device("/job:ps/task:1"):
weights_2 = tf.Variable(...)
biases_2 = tf.Variable(...)
with tf.device("/job:worker/task:7"):
input, labels = ...
layer_1 = tf.nn.relu(tf.matmul(input, weights_1) + biases_1)
logits = tf.nn.relu(tf.matmul(layer_1, weights_2) + biases_2)
# ...
train_op = ...
with tf.Session("grpc://worker7:2222") as sess:
for _ in range(10000):
sess.run(train_op)
在上面的例子中,ps
的两个work
上。job
到work
是前向传递,而从worker
到ps
是梯度应用
Replicated Computation
一个常见的训练配置ps
上共享参数以及work
上的多个任务来训练相同的模型。每个
-
构建单一的包含了一系列参数的图
(in tf.Variable
nodes pinned to /job:ps
), 并且创建多个模型的副本来映射到/job:worker
中的不同tasks 。每个model 的副本有一个不同的train_op
,并且对于每个worker i
而言一个或者多个的客户端线程可以调用sess.run(train_ops[i])
。这种方法使用了单一的tf.Session
,它的工作目标是集群中的某个workers 。 -
As above, but where the gradients from all workers are averaged. See the CIFAR-10 multi-GPU trainer for an example of this form of replication. The implements synchronous training
-
另一种分布式训练器的方法使用多张图,一张图对应一个
worker ,并且每张图都包含了一系列的参数的集合( /job:ps
) 和一份模型的赋值。而容器的机制就是在不同的图之间共享变量:一旦某个变量构造完成,可选的container
参数会由图中每份复制的相同值来决定。对于较大的模型而言,这种方法会更加有效,毕竟整个图更小了一点。 这种方法使用多个tf.Session
对象:每个worker 过程都会包含一个,不过不同的Session 会指向不同的目标worker 。这个tf.Session
对象即可以在单一的Python 客户端中创建,也可以在多个客户端中创建。
术语
Client
一个典型的客户端一般会构建一个tensorflow::Session
来完成与集群的交互。客户端一般会用
Cluster
一个
Job
一个ps
worker
的
Master service
tensorflow::Session
接口
Task
一个
TensorFlow server
用于运行
Worker service
一个执行部分