tensorflow学习笔记(十九):分布式Tensorflow

2023-05-16

最近在学习怎么分布式Tensorflow训练深度学习模型,看官网教程看的云里雾里,最终结合着其它资料,终于对分布式Tensorflow有了些初步了解.

gRPC (google remote procedure call)

分布式Tensorflow底层的通信是gRPC
gRPC首先是一个RPC,即远程过程调用,通俗的解释是:假设你在本机上执行一段代码num=add(a,b),它调用了一个过程 call,然后返回了一个值num,你感觉这段代码只是在本机上执行的, 但实际情况是,本机上的add方法是将参数打包发送给服务器,然后服务器运行服务器端的add方法,返回的结果再将数据打包返回给客户端.

Cluster.Job.Task

Job是Task的集合.
Cluster是Job的集合

为什么要分成Cluster,Job,和Task呢?

首先,我们介绍一下Task:Task就是主机上的一个进程,在大多数情况下,一个机器上只运行一个Task.

为什么JobTask的集合呢? 在分布式深度学习框架中,我们一般把Job划分为ParameterWorker,Parameter Job是管理参数的存储和更新工作.Worker Job是来运行ops.如果参数的数量太大,一台机器处理不了,这就要需要多个Tasks.

ClusterJobs 的集合: Cluster(集群),就是我们用的集群系统了

如何创建集群

从上面的描述我们可以知道,组成Cluster的基本单位是Task(动态上理解,主机上的一个进程,从静态的角度理解,Task就是我们写的代码).我们只需编写Task代码,然后将代码运行在不同的主机上,这样就构成了Cluster(集群)

如何编写Task代码

首先,Task需要知道集群上都有哪些主机,以及它们都监听什么端口.tf.train.ClusterSpec()就是用来描述这个.

tf.train.ClusterSpec({
    "worker": [
        "worker_task0.example.com:2222",# /job:worker/task:0 运行的主机
        "worker_task1.example.com:2222",# /job:worker/task:1 运行的主机
        "worker_task2.example.com:2222"# /job:worker/task:3 运行的主机
    ],
    "ps": [
        "ps_task0.example.com:2222",  # /job:ps/task:0 运行的主机
        "ps_task1.example.com:2222"   # /job:ps/task:0 运行的主机
    ]})

这个ClusterSec告诉我们,我们这个Cluster(集群)有两个Job(worker.ps),worker中有三个Task(即,有三个Task执行Tensorflow op操作)

然后,将ClusterSpec当作参数传入到 tf.train.Server()中,同时指定此TaskJob_nametask_index.

#jobName和taskIndex是函数运行时,通过命令行传递的参数
server = tf.train.Server(cluster, job_name=jobName, task_index=taskIndex)

下面代码描述的是,一个cluster中有一个Job,叫做(worker), 这个job有两个task,这两个task是运行在两个主机上的

#在主机(10.1.1.1)上,实际是运行以下代码
cluster = tf.train.ClusterSpec({"worker": ["10.1.1.1:2222", "10.1.1.2:3333"]})
server = tf.train.Server(cluster, job_name="local", task_index=0)

#在主机(10.1.1.2)上,实际运行以下代码
cluster = tf.train.ClusterSpec({"worker": ["10.1.1.1:2222", "10.1.1.2:3333"]})
server = tf.train.Server(cluster, job_name="local", task_index=1)

tf.trian.Server干了些什么呢?
首先,一个tf.train.Server包含了: 本地设备(GPUs,CPUs)的集合,可以连接到到其它taskip:port(存储在cluster中), 还有一个session target用来执行分布操作.还有最重要的一点就是,它创建了一个服务器,监听port端口,如果有数据传过来,他就会在本地执行(启动session target,调用本地设备执行运算),然后结果返回给调用者.

我们继续来写我们的task代码:在你的model中指定分布式设备

with tf.device("/job:ps/task:0"):
  weights_1 = tf.Variable(...)
  biases_1 = tf.Variable(...)

with tf.device("/job:ps/task:1"):
  weights_2 = tf.Variable(...)
  biases_2 = tf.Variable(...)

with tf.device("/job:worker/task:0"): #映射到主机(10.1.1.1)上去执行
  input, labels = ...
  layer_1 = tf.nn.relu(tf.matmul(input, weights_1) + biases_1)
  logits = tf.nn.relu(tf.matmul(layer_1, weights_2) + biases_2)
with tf.device("/job:worker/task:1"): #映射到主机(10.1.1.2)上去执行
  input, labels = ...
  layer_1 = tf.nn.relu(tf.matmul(input, weights_1) + biases_1)
  logits = tf.nn.relu(tf.matmul(layer_1, weights_2) + biases_2)
  # ...
  train_op = ...
with tf.Session("grpc://10.1.1.2:3333") as sess:#在主机(10.1.1.2)上执行run
  for _ in range(10000):
    sess.run(train_op)

with tf.Session("grpc://..")是指定gprc://..master,masterop分发给对应的task

写分布式程序时,我们需要关注一下问题:
(1) 使用In-graph replication还是Between-graph replication

In-graph replication:一个client(显示调用tf::Session的进程),将里面的参数ops指定给对应的job去完成.数据分发只由一个client完成.

Between-graph replication:下面的代码就是这种形式,有很多独立的client,各个client构建了相同的graph(包含参数,通过使用tf.train.replica_device_setter,将这些参数映射到ps_server上.)

(2)同步训练,还是异步训练

Synchronous training:在这种方式中,每个graph的副本读取相同的parameter的值,并行的计算gradients,然后将所有计算完的gradients放在一起处理.Tensorlfow提供了函数(tf.train.SyncReplicasOptimizer)来处理这个问题(在Between-graph replication情况下),在In-graph replication将所有的gradients平均就可以了

Asynchronous training:自己计算完gradient就去更新paramenter,不同replica之间不会去协调进度
同步与异步(between-graph)
(3)
一个完整的例子,来自官网链接:

import tensorflow as tf

# Flags for defining the tf.train.ClusterSpec
tf.app.flags.DEFINE_string("ps_hosts", "",
                           "Comma-separated list of hostname:port pairs")
tf.app.flags.DEFINE_string("worker_hosts", "",
                           "Comma-separated list of hostname:port pairs")

# Flags for defining the tf.train.Server
tf.app.flags.DEFINE_string("job_name", "", "One of 'ps', 'worker'")
tf.app.flags.DEFINE_integer("task_index", 0, "Index of task within the job")

FLAGS = tf.app.flags.FLAGS

由于是相同的代码运行在不同的主机上,所以要传入job_nametask_index加以区分,而ps_hostsworker_hosts对于所有主机来说,都是一样的,用来描述集群的

def main(_):
  ps_hosts = FLAGS.ps_hosts.split(",")
  worker_hosts = FLAGS.worker_hosts.split(",")

  # Create a cluster from the parameter server and worker hosts.
  cluster = tf.train.ClusterSpec({"ps": ps_hosts, "worker": worker_hosts})

  # Create and start a server for the local task.
  server = tf.train.Server(cluster,
                           job_name=FLAGS.job_name,
                           task_index=FLAGS.task_index)

  if FLAGS.job_name == "ps":
    server.join()

我们都知道,服务器进程如果执行完的话,服务器就会关闭.为了是我们的ps_server能够一直处于监听状态,我们需要使用server.join().这时,进程就会block在这里.至于为什么ps_server刚创建就join呢:原因是因为下面的代码会将参数指定给ps_server保管,所以ps_server静静的监听就好了.

  elif FLAGS.job_name == "worker":

    # Assigns ops to the local worker by default.
    with tf.device(tf.train.replica_device_setter(
        worker_device="/job:worker/task:%d" % FLAGS.task_index,
        cluster=cluster)):

tf.train.replica_device_setter(ps_tasks=0, ps_device='/job:ps', worker_device='/job:worker', merge_devices=True, cluster=None, ps_ops=None)),返回值可以被tf.device使用,指明下面代码中variableops放置的设备.

example:

# To build a cluster with two ps jobs on hosts ps0 and ps1, and 3 worker
# jobs on hosts worker0, worker1 and worker2.
cluster_spec = {
    "ps": ["ps0:2222", "ps1:2222"],
    "worker": ["worker0:2222", "worker1:2222", "worker2:2222"]}
with tf.device(tf.replica_device_setter(cluster=cluster_spec)):
  # Build your graph
  v1 = tf.Variable(...)  # assigned to /job:ps/task:0
  v2 = tf.Variable(...)  # assigned to /job:ps/task:1
  v3 = tf.Variable(...)  # assigned to /job:ps/task:0
# Run compute

这个例子是没有指定参数worker_deviceps_device的,你可以手动指定

继续代码注释,下面就是,模型的定义了

      # Build model...variables and ops
      loss = ...
      global_step = tf.Variable(0)

      train_op = tf.train.AdagradOptimizer(0.01).minimize(
          loss, global_step=global_step)

      saver = tf.train.Saver()
      summary_op = tf.merge_all_summaries()
      init_op = tf.initialize_all_variables()

    # Create a "supervisor", which oversees the training process.
    sv = tf.train.Supervisor(is_chief=(FLAGS.task_index == 0),
                             logdir="/tmp/train_logs",
                             init_op=init_op,
                             summary_op=summary_op,
                             saver=saver,
                             global_step=global_step,
                             save_model_secs=600)

    # The supervisor takes care of session initialization, restoring from
    # a checkpoint, and closing when done or an error occurs.
    with sv.managed_session(server.target) as sess:
      # Loop until the supervisor shuts down or 1000000 steps have completed.
      step = 0
      while not sv.should_stop() and step < 1000000:
        # Run a training step asynchronously.
        # See `tf.train.SyncReplicasOptimizer` for additional details on how to
        # perform *synchronous* training.
        _, step = sess.run([train_op, global_step])

    # Ask for all the services to stop.
    sv.stop()

考虑一个场景(Between-graph),我们有一个parameter server(存放着参数的副本),有好几个worker server(分别保存着相同的graph的副本).更通俗的说,我们有10台电脑,其中一台作为parameter server,其余九台作为worker server.因为同一个程序在10台电脑上同时运行(不同电脑,job_name,task_index不同),所以每个worker server上都有我们建立的graph的副本(replica).这时我们可以使用Supervisor帮助我们管理各个process.Supervisoris_chief参数很重要,它指明用哪个task进行参数的初始化工作.sv.managed_session(server.target)创建一个被sv管理的session

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

To start the trainer with two parameter servers and two workers, use the following command line (assuming the script is called trainer.py):

# On ps0.example.com:
$ python trainer.py \
     --ps_hosts=ps0.example.com:2222,ps1.example.com:2222 \
     --worker_hosts=worker0.example.com:2222,worker1.example.com:2222 \
     --job_name=ps --task_index=0
# On ps1.example.com:
$ python trainer.py \
     --ps_hosts=ps0.example.com:2222,ps1.example.com:2222 \
     --worker_hosts=worker0.example.com:2222,worker1.example.com:2222 \
     --job_name=ps --task_index=1
# On worker0.example.com:
$ python trainer.py \
     --ps_hosts=ps0.example.com:2222,ps1.example.com:2222 \
     --worker_hosts=worker0.example.com:2222,worker1.example.com:2222 \
     --job_name=worker --task_index=0
# On worker1.example.com:
$ python trainer.py \
     --ps_hosts=ps0.example.com:2222,ps1.example.com:2222 \
     --worker_hosts=worker0.example.com:2222,worker1.example.com:2222 \
     --job_name=worker --task_index=1

可以看出,我们只需要写一个程序,在不同的主机上,传入不同的参数使其运行

参考博客:
[1] http://weibo.com/ttarticle/p/show?id=2309403987407065210809
[2] http://weibo.com/ttarticle/p/show?id=2309403988813608274928
[3] http://blog.csdn.net/luodongri/article/details/52596780

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

tensorflow学习笔记(十九):分布式Tensorflow 的相关文章

  • RYU功能开发(一)从simple switch开始

    对于任意一款控制器 xff0c 想要快速了解其开发机制 xff0c 从转发模块入手无疑是最佳的学习方式 RYU通过App的形式提供了一系列功能模块 xff0c 其中包括使用了OpenFlow作为控制协议的二层交换机控制模块simple sw
  • arm-linux-gcc交叉工具链

    Linux ARM交叉编译工具链制作过程 一 下载源文件 源代码文件及其版本与下载地址 xff1a Binutils 2 19 tar bz2 Index of gnu binutils gcc 4 4 4 tar bz2 Index of
  • 我使用过的Linux命令之cal - 显示日历

    我使用过的Linux命令之cal 显示日历 本文链接 xff1a http codingstandards iteye com blog 807962 xff08 转载请注明出处 xff09 用途说明 cal命令可以用来显示公历 xff08
  • 驼峰式与下划线命名规则

    在实际代码开发过程中 xff0c 代码编写格式清晰与否不仅决定了自己的代码编写与维护成本 xff0c 也直接影响到项目的开发进度 编码中常用的有驼峰法和下划线两种编码格式 xff0c 其中驼峰法常用在面向对象的高层语言中 xff0c 下划线
  • 全图文分析:如何利用Google的protobuf,来思考、设计、实现自己的RPC框架

    文章目录 一 前言二 RPC 基础概念1 RPC 是什么 xff1f 2 需要解决什么问题 xff1f 3 有哪些开源实现 xff1f 三 protobuf 基本使用1 基本知识2 使用步骤 四 libevent1 libevent 简介2
  • 针对vue的配置文件

    针对vue的配置文件 我们在根目录下创建一个 vue config js 文件 xff0c 将下方配置下去 module exports 61 区分打包环境与开发环境 process env NODE ENV 61 61 61 39 pro
  • Linux | LVM | 对比三种逻辑卷(Logic Volume)

    概述 为了满足在性能和冗余等方面的需求 xff0c LVM支持了下面三种Logic Volume xff1a Linear Logic Volume 线性逻辑卷Striped Logic Volume 条带化逻辑卷Mirror Logic
  • MySql ERROR 1129

    ERROR 1129 HY000 Host 39 mysql02 39 is blocked because of many connection errors unblock with 39 mysqladmin flush hosts
  • SpringBoot整合Shiro

    Apache Shiro是一个强大且易用的Java安全框架 执行身份验证 授权 密码学和会话管理 相比较Spring Security xff0c shiro有小巧 简单 易上手等的优点 所以很多框架都在使用shiro Shiro包含了三个
  • PB数据窗口对象之Button

    Button 重要属性 Action 属性 该属性是Button 控件最重要的一个属性 在数据窗口画板中 xff0c 可以选择一个按钮有哪个动作 可选的动作都是事先定义好的 xff0c 开发人员没有机会精确定义某个动作的执行 xff0c 只
  • 聊聊前端八股文?

    大家好 xff0c 我是若川 xff0c 点此加我微信进源码群 xff0c 一起学习源码 同时可以进群免费看Vue专场直播 xff0c 有尤雨溪分享 Vue3 生态现状以及展望 前些天 xff0c 我看到 剑指前端offer 一系列文章 x
  • 新手向:前端程序员必学基本技能——调试JS代码

    1前言 大家好 xff0c 我是若川 最近组织了源码共读活动 xff0c 感兴趣的可以加我微信 ruochuan12 参与 xff0c 已进行三个月了 xff0c 大家一起交流学习 xff0c 共同进步 想学源码 xff0c 极力推荐之前我
  • 全新的 Vue3 状态管理工具:Pinia

    大家好 xff0c 我是若川 最近组织了源码共读活动 xff0c 感兴趣的可以点此加我微信 ruochuan12 参与 xff0c 每周大家一起学习200行左右的源码 xff0c 共同进步 同时极力推荐订阅我写的 学习源码整体架构系列 包含
  • 推荐2022前端必看的新书 《Vue.js设计与实现》

    大家好 xff0c 我是若川 持续组织了6个月源码共读活动 xff0c 感兴趣的可以点此加我微信 ruochuan12 参与 xff0c 每周大家一起学习200行左右的源码 xff0c 共同进步 同时极力推荐订阅我写的 学习源码整体架构系列
  • 面试官问:跨域请求如何携带cookie?

    大家好 xff0c 我是若 川 持续组织了6个月源码共读活动 xff0c 感兴趣的可以点此加我微信 ruochuan12 参与 xff0c 每周大家一起学习200行左右的源码 xff0c 共同进步 同时极力推荐订阅我写的 学习源码整体架构系
  • 如何写好技术文章(看张鑫旭老师的直播总结

    大家好 xff0c 我是若川 持续组织了6个月源码共读活动 xff0c 感兴趣的可以点此加我微信 ruochuan12 参与 xff0c 每周大家一起学习200行左右的源码 xff0c 共同进步 同时极力推荐订阅我写的 学习源码整体架构系列
  • Element使用的async-validator表单校验库源码超详细解析

    大家好 xff0c 我是若川 持续组织了8个月源码共读活动 xff0c 感兴趣的可以 点此加我微信ruochuan12 参与 xff0c 每周大家一起学习200行左右的源码 xff0c 共同进步 同时极力推荐订阅我写的 学习源码整体架构系列
  • 我捡到宝了!2022版前端面试上岸手册,最新最细致!

    大裁员背景下 xff0c 没什么比辞职后找不到工作更扎心 xff01 在行情好转前 xff0c 前端程序员只能 猥琐发育 xff0c 不轻易跳槽 xff0c 同时要修炼内功 xff1a 对八股文 底层源码 重点项目等进行查缺补漏 xff0c
  • 点击页面元素跳转IDE对应代码,试试这几个工具!

    大家好 xff0c 我是若川 我持续组织了近一年的源码共读活动 xff0c 感兴趣的可以 点此扫码加我微信 ruochuan12 参与 xff0c 每周大家一起学习200行左右的源码 xff0c 共同进步 同时极力推荐订阅我写的 学习源码整
  • 为什么说组件库的源码非常值得学习?

    大家好 xff0c 我是若川 最近来了一些新朋友 xff0c 感谢大家关注 相比于原生 JS 等源码 我们或许更应该学习正在使用的组件库的源码 xff08 如 xff1a element antd vant semi arco tdesig

随机推荐

  • 写一个Vue DevTools,让开发体验飞一会

    大家好 xff0c 我是若川 我持续组织了近一年的源码共读活动 xff0c 感兴趣的可以 点此扫码加我微信 lxchuan12 参与 xff0c 每周大家一起学习200行左右的源码 xff0c 共同进步 同时极力推荐订阅我写的 学习源码整体
  • 偷偷盘点前端面试官才知道的进阶秘籍

    很多人都说35岁是程序员的职业尽头 而我们部门leader是位80年的大哥 xff0c 曾经是字节3 1大佬 xff0c 今年43岁了依然独当一面 于是 xff0c 我向他请教了 不被淘汰 的秘籍 他总结了两点 xff1a 1 努力修炼内功
  • Facebook CrypTen安全多方计算(MPC)框架介绍及核心代码分析

    简单介绍 CrypTen是Facebook在2019年10月开源的 用于多方安全计算 MPC 的框架 其底层依赖于深度学习框架PyTorch 官网说明见 xff1a https ai facebook com blog crypten a
  • 开源软件Asterisk:386变身交换机

    有关开源软件最令人激动的事情之一就是其创建超越传统的IT基础架构的应用程序的方式 一个恰当的例子是称作 Asterisk 的电话应用程序 Asterisk是一种功能非常齐全的应用程序 xff0c 提供了许多电信功能 也许它最著名的应用是当作
  • 2016.9---2017.1半年总,外派工作的感觉真爽 (补17年1月)

    16年8月份 xff0c 第二版订餐系统上线 xff0c 我就着手出去上班 xff0c 8月初提交简历后 xff0c 面试就一发不可收 xff0c 一直到12月初才出去 xff0c 历时四个月 xff0c 期间边学习边面试 xff0c 但这
  • gerrit - first commit

    最近公司有新项目 xff0c 已经让领导帮我把clone和push的权限都开通了 xff0c 但是在push的时候还是提交失败 xff0c 错误信息如下 xff1a git push origin master Counting objec
  • AutoML领域的一把利器---HyperGBM

    AutoML领域的一把利器 HyperGBM 文章目录 AutoML领域的一把利器 HyperGBM 前言一 何为AutoML xff1f 二 如何使用HyperGBM1 引入库2 读入数据3 初始化make experiment4 调用m
  • AutoML工具之HyperGBM介绍

    HyperGBM介绍 本文章主要是对autoML开源框架HyperGBM的一个介绍 文章目录 HyperGBM介绍一 关于HyperGBM二 功能特性总览二 如何安装HyperGBM三 HyperGBM入门样例1 准备数据集2 创建实验并进
  • HyperGBM如何定义autoML的搜索空间

    HyperGBM学习笔记之如何定义autoML搜索空间 文章目录 HyperGBM学习笔记之如何定义autoML搜索空间前言一 入门篇1 定义需求2 需求解析 二 进阶篇1 定义参数的搜索范围2 构建autoML伪代码3 HyperGBM定
  • HyperGBM之进化搜索算法

    HyperGBM学习笔记之进化搜索算法 文章目录 HyperGBM学习笔记之进化搜索算法一 什么是进化搜索算法 xff1f 二 HyperGBM中的变异算法实现1 构建进化搜索实例2 变异算法实现3 进化搜索算法整体流程 三 HyperGB
  • 机器学习之如何处理缺失值(missing value)

    机器学习之如何处理缺失值 备注 xff1a 本次数据来源于kaggle xff0c 详情请戳here xff0c 原文参考连接 xff0c 请戳here xff0c 本文篇幅较长 xff0c 旨在多介绍EDA过程中的一些思想和细节 文章目录
  • 机器学习中的早停策略

    前言 在做机器学习模型调优的时候 xff0c 往往会通过一系列的操作去提升调优效率 xff0c 其中有一种技术就是合理运用早停策略 关于数据集 xff1a 本文直接使用kaggle的数据集 xff0c 你可以直接点击链接下载 一 入门 1
  • 机器学习中如何处理非数值型的特征

    前言 传统的机器算法一般处理的是结构化数据 xff0c 而结构化数据中往往包含以下几种类别 xff1a 传统的机器学习算法 SVM xff0c LR xff0c lightgbm xff0c xgboost等 结构化数据类别 Categor
  • automl中如何提升搜索效率

    前言 automl 简单来说 xff0c 就是将机器学习应用于现实问题的端到端流程自动化的过程 xff0c 其产生的主要原因就是因为机器学习的应用需要大量的人工干预 xff0c 这些人工干预表现在 xff1a 特征分析 模型选择 参数调节等
  • Linux操作系统下搭建VNC远程控制软件详尽教程

    摘自 xff1a http os 51cto com art 200802 65589 htm VNC简介 xff1a 虽然VNC 还有着在Linux下无法按热键呼出中文输入等等小小不足 xff0c 但仍然无法阻止其在Linux系统中的地位
  • automl工具入门介绍

    前言 自动化机器学习已经被广泛应用于各种 跨 业务场景的模型构建 xff0c 实验以及生产部署当中 automl领域中有各种各样的开源项目可以直接使用 xff0c 本篇文章尝试对一些主流的开源框架进行介绍 autogluon hypergb
  • Ensemble算法之GreedyEnsemble

    前言 我们常说三个臭皮匠顶个诸葛亮 xff0c 在机器学习领域中将这个理念应用到极致的技术是boosting xff0c 将N多的弱分类器组合到一起 xff0c 达到一个强分类器的效果 xff0c 主流代表的算法就是xgboost xff0
  • Hadoop URL数据读取操作

    hadoop可以从命令行上使用hadoop fs command 来读取文件系统中的文件 同时也可以使用java接口来实现这些功能 刚写好了一个权威指南上的例子 xff0c 附上代码 xff1a package baseOperation
  • ubuntu更改默认启动项顺序

    ubuntu更改默认启动项顺序 因为经常需要在ubuntu下调试openstack代码 xff0c 在windows下用虚拟机又会严重影响使用性能 xff0c 所以干脆将笔记本装了windows 43 ubuntu双系统 xff0c 曾多次
  • tensorflow学习笔记(十九):分布式Tensorflow

    最近在学习怎么分布式Tensorflow训练深度学习模型 看官网教程看的云里雾里 最终结合着其它资料 终于对分布式Tensorflow有了些初步了解 gRPC google remote procedure call 分布式Tensorfl