陈迪豪
责编
何永灿
深度学习服务介绍
机器学习与人工智能,相信大家已经耳熟能详,随着大规模标记数据的积累、神经网络算法的成熟以及高性能通用GPU的推广,深度学习逐渐成为计算机专家以及大数据科学家的研究重点。近年来,无论是图像的分类、识别和检测,还是语音生成、自然语言处理,甚至是AI下围棋或者打游戏都基于深度学习有了很大的突破。而随着TnsorFlow、Caff等开源框架的发展,深度学习的门槛变得越来越低,甚至初中生都可以轻易实现一个图像分类或者自动驾驶的神经网络模型,但目前最前沿的成果主要还是出自Googl、微软等巨头企业。
Googl不仅拥有优秀的人才储备和大数据资源,其得天独厚的基础架构也极大推动了AI业务的发展,得益于内部的大规模集群调度系统Borg,开发者可以快速申请大量GPU资源进行模型训练和上线模型服务,并且通过资源共享和自动调度保证整体资源利用率也很高。Googl开源了TnsorFlow深度学习框架,让开发者可以在本地轻易地组合MLP、CNN和RNN等模块实现复杂的神经网络模型,但TnsorFlow只是一个数值计算库,并不能解决资源隔离、任务调度等问题,将深度学习框架集成到基于云计算的基础架构上将是下一个关键任务。
除了Googl、微软,国内的百度也开源了PaddlPaddl分布式计算框架,并且官方集成了Kubrnts等容器调度系统,用户可以基于PaddlPaddl框架实现神经网络模型,同时利用容器的隔离性和Kubrnts的资源共享、自动调度、故障恢复等特性,但平台不能支持更多深度学习框架接口。而亚马逊和腾讯云相继推出了面向开发者的公有云服务,可以同时支持多种主流的开源深度学习框架,阿里、金山和小米也即将推出基于GPU的云深度学习服务,还有无数企业在默默地研发内部的机器学习平台和大数据服务。
面对如此眼花缭乱的云服务和开源技术,架构师该如何考虑其中的技术细节,从用户的角度又该如何选择这些平台或者服务呢。我将介绍小米云深度学习平台的架构设计与实现细节,希望能给AI领域的研发人员提供一些思考和启示。
云深度学习平台设计
云深度学习平台,我定义为CloudMachinLarning,就是基于云计算的机器学习和深度学习平台。首先TnsorFlow、MXNt是深度学习框架或者深度学习平台,但并不是云深度学习平台,它们虽然可以组成一个分布式计算集群进行模型训练,但需要用户在计算服务器上手动启动和管理进程,并没有云计算中任务隔离、资源共享、自动调度、故障恢复以及按需计费等功能。因此我们需要区分深度学习类库以及深度学习平台之间的关系,而这些类库实现的随机梯度下降和反向传播等算法却是深度学习应用所必须的,这是一种全新的编程范式,需要我们已有的基础架构去支持。
云计算和大数据发展超过了整整十年,在业界催生非常多优秀的开源工具,如实现了类似AWSIaaS功能的OpnStack项目,还有Hadoop、Spark、Hiv等大数据存储和处理框架,以及近年很火的Dockr、Kubrnts等容器项目,这些都是构建现代云计算服务的基石。这些云服务有共同的特点,例如我们使用HDFS进行数据存储,用户不需要手动申请物理资源就可以做到开箱即用,用户数据保存在几乎无限制的公共资源池中,并且通过租户隔离保证数据安全,集群在节点故障或者水平扩容时自动触发Failovr且不会影响用户业务。虽然Spark通过MLib接口提供部分机器学习算法功能,但绝不能替代TnsorFlow、Caff等深度学习框架的作用,因此我们仍需要实现CloudMachinLarning服务,并且确保实现云服务的基本特性——我将其总结为下面几条:
屏蔽硬件资源保证开箱即用
缩短业务环境部署和启动时间
提供“无限”的存储和计算能力
实现多租户隔离保证数据安全
实现错误容忍和自动故障迁移
提高集群利用率和降低性能损耗
相比于MapRduc或者Spark任务,深度学习的模型训练时间周期长,而且需要调优的超参数更多,平台设计还需要考虑以下几点:
支持通用GPU等异构化硬件
支持主流的深度学习框架接口
支持无人值守的超参数自动调优
支持从模型训练到上线的工作流
这是我个人对云深度学习平台的需求理解,也是小米在实现cloud-ml服务时的基本设计原则。虽然涉及到高可用、分布式等颇具实现难度的问题,但借助目前比较成熟的云计算框架和开源技术,我们的架构和实现基本满足了前面所有的需求,当然如果有更多需求和想法欢迎随时交流。
云深度学习平台架构
遵循前面的平台设计原则,我们的系统架构也愈加清晰明了,为了满足小米内部的所有深度学习和机器学习需求,需要有一个多租户、任务隔离、资源共享、支持多框架和GPU的通用服务平台。通过实现经典的MLP、CNN或RNN算法并不能满足业务快速发展的需求,因此我们需要支持TnsorFlow等用户自定义的模型结构,并且支持高性能GPU和分布式训练是这个云深度学习平台的必须功能,不仅仅是模型训练,我们还希望集成模型服务等功能来最大化用户的使用效益。
计算机领域有句名言“任何计算机问题都可以通过增加一个中间层来解决”。无论是AWS、OpnStack、Hadoop、Spark还是TCP/IP都是这样做的,通过增加一个抽象层来屏蔽底层资源,对上层提供更易用或者更可靠的访问接口。小米的cloud-ml平台也需要实现对底层物理资源的屏蔽,尤其是对GPU资源的抽象和调度,但我们不需要重新实现,因为社区已经有了很多成熟的分布式解决方案,如OpnStack、Yarn和Kubrnts。目前OpnStack和Yarn对GPU调度支持有所欠缺,虚拟机也存在启动速度慢、性能ovrhad较大等问题,而容器方案中的Kubrnts和Msos发展迅速,支持GPU调度等功能,是目前最值得推荐的架构选型之一。
目前小米cloud-ml平台的任务调度和物理机管理基于多节点的分布式Kubrnts集群,对于OpnStack、Yarn和Msos我们也保留了实现接口,可以通过实现Msos后端让用户的任务调度到Msos集群进行训练,最终返回给用户一致的使用接口。目前Kubrnts最新稳定版是1.6,已经支持NvidiaGPU的调度和访问,对于其他厂商GPU暂不支持但基本能满足企业内部的需求,而且Pod、Dploymnt、Job、StatfulSt等功能日趋稳定,加上Dockr、Promthus、Harbor等生态项目的成熟,已经在大量生产环境验证过,可以满足通用PaaS或者CloudMachinlarning等定制服务平台的需求。
使用Kubrnts管理用户的Dockr容器,还解决了资源隔离的问题,保证不同深度学习训练任务间的环境不会冲突,并且可以针对训练任务和模型服务使用Job和Dploymnt等不同的接口,充分利用分布式容器编排系统的重调度和负载均衡功能。但是,Kubrnts并没有完善的多租户和Quota管理功能,难以与企业内部的权限管理系统对接,这要求我们对KubrntsAPI进行再一次“抽象”。我们通过APISrvr实现了内部的AKSK签名和认证授权机制,在处理用户请求时加入多租户和Quota配额功能,并且对外提供简单易用的RESTfulAPI,进一步简化了整个云深度学习平台的使用流程,整体架构设计如图1。
图1云深度学习平台整体架构通过实现APISrvr,我们对外提供了API、SDK、命令行以及Wb控制台多种访问方式,最大程度上满足了用户复杂多变的使用环境。集群内置了Dockr镜像仓库服务,托管了我们支持的17个深度学习框架的容器镜像,让用户不需要任何初始化命令就可以一键创建各框架的开发环境、训练任务以及模型服务。多副本的APISrvr和Etcd集群,保证了整个集群所有组件的高可用,和Hadoop或者Spark一样,我们的cloud-ml服务在任意一台服务器经历断网、宕机、磁盘故障等暴力测试下都能自动Failovr保证业务不受任何影响。
前面提到,我们通过抽象层定义了云深度学习平台的接口,无论后端使用Kubrnts、Msos、Yarn甚至是OpnStack、AWS都可以支持。通过容器的抽象可以定义任务的运行环境,目前已经支持17个主流的深度学习框架,用户甚至可以在不改任何一行代码的情况下定义自己的运行环境或者使用自己实现的深度学习框架。在灵活的架构下,我们还实现了分布式训练、超参数自动调优、前置命令、NodSlctor、BringYourOwnImag和FUSE集成等功能,将在下面逐一介绍。
云深度学习平台实现
前面提到我们后端使用Kubrnts编排系统,通过APISrvr实现授权认证和Quota配额功能。由于云深度学习服务是一个计算服务,和我以前做过的分布式存储服务有着本质的区别,计算服务离线运算时间较长,客户端请求延时要求较低而且吞吐很小,因此我们的API服务在易用性和高性能上可以选择前者,目前主流的Wb服务器都可以满足需求。基于Wb服务器我们可以实现集成内部权限管理系统的业务逻辑,小米生态云提供了类似AWS的AKSK签名认证机制,用户注册登录后可以自行创建Accssky和Scrtky,请求时在客户端进行AKSK的签名后发送,这样用户不需要把账号密码或密钥加到请求中,即使密钥泄露也可以由用户来禁用,请求时即使签名被嗅探也只能重放当前的请求内容,是非常可靠的安全机制。除此之外,我们参考OpnStack项目的体系架构,实现了多租户和Quota功能,通过认证和授权的请求需要经过Quota配额检查,在高可用数据库中持久化相应的数据,这样平台管理员就可以动态修改每个租户的Quota,而且用户可以随时查看自身的审计信息。
小米cloud-ml服务实现了深度学习模型的开发、训练、调优、测试、部署和预测等完整功能,都是通过提交到后端的Kubrnts集群来实现,完整的功能介绍可以查看官方文档