本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

PaddlePaddle Fluid:Kubernetes 上的弹性深度学习

编者按:今天的博文是百度深度学习团队和 CoreOS etcd 团队联合发表的。

PaddlePaddle Fluid:Kubernetes 上的弹性深度学习

两个开源社区——源自百度的深度学习框架 PaddlePaddle 和最著名的容器化应用调度器 Kubernetes®——宣布在 PaddlePaddle 新版本(代号 Fluid)中推出弹性深度学习 (EDL) 功能。

Fluid EDL 包括一个 Kubernetes 控制器,即 PaddlePaddle 自动扩缩器,它根据集群中闲置硬件资源更改分布式作业的进程数量,以及 PaddlePaddle 设计文档中描述的新容错架构 PaddlePaddle 设计文档

工业深度学习需要大量的计算能力。研究实验室和公司通常会构建由 SLURM、MPI 或 SGE 管理的 GPU 集群。这些集群要么在提交的作业所需的资源少于闲置资源时运行该作业,要么让作业挂起一段不可预测的长久时间。这种方法有其缺点:在一个拥有 99 个可用节点,而提交的作业需要 100 个节点的示例中,该作业必须等待而不能使用任何可用节点。Fluid 与 Kubernetes 配合,为弹性深度学习作业提供支持,这些作业通常缺乏最佳资源,通过尽早暴露潜在的算法问题。

另一个挑战是,工业用户倾向于将深度学习作业作为完整数据管道(包括 Web 服务器和日志收集器)的一个子阶段来运行。这种通用集群需要基于优先级的弹性调度。这使得在 Web 流量高峰期,Web 服务器作业可以运行更多的进程,而深度学习作业可以运行更少的进程;当 Web 流量较低时,则优先进行深度学习。Fluid 与 Kubernetes 的 API 服务器通信,以了解全局情况并协调与各种作业相关的进程数量。

在这两种情况下,PaddlePaddle 作业都能够容忍进程的增减。我们通过实施新设计来实现这一点,该设计在旧的 PaddlePaddle 架构(如之前博客文章中所述)的基础上引入了一个主进程。在新设计中,只要作业中还剩三个进程,它就会继续运行。在所有进程都被终止的极端情况下,作业可以恢复并继续。

我们测试了 Fluid EDL 的两个用例:1) Kubernetes 集群仅运行 PaddlePaddle 作业;2) 集群同时运行 PaddlePaddle 和 Nginx 作业。

在第一个测试中,我们以 10 秒的间隔一个接一个地启动了多达 20 个 PaddlePaddle 作业。每个作业有 60 个训练器和 10 个参数服务器进程,并将持续数小时。我们重复了实验 20 次:10 次关闭 FluidEDL,10 次打开 FluidEDL。在图 1 中,实线对应前 10 次实验,虚线对应其余实验。在图的上半部分,我们看到在没有 EDL 的情况下,待处理作业的数量单调递增。然而,当启用 EDL 时,资源被均匀分配给所有作业。Fluid EDL 终止一些现有进程,以便为新作业和稍后进入的作业腾出空间。在这两种情况下,集群的利用率相等(见图下半部分)。

| | | 图 1. Fluid EDL 在作业之间均匀分配资源。
|

在第二个测试中,每个实验运行 400 个 Nginx Pod,这些 Pod 的优先级高于六个 PaddlePaddle 作业。最初,每个 PaddlePaddle 作业有 15 个训练器和 10 个参数服务器。我们每 90 秒杀死 100 个 Nginx Pod,直到剩下 100 个,然后我们开始每 90 秒增加 100 个 Nginx 作业。图 2 的上半部分展示了这个过程。图的中间显示,Fluid EDL 通过减少 Nginx Pod 自动启动了一些 PaddlePaddle 进程,然后通过增加 Nginx Pod 杀死了 PaddlePaddle 进程。结果是,集群保持了大约 90% 的利用率,如图底部所示。当 Fluid EDL 关闭时,没有 PaddlePaddle 进程自动增加,并且利用率随着 Nginx Pod 数量的变化而波动。

| | | 图 2. Fluid 随着 Nginx 进程的变化而改变 PaddlePaddle 进程。 |

我们将继续开发 FluidEDL,并欢迎提出意见和贡献。请访问 PaddlePaddle 仓库,您可以在其中找到设计文档简单教程实验细节