使用Tensorflow进行分布式训练介绍
我们大多数人都知道Tensorflow是一个广泛应用的开源机器学习框架。
Tensorflow允许使用神经网络构建,训练和预测。
在训练中,我们使用数据了解网络的参数。
用大量数据训练复杂的神经网络通常需要很长时间。有时它可能需要超过80小时的图像识别模型才能在单个GPU上达到75%的准确度。更准确地说,像resnet50这样的复杂模型,在单个但功能强大的GPU(比如特斯拉P100)上训练大约需要一周时间。
所以,一个很自然的问题要问,“我们怎样才能让训练更快?”
有很多方法可以尝试,我们可以使用更快的加速器,如TPU或Tensor Processing Units,另一种选择是使用分布式训练,即在多个设备上并行运行训练,如CPU,GPU和TPU。
分布式训练中的一些高级模型和体系结构
这些模型和架构将使我们更好地了解解决方案,从而加快训练速度。
循环训练
假设您有一个简单的神经网络模型,其中包含几个隐藏层,每个层都有一堆权重和偏差,也称为模型参数或可训练变量。
训练步骤从对输入数据的一些处理开始,并将此输入馈送到模型中并计算forward pass中的预测,然后我们将预测与输入标签进行比较并计算损失。然后,在backward pass中,我们计算梯度,最后,我们使用这些梯度更新模型参数。整个过程称为整个训练步骤。因此,训练循环重复这个训练步骤,直到您达到所需的精度。
假设您使用多核CPU在桌面下的设备开始训练。幸运的tensorflow自动扩展到多核CPU。接下来,您可以添加加速器以使用GPU或TPU加速您的机器。
使用分布式系统,您可以从一台具有单个设备的计算机过渡到具有多个设备的计算机,最后,从具有多个设备的多台计算机过渡到具有多个设备的多台计算机,每个设备都位于连接网络上。
最终可以扩展超过100个设备,这是在许多谷歌系统中应用的
那么,分布式训练如何运作的呢?
与软件工程中的其他所有内容一样,当您考虑分发训练时,有很多方法可以解决。您选择的方法取决于您的模型大小,您拥有的训练数据量以及可用的设备。分布式训练中最常见的架构是数据并行。
在数据并行性中,我们对每个工作者(GPU / TPU)运行一些模型和计算,但使用不同的输入数据片。每个设备计算损耗和梯度以及如上所述的这些梯度用于更新模型参数,更新的模型用于下一轮计算
当您考虑如何使用这些梯度更新模型时,有两种常用方法。第一种方法称为异步参数服务器方法。在这种方法中,我们将一些设备指定为蓝色显示的参数服务器,
这些服务器包含模型的参数,其他服务器被指定为工作程序,如绿色所示。workers进行大部分计算。每个worker从参数服务器获取参数,然后计算损失和梯度,然后将梯度发送回服务器,然后服务器使用这些梯度更新模型参数。每个worker都独立完成。因此,这种方法允许我们将这种方法扩展到大量workers。
对于Google中的许多模型而言,这一点非常有效,在这些神经网络模型中,训练工作者可能会被高优先级的生产工作所抢占,或者不同的workers之间存在不对称,或者机器可能会因常规维护而停工。因此,缺点是,workers可能总是不同步,他们在陈旧参数上计算他们的价值,这可能会延迟收敛。
第二种方法是所谓的同步Allreduce架构。随着诸如TPU或GPU的快速加速器的出现,这种方法变得更加普遍。
在这种方法中,每个worker都有自己的参数副本,没有特殊的参数服务器,每个worker根据训练样本的子集计算最后的结束梯度。一旦计算出梯度,workers就相互通信以传播梯度并更新其模型参数。
所有workers都是同步的,这意味着在每个worker收到更新的梯度并更新其模型之前,下一轮计算才会开始。
最重要的是,在单台机器或少量机器上使用多台设备时,Allreduce可以很快。
因此,鉴于这两种广泛的数据并行体系结构,您可能想知道选择哪种方法。没有一个正确的答案,因为参数服务器方法是大量不那么强大或不那么可靠的机器(如只有CPU的大型机器集群)的首选。另一方面,如果您在一台计算机上拥有具有强大通信链路的快速设备(如TPU或多个GPU),则同步allreduce方法更为可取。