tensorflow的分布式

来源:互联网 发布:南京市软件协会地址 编辑:程序博客网 时间:2024/05/21 10:09

1.在指定设备上跑计算

TensorFlow支持使用 allow_soft_placement来将不能放在GPU的操作,自动放置到CPU来进行运算。


import tensorflow as tf
# # 通过tf.device将运算指定到特定的设备上。
with tf.device('/cpu:0'):
    a = tf.constant([1.0, 2.0, 3.0], shape=[3], name='a')
    b = tf.constant([1.0, 2.0, 3.0], shape=[3], name='b')
with tf.device('/gpu:0'):
    c = a + b
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True,allow_soft_placement=True))
print(sess.run(c))


2.两台服务器集群

2.1 WHY分布式集群?

参数服务器
当计算模型越来越大,模型的参数越来越多,多到模型参数的更新,一台机器的性能都不够时,我们需要将参数分开到不同的机器去存储和更新。
参数服务器可以是多台机器组成的集群,类似于分布式的存储结构。主要用来解决参数存储和更新的性能问题。

2.2 PS服务器两种模式

in-graph模式
in-graph模式下数据分发在一个节点上。
这种方式配置简单,其他结算节点只需join操作,暴露一个网络接口,等在那里接受任务就好。
但坏处就是训练数据的分发在一个节点上,要把训练数据分到不同的机器上,严重影响了并发的训练速度。
between-graph模式
between-graph模式下,训练的参数保存在参数服务器,数据不用分发,数据分片的保存在各个计算节点,各个计算节点自己算自己的,算完后把要更新的参数告诉参数服务器,参数服务器更新参数。
这种模式的优点是不用进行训练数据的分发,尤其数据量在TB级的时候,节省了大量的时间,所以大数据深度学习推荐使用between-graph模式。

2.3 同步更新和异步更新

in-graph和between-graph模式都支持同步更新和异步更新。
在同步更新的时候,每次梯度更新,要等所有分发的数据计算完成,返回结果,把梯度累加算了均值之后,再更新参数。这样的好处是loss的下降比较稳定,但这个的坏处也比较明显,处理的速度取决于最慢的那个分片的计算时间。
在异步更新时,所有的计算节点,自己算自己的,更新参数也是自己更新自己的计算结果,这样的优点是计算速度快,计算资源能得到充分利用,但是缺点是loss的下降不稳定,抖动大。
在数据量小的情况下,各个节点的计算能力比较均衡的情况下,推荐使用同步模式;数据量很大,各个机器的计算性能参差不齐的情况下,推荐使用异步的方式。


一台作为ps:10.11.2.31,一台作为worker:10.11.2.35

===============================1. PS=======================================

PS代码:

#coding=utf-8
#distributed

import numpy as np
import tensorflow as tf

# Define parameters
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_float('learning_rate', 0.00003, 'Initial learning rate.')
tf.app.flags.DEFINE_integer('steps_to_validate', 1000,
                     'Steps to validate and print loss')

# For distributed
tf.app.flags.DEFINE_string("ps_hosts", "10.11.2.31:1234",
                           "Comma-separated list of hostname:port pairs")
tf.app.flags.DEFINE_string("worker_hosts", "10.11.2.35:2223",
                           "Comma-separated list of hostname:port pairs")
tf.app.flags.DEFINE_string("job_name", "ps", "One of 'ps', 'worker'")
tf.app.flags.DEFINE_integer("task_index", 0, "Index of task within the job")
tf.app.flags.DEFINE_integer("issync", 0, "是否采用分布式的同步模式,1表示同步模式,0表示异步模式")

# Hyperparameters
learning_rate = FLAGS.learning_rate
steps_to_validate = FLAGS.steps_to_validate

def main(_):
    ps_hosts = FLAGS.ps_hosts.split(",")
    worker_hosts = FLAGS.worker_hosts.split(",")
    cluster = tf.train.ClusterSpec({"ps": ps_hosts,"worker": worker_hosts})
    server = tf.train.Server(cluster,job_name=FLAGS.job_name,task_index=FLAGS.task_index)

    issync = FLAGS.issync
    if FLAGS.job_name == "ps":
        server.join()
    elif FLAGS.job_name == "worker":
        with tf.device(tf.train.replica_device_setter(
                    worker_device="/job:worker/task:%d" % FLAGS.task_index,
                    cluster=cluster)):
            global_step = tf.Variable(0, name='global_step', trainable=False)

            input = tf.placeholder("float")
            label = tf.placeholder("float")

            weight = tf.get_variable("weight", [1], tf.float32, initializer=tf.random_normal_initializer())
            biase  = tf.get_variable("biase", [1], tf.float32, initializer=tf.random_normal_initializer())
            pred = tf.multiply(input, weight) + biase

            loss_value = loss(label, pred)
            optimizer = tf.train.GradientDescentOptimizer(learning_rate)

            grads_and_vars = optimizer.compute_gradients(loss_value)
            if issync == 1:
            #同步模式计算更新梯度
                rep_op = tf.train.SyncReplicasOptimizer(optimizer,
                                                replicas_to_aggregate=len(
                                                  worker_hosts),
                                                replica_id=FLAGS.task_index,
                                                total_num_replicas=len(
                                                  worker_hosts),
                                                use_locking=True)
                train_op = rep_op.apply_gradients(grads_and_vars,
                                       global_step=global_step)
                init_token_op = rep_op.get_init_tokens_op()
                chief_queue_runner = rep_op.get_chief_queue_runner()
            else:
            #异步模式计算更新梯度
                train_op = optimizer.apply_gradients(grads_and_vars,
                                       global_step=global_step)
        init_op = tf.initialize_all_variables()
        saver = tf.train.Saver()
        tf.summary.scalar('cost', loss_value)
        summary_op = tf.summary.merge_all()

    sv = tf.train.Supervisor(is_chief=(FLAGS.task_index == 0),
                            logdir="./checkpoint/",
                            init_op=init_op,
                            summary_op=None,
                            saver=saver,
                            global_step=global_step,
                            save_model_secs=60)
    with sv.prepare_or_wait_for_session(server.target) as sess:
    # 如果是同步模式
        if FLAGS.task_index == 0 and issync == 1:
            sv.start_queue_runners(sess, [chief_queue_runner])
            sess.run(init_token_op)
        step = 0
        while  step < 1000000:
            train_x = np.random.randn(1)
            train_y = 2 * train_x + np.random.randn(1) * 0.33  + 10
            _, loss_v, step = sess.run([train_op, loss_value,global_step], feed_dict={input:train_x, label:train_y})
            if step % steps_to_validate == 0:
                w,b = sess.run([weight,biase])
                print("step: %d, weight: %f, biase: %f, loss: %f" %(step, w, b, loss_v))
    sv.stop()

def loss(label, pred):
    return tf.square(label - pred)

if __name__ == "__main__":
    tf.app.run()

==============================2.worker=========================================

Worker代码:

#coding=utf-8
#distributed

import numpy as np
import tensorflow as tf

# Define parameters
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_float('learning_rate', 0.00003, 'Initial learning rate.')
tf.app.flags.DEFINE_integer('steps_to_validate', 1000,
                     'Steps to validate and print loss')

# For distributed
tf.app.flags.DEFINE_string("ps_hosts", "10.11.2.31:1234",
                           "Comma-separated list of hostname:port pairs")
tf.app.flags.DEFINE_string("worker_hosts", "10.11.2.35:2223",
                           "Comma-separated list of hostname:port pairs")
tf.app.flags.DEFINE_string("job_name", "worker", "One of 'ps', 'worker'")
tf.app.flags.DEFINE_integer("task_index", 0, "Index of task within the job")
tf.app.flags.DEFINE_integer("issync", 0, "是否采用分布式的同步模式,1表示同步模式,0表示异步模式")

# Hyperparameters
learning_rate = FLAGS.learning_rate
steps_to_validate = FLAGS.steps_to_validate

def main(_):
    ps_hosts = FLAGS.ps_hosts.split(",")
    worker_hosts = FLAGS.worker_hosts.split(",")
    cluster = tf.train.ClusterSpec({"ps": ps_hosts,"worker": worker_hosts})
    server = tf.train.Server(cluster,job_name=FLAGS.job_name,task_index=FLAGS.task_index)

    issync = FLAGS.issync
    if FLAGS.job_name == "ps":
        server.join()
    elif FLAGS.job_name == "worker":
        with tf.device(tf.train.replica_device_setter(
                    worker_device="/job:worker/task:%d" % FLAGS.task_index,
                    cluster=cluster)):
            global_step = tf.Variable(0, name='global_step', trainable=False)

            input = tf.placeholder("float")
            label = tf.placeholder("float")

            weight = tf.get_variable("weight", [1], tf.float32, initializer=tf.random_normal_initializer())
            biase  = tf.get_variable("biase", [1], tf.float32, initializer=tf.random_normal_initializer())
            pred = tf.multiply(input, weight) + biase

            loss_value = loss(label, pred)
            optimizer = tf.train.GradientDescentOptimizer(learning_rate)

            grads_and_vars = optimizer.compute_gradients(loss_value)
            if issync == 1:
            #同步模式计算更新梯度
                rep_op = tf.train.SyncReplicasOptimizer(optimizer,
                                                replicas_to_aggregate=len(
                                                  worker_hosts),
                                                replica_id=FLAGS.task_index,
                                                total_num_replicas=len(
                                                  worker_hosts),
                                                use_locking=True)
                train_op = rep_op.apply_gradients(grads_and_vars,
                                       global_step=global_step)
                init_token_op = rep_op.get_init_tokens_op()
                chief_queue_runner = rep_op.get_chief_queue_runner()
            else:
            #异步模式计算更新梯度
                train_op = optimizer.apply_gradients(grads_and_vars,
                                       global_step=global_step)
        init_op = tf.initialize_all_variables()
        saver = tf.train.Saver()
        tf.summary.scalar('cost', loss_value)
        summary_op = tf.summary.merge_all()

    sv = tf.train.Supervisor(is_chief=(FLAGS.task_index == 0),
                            logdir="./checkpoint/",
                            init_op=init_op,
                            summary_op=None,
                            saver=saver,
                            global_step=global_step,
                            save_model_secs=60)
    with sv.prepare_or_wait_for_session(server.target) as sess:
    # 如果是同步模式
        if FLAGS.task_index == 0 and issync == 1:
            sv.start_queue_runners(sess, [chief_queue_runner])
            sess.run(init_token_op)
        step = 0
        while  step < 1000000:
            train_x = np.random.randn(1)
            train_y = 2 * train_x + np.random.randn(1) * 0.33  + 10
            _, loss_v, step = sess.run([train_op, loss_value,global_step], feed_dict={input:train_x, label:train_y})
            if step % steps_to_validate == 0:
                w,b = sess.run([weight,biase])
                print("step: %d, weight: %f, biase: %f, loss: %f" %(step, w, b, loss_v))
    sv.stop()

def loss(label, pred):
    return tf.square(label - pred)

if __name__ == "__main__":
    tf.app.run() 

Supervisor,类似于一个监督者,因为分布式了,很多机器都在运行,像参数初始化、保存模型、写summary,这个supervisor帮你一起弄起来了,就不用自己手动去做这些事情了,而且在分布式的环境下涉及到各种参数的共享,其中的过程自己手工写也不好写,于是TensorFlow就给大家包装好这么一个东西。这里的参数is_chief比较重要。
在所有的计算节点里还是有一个主节点的,这个主节点来负责初始化参数,模型的保存,summary的保存。logdir就是保存和装载模型的路径。不过这个似乎启动后会去这个logdir的目录去看有没有checkpoint的文件,有的话就自动装载了,没用就用init_op指定的初始化参数,好像没有参数指定不让它自动load的
主worker节点负责模型参数初始化等工作,在这个过程中,其他worker节点等待主节点完成初始化工作,等主节点初始化完成后,就可以跑数据了。
这里的global_step的值,是可以所有计算节点共享的,在执行optimizer的minimize的时候,会自动+1, 虽有可以通过这个可以知道所有的计算节点一共计算了多少步了。

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 庞大股票行情 岩崎千鹤庞大体积 庞大集团遭起诉 庞大集团股票吧 601258庞大集团股票 庞大集团股市行情 庞大汽贸集团内部 庞大集团董事长 庞大集团资金流向 601258 庞大集团股票行情 601258 庞大集团 庞大集团股票解禁 庞大集团是做什么的 庞大集团股票分析 庞大集团股票行情 庞大集团怎么样 庞大集团601258 庞大汽车租赁集团 庞大欧力士汽车租赁 庞大集团股票价格 庞大集团是干什么的 庞大集团网站 庞大集团无纸化办公 庞大汽贸股票 庞大集团招聘信息 庞大集团股价 庞大集团会涨吗 庞大集团季报 庞大集团汽车贷款 庞大集团 发行价 庞大集团斯巴鲁 庞大汽贸集团有限公司 庞大集团员工 庞大集团业绩 庞大集团在哪 庞大汽车集团 庞大集团财务报表 庞大集团主页 庞大集团有限公司 庞大集团卖什么车 庞大集团招股说明书