1、多GPU原理
单GPU时,思路很简单,前向、后向都在一个GPU上进行,模型参数更新时只涉及一个GPU。多GPU时,有模型并行和数据并行两种情况。模型并行指模型的不同部分在不同GPU上运行。数据并行指不同GPU上训练数据不同,但模型是同一个(相当于是同一个模型的副本)。TensorFlow支持的是数据并行。数据并行的原理:CPU负责梯度平均和参数更新,在GPU上训练模型的副本。多GPU并行计算的过程:
1)模型副本定义在指定的GPU/CPU上;
2)对于每一个GPU, 都是从CPU获得数据,前向传播进行计算,得到loss,并计算出梯度;
3)CPU接到GPU的梯度,取平均值,然后进行梯度更新。
这个在tf的实现思路如下:
模型参数保存在一个指定gpu/cpu上,模型参数的副本在不同gpu上,每次训练,提供batch_size*gpu_num数据,并等量拆分成多个batch,分别送入不同GPU。前向在不同gpu上进行,模型参数更新时,将多个GPU后向计算得到的梯度数据进行平均,并在指定GPU/CPU上利用梯度数据更新模型参数。假设有两个GPU(gpu0,gpu1),模型参数实际存放在cpu0上,实际一次训练过程如下图所示:
2、model_deploy.py文件及其用法
为了能让一个Slim模型在多个GPU上训练更加容易,这个模块提供了一系列帮助函数,比如create_clones()、optimize_clones()、deploy()、gather_clone_loss()、_add_gradients_summaries()、_sum_clones_gradients()等,该模块位于:https://github.com/tensorflow/models/blob/master/research/slim/deployment/model_deploy.py
详细步骤:
(1)创建DeploymentConfig对象:config = model_deploy.DeploymentConfig()
Deployment类定义的源码如下:
class DeploymentConfig(object):
''' 这个配置类描述了如何将一个模型部署在多个单机的多个GPU上,在每个单机上,模型将挥被复制num_clones次
'''
def __init__(self,num_clones=1, clone_on_cpu=False,
replica_id=0, num_replicas=1,num_ps_tasks=0,
worker_job_name='worker',ps_job_name='ps'):
参数:
num_clones : 每个单机部署多少个clone(即部署在多少个GPU)
clone_on_cpu : 如果为True,则单机中的每个clone将被放在CPU中
replica_id : 整数,模型所部署的单机的索引,通常是0.
num_replicas: 使用多少个单机,通常为1,表示单机部署。此时`worker_device`, `num_ps_tasks`和 `ps_device`这几个参数将被忽略。
num_ps_tasks: ‘ps’作业(分布式作业)使用多少个单机,如果为0表示不使用单机
worker_job_name: 默认为“worker”
ps_job_name:默认为'ps'
if num_replicas > 1:
if num_ps_tasks < 1:
raise ValueError('When using replicas num_ps_tasks must be positive')
if num_replicas > 1 or num_ps_tasks >