分布式 TF:非 chief worker 看到 chief worker 的更新,反之则不然

Distributed TF: Non-chief worker sees updates from chief worker but not vice versa

我正在尝试起床 运行 分布式张量流,但发现了很多令人困惑的行为。目前我正在 运行 设置一台 ps 服务器和两台工作服务器,一台工作服务器与 ps 服务器在同一台计算机上,另一台在另一台计算机上。我想从一个简单的例子开始,所以我写了一些东西试图添加一个常量来增加每个工人的变量。 我观察到的是 chief worker 看不到 non-chief worker 执行的增量,即使 non-chief worker 确实看到了 chief worker 执行的增量。

这是我的脚本(您会注意到它是我上一个问题的放大版:):

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, ... 等等。但是,如果我对 chief 和 non-chief worker 都 运行,我会看到一种模式,表明 non-chief worker 知道并使用 chief worker 的更新,但 chief worker 不知道并不知道不使用非首席工人的更新。首席工作者继续增加自己的价值,而非首席工作者使用它的最后一个值或首席工作者的最后一个值,以较晚者为准。所以这里有一个示例模式:

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 中查看 ps,我会看到文件在 chief 运行 时更新,但在 [=15= 时不会] 运行s.

我尝试了一些方法:

我觉得 ps server 除了存在 checkpoint files 之外还保留了一些状态(斜线变量的值),但我不清楚这些状态如何相互关联或就 ps server 中保留的信息与文件中保留的信息而言,可能出了什么问题。

我欢迎就我的代码有什么问题或更笼统地提供有关故障排除想法的建议。谢谢你。

似乎是这种情况(如果有人能在示例或文档中指出这一点,我将不胜感激)工人必须始终同时 运行 和 运行 .所以我的例子是一个很短的玩具例子,这不是真的,我想框架的基本假设不成立了。

将脚本的末尾修改为以下内容使一切都按预期进行,因为两个工作人员同时 运行:

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