J'ai écrit un code de test simple pour tester tf.control_dependencies()
entre deux machines. Je pense que le code doit toujours retourner le même résultat, mais le résultat n'est pas cohérent.
Code
Il y a deux hôtes et chacun a sa propre variable. L'un d'entre eux met à jour sa variable via SGD, et lorsque cela se termine, l'autre hôte copie la variable résultante dans sa propre variable.
### 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]))
J'exécute ce code en tapant python test.py --task_id=0
sur l'hôte 0 (10.0.0.1) et python test.py --task_id=1
sur l'hôte 1 (10.0.0.2).
J'attends [0.4, 0.4]
à imprimer, car var1
est mis à jour via apply_op
et le résultat var1
est copié dans var0
de sorte que les deux var0
y var1
ont des valeurs actualisées. Cependant, le résultat est un [0.0, 0.4]
o [0.4, 0.0]
o [0.4, 0.4]
et il change à chaque fois que j'exécute le code. Pourquoi cela se produit-il ?
Caractéristiques importantes
Si j'utilise '/task:0/device:CPU:0'
pour les deux variables, le résultat est toujours [0.4, 0.4]
comme je m'y attendais, ce qui peut indiquer que le problème provient de la communication entre les machines.
De même, si j'utilise '/task:1/device:CPU:0'
pour les deux variables, le résultat est l'un des suivants [0.4, 0]
o [0.4, 0.4]
.
Informations sur le système (pour les deux machines)
Linux Ubuntu 16.04.1, CUDA 8.0,
TensorFlow r1.1, version GPU, installé à partir des sources
(commit 1ec6ed51182adf8f1b03a3188c16cd8a45ca6c85)