速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

开源 Kubeflow:在 Kubernetes 上运行机器学习

  • 2019-09-30
  • 本文字数:4306 字

    阅读完需:约 14 分钟

开源Kubeflow:在Kubernetes上运行机器学习

这篇文章主要介绍了 Kubeflow 的使用以及未来的计划,面向人群为对在 Kubernetes 上运行机器学习负载感兴趣的同学。

问题背景

Kubernetes 本来是一个用来管理无状态应用的容器平台,但是在近两年,有越来越多的公司用它来运行各种各样的工作负载,尤其是机器学习炼丹。各种 AI 公司或者互联网公司的 AI 部门都会尝试在 Kubernetes 上运行 TensorFlow、Caffe、MXNet 等等分布式学习的任务,这为 Kubernetes 带来了新的挑战。


首先,分布式的机器学习任务一般会涉及参数服务器(以下称为 PS)和工作节点(以下成为 worker)两种不同的工作类型。而且不同领域的学习任务对 PS 和 worker 有不同的需求,这体现在 Kubernetes 中就是配置难的问题。以 TensorFlow 为例,TensorFlow 的分布式学习任务通常会启动多个 PS 和多个 worker,而且在 TensorFlow 提供的最佳实践中,每个 worker 和 PS 要求传入不同的命令行参数。举例说明:


# On ps0.example.com:$ python trainer.py \    --ps_hosts=ps0.example.com:2222,ps1.example.com:2222 \    --worker_hosts=worker0.example.com:2222,worker1.example.com:2222 \    --job_name=ps --task_index=0# On ps1.example.com:$ python trainer.py \    --ps_hosts=ps0.example.com:2222,ps1.example.com:2222 \    --worker_hosts=worker0.example.com:2222,worker1.example.com:2222 \    --job_name=ps --task_index=1# On worker0.example.com:$ python trainer.py \    --ps_hosts=ps0.example.com:2222,ps1.example.com:2222 \    --worker_hosts=worker0.example.com:2222,worker1.example.com:2222 \    --job_name=worker --task_index=0# On worker1.example.com:$ python trainer.py \    --ps_hosts=ps0.example.com:2222,ps1.example.com:2222 \    --worker_hosts=worker0.example.com:2222,worker1.example.com:2222 \    --job_name=worker --task_index=1
复制代码


其中需要的参数有四个,一个是所有的 PS 的网络地址(主机名 - 端口),以及所有的 worker 的网络地址。另外是 job 的类型,分为 PS 与 worker 两种。最后是任务的 index,从 0 开始递增。因此在此例中,用户需要写至少四个 pod 的配置文件,以及四个 service 的配置文件,使得 PS 跟 worker 可以互相访问,况且这只是一个机器学习任务。如果大规模地在 Kubernetes 上运行 TensorFlow 分布式任务,可以预见繁杂的配置将成为机器学习工程师们新的负担。


其次,Kubernetes 默认的调度器对于机器学习任务的调度并不友好。如果说之前的问题只是在应用与部署阶段比较麻烦,那调度引发的资源利用率低,或者机器学习任务效率下降的问题,就格外值得关注。机器学习任务对于计算和网络的要求相对较高,一般而言所有的 worker 都会使用 GPU 进行训练,而且为了能够得到一个较好的网络支持,尽可能地同一个机器学习任务的 PS 和 worker 放在同一台机器或者网络较好的相邻机器上会降低训练所需的时间。

Hello, Kubeflow

针对这些问题,Kubeflow 项目应运而生,它以 TensorFlow 作为第一个支持的框架,在 Kubernetes 上定义了一个新的资源类型:TFJob,即 TensorFlow Job 的缩写。通过这样一个资源类型,使用 TensorFlow 进行机器学习训练的工程师们不再需要编写繁杂的配置,只需要按照他们对业务的理解,确定 PS 与 worker 的个数以及数据与日志的输入输出,就可以进行一次训练任务。在本节中,我们将从零开始搭建一个 Kubernetes 集群,并且将 Kubeflow 运行在其上,最后利用其进行一次完整的学习任务运行。


首先,我们需要有一个正在运行的 Kubernetes 集群,而且集群的版本要大于等于 1.8。在这一步里,个人推荐以下两种方式创建一个单节点的本地 Kubernetes 集群:


  1. 使用 Kubernetes 里的 local-up-cluster.sh 脚本

  2. https://github.com/kubernetes/kubernetes/blob/master/hack/local-up-cluster.sh

  3. 使用 minikube 项目

  4. https://github.com/kubernetes/minikube


其中前者会在本地创建一个 native 的 Kubernetes 集群,而后者则会在本地的虚拟机里创建出 Kubernetes 集群。因为本文侧重点不在此,因此整个过程不再赘述。


如果你已经成功地创建了一个 Kubernetes 集群,那么接下来就是在这一集群上创建 Kubeflow 所有的组件,这一步需要用到 ksonnet,一个简化应用在 Kubernetes 上的分发与部署的命令行工具,它会帮助你创建 Kubeflow 所需组件。在安装了 ksonnet 后,接下来就是一片坦途了,只需要运行下面的命令,就可以完成 Kubeflow 的部署。


# Initialize a ksonnet APPAPP_NAME=my-kubeflowks init ${APP_NAME}cd ${APP_NAME}
# Install Kubeflow componentsks registry add kubeflow github.com/kubeflow/kubeflow/tree/master/kubeflowks pkg install kubeflow/coreks pkg install kubeflow/tf-servingks pkg install kubeflow/tf-job
# Deploy KubeflowNAMESPACE=defaultkubectl create namespace ${NAMESPACE}ks generate core kubeflow-core --name=kubeflow-core --namespace=${NAMESPACE}ks apply default -c kubeflow-core
复制代码


Kubeflow 的部署会附带一个 JupyterHub 但笔者并不知道如何使用它,因此下面的操作是用 Docker 打包训练数据和代码,用 kubectl 在 Kubernetes 上启动一次训练任务的。


示例代码可见 tf_smoke.py,与正常的训练代码类似,只不过 clusterspec 的传递方式是遵循了 Cloud ML 的 TF_CONFIG 的方式。Kubeflow 已经根据这一训练文件打好了一个 Docker 镜像:gcr.io/tf-on-k8s-dogfood/tf\_sample:dc944ff,在这里直接使用就好:


kubectl create -f https://raw.githubusercontent.com/tensorflow/k8s/master/examples/tf_job.yaml
复制代码

Kubeflow 实现介绍

本部分主要涉及对 Kubeflow 内部实现的介绍和未来可能的开发计划,如果不感兴趣可以就此打住 :)

对分布式训练任务的支持

为了解决配置困难的问题,Kubeflow 以 TensorFlow 作为第一个支持的框架,为其实现了一个在 Kubernetes 上的 operator:tensorflow/k8s。由于在 Kubernetes 上内置的资源类型,如 deployment,replicaset,或者是 pod 等,都很难能够简练而清晰地描述一个分布式机器学习的任务,因此我们利用 Kubernetes 的 Custom Resource Definition 特性,定义了一个新的资源类型:TFJob,即 TensorFlow Job 的缩写。一个 TFJob 配置示例如下所示:


apiVersion: "kubeflow.org/v1alpha1"kind: "TFJob"metadata: name: "example-job"spec: replicaSpecs:   - replicas: 1     tfReplicaType: MASTER     template:       spec:         containers:           - image: gcr.io/tf-on-k8s-dogfood/tf_sample:dc944ff             name: tensorflow         restartPolicy: OnFailure   - replicas: 1     tfReplicaType: WORKER     template:       spec:         containers:           - image: gcr.io/tf-on-k8s-dogfood/tf_sample:dc944ff             name: tensorflow         restartPolicy: OnFailure   - replicas: 2     tfReplicaType: PS     template:       spec:         containers:           - image: gcr.io/tf-on-k8s-dogfood/tf_sample:dc944ff             name: tensorflow         restartPolicy: OnFailure
复制代码


其中每个字段就不多介绍了,这里主要是说一下实现。任何一个 PS 或者 worker,都由两个资源组成,分别是 job 和 service。其中 job 负责创建出 PS 或者 worker 的 pod,而 service 负责将其暴露出来。这里社区目前也在重新考虑选型,目前希望可以直接创建 pod 而非 job,而用 headless service 替代 service,因为 PS worker 不需要暴露给除了该分布式学习任务外的其他服务。


TFJob operator 的实现早期是从 etcd-operator 复制来的,因此整体的架构在最初是完全仿照其改写而成。在最初的实现中,当有一个 TFJob 被创建时,在 operator 内都会有一个新的 goroutine,以轮询的方式获取 TFJob 的状态,然后基于此状态做出相应的操作,相当于是在 operator 内部维护了一个状态机。这样的方式会有一些缺点:


  • 这样的架构使得 operator 是有状态的,使得状态很难横向扩展

  • 维护基于 Phase 的状态机是 Kubernetes 社区不推崇的一种方式


基于这些问题,operator 的架构正在往事件驱动重构,这部分工作由 @caicloud 在推进。重构之后,operator 会在 Kubernetes 的一些资源上注册 informer 的事件回调,比较现在的状态与理想状态的不同而采取相应的操作。比如当有一个新的 TFJob 被创建时,理想状态是所有对应的 PS, worker 都被创建好,而当下的状态则是没有任何 pod 和 service 被创建,此时 operator 会创建出对应的 PS,worker 的 pod 和 service,以达到理想状态,这也是 Kubernetes 社区对于 operator/controller 的最佳实践。

对分布式学习任务效率的关注

目前社区还停留在如何对 AI 工程师更友好,更好地维护上面提到的 operator 这一步,在效率方面考虑地较少。目前有利用 kube-arbitrator 来进行 gang scheduling 的探索,目前还没有尝试过因此不好评价。但是整体来说 Kubeflow 的性能提高还有很大的空间。


因为机器学习任务根据模型的不同,其输入数据的规模,特征,模型的大小等等都有很大不同。比如 CV 领域与推荐领域的学习模型就有完全不同的特点,因此 TensorFlow 的分布式模型提供了极强的灵活性。而对于 Kubernetes 而言,如何能够在保持灵活性的基础上,同时也保证任务在较高的性能下运行,同时集群的利用率也相对较高,是一个值得研究的问题。

对其他机器学习框架的支持

目前 Kubeflow 主要关注 TensorFlow,而其他机器学习框架的支持将于之后展开,目前有一些第三方实现的 operator,比如 MXNet operator,但是质量难以保证。

开发情况与未来展望

目前 Kubeflow 有来自 Google、Caicloud、RedHat 等公司的积极参与,短期的目标有这么几个:

operator 方面

  • 使用 pod 替换 job tensorflow/k8s#325

  • 使用 headless service 替换 service tensorflow/k8s#40

  • 由 etcd operator 主动轮询的方式改为事件驱动 tensorflow/k8s#314

  • 分离对 TensorBoard 的支持 tensorflow/k8s#347

  • 支持细粒度的任务状态 tensorflow/k8s#333

模型服务方面

  • GPU 支持 kubeflow/kubeflow#64

  • 监控支持 kubeflow/kubeflow#64

  • 多框架支持下的统一 API 支持 kubeflow/kubeflow#102

UI 方面

  • 为各个部件支持统一的 UI kubeflow/kubeflow#199


目前 KubeflowGitHub 上有 2400 多个 star,有 40 个左右的贡献者。其长期的目标是成为 CNCF 的一个项目,目前实现仍存在很多问题,窃以为也并不是 production ready 的状态,但它仍然值得一试。


本文经授权转载自知乎专栏,原文链接:https://zhuanlan.zhihu.com/p/33583636


2019-09-30 14:505870

评论

发布
暂无评论
发现更多内容

一文为你详解Unique SQL原理和应用

华为云开发者联盟

数据库 sql unique

Shell脚本命令常用技巧

MySQL从删库到跑路

shell脚本编写

云南区块链电子发票全面推广啦!

CECBC

区块链 纳税人

传统巨头抢占区块链场景高地 医疗、汽车、金融成为热门赛道

CECBC

区块链 金融

AWS 助力贝壳VR看房走出国门,升级全球居住服务新体验

亚马逊云科技 (Amazon Web Services)

AWS

面向全场景模块化设计 京东智联云的服务器部署有多灵活?

京东科技开发者

服务器 云主机

浅谈JDK并发包下面的分治思想及分治思想在高并发场景的运用

AI乔治

Java 架构 jdk 分布式 多线程与高并发

记一次MapReduce的内存溢出

AI乔治

Java mapreduce 架构 内存溢出

80%Java开发者面试都问的SpringBoot你竟不会?看完这些笔记足以

Java架构之路

Java 程序员 架构 面试 编程语言

VACUUM无法从表中删除死元组的三个原因

PostgreSQLChina

数据库 postgresql

一口气说出四种幂等性解决方案,面试官露出了姨母笑~

不才陈某

Java 分布式 接口

搭建网站/APP最全准备攻略

前嗅大数据

小程序 建站 APP发布

住建部等六部门:广泛运用区块链等技术,建设智慧物业管理服务平台

CECBC

物业生活

信任的传递——为什么我们需要第三方授权?

张凯峰

证书 身份认证

如何在数智化时代少走弯路? 这里有100个案例可以借鉴

京东科技开发者

DevOps 云原生

Elasticsearch 新机型发布,性能提升30%

腾讯云大数据

大数据 elasticsearch Elastic Stack

好久不见!这份Spring全家桶、Docker、Redis架构大礼包免费赠送

Java架构之路

Java 程序员 架构 面试 编程语言

耗时一个月整理的97道大厂Java核心面试题出炉,精心整理,无偿分享

Java架构之路

Java 程序员 架构 面试 编程语言

即构实时音视频多中心调度设计

ZEGO即构

EMAS远程日志 - 移动端问题排查利器

移动研发平台EMAS

阿里云 运维 日志 监控告警 应用

图文回顾丨北京「解构云原生:企业数字化转型新支点」沙龙

Rancher

k8s rancher

附PPT丨AI和云原生时代的数据库进化之路

dbaplus社群

数据库 云原生

建信金科大咖访谈:金融衍生品定价与建行实践

金科优源汇

金融科技 金融创新

面试被问高并发一脸懵?那是你没看过我整理得高并发回答模板

小Q

Java 学习 面试 高并发 性能调优

Java进阶文档:彻底搞懂JVM+Linux+MySQL+Netty+Tomcat+并发编程

Java架构之路

Java 程序员 架构 面试 编程语言

云图说 | 云上资源管控有神器!关于IAM,你想知道的都在这里!

华为云开发者联盟

服务 权限管理 iam

太赞了!滴滴开源了一套分布式ID的生成系统...

Java架构师迁哥

我和阿里P7差的不是薪资?而是Redis+微服务+Nginx+MySQL+Tomcat

Java架构之路

Java 程序员 架构 面试 编程语言

Java中多线程安全问题实例分析

叫练

Java 多线程 什么是多线程 多线程与高并发

第13周作业

饭桶

第十三周学习总结

饭桶

开源Kubeflow:在Kubernetes上运行机器学习_语言 & 开发_gaocegege_InfoQ精选文章