返回 登录
0

如何构建自己的深度学习基础设施

原文链接:Infrastructure for Deep Learning

翻译:刘翔宇 审校:赵屹华

深度学习是一门经验科学,许多基础设施的质量也在倍增。幸运的是,现在的开源生态系统可以使任何人建立不错的深度学习基础设施。

在这篇文章中,我们将讲述深度学习研究通常如何进行,介绍可选的对应基础设施以及开源的kubernetes-ec2-autoscaler,用于Kubernetes的批次优化扩展管理。希望这篇文章对你构建自己的深度学习基础设施有所帮助。

用例

深度学习典型的进步是从一个想法开始的,你在一个小问题上进行测试。在这个阶段,你想要快速的进行许多临时实验。理想情况下,你可以通过SSH连上一台机器,然后运行脚本,并在一小时以内得到结果。

要使模型真正工作,通常需要预见所有可能出错的情况,并且设法解决这些限制。(这类似于构建新的软件系统,你多次运行代码来了解它的运行情况。)

视频

你需要从多个角度来考察你的模型,以了解它们的实际学习情况。上面这个来自于Dario Amodei强化学习Agent(控制右边的球拍)取得了高比分,但当你看着它玩时,你会发现它只是呆在一个地方。因此,深度学习基础设施必须能够让用户灵活观察模型,仅仅给出汇总统计是不够的。

一旦模型表现不错,你可以将它使用在更大的数据集和更多的GPU上。这是需要进行长期任务时才这么做,它们会消耗很多周期,并持续数天。你需要对实验小心管理,对所选择的超参数范围要考虑非常周到。

前期的研究过程都是非结构化的、敏捷的;后期研究则是有条不紊的,并在一定程度上让人感到痛苦,但这都是得到良好结果所必须的。

例子

论文Improved Techniques for Training GANs 开头讲述了Tim Salimans设计了几种改善生成对抗性网络训练的思想。我们将介绍最简单的思想(产生最好的样本,但不是最好的半监督学习)。GAN包含一个生成器和一个鉴别器网络。生成器尝试愚弄鉴别器,而鉴别器则尝试区分生成数据和真实数据。直观地说,可以愚弄所有鉴别器的生成器是一个好的生成器。但是有一个难以修复的错误:生成器可能会“崩溃”,总是会输出完全一样(可能是逼真的!)的样本。

Tim提出这样的想法,给鉴别器输入样本的一个小批次,而不是将整个样本作为输入。因此鉴别器就可以区分生成器是不是不断产生一张图像。当发现崩溃,生成器将会进行梯度调整来纠正这一问题。

下一步就是将这个想法在MNISTCIFAR10上构建原型。这需要尽快原型化一个小模型,使用真实数据,并检查结果。经过一番快速迭代,TIm得到了非常令人振奋的CIFAR-10样本——这个数据集上我们见过最好的样本。

然而,深度学习(和一般的AI算法)必须进行扩展——小的神经网络可以证明一个概念,但是大的神经网络才能真正解决问题,才能为人所用。所以Ian Goodfellow 将这个模型扩展到ImageNet上进行使用。

我们的模型学会了生成ImageNet的图画

对于更大的模型和数据集,Ian需要将模型并行部署在多个GPU上。每个Job将会占用90%的CPU和GPU,但即便如此,该模型还是需要经过多天的训练。在这种情况下,每个实验显得弥足珍贵,他会一丝不苟地记录每个实验结果。

最终,虽然结果还不错,但并没有我们期望的那么好。虽然已经测试过很多假设,但仍然没有解决。这就是科学的本质。

基础设施

软件

我们Tensorflow代码的一个例子

我们绝大多数的研究代码是使用Python所写的,可以在我们项目中看到。我们主要使用Tensorflow(或者在特殊情况下使用Theano)进行GPU计算;对于CPU计算我们还会使用Numpy。研究人员有时还会使用高层框架,例如基于Tensorflow的Keras

与多数深度学习社区一样,使用Python 2.7。我们通常使用Anaconda,它能很方便的打包,如OpenCV,和对一些科学计算库文件进行性能优化

硬件

对于理想的批处理作业,加倍集群中的节点可以减半作业运行时间。不幸的是,在深度学习方面,增加GPU个数会次线性加快速度。因此,要达到顶级性能需要超顶级的GPU。我们还在模拟器强化学习环境、或小规模模型上使用了许多CPU(这不比在GPU上运行的快)。

Nvidia-smi下满载的Titan Xs

AWS慷慨地给我们提供了大量的计算机。使用它们进行CPU实例以及水平扩展GPU作业。我们同样会运行自己的物理机,主要使用的是Titan X GPU。我们希望有混合云:它可以使用不同GPU、互联以及将来可能成为重要深度学习的技术进行实验。

htop上同样的物理单元显示有许多空闲的CPU。我们通常将CPU密集型工作与GPU密集型分开运行。

配置

我们使用基础设施与其他公司对待产品一样:它必须有简洁的界面,可用性与功能同等重要。我们使用一套统一的工具来管理所有的服务器并尽可能对它们进行同样的配置。

Terraform配置管理自动扩展组片段。Terraform创建,修改,或销毁运行的云资源来匹配你的配置文件。

我们使用Terraform来建立AWS云资源(实例,网络路由,DNS记录等)。云和物理节点运行的是Ubuntu,使用Chef进行配置。为了加速处理,我们使用Packer来对集群AMI进行预处理。我们所有的集群使用非重叠的IP范围,通过用户笔记本上OpenVPN在共用网络上互联,strongSwan部署在物理节点上(作为AWS客户端网关)。

我们将用户的主目录,数据集以及结果存储在NFS(物理硬件)和EFS/S3(AWS)上。

编制

可扩展的基础设施通常会导致简单用例变复杂。我们在基础设施的小型和大型作业上投入了同等精力,并且正在积极固化我们的工具包,使分布式用例与本地用例一样可用。

我们提供了SSH节点(有的有GPU,有的没有)的集群用于临时实验,并在物理节点和AWS节点上使用 Kubernetes 作为集群调度器。集群跨越3个AWS regions——我们的作业比较耗费资源,有时候会占满单个regions所有资源。

Kubernetes要求每个作业都是一个Docker容器,这样可以提供依赖隔离和代码快照。然而,构建一个新的Docker容器会给研究人员迭代周期增加少量额外的时间,所以我们也提供工具将研究人员笔记本上的代码转换成标准镜像。

TensorBoard中模型的学习曲线

我们将Kubernetes的flannel网络直接暴露给研究人员的笔记本电脑,允许用户无缝网络访问他们运行的作业。这在访问监控服务时非常有用,比如TensorBoard。(最初的做法——从严格隔离的角度来看更明确——需要用户为他们想要暴露的端口创建一个Kubernetes服务,但发现这会带来很大阻力。)

kubernetes-ec2-autoscaler

我们的工作量会爆发性激增,并且不可预知:一项研究可能从单台机器可以进行的实验迅速地发展到需要1000个核心才能进行。比如,过了几个星期,一项实验交互阶段只需一个Titan X,到了实验阶段需要60块Titan X,再到需要将近1600块 AWS GPU。因此,我们的云基础设施需要动态的配置Kubernetes节点。

自动扩展组中很容易运行Kubernetes节点,但是要正确管理这些组的大小就很难。在批处理作业提交后,集群知道它需要多少资源,然后直接分配。(相反,AWS的扩展策略将会产生新的节点碎片,直到有剩余资源,这可能会多次进行。)此外,在集群终止节点前,需要洩流节点,避免丢失正在执行的作业。

只使用原始的EC2进行大批量作业很诱人,而我们开始也是这么做的。然而,Kubernetes 生态系统带来了很多价值:低阻力工具,日志,监控,能够从运行实例中分别管理物理节点等。正确配置Kubernetes自动扩展比在原始EC2上重新构建这个生态系统更简单。

我们即将推出kubernetes-ec2-autoscaler,面向Kubernetes的批处理优化的扩展管理。它在Kubernetes上作为普通的Pod运行,只需你的工作节点在自动扩展组内。

Kubernetes集群的启动配置

自动扩展器获取Kubernetes 主节点的状态,包括计算集群资源需求和容量所需的一切信息。如果资源不足,它将会洩流节点,然后终止它们。如果需要更多的资源,它会计算应该创建什么服务并适当增大自动扩展组的大小(或是简单的取消已洩流节点警告,从而避免了新节点起转的时间)。

kubernetes-ec2-autoscaler 负责处理多个自动扩展组,超过CPU(内存和GPU)的资源,限制你作业的细粒度因素,比如AWS region和实例大小。此外,突发性工作负载可能导致自动扩展组超时和错误,因为(令人惊讶!)AWS不具有无限容量。在这种情况下,kubernetes-ec2-autoscaler 检测到错误并把作业发配到第二个AWS region。

我们的基础设施旨在最大限度地提高深度学习研究人员的工作效率,让他们能够专注于科学研究。我们正在构建工具进一步提高我们的基础设施和工作流程,并会在未来几周和几个月内分享它们。我们欢迎大家提供帮助来促进这事业的发展!

评论