tensorflow问题总结

一级目录

Tensorflow分布式训练

分布式
分布式是指训练在多个工作节点(worker)上,工作节点是指实现计算的一个单元(一般为反向传播和参数更新),如果计算服务器是单卡,一般就是指的这台服务器;如果计算服务器是多卡,还可以根据多个GPU划分多个工作节点。当数据量达到超过一台机器的处理能力时,必须使用分布式。

分布式TensorFlow的底层通信是gRPC(google remote proceduce call)。gRPC是google开源的一个高性能,跨语言的RPC框架。RPC协议,即远程调用协议,是指通过网络从远程计算机程序上请求服务。也就是说,假设记载本机上执行了一段代码num=add(a,b),他被调用后得到一个返回结果,你感觉这段代码是在本机执行的,但实际上的add方法是将参数打包发送给远程服务器,由远程服务器运行add方法,将返回的结果在打包发送给本机客户端。

  • 假设有4块GPU,在单机多卡中一次处理4个批次的数据,每个GPU处理一个批次的数据计算。

  • 变量,也就是参数,保存在CPU上,数据由CPU分发给4个GPU,在GPU上完成计算,得到每个批次要更新的梯度。

  • 在GPU上收集完4个GPU上更新的梯度,计算一下平均梯度,然后更新参数。

  • 继续2和3步,循环这个过程。

工作节点服务是worker_service.proto接口的实现,使用本地设备对部分图进行计算,在TensorFlow服务端中,所有工作节点都包含工作节点的服务逻辑,每个工作节点负责管理一个或多个设备。工作节点也可以是不同端口的不同进程,或者多台服务器上的多个进程

在运行TF分布式时,我们首先要创建一个TF集群(cluster)对象,集群是参与分布式计算的机器组成的集群,有一个或多个作业(job)组成,而每个作业又有一个或多个具有相同目的的任务(task)组成。每个任务一帮有一个进程来执行。由此可知 作业是任务的集合,集群是作业的集合。

cluster = {'chief': ['host0:2222'],
            'ps': ['host1:2222', 'host2:2222'],
            'worker': ['host3:2222', 'host4:2222', 'host5:2222']}

在分布式机器学习框架中,一般把作业划分为参数作业(parameater job)和工人作业(worker job),参数作业运行的服务器称为参数服务器(PS)负责管理参数的存储和更新;工作节点的作业负责管理无状态且主要从事计算的任务(反向传播)。

集群中一般有多个worker,需要指定其中一个worker为主节点(cheif),chief节点会执行一些额外的工作,比如模型导出之类的。在PS分布式架构环境中,还需要定义ps节点。

要运行分布式Estimator模型,只需要设置好TF_CONFIG环境变量即可,可参考如下代码:

# Example of non-chief node:
os.environ['TF_CONFIG'] = json.dumps(
    {'cluster': cluster,
     'task': {'type': 'worker', 'index': 1}})

# Example of chief node:     
os.environ['TF_CONFIG'] = json.dumps(
    {'cluster': cluster,
     'task': {'type': 'chief', 'index': 0}})

# Example of evaluator node (evaluator is not part of training cluster)     
os.environ['TF_CONFIG'] = json.dumps(
    {'cluster': cluster,
     'task': {'type': 'evaluator', 'index': 0}})

定义好上述环境变量后,调用tf.estimator.train_and_evaluate即可开始分布式训练和评估,其他部分的代码跟开发单机的程序是一样的

1 分布式训练策略

1.1 模型并行

所谓模型并行指的是将模型部署到很多设备上(设备可能分布在不同机器上,下同)运行,比如多个机器的GPUs。当神经网络模型很大时,由于显存限制,它是难以完整地跑在单个GPU上,这个时候就需要把模型分割成更小的部分,不同部分跑在不同的设备上,例如将网络不同的层运行在不同的设备上。

由于模型分割开的各个部分之间有相互依赖关系,因此计算效率不高。所以在模型大小不算太大的情况下一般不使用模型并行。

在tensorflow的术语中,模型并行称之为”in-graph replication”。

1.2 数据并行

数据并行在多个设备上放置相同的模型,各个设备采用不同的训练样本对模型训练。每个Worker拥有模型的完整副本并且进行各自单独的训练。
在这里插入图片描述
相比较模型并行,数据并行方式能够支持更大的训练规模,提供更好的扩展性,因此数据并行是深度学习最常采用的分布式训练策略

在tensorflow的术语中,数据并行称之为”between-graph replication”。

2. 分布式并行模式

不同并行模式的区别在于不同的参数更新方式,数据并行可以是同步的(synchronous),也可以是异步的(asynchronous)。

2.1 异步训练

异步训练中,各个设备完成一个mini-batch训练之后,不需要等待其它节点,直接去更新模型的参数。根据当前参数的取值和随机获取的一小部分训练数据,不同设备各自运行反向传播的过程并独立地更新参数。

异步训练总体会训练速度会快很多,但是异步训练的一个很严重的问题是梯度失效问题(stale gradients),刚开始所有设备采用相同的参数来训练,但是异步情况下,某个设备完成一步训练后,可能发现模型参数已经被其它设备更新过了,此时这个设备计算出的梯度就过期了。由于梯度失效问题,异步训练可能陷入次优解(sub-optimal training performance)。

在tensorflow中异步训练是默认的并行训练模式。

2.2 同步训练

同步指的是所有的设备都是采用相同的模型参数来训练,等待所有设备的mini-batch训练完成后,收集它们的梯度后执行模型的一次参数更新。在同步模式下,所有的设备同时读取参数的取值,并且当反向传播算法完成之后同步更新参数的取值。单个设备不会单独对参数进行更新,而会等待所有设备都完成反向传播之后再统一更新参数 。

同步模式相当于通过聚合多个设备上的mini-batch形成一个更大的batch来训练模型,相对于异步模式,在同步模型下根据并行的worker数量线性增加学习速率会取得不错的效果。如果使用tensorflow estimator接口来分布式训练模型的话,在同步模式下需要适当减少训练步数(相对于采用异步模式来说),否则需要花费较长的训练时间。Tensorflow estimator接口唯一支持的停止训练的条件就全局训练步数达到指定的max_steps。

Tensorflow提供了tf.train.SyncReplicasOptimizer类用于执行同步训练。通过使用SyncReplicasOptimzer,你可以很方便的构造一个同步训练的分布式任务。把异步训练改造成同步训练只需要两步:

  1. 在原来的Optimizer上封装SyncReplicasOptimizer,将参数更新改为同步模式;optimizer = tf.train.SyncReplicasOptimizer(optimizer, replicas_to_aggregate=num_workers)
  2. 在MonitoredTrainingSession或者EstimatorSpec的hook中增加sync_replicas_hook:sync_replicas_hook = optimizer.make_session_run_hook(is_chief, num_tokens=0)

3.分布式训练架构

3.1 Parameter Server架构

Parameter server架构(PS架构)是深度学习最常采用的分布式训练架构。在PS架构中,集群中的节点被分为两类:parameter server和worker。其中parameter server存放模型的参数,而worker负责计算参数的梯度。在每个迭代过程,worker从parameter sever中获得参数,然后将计算的梯度返回给parameter server,parameter server聚合从worker传回的梯度,然后更新参数,并将新的参数广播给worker。
在这里插入图片描述

3.2 Ring AllReduce架构

PS架构中,当worker数量较多时,ps节点的网络带宽将成为系统的瓶颈。

Ring AllReduce架构中各个设备都是worker,没有中心节点来聚合所有worker计算的梯度。Ring AllReduce算法将 device 放置在一个逻辑环路(logical ring)中。每个 device 从上行的device 接收数据,并向下行的 deivce 发送数据,因此可以充分利用每个 device 的上下行带宽。
在这里插入图片描述

feature_column

feature_column 输入输出类型

1.深度模型的输入必须是Dense类型,所有输出是categorical类型需要经过indicator或者embedding的转换才可以
2.indicator, embedding, bucketized的输入不能是原始特征,前两者只能是categorical类型的feature_column, 后者只能是numeric_column
在这里插入图片描述

tf.feature_column.input_layer

1.input_layer 作为model的一个输入。

tf.feature_column.input_layer(
		features,
		feature_columns,
		weight_collections=None,
		trainable=True,
		cols_to_vars=None,
		cols_to_output_tensors=None
)

2.参数:
features:字典,最主要的是dict的key一定要与 feature_columns的key一致,后续才能根据key进行匹配。
feature_columns:该参数必须是继承于DenseColumn的,如numeric_column, embedding_column, bucketized_column, indicator_column,
如果feature是类别型的,那么必须先用embedding_column / indicator_column封装一下使用。
如果feature是连续型的,那么必须使用numeric_column / bucketized_column

高阶API原文
分布式原文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值