分布式TF:非首席工作者看到主要工作人员的更新,但反之亦然

时间:2018-01-09 16:49:14

标签: python tensorflow distributed-computing

我尝试使用分布式张量流来启动并运行,但却发现了许多令人困惑的行为。目前我正在运行一个ps服务器和两个工作服务器,一个工作服务器与ps服务器在同一台计算机上,另一个在另一台计算机上。我想从一个简单的例子开始,所以我写了一些东西试图添加一个常量来增加每个worker的变量。 我所观察到的是,即使非首席工作人员确实看到了主要工作人员的增量,但主要工作人员并未看到非首席执行官的增量。

这是我的剧本(你会注意到它是我上一个问题的扩大:Distributed tensorflow monopolizes GPUs after running server.__init__):

JOB_NAME   = args.job_name
TASK_INDEX = args.task_idx
DIR_NAME   = args.dir_name
CHECKPOINT_DIR = "/tmp/TF_%s" % (DIR_NAME)

ps_hosts     = ["computerB-i9:2222"]
worker_hosts = ["computerA-i7:2222", "computerB-i9:2223"]

cluster = tf.train.ClusterSpec({"ps": ps_hosts, "worker": worker_hosts})
server  = tf.train.Server(cluster, job_name = JOB_NAME, task_index = TASK_INDEX)

if JOB_NAME == "ps":        
    if not os.path.exists(CHECKPOINT_DIR):
        os.makedirs(CHECKPOINT_DIR)

    server.join()

elif JOB_NAME == "worker":
    with tf.device(tf.train.replica_device_setter(
            worker_device = "/job:worker/task:%d" % TASK_INDEX, cluster = cluster)):

        global_step = tf.train.get_or_create_global_step()
        a = tf.get_variable("a", [1], initializer = tf.constant_initializer(8))
        b = tf.get_variable("b", [1], initializer = tf.constant_initializer(5))
        c = tf.assign_add(a, b)

    hooks = [tf.train.StopAtStepHook(last_step = 1000000)]

    sess_config = tf.ConfigProto(
        allow_soft_placement=True,
        log_device_placement=True,
        device_filters=["/job:ps", "/job:worker/task:%d" % TASK_INDEX])

    with tf.train.MonitoredTrainingSession(master   = server.target,
                                           is_chief = (TASK_INDEX == 0),
                                           checkpoint_dir = CHECKPOINT_DIR,
                                           hooks    = hooks,
                                           config   = sess_config) as sess:

        val = sess.run([c])
        print(val)

我看到的行为是,当我单独在非主要工作服务器上运行脚本或仅在主工作服务器上运行脚本时,我看到:8, 13, 18, 23, ...等等。但是,如果我同时兼任主要和非主要工作人员,我会看到一种模式表明非首席工作人员知道并使用了主要工作人员的更新,但是主要工作人员并不知道和不使用非首席工作人员的更新。主要工作人员继续增加自己的价值,而非首席工作人员使用其最后一个值或主要的最后一个值,以较晚者为准。所以在这里,例如是一个样本模式:

run chief: 8
run chief: 13
run chief: 18
run non-chief: 23
run non-chief: 28
run non=chief: 33 (so both are seeming to increment normally....BUT then...)
run chief: 23 (as though non-chief did not run)
run non-chief: 28 (sees chief's update and runs off that)
run non-chief: 33 (continuing off 'the latest')
run chief: 28 (again chief sees only its own)

我还注意到,如果我在时间戳中查看CHECKPOINT_DIR,我会看到文件在chief运行时更新,但在non-chief运行时不会更新。

我尝试了一些事情:

  • 文件保存行为略有不同,具体取决于chief worker是否与ps server在同一台计算机上,只有当chief worker不在同一台计算机上时才会保存其文件在任何计算机上本地。但是,上述行为保持不变。
  • 我尝试更改首先运行的工作人员,chiefnon chief,但它不会影响上述行为。

我感觉ps server除了存在checkpoint files之外还保留了一些状态(削减了变量的值)但是我不清楚这些状态如何相互关联或者可能是什么在ps server与文件内容中保留哪些信息时会出错。

我欢迎提出有关我的代码有什么问题的建议,或者更多关于故障排除方法的建议。谢谢。

1 个答案:

答案 0 :(得分:0)

似乎是这种情况(如果有人可以在示例或文档中指出这一点,我会很感激)工人必须始终在同一时间运行和运行。所以我的例子是如此简短的玩具示例,这不是真的,我认为框架的基本假设已经破裂。

将脚本的结尾修改为以下内容使得一切都按预期工作,因为两个工作程序同时运行:

  while True:
            val = sess.run([c])
            print(val)
            time.sleep(15)