机器之心发布
来源:AWS云计算
大多数人都喜欢在笔记本电脑上做原型开发。当想与人协作时,通常会将代码推送到GitHub并邀请协作者。当想运行实验并需要更多的计算能力时,会在云中租用CPU和GPU实例,将代码和依赖项复制到实例中,然后运行实验。如果您对这个过程很熟悉,那么您可能会奇怪:为什么一定要用Docker容器呢?
运营团队中优秀的IT专家们可以确保您的代码持续可靠地运行,并能够根据客户需求进行扩展。那么对于运营团队而言,容器不就成了一种罕见的工具吗?您能够高枕无忧,无需担心部署问题,是因为有一群基础设施专家负责在Kubernetes上部署并管理您的应用程序吗?
在本文中,AWS会尝试说明为什么您应该考虑使用Docker容器进行机器学习开发。在本文的前半部分,将讨论在使用复杂的开源机器学习软件时遇到的主要难题,以及采用容器将如何缓和这些问题。然后,将介绍如何设置基于Docker容器的开发环境,并演示如何使用该环境来协作和扩展集群上的工作负载。
机器学习开发环境:基本需求
首先了解一下机器学习开发环境所需的四个基本要素:
计算:训练模型离不开高性能CPU和GPU。存储:用于存储大型训练数据集和您在训练过程中生成的元数据。框架和库:提供用于训练的API和执行环境。源代码控制:用于协作、备份和自动化。
作为机器学习研究人员、开发人员或数据科学家,您可以在单个AmazonElasticComputeCloud(AmazonEC2)实例或家庭工作站上搭建满足这四种要素的环境。
那么,此设置有什么问题吗?
其实也谈不上有问题。因为几十年来,大多数开发设置都是如此:既没有集群,也没有共享文件系统。
除了高性能计算(HPC)项目的一小群研究人员能够将开发的代码放在超级计算机上运行之外,绝大多数人都只能依靠自己专用的计算机进行开发。
事实证明,与传统软件开发相比,机器学习与HPC具有更多的共同点。与HPC工作负载一样,若在大型集群上运行机器学习工作负载,执行速度更快,实验速度也更快。要利用集群进行机器学习训练,您需要确保自己的开发环境可移植,并且训练在集群上可重复。
为什么需要可移植的训练环境?
在机器学习开发流程中的某个阶段,您会遇到以下两个难题:
您正在进行实验,但您的训练脚本发生了太多次的更改导致无法运行,并且只用一台计算机无法满足需求。您在具有大型数据集的大型模型上进行训练,但仅在一台计算机上运行使您无法在合理的时间内获得结果。
这两个原因往往会让您希望在集群上运行机器学习训练。这也是科学家选择使用超级计算机(例如Summit超级计算机)进行科学实验的原因。要解决第一个难题,您可以在计算机集群上独立且异步地运行每个模型。要解决第二个难题,您可以将单个模型分布在集群上以实现更快的训练。
这两种解决方案都要求您能够在集群上以一致的方式成功复现开发训练设置。这一要求很有挑战性,因为集群上运行的操作系统和内核版本、GPU、驱动程序和运行时以及软件依赖项可能与您的开发计算机有所不同。
您需要可移植的机器学习环境的另一个原因是便于协作开发。通过版本控制与协作者共享训练脚本很容易。但在不共享整个执行环境(包括代码、依赖项和配置)的情况下保证可重复性却很难。这些内容将在下一节中介绍。
机器学习、开源和专用硬件
机器学习开发环境面临的挑战是,它们依赖于复杂且不断发展的开源机器学习框架和工具包以及同样复杂且不断发展的硬件生态系统。虽然这两者都是我们需要的积极特质,但它们却在短期内构成了挑战。
在进行机器学习训练时,您有多少次问过自己以下这些问题:
我的代码是否利用了CPU和GPU上的所有可用资源?我是否使用了正确的硬件库和硬件库版本?当运行环境大同小异时,为什么我的训练代码在自己的计算机上可以正常工作,而在同事的计算机上就会崩溃?我今天更新了驱动程序,现在训练变慢/出错了。这是为什么?
如果您检查自己的机器学习软件堆栈,会发现自己的大部分时间都花在了紫红色框(即图中的我的代码)上。这部分包括您的训练脚本、实用程序和帮助例程、协作者的代码、社区贡献等。如果这还不够复杂,您还会注意到您的依赖项包括:
迅速演进的机器学习框架API;机器学习框架依赖项,其中有很多是独立的项目;CPU专用库,用于加速数学例程;GPU专用库,用于加速数学例程和GPU间通信例程;以及需要与用于编译上述GPU库的GPU编译器协调一致的GPU驱动程序。
由于开源机器学习软件堆栈的高度复杂性,在您将代码移至协作者的计算机或集群环境时,会引入多个故障点。在下图中,请注意,即使您控制对训练代码和机器学习框架的更改,也可能无法顾及到较低级别的更改,从而导致实验失败。
最终,白白浪费了您的宝贵时间。
为什么不使用虚拟Python环境?
您可能会认为,conda和virtualenv之类的虚拟环境方法可以解决这些问题。没错,但是它们只能解决部分问题。有些非Python依赖项不由这些解决方案管理。由于典型机器学习堆栈十分复杂,因此很大一部分框架依赖项(例如硬件库)都在虚拟环境范围之外。
使用容器进行机器学习开发
机器学习软件是具有多个项目和参与者的零散生态系统的一部分。这可能是件好事,因为每个人都可以从自己的参与中获益,并且开发人员始终拥有充分的选择。不利方面是要应对一些问题,例如一致性、可移植性和依赖项管理。这就是容器技术的用武之地。在本文中,我不想讨论容器的常规优势,而想讲讲讲机器学习如何从容器中获益。
容器不仅可以完全封装您的训练代码,还能封装整个依赖项堆栈甚至硬件库。您会得到一个一致且可移植的机器学习开发环境。通过容器,在集群上开展协作和进行扩展都会变得更加简单。如果您在容器环境中开发代码和运行训练,不仅可以方便地共享您的训练脚本,还能共享您的整个开发环境,只需将您的容器映像推送到容器注册表中,并让协作者或集群管理服务提取容器映像并运行,即可重现您的结果。
应将/不应将哪些内容包含在您的机器学习开发容器中
这个问题没有正确答案,您的团队如何运营由您来决定,但是关于可以包含哪些内容,有以下几个方案:
只包含机器学习框架和依赖项:这是最简洁的方法。每位协作者都可以获得相同执行环境的相同副本。他们可以在运行时将自己的训练脚本克隆到容器中,也可以挂载包含训练代码的卷。机器学习框架、依赖项和训练代码:当扩展集群上的工作负载时,首选此方法。您可以获得一个可在集群上扩展的可执行的机器学习软件单元。根据您对训练代码的组织方式,您可以允许脚本执行多种训练变体,以运行超参数搜索实验。
共享您的开发容器也非常轻松。您可以按以下方式进行共享:
容器映像:这是最简单的方法。这种方法允许每位协作者或集群管理服务(例如Kubernetes)提取容器映像,对映像进行实例化,然后直接执行训练。Dockerfile:这是一种轻量型方法。Dockerfile中包含关于创建容器映像时需要下载、构建和编译哪些依赖项的说明。可以在您编写训练代码时对Dockerfile进行版本控制。您可以使用持续集成服务(例如AWSCodeBuild),自动完成从Dockerfile创建容器映像的过程。
Docker中心提供了广泛使用的开源机器学习框架或库的容器映像,这些映像通常由框架维护人员提供。您可以在他们的存储库中找到TensorFlow、PyTorch和MXNet等。在决定从哪里下载以及下载哪种类型的容器映像时,要十分谨慎。
大部分上游存储库都会将其容器构建为在任何位置均可使用,这意味着这些容器需要与大部分CPU和GPU架构兼容。如果您确切知晓将在怎样的系统上运行容器,最好选择已经针对您的系统配置进行优化的合格容器映像。
使用Jupyter和Docker容器设置您的机器学习开发环境
AWS使用常用的开源深度学习框架来托管可用于计算优化型CPU和GPU实例的AWSDeepLearningContainers。接下来,我将说明如何使用容器通过几个步骤设置开发环境。在此示例中,我假设您使用的是AmazonEC2实例。
第1步:启动您的开发实例。
C5、P3或G4系列实例都适合用于机器学习工作负载。后两者每个实例最多可提供多达八个NVIDIAGPU。有关如何启动实例的简要指南,请阅读AmazonEC2入门文档(
转载请注明:http://www.0431gb208.com/sjszlfa/8519.html