深度学习(五十五)tensorflow分布式训练

hjimce hjimce     2022-08-24     580

关键词:

tensorflow分布式训练

博客http://blog.csdn.net/hjimce

微博黄锦池-hjimce   qq:1393852684


情况一、单机单卡

单机单卡是最普通的情况,当然也是最简单的,示例代码如下:

#coding=utf-8
#单机单卡
#对于单机单卡,可以把参数和计算都定义再gpu上,不过如果参数模型比较大,显存不足等情况,就得放在cpu上
import  tensorflow as tf

with tf.device('/cpu:0'):#也可以放在gpu上
	w=tf.get_variable('w',(2,2),tf.float32,initializer=tf.constant_initializer(2))
	b=tf.get_variable('b',(2,2),tf.float32,initializer=tf.constant_initializer(5))

with tf.device('/gpu:0'):
	addwb=w+b
	mutwb=w*b


ini=tf.initialize_all_variables()
with tf.Session() as sess:
	sess.run(ini)
	np1,np2=sess.run([addwb,mutwb])
	print np1
	print np2

情况二、单机多卡

单机多卡,只要用device直接指定设备,就可以进行训练,SGD采用各个卡的平均值,示例代码如下:

#coding=utf-8
#单机多卡:
#一般采用共享操作定义在cpu上,然后并行操作定义在各自的gpu上,比如对于深度学习来说,我们一把把参数定义、参数梯度更新统一放在cpu上
#各个gpu通过各自计算各自batch 数据的梯度值,然后统一传到cpu上,由cpu计算求取平均值,cpu更新参数。
#具体的深度学习多卡训练代码,请参考:https://github.com/tensorflow/models/blob/master/inception/inception/inception_train.py
import  tensorflow as tf

with tf.device('/cpu:0'):
	w=tf.get_variable('w',(2,2),tf.float32,initializer=tf.constant_initializer(2))
	b=tf.get_variable('b',(2,2),tf.float32,initializer=tf.constant_initializer(5))

with tf.device('/gpu:0'):
	addwb=w+b
with tf.device('/gpu:1'):
	mutwb=w*b


ini=tf.initialize_all_variables()
with tf.Session() as sess:
	sess.run(ini)
	while 1:
		print sess.run([addwb,mutwb])



情况三、多机多卡

一、基本概念

Cluster、Job、task概念:三者可以简单的看成是层次关系,task可以看成每台机器上的一个进程,多个task组成job;job又有:ps、worker两种,分别用于参数服务、计算服务,组成cluster。

二、同步SGD与异步SGD

1、所谓的同步更新指的是:各个用于并行计算的电脑,计算完各自的batch 后,求取梯度值,把梯度值统一送到ps服务机器中,由ps服务机器求取梯度平均值,更新ps服务器上的参数。

如下图所示,可以看成有四台电脑,第一台电脑用于存储参数、共享参数、共享计算,可以简单的理解成内存、计算共享专用的区域,也就是ps job;另外三台电脑用于并行计算的,也就是worker task。


这种计算方法存在的缺陷是:每一轮的梯度更新,都要等到A、B、C三台电脑都计算完毕后,才能更新参数,也就是迭代更新速度取决与A、B、C三台中,最慢的那一台电脑,所以采用同步更新的方法,建议A、B、C三台的计算能力都不想。

2、所谓的异步更新指的是:ps服务器收到只要收到一台机器的梯度值,就直接进行参数更新,无需等待其它机器。这种迭代方法比较不稳定,收敛曲线震动比较厉害,因为当A机器计算完更新了ps中的参数,可能B机器还是在用上一次迭代的旧版参数值。



三、代码编写

1、定义集群

比如假设上面的图所示,我们有四台电脑,四台电脑的名字假设为:A、B、C、D,那么集群可以定义如下

#coding=utf-8
#多台机器,每台机器有一个显卡、或者多个显卡,这种训练叫做分布式训练
import  tensorflow as tf
#现在假设我们有A、B、C、D四台机器,首先需要在各台机器上写一份代码,并跑起来,各机器上的代码内容大部分相同
# ,除了开始定义的时候,需要各自指定该台机器的task之外。以机器A为例子,A机器上的代码如下:
cluster=tf.train.ClusterSpec({
    "worker": [
        "A_IP:2222",#格式 IP地址:端口号,第一台机器A的IP地址 ,在代码中需要用这台机器计算的时候,就要定义:/job:worker/task:0
        "B_IP:1234"#第二台机器的IP地址 /job:worker/task:1
        "C_IP:2222"#第三台机器的IP地址 /job:worker/task:2
    ],
    "ps": [
        "D_IP:2222",#第四台机器的IP地址 对应到代码块:/job:ps/task:0
    ]})

然后我们需要写四分代码,这四分代码文件大部分相同,但是有几行代码是各不相同的。

2、在各台机器上,定义server

比如A机器上的代码server要定义如下:

server=tf.train.Server(cluster,job_name='worker',task_index=0)#找到‘worker’名字下的,task0,也就是机器A

3、在代码中,指定device

with tf.device('/job:ps/task:0'):#参数定义在机器D上
	w=tf.get_variable('w',(2,2),tf.float32,initializer=tf.constant_initializer(2))
	b=tf.get_variable('b',(2,2),tf.float32,initializer=tf.constant_initializer(5))

with tf.device('/job:worker/task:0/cpu:0'):#在机器A cpu上运行
	addwb=w+b
with tf.device('/job:worker/task:1/cpu:0'):#在机器B cpu上运行
	mutwb=w*b
with tf.device('/job:worker/task:2/cpu:0'):#在机器C cpu上运行
	divwb=w/b


在深度学习训练中,一般图的计算,对于每个worker task来说,都是相同的,所以我们会把所有图计算、变量定义等代码,都写到下面这个语句下:

with tf.device(tf.train.replica_device_setter(worker_device='/job:worker/task:indexi',cluster=cluster)):

函数replica_deviec_setter会自动把变量参数定义部分定义到ps服务中(如果ps有多个任务,那么自动分配)。下面举个例子,假设现在有两台机器A、B,A用于计算服务,B用于参数服务,那么代码如下:

#coding=utf-8
#上面是因为worker计算内容各不相同,不过再深度学习中,一般每个worker的计算内容是一样的,
# 以为都是计算神经网络的每个batch 前向传导,所以一般代码是重用的
import  tensorflow as tf
#现在假设我们有A、B台机器,首先需要在各台机器上写一份代码,并跑起来,各机器上的代码内容大部分相同
# ,除了开始定义的时候,需要各自指定该台机器的task之外。以机器A为例子,A机器上的代码如下:
cluster=tf.train.ClusterSpec({
    "worker": [
        "192.168.11.105:1234",#格式 IP地址:端口号,第一台机器A的IP地址 ,在代码中需要用这台机器计算的时候,就要定义:/job:worker/task:0
    ],
    "ps": [
        "192.168.11.130:2223"#第四台机器的IP地址 对应到代码块:/job:ps/task:0
    ]})

#不同的机器,下面这一行代码各不相同,server可以根据job_name、task_index两个参数,查找到集群cluster中对应的机器

isps=False
if isps:
	server=tf.train.Server(cluster,job_name='ps',task_index=0)#找到‘worker’名字下的,task0,也就是机器A
	server.join()
else:
	server=tf.train.Server(cluster,job_name='worker',task_index=0)#找到‘worker’名字下的,task0,也就是机器A
	with tf.device(tf.train.replica_device_setter(worker_device='/job:worker/task:0',cluster=cluster)):
		w=tf.get_variable('w',(2,2),tf.float32,initializer=tf.constant_initializer(2))
		b=tf.get_variable('b',(2,2),tf.float32,initializer=tf.constant_initializer(5))
		addwb=w+b
		mutwb=w*b
		divwb=w/b

saver = tf.train.Saver()
summary_op = tf.merge_all_summaries()
init_op = tf.initialize_all_variables()
sv = tf.train.Supervisor(init_op=init_op, summary_op=summary_op, saver=saver)
with sv.managed_session(server.target) as sess:
	while 1:
		print sess.run([addwb,mutwb,divwb])

把该代码在机器A上运行,你会发现,程序会进入等候状态,等候用于ps参数服务的机器启动,才会运行。因此接着我们在机器B上运行如下代码:

#coding=utf-8
#上面是因为worker计算内容各不相同,不过再深度学习中,一般每个worker的计算内容是一样的,
# 以为都是计算神经网络的每个batch 前向传导,所以一般代码是重用的
#coding=utf-8
#多台机器,每台机器有一个显卡、或者多个显卡,这种训练叫做分布式训练
import  tensorflow as tf
#现在假设我们有A、B、C、D四台机器,首先需要在各台机器上写一份代码,并跑起来,各机器上的代码内容大部分相同
# ,除了开始定义的时候,需要各自指定该台机器的task之外。以机器A为例子,A机器上的代码如下:
cluster=tf.train.ClusterSpec({
    "worker": [
        "192.168.11.105:1234",#格式 IP地址:端口号,第一台机器A的IP地址 ,在代码中需要用这台机器计算的时候,就要定义:/job:worker/task:0
    ],
    "ps": [
        "192.168.11.130:2223"#第四台机器的IP地址 对应到代码块:/job:ps/task:0
    ]})

#不同的机器,下面这一行代码各不相同,server可以根据job_name、task_index两个参数,查找到集群cluster中对应的机器

isps=True
if isps:
	server=tf.train.Server(cluster,job_name='ps',task_index=0)#找到‘worker’名字下的,task0,也就是机器A
	server.join()
else:
	server=tf.train.Server(cluster,job_name='worker',task_index=0)#找到‘worker’名字下的,task0,也就是机器A
	with tf.device(tf.train.replica_device_setter(worker_device='/job:worker/task:0',cluster=cluster)):
		w=tf.get_variable('w',(2,2),tf.float32,initializer=tf.constant_initializer(2))
		b=tf.get_variable('b',(2,2),tf.float32,initializer=tf.constant_initializer(5))
		addwb=w+b
		mutwb=w*b
		divwb=w/b

saver = tf.train.Saver()
summary_op = tf.merge_all_summaries()
init_op = tf.initialize_all_variables()
sv = tf.train.Supervisor(init_op=init_op, summary_op=summary_op, saver=saver)
with sv.managed_session(server.target) as sess:

	while 1:
		print sess.run([addwb,mutwb,divwb])

分布式训练需要熟悉的函数:


参考文献:

https://www.tensorflow.org/versions/master/how_tos/distributed/index.html




sklearn与tensorflow机器学习实用指南第二版

...ras搭建人工神经网络十一、训练深度神经网络十二、使用TensorFlow自定义模型并训练十三、使用TensorFlow加载和预处理数据十四、使用卷积神经网络实现深度计算机视觉十五、使用RNN和CNN处理序列十六、使用RNN和注意力机制进行自... 查看详情

tensorflow——分布式的tensorflow运行环境(代码片段)

...行资源,而且还要花费大量时间才能完成训练。1.分布式TensorFlow的角色与原理在分布式的TensorFlow中的角色分配如下:PS:作为分布式训练的服务端,等待各个终端(supervisors)来连接。worker:在TensorFlow的代码注释中被称为终端(superv... 查看详情

当spark遇上tensorflow分布式深度学习框架原理和实践

近年来,机器学习和深度学习不断被炒热,tensorflow作为谷歌发布的数值计算和神经网络的新框架也获得了诸多关注,spark和tensorflow深度学习框架的结合,使得tensorflow在现有的spark集群上就可以进行深度学习,而不需要为深度学... 查看详情

java应用xv使用java中的tensorflow来构建和训练机器学习模型

...在评论区留言,分享想法和建议。谢谢支持!一、引言1.1TensorFlow简介TensorFlow是由GoogleBrain团队开发的开源深度学习框架,于2015年首次发布,目前已成为业界广泛使用的深度学习框架之一。TensorFlow提供了一个灵活的、高度可扩展... 查看详情

深度学习tensorflow如何使用多gpu并行模式?

TensorFlow可以用单个GPU,加速深度学习模型的训练过程,但要利用更多的GPU或者机器,需要了解如何并行化地训练深度学习模型。常用的并行化深度学习模型训练方式有两种:同步模式和异步模式。下面将介绍这两种模式的工作... 查看详情

tensorflow中使用batchnormalization(代码片段)

在深度学习中为了提高训练速度,经常会使用一些正正则化方法,如L2、dropout,后来SergeyIoffe等人提出BatchNormalization方法,可以防止数据分布的变化,影响神经网络需要重新学习分布带来的影响,会降低学习速率,训练时间等问... 查看详情

tensorflow机器学习:如何正确的掌握google深度学习框架tensorflow(第二代分布式机器学习系统)?

本文标签:  机器学习TensorFlowGoogle深度学习框架分布式机器学习唐源VGGREST 服务器自2015年底开源到如今更快、更灵活、更方便的1.0版本正式发布,由Google推出的第二代分布式机器学习系统TensorFlow一直在为我们带来惊... 查看详情

tensorflow2深度学习实战(十五):目标检测算法yolov4实战(代码片段)

前言:本专栏以理论与实战相结合的方式,左手看论文,右手敲代码,带你一步步吃透深度学习原理和源码,逐一攻克计算机视觉领域中的三大基本任务:图像分类、目标检测、语义分割。本专栏完整代码... 查看详情

tensorflow深度学习学习率

为什么我用学习率递减,没有效果,loss值一直停留在某个值浮动,正确率也很低求大佬指点参考技术A说明优化到一个极小值了呗。试试adam?追问我之前用0.001的学习率训练过模型了,能达到95%,大概2000多轮,我想做成学习率自... 查看详情

小白入门深度学习|第六篇:tensorflow2回调极速入门

...学习》配套实例教程:《深度学习100例》文章目录什么是Tensorflow回调?如何使用回调?如何设置早停?Lambda回调动态学习率模型检查点学习率降低LROnPlateau终止OnNaN什么是Tensorflow回调?Tensorflow回调是在训练深度学习模型时,在特... 查看详情

[翻译]使用tensorflow进行分布式训练

本文以两篇官方文档为基础来学习TensorFlow如何进行分布式训练,借此进入Strategy世界。本文以两篇官方文档为基础来学习TensorFlow如何进行分布式训练,借此进入Strategy世界。 查看详情

谷歌开源了tensorflow,世界就要马上被改变了吗

Google开源了其第二代深度学习技术TensorFlow——被使用在Google搜索、图像识别以及邮箱的深度学习框架。这在相关媒体圈、工程师圈、人工智能公司、人工智能研究团队里有了一些讨论。比较有趣的是,微软亚洲研究院立刻向媒... 查看详情

感悟:微博深度学习平台架构和实践

TensorFlow、Caffe和MXNet是三大主流的深度学习开源框架:TensorFlow的优势是社区最活跃,开源算法和模型最丰富;Caffe则是经典的图形领域框架,使用简单,在科研领域占有重要地位;MXNet在分布式性能上表现优异。PaddlePaddle、鲲鹏... 查看详情

深度学习入门篇--手把手教你用tensorflow训练模型

...获取更多腾讯海量技术实践干货哦~作者:付越 导语Tensorflow在更新1.0版本之后多了很多新功能,其中放出了很多用tf框架写的深度网络结构(https://github.com/tensorflow/models ),大大降低了开发难度,利用现成的网络结构,... 查看详情

tensorflow:模型训练tensorflow.train

深度学习训练中的几个概念(1)batchsize:批大小。在深度学习中,一般采用SGD训练,即每次训练在训练集中取batchsize个样本训练;一次Forword运算以及BP运算中所需要的训练样本数目,其实深度学习每一... 查看详情

深度学习中的分布式训练

1.为什么需要分布式训练随着人工智能与深度学习的发展,大规模和超大规模的模型越来越受到业界的推崇。以NLP行业为例,从最开始的Bert-base只有1亿左右的参数量,到千亿级别的GPT-3,再到今年6月发布的目前全球最大预训练模... 查看详情

数据并行:提升训练吞吐的高效方法|深度学习分布式训练专题

数据并行是大规模深度学习训练中非常成熟和常用的并行模式。本文将介绍数据并行的原理和主流实现方案,使用数据并行加速训练过程中需要注意的问题,以及如何优化数据并行进一步提高训练速度。希望能帮助用户... 查看详情

tensorflow如何入门?

1.TensorFlow是什么是一个深度学习库,由Google开源,可以对定义在Tensor(张量)上的函数自动求导。Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow即为张量从图的一端流动到另一端。它的一大亮点是支持异构... 查看详情