2017-09-26 16 views
2

Le script simple ci-dessous est lancé avec les arguments affichés dans son en-tête. Il se comporte différemment, mais souvent l'un des travailleurs se bloque et imprime ces messages «CreateSession toujours en attente d'une autre tâche». Pourquoi une nouvelle session MonitoredTrainingSession en at-elle besoin? Et pourquoi les autres ne l'attendent-ils pas?Tensorflow distribué: CreateSession toujours en attente

# #!/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() 

Il pourrait attendre que le chef commence ses variables. Mais il arrive aussi d'attendre un autre travailleur non chef. Donc, MonitoredTrainingSession synchronise-t-il les tâches? Si ce n'est pas le cas, FIFOQueues est-elle la seule primitive à effectuer une synchronisation manuelle?

Répondre

0

Par défaut, une session distribuée TensorFlow tentera de se connecter à tous les serveurs nommés dans le tf.train.ClusterSpec et bloquera jusqu'à ce qu'ils répondent. Cela constitue une barrière utile qui garantit que tous les travailleurs sont prêts à recevoir des demandes de calcul avant de retourner le contrôle à l'utilisateur. Cette barrière se produit avant le code MonitoredTrainingSession qui attend que le chef initialise les variables. Si vous ne voulez pas que votre session soit en attente sur tous les serveurs (par exemple, attendez les tâches au "/job:ps" et non les autres tâches dans "/job:worker", qui est une stratégie de déploiement commune entre les graphiques), l'option la plus simple est de spécifier un "filtre de périphérique" lorsque vous créez votre session. Le filtre de périphérique est une liste blanche des spécifications de périphériques (partielles) qui détermine les tâches qu'un tf.Session contactera au démarrage. Par exemple, le mnist_replica.py test specifies un filtre de périphérique dans le cadre du tf.ConfigProto qui est utilisé pour configurer la session.

+0

Le chef initialise les variables sur les tâches 0, 1, 2 même si la tâche 2 n'a pas encore lancé de session, mais que le serveur est déjà en cours d'exécution. Est-ce vrai? – Leonid

+0

Les variables seront initialisées partout où elles sont placées par un bloc 'avec tf.device():'. Par exemple, dans votre code, 'global_step' sera créé sur' "/ job: master/task: 0" ', et aucune autre tâche n'aura de variables. Lorsque le 'tf.train.MonitoredTrainingSession' commence, la tâche pour laquelle' is_chief' est 'True' (c'est-à-dire' '/": job/task: 0 "') lancera une étape pour effectuer l'initialisation. Cette étape d'initialisation bloquera jusqu'à ce que tous les serveurs répondent à un ping (mais ils n'ont pas besoin d'avoir démarré une session). Ensuite, tous les autres travailleurs vont se bloquer jusqu'à ce que l'étape d'initialisation soit terminée. – mrry