深度学习基础设施

by admin on 2020年4月25日

class=”zhaiyao”>摘要:深度学习是一门依据经验的科学,基础设施的质量,能够对深度学习的效果起到非常大的作用。幸运的是,如今的开源生态系统,能让任何人都搭建起优秀的深度学习基础设施。在这篇文章中,我们将会讲述深度学习的工作方式,以及它所依赖的基础设施。

   
(转载至:)
说到机器学习、大数据,大家听到的是 Hadoop 和 Spark 居多,它们跟
TensorFlow 是一个什么样的关系呢?是不是有 TensorFlow 就不需要 Spark
这些?
     像 Hadoop 跟
Spark,背后都是 MapReduce。Hadoop 更多是去写文件,Spark
更多是通过内存。它们通过 MapReduce,下发 task 给这些 executor
去做。它们擅长的这种并行运算叫“Embarrassingly
Parallel”,这种并行是非常完美的并行,要非常完美,最后收集结果。那么
Hadoop、Spark 用在哪?

容器拉取/启动快速。隔离资源效果好。抽象来看,可以将容器的image作为job的一部分分发调度执行。但是容器化后会引入gpu,网络等性能的代价。nvidia
gpu
对docker提供了支持,nvidia-docker代替docker执行create和run操作。cuda和cudnn镜像在这里

图片 1

 
 图片 2

图片 3nvidia-docker架构

深度学习是一门依据经验的科学,基础设施的质量,能够对深度学习的效果起到非常大的作用。幸运的是,如今的开源生态系统,能让任何人都搭建起优秀的深度学习基础设施。

  
机器学习第一步非常关键,就是对数据的预处理,因为互联网公司有非常多结构化数据,存在
Hive、MySQL
里面。这些数据经过处理以后才能供机器学习使用。这类的预处理非常适合用
Hadoop、Spark
这些来做。

kubernetes作为google开源的容器编排工具,发展十分迅速。最近release的版本是v1.4.1,已经十分稳定。

在这篇文章中,我们将会讲述深度学习的工作方式,以及它所依赖的基础设施。

   TensorFlow
特别擅长做深度学习
,如果一些神经网络,最后放在一个 graph
上看的话,很轻松就会达到一个很复杂的程度。所以,这样一个 graph,用前面的
MapReduce
其实很难写,而且它也没办法那样完美并行,而且深度学习还有个反向传播的过程,更难做了。所以 Hadoop 跟 Spark
从架构本质上,根本就是做不了深度学习的
。所以就出现了
TensorFlow。

图片 4kubernetes架构

使用场景


一般情况下,深度学习的作用是着手去让一个想法生效,然后你再用这个想法去解决某个小问题。在这个时候,你要立刻进行大量的ad-hoc实验。理想情况下,你只需要SSH进一台机器,在屏幕中运行一段代码,然后在不到一个小时的时间里,就可以获得结果。

要想让这个模式起作用,通常情况下需要看到它在哪种情况下无法起作用,然后再去寻找解决这些限制的方式(和开发新软件系统差不多,你需要多次运行代码,了解它的表现情况)。 

你需要从多个角度来审视深度学习的模式,才能真正的了解它在学习些什么。 

在你证明了模式有效之后,你就需要扩大其规模,为其配备更大的数据集和更多的GPU。这个工作需要你付出巨大的精力,还要好几天的时间。

早期的研究过程不成架构,但是速度快;之后的研究过程则更加有条理,但是过程却很痛苦。然而,要想获得好的结果,你必须要经历这种痛苦。 

   为什么需要
TensorFlow 来做深度学习?TensorFlow 大体的思路是这样,用
Python,一般是用 Python 定义好深度学习神经网络以后,TensorFlow 会做成
DAG,有向无环图,然后把 DAG 交给 TensorFlow 的 C++ Core
来运行,这样保证它的运算效率非常高。所以我个人认为,对于一个 framework
是否支持深度学习,最关键的就是:它是否支持构建 DAG 和进行 DAG
运算

说明

基础设施 


  • 软件

图片 5 

我们的大多数研究代码都是用Python写的。在GPU计算方面,我们主要使用TensorFlow(在一些特别的时候还会使用Theano)。而在CPU方面,除了TensorFlow和Theano之外,我们还使用了Numpy。有的时候,研究人员还会在TensorFlow之上使用一些更高级别的框架,例如Keras。与大多数深度学习社区一样,我们使用的是Python
2.7版本。

  • 硬件 

在理想状态下,让cluster中node的数量翻倍,能够让runtime所需的时间减少一半。然而,在深度学习领域,很多GPU却并非如此。要想获得最好的性能,你就需要使用最好的GPU。我们还需要很多的CPU,用作模拟装置,加强学习环境,或者降低模块的规模。

图片 6 

AWS为我们贡献了很好的计算能力,我们使用它们来当做CPU实例,减少GPU的负担。我们需要自己的实体服务器,主要用来运行Titan
X
GPU。从长期来看,我们还需要一个混合云:在使用不同的GPU、互联连接时,它会发挥重要的作用,对于未来的深度学习来说非常重要。 

图片 7 

  • 供给

我们使搭建基础设施的方式,类似许多公司对待产品的方式:它必须要展示一个简单的界面,可用性和功能性一样重要。我们使用了多种工具来管理所有服务器,并且尽可能用相同的方式对它们进行配置。

图片 8 

在设置AWS云资源(实例、网络路由、DNS记录等)时,我们使用了 Terraform。我们的云端和物理node运行的是 Ubuntu,并且使用用Chef进行配置的。所有的cluster都使用了非重叠IP范围,在接入公共互联网的时候,都使用了用户笔记本上的OpenVPN,以及物理node上的strongSwan(它扮演的是AWS Customer
Gateways的角色)。

我们会储存人们的home目录、数据集、以及 NFS(实体硬件上)和EFS/S3(AWS上)的结果。

  • 组织

很多时候,可扩展基础设施会让一些简单的事情变得复杂。因此我们为此付出了很多的经历,我们不断使用新的工具,让使用分布式use-case变得和本地use-case一样简单。

我们提供了一个SSH node的cluster用来完成ad-hoc实验,并且为物理和AWS
node运行 Kubernetes。我们的cluster覆盖了3种AWS区域。

Kubernetes要求每一个job都是一个Docker容器,这给我们提供了依赖隔绝和代码快照功能。然而,打造一个新的Docker容器会让研究者花费更多本来已经非常宝贵的时间,因此我们提供了一个工具,它可以将研究者笔记本中的代码转化为一张标准图像。

图片 9 

TensorBoard中的模式学习曲线

我们将Kubernetes的flannel网络直接暴露在研究者的笔记本上,允许用户将无缝通过网络接入正在运行的job,这对于接入TensorBoard等检测服务来说非常实用。

 图片 10

  1. 每个node下面docker
    engine:负责下载运行镜像kubelet:管理pod已经里面的containerkube-proxy:服务发现的proxy,代理网络流量
  2. kubernetes控制中心etcd:持久化支持观察者模式的配置中心,etcd高可用十分重要API
    Server:操作的接口Scheduler:调度pods(container的小集合)到指定node运行,这个实际可以替换使用MesosKubernetes
    Controller Manager
    Server:管理如保持副本个数等功能Kubernetes与mesos的区别
    @stackoverflow

kubernetes-ec2-autoscaler


我们的工作充满了突发性和各种难以预料的事情:一个原本只需要一个核心的实验突然需要1000个核心。例如,在几周的时间内,一个本来只需要一个Titan
X的实验,变成了需要60个Titan X的实验,然后突然又需要将近1600个AWS
GPU。因此,我们的云端基础设施需要能够动态调节Kubernetes node的能力。

在 Auto
Scaling群组中运行Kubernetes
node很简单,但是很难正确管理这些群组的数量。在batch
job提交之后,cluster就能马上知道它所需要的资源,并且直接对资源进行分配。(对比之下,AWS的Scaling
Policies会逐渐的增加新node,知道满足对资源的需求,这种做法需要经过多次迭代)。另外,在终止它们以避免丢失in-flight
job之前,cluster还需要drain node,

在进行大规模的batch
job时,我们总是会倾向于使用原始EC2,然而Kubernetes生态系统却能给我们带来很多价值:简单易用的工具、登录、检测、在运行的实例中对物理node进行拆分管理等等。准确的让Kubernetes完成自动规模化,比使用原始EC2重建整个生态系统要简单的多。

因此,我们推出了kubernetes-ec2-autoscaler,这是一个针对Kubernetes推出的对批处理进行了优化的规模化管理工具。在Kubernetes上,它扮演了普通的Pod的角色,而且只需要将你的worker
node放在Auto Scaling群组中。 

图片 11 

Kubernetes cluster的Launch配置

只有在poll了Kubernetes master的状态后,自动规模化工具才会生效,如果有额外的计算能力存在,它会耗干相关的node,并且最终终止它们。如果需要更多的资源,它会计算哪些服务器需要被创建,然后根据计算结果增加适量的Auto
Scaling群组。

kubernetes-ec2-autoscaler会处理多个Auto
Scaling群组、CPU之外的资源(内存和GPU),以及Job的细微限制(例如AWS区域和实例体积)。

另外,突发的工作量会导致Auto
Scaling群组超时和错误,这是由于AWS并不提供无线的容量。在这些情况下,kubernetes-ec2-autoscaler会探测错误,并且向次要的AWS区域进行溢出。

我们的基础设施,正在为深度学习研究人员提供最大化的效率,让他们专注于科研。我们正在打造更多的工具,继续改善这个基础设施,并且将会在未来几周或几个月内将最新进展分享给所有人。

转载自:SDK.cn

原    文:Infrastructure for Deep
Learning
译    文:SDK.cn
作    者:Christian(编译)

来源:SDK.cn

数据准备好了之后,我们把数据放在分布式存储里面。上面跑分布式
TensorFlow
,然后 TensorFlow 用集群里的 CPU 资源和 GPU 资源做
training
。 当模型训练好,用 TensorFlow Serving
能够接收线上的请求,实时做出预测
。分布式存储和计算,这样两块组合起来,这是深度学习平台
elearn 做的事情

  1. Kubernetes is a great place to start if you are new to the
    clustering world; it is the quickest, easiest and lightest way to
    kick the tires and start experimenting with cluster oriented
    development. It offers a very high level of portability since it
    is being supported by a lot of different providers (Microsoft,
    IBM, Red Hat, CoreOs, MesoSphere, VMWare, etc).

图片 12

  1. If you have existing workloads (Hadoop, Spark, Kafka, etc), Mesos
    gives you a framework that let’s you interleave those workloads with
    each other, and mix in a some of the new stuff including Kubernetes
    apps.
  2. Mesos gives you an escape valve if you need capabilities that are
    not yet implemented by the community in the Kubernetes framework.

overview

Kubernetes可以代替Marathon,在Mesos之上搭建cluster的工具


openai科学家们的训练日常需求

    elearn 是 TaaS
(TensorFlow as a Service),去年 8 月底开始研发,受到 Google CloudML
的启发。我们 elearn
的一个核心想法就是:我们让算法工程师可以专注于算法,他们不用再多花精力去搞
CPU 资源、去搞发布
。他们只要专心写算法就可以了,后面的事情全部交给
elearn。繁琐的事情,比如分布式存储、计算资源的弹性伸缩、IP / port
的管理、container 的生命周期,全部变成 API,不用管了。尤其这里面 IP
的管理 pod 的管理,本来也不应该算法工程师操心的。

  1. 小数据量,小模型的实验,快速尝试,一般需要几小时完成一次实验
  2. 大数据量,大模型。一般需要几天完成一次实验
  3. 日志对于分析定位十分重要,应该被持久化和更好的展示

  
而他们的现在现状是什么呢?现在算法工程师要操心非常多,他写完了之后,不知道怎么转化成工程产品;怎样大规模做
training;怎么做模型的版本管理,再到上线了以后,预测的性能不行。
  
这一切,导致深度学习没有办法拓展到更多业务,无法拓展到工程师这边来。然后让我们觉得
Deep Learning 好像有一点束之高阁的感觉

一般使用的工具箱

GPU: 讲到深度学习,大家一般都比较好奇
GPU 这方面的东西。GPU 很有意思,一般服务器会装好多块 GPU
卡,但是如果用的时候不做限制,就会导致 10
块卡全部用满。因此,需要所有同事建个微信群,大家商量好,你用 1
号卡,我用 2 号卡,第三个人用 3 号卡,基本上沟通靠微信群。这样 10
块卡的利用率极低。关键问题就在于需要手动设置两个环境变量
CUDA_DEVICE_ORDER 和 CUDA_VISIBLE_DEVICES 来限制使用 GPU。
你要知道没有开发者能一定记得每次设置这两个环境变量,而且这两个环境变量不能写在
.bashrc 这样的配置里面,因为每个人每次能够用的空闲 GPU
卡是不一样的。
但是如果在 elearn 的
container 里看到的,机器上虽然有 10 块卡,如果你只要一块卡,那么 elearn
就能做到让你在 container
里就只能看到一块卡,即使用爆了,也只能用这一张卡。这就是为什么要通过
container 来使用 GPU

  1. python2.7,一般使用Anaconda
  2. 使用tensorflow或者之上更高级的api Keras

图片 13

分布式深度学习关键技术

  • 说到
    GPU,提一句它的“内存”,跟平常的内存不一样, TensorFlow
    里它默认是抢占式的
    ,一上来就把这块 GPU
    所有的内存都抢掉,防止后续的内存碎片问题,但这个设置其实是可以取消的。
  • 再看 GPU 的 Docker
    image 直接用 Nvidia 打的 image 就可以了,还有基于此的
    TensorFlow官方GPU image,非常好用。
  • 最后讲到 GPU 跟
    Docker。一说到在 Docker 上用 GPU,很多人都以为一定要用 Nvidia
    修改版的 nvidia-docker 才行。其实根本不需要,直接用原生 Docker
    就能做到前面的效果,而且 Kubernetes 也是这样做的。Kubernetes
    只是帮你分 GPU ID,剩下的事情,比如原来 nvidia-docker
    帮你做掉的事情,是需要 elearn 帮你做的。
  1. 使用物理gpu机器和aws 提供的cpu机器搭建混合集群
  2. 使用kubernetes编排容器
  3. 自定义组件来支持不同job动态扩容/缩容的需求,kubernetes-ec2-autoscaler
  4. 使用 Terraform 构建每个机器的基础环境,使用Chef统一服务器配置。

分布式
training

tensorflow从V0.8开始支持分布式训练,目前稳定的版本是r0.11。详细的分布式训练的方案在这里。


几个主要的概念

  •   说起分布式
    training,就得提 TensorFlow
    的上一代产品,DistBelief。它是谷歌内部的上一代机器学习框架。这一代的出现,就已经解决
    model 的变量 size 超过了 GPU
    显存的范围的问题了。随着公司的发展,大家多多少少会在这方面遇到这样的问题。就跟谷歌在好多年前就已经开始用
    Borg,而直到现在,我们大家才用上
    Kubernetes,才意识到企业确实需要这样一个东西。另外,分布式 training
    可以给训练的过程加速。
  • 图片 14
  • 从单机版变成分布式
    training,其原理,首先是把模型参数这块单独拆出来,放在单独的 PS
    (parameter server) 上面
  • 图片 15
  • 这个 PS
    也是可以分布式
    的,这样就对模型大小理论上没有限制了。当再加一个
    worker 进来的时候,每个 worker 在每一轮训练开始时,去拉 model
    的最新状态。当它自己 Training 完了再把更新的内容告诉
    PS,这样完成一次 Training。如果两个甚至更多 worker
    在同时做这样的事情,那么就有两种模式,一种是同步,一种是异步
  • 图片 16
  • 但值得注意的是,TensorFlow
    只是一个代码框架
    ,它是不管你如何启动运行的。所以一个 TensorFlow
    cluster 的启动运行全得靠工程师自己来
  • 如果想启动一个 10
    台服务器组成的 cluster,你需要登录 10 台服务器、记下每个
    DNS、IP、Port,设计 10 条不一样的启动命令,手动敲 10
    遍等等;然后,还要自己搞分布式存储,mkdir
    把模型存放整齐。一个月后,你或许早就忘了你的模型存在哪台机器的哪台目录了。这还没完,training
    的时候,算法工程师要看
    TensorBoard,才能知道训练得好不好(如果训练到一半,看效果不好,就可以直接把训练停掉了)。
  • 图片 17
  • 好了,做这么多事情,到现在只训练了一个模型。业务上希望每周,甚至每天的新数据都要训练一版型模型,如果训练一个都这样麻烦,谁还受得了。
  1. ClusterCluser由一组Server组成,Server的功能可以是Worker也可以是PS。Worker中被client用session连接的作为master,提供协调,记录,checkpoint的功能
  2. JobJob包含多个Task,Job的典型角色是Worker或者PS
  3. Master
    service
    实现接口tensorflow::Session功能,协调worker工作。每个server都有实现
  4. TensorFlow server每个server都实现了”master service” 和 “worker
    service”

elearn
功能介绍

个人理解


  1. 提供的分布式功能还不是很完善提交脚本需要多台机器上执行,不方便
  2. 粒度为整个机器一个task在一台机器上可能占不满,也可能与其他job中的task相互影响,比如:都使用gpu0
  •   图片 18
  • 上图是elearn
    主界面,在上面可以轻松创建 TensorFlow cluster,现在只需要提供你的
    Docker image。然后借助 Datastore
    定义任何的数据来源,启动命令。这和算法工程师在本地开发的时候敲命令一模一样,没有很大的迁移成本。
  • 看到这里,你可能会发现
    elearn 不仅仅可以做分布式 training,如果做单机版 training 怎么办?把
    PS 和 worker 两项写成 0,只靠 master 工作,就是单机版
    training
  • 图片 19
  • 有了
    elearn,要跑一个这样的 GPU & CPU 跑分就非常轻松,发四个 API 请求给
    elearn, 过一会儿就可以看到结果
  • 图片 20
  • 这里面进行了分布式
    GPU 对比和 GPU & CPU 的对比,依次是 3 块 GPU、6 块 GPU、9 块
    GPU。可以看到多块 GPU 一起接近于线性的性能提升。
  • 这里即使大家觉得
    GPU 很牛,但是 CPU 跟 GPU 到底差多少?这个地方也能看出来,同样是 9
    个 CPU 和 9 个 GPU,性能差 9 到 10 倍,这算比较好的情况了。
  • 也就是说 GPU
    并没有你想想中的那么夸张,比如说 100 倍、1000 倍的提升,但是 GPU
    的提升意义也非常大,以前训练等 10 天要出结果,现在用了 GPU 等 1
    天就出结果了。
  • 但是 GPU
    非常贵,在企业里面 CPU 非常多非常多,如果 9 个 CPU 能顶一个
    GPU。(当然再往上去,就不可以做这样的数学运算了,CPU
    多了,瓶颈在于网络通讯之间的消耗了) 至少我觉得 1 块 GPU 跟 10 块
    CPU 对于一个企业的成本是不一样的

update–将开源资源调度工具与tensorflow分布式训练结合起来的github,
ecosystem

Model +
Serving

docker – Docker configuration for running TensorFlow on cluster
managers.kubernetes – Templates for running distributed TensorFlow on
Kubernetes.marathon – Templates for running distributed TensorFlow
using Marathon, deployed on top of Mesos.hadoop – TFRecord file
InputFormat/OutputFormat for Hadoop MapReduce and Spark.


  • 用户用着自己带来的
    Datastore 做 training,model 也是先往用户的 Datastore
    上面存。当你觉得这个 model 训练得效果比较好,就可以选择把这个 model
    存进 elearn,由 elearn 帮你托管 model。这个 model
    存了几次,都会记录好不同的版本。
  • 当在线上使用 model
    做预测的时候,有两种方式:第一种,由 elearn,启动 GRPC
    Serving,可以水平扩展;第二种,你可以把这个 model 下载,用
    Golang、Java 这些语言把 model
    直接加载进代码里,跟随着业务一起上线
  • 图片 21

实现过程思考


  • 第一,为 TensorFlow
    量身打造的。目前为止 elearn 是为 TensorFlow 量身打造的。包括现在
    Amazon 的 MXNet 和 Facebook pyTorch,还有一些新的
    framework,尤其是新手,觉得非常乱,社区和微信群各种横向的比拼,不知改选哪个。
    其实,你要知道为什么
    TensorFlow 会被 Google
    发明出来,就是因为谷歌意识到每个算法工程师,都是自己实现一套代码,只能做某一件事,别人很难看懂。等工程师应用的时候,根本没有办法分布式用、没有办法大范围用。这就造成了科学家、算法工程师跟实际场景的脱节。这个时候谷歌才推出了
    TensorFlow,用同一个 framework
    写,大家都能看懂,工具很多,还保证性能不错。所以 TensorFlow
    被发明出来了,就不要再折腾别的框架了,好好把 TensorFlow
    做好。
    除非有一种情况,需要再接受一个框架,就是当“下一代”架构被设计出来的时候,那么“下一代”框架可以取代
    TensorFlow,这时 elearn 也只要多写个 driver
    就可以立马支持。但是在此之前,我不会那么做,我们把 TensorFlow
    支持好,其他 framework 的所谓特色功能,TensorFlow
    一定在未来版本实现不了吗?Google
    有着非常丰富的社区运营经验,TensorFlow 的社区会让
    TensorFlow更加领先。

  • 第二,我在设计
    elearn 的 cloud interfaces 的时候,不是设计成“以 Pod
    为最小单元”,如果以这样作为接口来写 interfaces,就可以轻松接各种
    cloud了,但一旦这样做了以后,elearn 就只能用各个 cloud
    功能的交集,也就是只剩下最通用的部分,而忽略了每个 cloud
    编排的特色。

    所以我在做 elearn
    cloud interfaces
    的时候是面向功能的。这个同样可以实现功能,同样可以写其他的 Driver
    来轻松支持 Kubernetes 以外的 cloud,而且这样还能够用到每个 cloud
    特色的编排和功能。所以 elearn 是用了非常多 Kubernetes
    所特有的编排特性的。

  • 第三,我在这个项目中第一次尝试,把
    Kubernetes 真的当成一个 OS
    来用,这是什么意思呢?举个最简单的例子,以 save model
    为例,如果按往常,一个很自然的想法,在一个中心化的存储上面启动一个
    daemon,完成文件操作的请求。但这样的劣势就是所有的瓶颈阻塞在那台
    daemon 上。所以我们对于 post run,保存 model,这些都是一个个独立的
    Kubernetes Job,并不在 elearn server 或某台专门的 server
    上运行。Kubernetes 调度 Job 就像 OS 调度一个进程一样,让 Job
    完全分布式运行。 

 elearn:未来
       在 elearn
的基础上,我们还会提供更多工具。使深度学习的训练变得方便,才能有助于它在应用上真正发力。

 

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图