2017-09-26 4 views
2

以下の単純なスクリプトは、そのヘッダーにargsを付けて起動します。それは異なった動作をしますが、しばしば作業者の1人がハングし、これらの "CreateSessionはまだ他のタスクを待っています"というメッセージを表示します。なぜ新しいMonitoredTrainingSessionは他のものを必要としますか?そして、他の人たちはなぜそれが始まるのを待たないのですか?分散Tensorflow:CreateSessionはまだ待機しています

# #!/bin/bash 
# python train.py --job master --task 0 & 
# python train.py --job worker --task 0 & 
# python train.py --job worker --task 1 & 
# python train.py --job worker --task 2 & 
import argparse 
import tensorflow as tf 

parser = argparse.ArgumentParser() 
parser.add_argument('--job', type=str) 
parser.add_argument('--task', type=int) 
args = parser.parse_args() 
hosts = { 
    "master": [ 
     "localhost:2222", 
    ], 
    "worker": [ 
     "localhost:2223", 
     "localhost:2224", 
     "localhost:2225", 
    ] 
} 

nworkers = len(hosts['worker']) 
cluster = tf.train.ClusterSpec(hosts) 
server = tf.train.Server(cluster, job_name=args.job, task_index=args.task) 

with tf.device(f'/job:master/task:0'): 
    global_step = tf.train.get_or_create_global_step() 
    inc_global_step = tf.assign(global_step, global_step + 1) 

if args.job == 'worker': 
    hooks = [ 
     tf.train.StopAtStepHook(last_step=4), 
    ] 
    with tf.train.MonitoredTrainingSession(master=server.target, 
              is_chief=(args.task == 0), 
              hooks=hooks) as sess: 
     while not sess.should_stop(): 
      print(args.task, sess.run(inc_global_step)) 
else: 
    server.join() 

これは変数を初期化するまで待つことができます。しかし、それは別の非主任労働者も待っている。 MonitoredTrainingSessionはタスクを同期させますか?そうでない場合、FIFOQueuesは手動同期を行う唯一のプリミティブですか?

答えて

0

デフォルトでは、分散型TensorFlowセッションはのすべてのサーバーtf.train.ClusterSpec)に接続しようとし、応答するまでブロックします。これは、すべての作業者が計算要求を受け取る準備ができてからユーザーに制御を戻せるようにする有用な障壁となります。この障壁は、チーフが変数を初期化するのを待つコードの前に発生します(MonitoredTrainingSession)。

セッションがすべてのサーバー上で待機しないようにする場合(たとえば、"/job:ps"のタスクを待ち、"/job:worker"の他のタスクは、グラフ間の一般的な展開方法です)、最も簡単な方法は、セッションを作成するときには「デバイスフィルタ」を使用します。デバイスフィルタは、起動時にtf.Sessionがどのタスクに連絡するかを決定する(部分的な)デバイス仕様のホワイトリストです。たとえば、mnist_replica.pyのテストspecifiesは、セッションを構成するために使用されるtf.ConfigProtoの一部としてのデバイスフィルタです。

+0

チーフは、タスク2がまだセッションを開始していないのに、サーバーがすでに実行中であっても、タスク0,1,2の変数を初期化します。本当ですか? – Leonid

+0

変数は、 'tf.device():'ブロックによって配置された場所であればどこでも初期化されます。例えば、あなたのコードでは 'global_step'は'/job:master/task:0 ''に作成され、他のタスクは変数を持たないでしょう。 'tf.train.MonitoredTrainingSession'が始まると、' is_chief'が 'True'であるタスク(' '/ job:worker/task:0:' ')が初期化を実行するステップを実行します。この初期化ステップは、すべてのサーバーがpingに応答するまでブロックされます(セッションを開始する必要はありません)。その後、他のすべてのワーカーは、初期化ステップが完了するまでブロックします。 – mrry

関連する問題