在2个分布式tensorflow进程之间共享数组列表或变量
我目前正在研究分布式tensorflow,考虑两个工作进程,并面临在这两个工作进程之间共享变量的问题。 我找到了tf.get_collection/tf.add_collection,但仍然无法获取两个进程之间共享的变量值 添加有关如何在分布式Tensorflow中的工作进程之间共享数据的一些详细信息:在2个分布式tensorflow进程之间共享数组列表或变量,tensorflow,distributed,data-sharing,Tensorflow,Distributed,Data Sharing,我目前正在研究分布式tensorflow,考虑两个工作进程,并面临在这两个工作进程之间共享变量的问题。 我找到了tf.get_collection/tf.add_collection,但仍然无法获取两个进程之间共享的变量值 添加有关如何在分布式Tensorflow中的工作进程之间共享数据的一些详细信息: def create_variable(layer_shape): with tf.variable_scope("share_lay"): la
def create_variable(layer_shape):
with tf.variable_scope("share_lay"):
layers = tf.get_variable("layers", shape=layer_shape, trainable=True)
with tf.variable_scope("share_lay", reuse=tf.AUTO_REUSE):
layers = tf.get_variable("layers", shape=layer_shape, trainable=True)
return layers
def set_layer(layers):
tf.add_to_collection("layers", layers)
def get_layer(name):
return tf.get_collection(name)[0]
taskid == 0:
layers = create_variable(layer_shape)
layers = <some value>
set_layer(layers)
taskid == 1:
layers = create_variable(layer_shape)
layers = get_layer("layers")
工作人员之间似乎无法共享数据
就同样的问题征求一些建议欢迎提出任何建议/建议 谢谢,
Kapil我最终解决了同样的问题,使用tf.train.replica\u device\u setter()将变量放置在参数服务器上,并将它们添加到集合中。稍后,我可以在任何worker中使用它来返回该集合,它实际上是一个python列表。请注意,tf.get_collection只返回原始集合的副本。如果要更改原始集合中的变量,应使用实际返回集合列表本身的 以下是一个例子:
import tensorflow as tf
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string('job_name', '',
"""One of 'ps', 'worker' """)
tf.app.flags.DEFINE_integer('task_index', 0,
"""Index of task within the job""")
cluster = tf.train.ClusterSpec(
{'ps': ['localhost:22222'],
'worker': ['localhost:22223', 'localhost:22227']})
config = tf.ConfigProto(
intra_op_parallelism_threads=1,
inter_op_parallelism_threads=1)
if FLAGS.job_name == 'ps':
server = tf.train.Server(cluster, job_name='ps', task_index=FLAGS.task_index, config=config)
server.join()
else:
server = tf.train.Server(cluster, job_name='worker', task_index=FLAGS.task_index, config=config)
with tf.device(tf.train.replica_device_setter(cluster=cluster)):
#create a colletion 'shared_list' and add two variables to the collection 'shared_list'
#note that these two variables are placed on parameter server
a = tf.Variable(name='a', initial_value=tf.constant(1.0),
collections=[tf.GraphKeys.GLOBAL_VARIABLES, 'shared_list'])
b = tf.Variable(name='b', initial_value=tf.constant(2.0),
collections=[tf.GraphKeys.GLOBAL_VARIABLES, 'shared_list'])
#now let's print out the value of a+2.0 and b+2.0 using the collection 'shared_list' from different worker
#note that tf.get_collection will return a copy of exiting collection which is actually a python list
with tf.device('/job:worker/task:%d' %FLAGS.task_index):
c = tf.get_collection('shared_list')[0] + 2.0 # a+2.0
d = tf.get_collection('shared_list')[1] + 2.0 # b+2.0
with tf.train.MonitoredTrainingSession(master=server.target,
is_chief=(FLAGS.task_index==0),
config=config) as sess:
print('this is worker %d' % FLAGS.task_index)
print(c.eval(session=sess))
print(d.eval(session=sess))
server.join()
工作进程0将打印:
this is worker 0
3.0
4.0
this is worker 1
3.0
4.0
worker 1将打印出:
this is worker 0
3.0
4.0
this is worker 1
3.0
4.0
编辑:工作0将变量“a”修改为10,然后工作1打印出新的“a”值,该值立即变为10。实际上,变量“a”对辅助进程0和辅助进程1都可用,因为它们处于分布式设置中。下面是一个例子。关于如何在分布式tensorflow中共享变量,请参阅Matthew Rahtz的博客。实际上,我们不需要任何参数服务器来共享变量。任何两个工作进程都可以彼此共享相同的变量,只要这两个工作进程创建两个名称完全相同的变量
这是一个例子
import tensorflow as tf
from time import sleep
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string('job_name', '',
"""One of 'ps', 'worker' """)
tf.app.flags.DEFINE_integer('task_index', 0,
"""Index of task within the job""")
cluster = tf.train.ClusterSpec(
{'ps': ['localhost:22222'],
'worker': ['localhost:22223', 'localhost:22227']})
if FLAGS.job_name == 'ps':
server = tf.train.Server(cluster, job_name='ps', task_index=FLAGS.task_index)
server.join()
else:
server = tf.train.Server(cluster, job_name='worker', task_index=FLAGS.task_index)
with tf.device(tf.train.replica_device_setter(cluster=cluster)):
# create a colletion 'shared_list' and add two variables to the collection 'shared_list'
# note that these two variables are placed on parameter server
a = tf.Variable(name='a', initial_value=tf.constant(1.0),
collections=[tf.GraphKeys.GLOBAL_VARIABLES, 'shared_list'])
b = tf.Variable(name='b', initial_value=tf.constant(2.0),
collections=[tf.GraphKeys.GLOBAL_VARIABLES, 'shared_list'])
# change the value of 'a' in worker 0
if FLAGS.task_index == 0:
change_a = a.assign(10)
# print out the new value of a in worker 1 using get_collction. Note that we may need to
# use read_value() method to force the op to read the current value of a
if FLAGS.task_index == 1:
with tf.device('/job:worker/task:1'): # place read_a to worker 1
read_a = tf.get_collection('shared_list')[0].read_value() # a = 10
with tf.train.MonitoredTrainingSession(master=server.target,
is_chief=(FLAGS.task_index == 0))as sess:
if FLAGS.task_index == 0:
sess.run(change_a)
if FLAGS.task_index == 1:
sleep(1) # sleep a little bit to wait until change_a has been executed
print(read_a.eval(session=sess))
server.join()
工人1打印出
10
我也有同样的问题。也许我们需要使用MPI。我目前正在探索使用mpi4py在进程之间执行发送和接收的MPI,但遇到Pickle.dump问题,mpi4py使用基于pickle的通用Python对象通信,但当尝试发送大缓冲区时,它会导致错误:无法pickle本地对象感谢Roochao Wang的响应,我对上述实现没有什么评论:1。如果您遍历副本设置器代码段,那么完整的代码将由两个工作人员执行,他们执行的是相同的操作,因此是预期的输出。2.我想要的是worker 0修改变量,比如说“C”,修改后的“C”值在worker 1访问tf.get_集合(key)时对其可用,就像我在前面的问题中所显示的那样,只要worker创建具有相同名称的变量并将变量放置到相同的设备上,然后这些变量在创建它们的工人之间共享。这意味着如果工作进程0和工作进程1都创建名为“a”的变量,并将其放置到任务0中。然后,在辅助进程0和辅助进程1之间共享变量“a”。当工作进程0对“a”执行某些操作时,工作进程1将立即知道。王洛超,感谢您的回答,我有一个问题,为了更好地理解,Tensorflow在两个进程之间使用的共享机制是什么,是MMAP、MPI共享内存、CUDA统一内存等。