分布式TensorFlow中control_dependencies的不一致性

时间:2017-05-10 15:11:11

标签: tensorflow

我写了一个简单的测试代码来测试两台机器之间的tf.control_dependencies()。我认为代码总是必须返回相同的结果,但结果并不一致。

代码

有两个主机,每个主机都有自己的变量。其中一个通过SGD更新其变量,当它结束时,另一个主机将结果变量复制到它自己的变量。

### test.py ###
import tensorflow as tf

tf.app.flags.DEFINE_integer('task_id', 0, 'Unique task ID. One of 0 or 1.')
FLAGS = tf.app.flags.FLAGS

cluster = tf.train.ClusterSpec({'hosts': ['10.0.0.1:7001', '10.0.0.2:7001']})
server = tf.train.Server(cluster, task_index=FLAGS.task_id, protocol='grpc')

# Host 1 is passive
if FLAGS.task_id == 1:
    server.join()

# Host 0 builds the operation graph

opt = tf.train.GradientDescentOptimizer(0.1)
with tf.device('/task:1/device:CPU:0'):
    # Task 1 optimizes its own variable
    var1 = tf.Variable(0, dtype=tf.float32)
    apply_op = opt.minimize(tf.square(var1 - 2.))

with tf.device('/task:0/device:CPU:0'):
    # Task 0 copies the optimized result to its own variable
    var0 = tf.Variable(0, dtype=tf.float32)
    with tf.control_dependencies([apply_op]):
        new_var0 = tf.assign(var0, var1)

sess = tf.Session(target=server.target)
# initialize variables
sess.run(tf.global_variables_initializer())
# expected: [0.4, 0.4]
print(sess.run([new_var0, var1]))

我通过在主机0(10.0.0.1)上键入python test.py --task_id=0和在主机1(10.0.0.2)上键入python test.py --task_id=1来执行此代码。

我希望打印[0.4, 0.4],因为var1已通过apply_op更新,结果var1会复制到var0,因此var0 {1}}和var1已更新值。但是,结果是[0.0, 0.4][0.4, 0.0][0.4, 0.4]之一,每次执行代码时都会更改。为什么会这样?

重要功能

如果我对两个变量都使用'/task:0/device:CPU:0',结果总是[0.4, 0.4],这可能表明问题来自机器之间的通信。

此外,如果我对这两个变量使用'/task:1/device:CPU:0',则结果为[0.4, 0][0.4, 0.4]之一。

系统信息(适用于两台机器)

Linux Ubuntu 16.04.1,CUDA 8.0,

TensorFlow r1.1,GPU版本,从源

安装

(commit 1ec6ed51182adf8f1b03a3188c16cd8a45ca6c85)

1 个答案:

答案 0 :(得分:1)

我怀疑你的问题是tf.Variable获取变量的缓存快照。这是一种优化,可以最大限度地减少分布式培训中的转移,但可能会产生一些令人惊讶的影响。

尝试使用tf.Variable.read_value()抓取最新副本。

请参阅value()read_value()的文档: https://www.tensorflow.org/api_docs/python/tf/Variable#value https://www.tensorflow.org/api_docs/python/tf/Variable#read_value

希望有所帮助!