ML平台_小米深度学习平台的架构与实践

    (转载:http://www.36dsj.com/archives/85383)机器学习与人工智能,相信你们已经耳熟能详,随着大规模标记数据的积累神经网络算法的成熟以及高性能通用GPU的推广,深度学习逐渐成为计算机专家以及大数据科学家的研究重点。近年来,不管是图像的分类识别和检测,仍是语音生成、天然语言处理,甚至是AI下围棋或者打游戏都基于深度学习有了很大的突破。而随着TensorFlow、Caffe等开源框架的发展,深度学习的门槛变得愈来愈低,甚至初中生均可以轻易实现一个图像分类或者自动驾驶的神经网络模型,但目前最前沿的成果主要仍是出自Google、微软等巨头企业。算法

     Google不只拥有优秀的人才储备和大数据资源,其得天独厚的基础架构也极大推进了AI业务的发展,得益于内部的大规模集群调度系统Borg,开发者能够快速申请大量GPU资源进行模型训练和上线模型服务,而且经过资源共享和自动调度保证总体资源利用率也很高。Google开源了TensorFlow深度学习框架,让开发者能够在本地轻易地组合MLP、CNN和RNN等模块实现复杂的神经网络模型,但TensorFlow只是一个数值计算库,并不能解决资源隔离、任务调度等问题,将深度学习框架集成到基于云计算的基础架构上将是下一个关键任务数据库

     除了Google、微软,国内的百度也开源了PaddlePaddle分布式计算框架,而且官方集成了Kubernetes等容器调度系统,用户能够基于PaddlePaddle框架实现神经网络模型,同时利用容器的隔离性和Kubernetes的资源共享、自动调度、故障恢复等特性,但平台不能支持更多深度学习框架接口。而亚马逊和腾讯云相继推出了面向开发者的公有云服务,能够同时支持多种主流的开源深度学习框架,阿里、金山和小米也即将推出基于GPU的云深度学习服务,还有无数企业在默默地研发内部的机器学习平台和大数据服务。编程

    面对如此眼花缭乱的云服务和开源技术,架构师该如何考虑其中的技术细节,从用户的角度又该如何选择这些平台或者服务呢。我将介绍小米云深度学习平台的架构设计与实现细节,但愿能给AI领域的研发人员提供一些思考和启示。后端

云深度学习平台设计api


     云深度学习平台(Cloud Machine Learning),就是基于云计算的机器学习和深度学习平台。首先TensorFlow、MXNet是深度学习框架或者深度学习平台,但并非云深度学习平台,它们虽然能够组成一个分布式计算集群进行模型训练,但须要用户在计算服务器上手动启动和管理进程,并没有云计算中任务隔离、资源共享、自动调度、故障恢复以及按需计费等功能。所以咱们须要区分深度学习类库以及深度学习平台之间的关系,而这些类库实现的随机梯度降低反向传播等算法倒是深度学习应用所必须的,这是一种全新的编程范式,须要咱们已有的基础架构去支持。数组

云计算和大数据发展超过了整整十年,在业界催生很是多优秀的开源工具,如实现了相似AWS IaaS功能的OpenStack项目,还有Hadoop、Spark、Hive等大数据存储和处理框架,以及近年很火的Docker、Kubernetes等容器项目,这些都是构建现代云计算服务的基石。安全

这些云服务有共同的特色,例如咱们使用HDFS进行数据存储,用户不须要手动申请物理资源就能够作到开箱即用,用户数据保存在几乎无限制的公共资源池中,而且经过租户隔离保证数据安全,集群在节点故障或者水平扩容时自动触发Failover且不会影响用户业务。虽然Spark经过MLib接口提供部分机器学习算法功能,但毫不能替代TensorFlow、Caffe等深度学习框架的做用,所以咱们仍须要实现Cloud Machine Learning服务,而且确保实现云服务的基本特性服务器

总结为下面几条:网络

  • 屏蔽硬件资源保证开箱即用
  • 缩短业务环境部署和启动时间
  • 提供“无限”的存储和计算能力
  • 实现多租户隔离保证数据安全
  • 实现错误容忍和自动故障迁移
  • 提升集群利用率和下降性能损耗 

相比于MapReduce或者Spark任务,深度学习的模型训练时间周期长,并且须要调优的超参数更多,平台设计还须要考虑如下几点:架构

  • 支持通用GPU等异构化硬件
  • 支持主流的深度学习框架接口
  • 支持无人值守的超参数自动调优
  • 支持从模型训练到上线的工做流

这是我我的对云深度学习平台的需求理解,也是小米在实现cloud-ml服务时的基本设计原则。虽然涉及到高可用、分布式等颇具实现难度的问题,但借助目前比较成熟的云计算框架和开源技术,咱们的架构和实现基本知足了前面全部的需求

云深度学习平台架构


遵循前面的平台设计原则,咱们的系统架构也越发清晰明了,为了知足小米内部的全部深度学习和机器学习需求:

  • 须要有一个多租户、任务隔离、资源共享、支持多框架和GPU的通用服务平台
  • 经过实现经典的MLP、CNN或RNN算法并不能知足业务快速发展的需求,所以咱们须要支持TensorFlow等用户自定义的模型结构
  • 支持高性能GPU和分布式训练是这个云深度学习平台的必须功能
  • 不只仅是模型训练,咱们还但愿集成模型服务等功能来最大化用户的使用效益

计算机领域有句名言“任何计算机问题均可以经过增长一个中间层来解决”。不管是AWS、OpenStack、Hadoop、Spark仍是TCP/IP都是这样作的,经过增长一个抽象层来屏蔽底层资源,对上层提供更易用或者更可靠的访问接口。小米的cloud-ml平台也须要实现对底层物理资源的屏蔽,尤为是对GPU资源的抽象和调度,但咱们不须要从新实现,由于社区已经有了不少成熟的分布式解决方案,如OpenStack、Yarn和Kubernetes。目前OpenStack和Yarn对GPU调度支持有所欠缺,虚拟机也存在启动速度慢、性能overhead较大等问题,而容器方案中的Kubernetes和Mesos发展迅速,支持GPU调度等功能,是目前最值得推荐的架构选型之一

进一步简化了整个云深度学习平台的使用流程,总体架构设计以下图:

  • 目前小米cloud-ml平台的任务调度和物理机管理基于多节点的分布式Kubernetes集群,对于OpenStack、Yarn和Mesos咱们也保留了实现接口,能够经过实现Mesos后端让用户的任务调度到Mesos集群进行训练,最终返回给用户一致的使用接口。
  • 目前Kubernetes最新稳定版是1.6,已经支持Nvidia GPU的调度和访问,对于其余厂商GPU暂不支持但基本能知足企业内部的需求,并且Pod、Deployment、Job、StatefulSet等功能日趋稳定,加上Docker、Prometheus、Harbor等生态项目的成熟,已经在大量生产环境验证过,能够知足通用PaaS或者Cloud Machine learning等定制服务平台的需求。
  • 使用Kubernetes管理用户的Docker容器,还解决了资源隔离的问题,保证不一样深度学习训练任务间的环境不会冲突,而且能够针对训练任务和模型服务使用Job和Deployment等不一样的接口,充分利用分布式容器编排系统的重调度和负载均衡功能。
  • 可是,Kubernetes并无完善的多租户和Quota管理功能,难以与企业内部的权限管理系统对接,这要求咱们对Kubernetes API进行再一次“抽象”。咱们经过API Server实现了内部的AKSK签名和认证受权机制,在处理用户请求时加入多租户和Quota配额功能,而且对外提供简单易用的RESTful API,

云深度学习平台实现


     前面提到咱们后端使用Kubernetes编排系统,经过API Server实现受权认证和Quota配额功能。因为云深度学习服务是一个计算服务,和我之前作过的分布式存储服务有着本质的区别,计算服务离线运算时间较长,客户端请求延时要求较低并且吞吐很小,所以咱们的API服务在易用性和高性能上能够选择前者,目前主流的Web服务器均可以知足需求。基于Web服务器咱们能够实现集成内部权限管理系统的业务逻辑,小米生态云提供了相似AWS的AKSK签名认证机制,用户注册登陆后能够自行建立Access key和Secret key,请求时在客户端进行AKSK的签名后发送,这样用户不须要把帐号密码或密钥加到请求中,即便密钥泄露也能够由用户来禁用,请求时即便签名被嗅探也只能重放当前的请求内容,是很是可靠的安全机制。除此以外,咱们参考OpenStack项目的体系架构,实现了多租户和Quota功能,经过认证和受权的请求须要通过Quota配额检查,在高可用数据库中持久化相应的数据,这样平台管理员就能够动态修改每一个租户的Quota,并且用户能够随时查看自身的审计信息。

  • 小米cloud-ml服务实现了深度学习模型的开发、训练、调优、测试、部署和预测等完整功能,都是经过提交到后端的Kubernetes集群来实现,
  • 完整的功能介绍能够查看官方文档 http://docs.api.xiaomi.com/cloud-ml
  • Kubernetes对外提供了RESTful API访问接口,经过YAML或者JSON来描述不一样的任务类型,不一样编程语言实现的系统也可使用社区开发的SDK来访问。
  • 对于咱们支持的多个深度学习框架,还有开发环境、训练任务、模型服务等功能,都须要定制Docker镜像,提交到Kubernetes时指定使用的容器镜像、启动命令等参数。
  • 经过对Kubernetes API的封装,咱们能够简化Kubernetes的使用细节,保证了对Mesos、Yarn等后端支持的兼容性,同时避免了直接暴露Kubernetes API带来的受权问题以及安全隐患。
  • 除了能够启动单个容器执行用户的训练代码,小米cloud-ml平台也支持TensorFlow的分布式训练,使用时只须要传入ps和worker个数便可
  • 考虑到对TensorFlow原生API的兼容性,咱们并无定制修改TensorFlow代码,用户甚至能够在本地安装开源的TensorFlow测试后再提交,一样能够运行在云平台上。
  • 本地运行分布式TensorFlow须要在多台服务器上手动起进程,同时要避免进程使用的端口与其余服务冲突,并且要考虑系统环境、内存不足、磁盘空间等问题,代码更新和运维压力成倍增长,
  • Cloud Machine Learning下的分布式TensorFlow只须要在提交任务时多加两个参数便可。有人以为手动启动分布式TensorFlow很是繁琐,在云端实现逻辑是否更加复杂?其实并非,经过云服务的控制节点,咱们在启动任务前就能够分配不会冲突的端口资源,启动时经过容器隔离环境资源,而用户不须要传入Cluster spec等繁琐的参数,

咱们遵循Google CloudML标准,会自动生成Cluster spec等信息经过环境变量加入到容器的启动任务中。这样不管是单机版训练任务,仍是几个节点的分布式任务,甚至是上百节点的分布式训练任务,cloud-ml平台均可以经过相同的镜像和代码来运行,只是启动时传入的环境变量不一样,在不改变任何外部依赖的状况下优雅地实现了看似复杂的分布式训练功能。

  

  • 小米的cloud-ml平台和Google的CloudML服务,都有点相似以前很火的PaaS(Platform as a Service)或者CaaS(Container as a Service)服务。确实如此,基于Kubernetes或者Mesos咱们能够很容易实现一个通用的CaaS,用户上传应用代码和Docker镜像,由平台调度和运行,但不一样的是Cloud Machine Learning简化了与机器学习无关的功能。咱们不须要用户了解PaaS的全部功能,也不须要支持全部编程语言的运行环境,暴露提交任务、查看任务、删除任务等更简单的使用接口便可,而要支持不一样规模的TensorFlow应用代码用户须要以标准的Python打包方式上传代码
  • Python的标准打包方式独立于TensorFlow或者小米cloud-ml平台,幸运的是目前Google CloudML也支持Python的标准打包方式,经过这种标准接口,咱们甚至发现Google CloudML打包好的samples代码甚至能够直接提交到小米cloud-ml平台上训练。这是很是有意思的尝试,意味着用户可使用原生的TensorFlow接口来实现本身的模型,在本地计算资源不充足的状况下能够提交到Google CloudML服务上训练,同时能够一行代码不用改直接提交到小米或者其余云服务厂商中的云平台上训练。若是你们在实现内部的云深度学习平台,不妨也参考下标准的Python打包方式,这样用户同一份代码就能够兼容全部云平台,避免厂商绑定
  • 除了训练任务,Cloud Machine Learning平台最好也能集成模型服务、开发环境等功能。

  • 对于模型服务,TensorFlow社区开源了TensorFlow Serving项目,能够加载任意TensorFlow模型而且提供统一的访问接口

  • Caffe社区也提供了Web demo项目方便用户使用。

  • 目前KubernetesMesos都实现了相似Deployment的功能,经过制做TensorFlow Serving等服务的容器镜像,咱们能够很方便地为用户快速启动对应的模型服务。

  • 经过对Kubernetes API的封装,咱们在暴露给用户API时也提供了replicas等参数,这样用户就能够直接经过Kubernetes API来建立多副本的Deployment实例,而且由Kubernetes来实现负载均衡等功能。

  • 除此以外,TensorFlow Serving自己还支持在线模型升级和同时加载多个模型版本等功能,咱们在保证TensorFlow Serving容器正常运行的状况下,容许用户更新分布式对象存储中的模型文件就能够轻易地支持在线模型升级的功能。

   对于比较小众但有特定使用场景的深度学习框架,Cloud Macine Learning的开发环境、训练任务和模型服务都支持Bring Your Own Image功能,也就是说用户能够定制本身的Docker镜像并在提交任务时指定使用。这种灵活的设置极大地下降了平台管理者的维护成本,咱们不须要根据每一个用户的需求定制通用的Golden image,事实上也不可能有完美的镜像能够知足全部需求,用户不一样的模型可能有任意的Python或者非Python依赖,甚至是本身实现的私有深度学习框架也能够直接提交到Cloud Machine Learning平台上训练。内测BYOI功能时,咱们还惊喜地发现这个功能对于咱们开发新的深度学习框架支持,以及提早测试镜像升级有很是大的帮助,同时用户本身实现的Caffe模型服务和XGBoost模型服务也能够完美支持。

   固然Cloud Machine Learning平台还能够实现不少有意思的功能,例如经过对线上不一样GPU机型打label,经过NodeSelector功能能够容许用户选择具体的GPU型号进行更细粒度的调度,这须要咱们暴露更底层Kubernetes API实现,这在集群测试中也是很是有用的功能。而不管是基于GPU的训练任务仍是模型服务,咱们都制做了对应的CUDA容器镜像,经过Kubernetes调度到对应的GPU计算节点就能够访问本地图像处理硬件进行高性能运算了。

   小米cloud-ml还开放了前置命令和后置命令功能,容许用户在启动训练任务前和训练任务结束后执行自定义命令,对于不支持分布式存储的深度学习框架,能够在前置命令中挂载S3 fuse和FDS fuse到本地目录,或者初始化HDFS的Kerberos帐号,灵活的接口能够实现更多用户自定义的功能。

   还有超参数自动调优功能,与Google CloudML相似,用户能够提交时指定多组超参数配置,云平台能够自动分配资源起多实例并行计算,为了支持读取用户自定义的指标数据,咱们实现了相似TensorBoard的Python接口直接访问TensorFlow event file数据,并经过命令行返回给用户最优的超参数组合。最后还有TensorFlow Application Template功能,在Cloud Machine Learning平台上用户能够将本身的模型代码公开或者使用官方维护的开源TensorFlow应用,用户提交任务时能够直接指定这些开源模板进行训练,模板已经实现了MLP、CNN、RNN和LR等经典神经网络结构,还能够经过超参数来配置神经网络每一层的节点数和层数,并且能够支持任意稠密和稀疏的数据集,这样不须要编写代码就能够在云平台上训练本身的数据快速生成AI模型了。

   在前面的平台设计和平台架构后,要实现完整的云深度学习服务并不困难,尤为是集成了Docker、Etcd、Kubernetes、TensorFlow等优秀开源项目,组件间经过API松耦合地交互,须要的重复工做主要是打通企业内部权限系统和将用户请求转化成Kubernetes等后端请求而已,而支持标准的打包方式还可让业务代码在任意云平台上无缝迁移。

云深度学习平台实践


    目前小米云深度学习平台已经在内部各业务部门推广使用,相比于直接使用物理机,云服务拥有超高的资源利用率、快速的启动时间、近乎“无限”的计算资源、自动的故障迁移、支持分布式训练和超参数自动调优等优势,相信能够获得更好的推广和应用。

    管理GPU资源和排查GPU调度问题也是至关繁琐的,尤为是须要管理不一样GPU设备和不一样CUDA版本的异构集群,咱们统一规范了CUDA的安装方式,保证Kubernetes调度的容器能够正常访问宿主机的GPU设备。固然对于GPU资源的调度和释放,咱们有完善的测试文档能够保证每个GPU均可以正常使用,根据测试需求实现的NodeSelector功能也帮忙咱们更快地定位问题。

    因为已经支持几十个功能和十几个深度学习框架,每次升级均可能影响已有服务的功能,所以咱们会在多节点的分布式staging集群进行上线演习和测试,而且实现smoke test脚本进行完整的功能性测试。服务升级须要更新代码,可是为了保证不影响线上业务,不管是Kubernetes仍是咱们实现的API Server都有多副本提供服务,经过高可用技术先迁移服务进行滚动升级,对于一些单机运行的脚本也经过Etcd实现了高可用的抢主机制,保证全部组件没有单点故障。

相关文章
相关标签/搜索