当前位置:   article > 正文

【MindSpore易点通机器人-04】MLOps 环境搭建过程_mindspore 平台搭建

mindspore 平台搭建

作者:王磊
更多精彩分享,欢迎访问和关注:https://www.zhihu.com/people/wldandan

在上一篇【MindSpore易点通机器人-03】迭代0的准备工作,我们从整体上概述了MindSpore易点通机器人项目开始前需要在迭代0的准备工作,本篇将会为大家讲述迭代0中具体的MLOps 环境搭建过程。整体的MLOps流水线设计如下图,包含持续训练流水线和CI/CD流水线。相关代码请参考MindSpore易点通机器人代码仓

实际的技术选型上,我们基于Jenkins构建CI/CD流水线,基于Argo构建持续训练流水线。同时,我们把Jenkins和Argo都运行在K8S上来保证可用性和弹性。下文将为大家介绍如何在本地使用Minikube完成机器人项目的MLOps流水线的搭建,并在本地运行起来。

具体的过程如下:

  1. 安装配置WSL+Ubuntu+Docker;
  2. 基于Minikube运行K8S;
  3. 基于K8S+Jenkins构建CI/CD流水线;
  4. 基于K8S+Argo持续训练流水线。

1. 安装配置WSL+Ubuntu+Docker

因为团队大部分人的开发环境都是Windows,所以需要选择WSL+Linux+Docker的方式。这里我们没有采用Docker Desktop+WSL Backend,而是利用Distord让Docker在Ubuntu上直接运行,相关的安装配置文档可以参考如何不安装Docker Desktop在WSL下运行Docker这篇文章。

2. 基于Minikube运行K8S

Minikube是一个单机安装配置K8S集群的工具,它支持多平台(Mac/Linux/Windows)。Minikube可以将K8S集群安装配置在单个Docker容器或者VM(hyper-v/VMWare等)中,过程也非常简单。首先在Ubuntu中安装Minikube:

  1. curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
  2. sudo install minikube-linux-amd64 /usr/local/bin/minikube

然后执行minikube start ,因为在第一步中我们已经配置好了Docker,Minikube在启动时会默认使用Docker作为VM,然后在容器中启动K8S集群。启动完成后在Ubuntu上使用docker ps只能看到一个容器:

  1. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  2. 699a71fee349 kicbase/stable:v0.0.30 "/usr/local/bin/entr…" 2 weeks ago Up 2 hours 127.0.0.1:49157->22/tcp, 127.0.0.1:49156->2376/tcp, 127.0.0.1:49155->5000/tcp, 127.0.0.1:49154->8443/tcp, 127.0.0.1:49153->32443/tcp minikube

如果我们执行docker exec -it 699a71fee349进入容器后再执行docker ps,就能发现K8S集群的服务了:

  1. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  2. af45f3caa0d9 99a3486be4f2 "kube-scheduler --au…" 2 hours ago Up 2 hours k8s_kube-scheduler_kube-scheduler-minikube_kube-system_be132fe5c6572cb34d93f5e05ce2a540_1
  3. e648e7d30a7d Error 404 (Not Found)!!1 "/pause" 2 hours ago Up 2 hours k8s_POD_kube-apiserver-minikube_kube-system_cd6e47233d36a9715b0ab9632f871843_1
  4. e26d9e92c4e3 k8s.gcr.io/pause:3.6 "/pause" 2 hours ago Up 2 hours k8s_POD_kube-scheduler-minikube_kube-system_be132fe5c6572cb34d93f5e05ce2a540_1
  5. e658bf17922d Error 404 (Not Found)!!1 "/pause" 2 hours ago Up 2 hours k8s_POD_kube-controller-manager-minikube_kube-system_b965983ec05322d0973594a01d5e8245_1
  6. 1f85a9bae877 Error 404 (Not Found)!!1 "/pause" 2 hours ago Up 2 hours k8s_POD_etcd-minikube_kube-system_9d3d310935e5fabe942511eec3e2cd0c_1
  7. ....

从容器中退出,安装kubectl之后就在Ubuntu上使用Kubectl管理集群了:

  1. curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
  2. sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

执行kubectl get nodes,查询K8S管理的节点。

  1. ~$ kubectl get nodes
  2. NAME STATUS ROLES AGE VERSION
  3. minikube Ready control-plane,master 19d v1.23.3

如果关注Kubernetes的界面,使用minikube dashboard就可以启动K8S的管理界面,并在Windows上通过浏览器访问 http://127.0.0.1:44185/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

使用Minikube可以让我们在本地拥有一个和生产环境一样功能的K8S集群,但这种方式同样带来了网络的复杂性,如下图,Ubuntu运行在Hyper-v的虚机中,在K8S部署的服务运行在Ubuntu的Docker容器的容器中(Docker in Docker)。所以,如果要在Windows的浏览器上访问K8S中运行的服务,需要先通过kubectl port-forward完成Ubuntu VM和Minikube容器的端口映射,然后再使用minikube tunnel完成VM到Windows的端口映射。

3. 基于K8S+Jenkins构建CI/CD流水线

Jenkins是一个经久不衰的持续集成工具,它的插件生态比较强大。我们构建基于Jenkins+Kubernetes的CI/CD流水线要达到的目的如下:

  1. 基于K8S实现Jenkins的弹性部署;
  2. 基于Jenkins插件实现CI任务在K8S上的运行;
  3. 基于Pipeline as Code实现Jenkins的流水线配置管理(持续集成任务+持续部署任务)。

基于K8S实现Jenkins的弹性部署

MindSpore易点通机器人的代码仓已经给出了在K8S上部署Jenkins的配置文件,这里要设置成LoadBalancer类型。

  1. ---
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: jenkins
  6. spec:
  7. type: LoadBalancer
  8. selector:
  9. name: jenkins
  10. ports:
  11. -
  12. name: http
  13. port: 8080
  14. targetPort: 8080
  15. protocol: TCP

再用kubectl create -n jenkins创建Jenkins的namespace,通过kubectl apply -f jenkins.yaml -n jenkins完成部署,然后用kubectl apply -f service-account.yaml -n jenkins完成API调用的授权。

在配置文件中我们指定了对外暴露的端口是8080,所以可以用kubectl port-forward svc jenkins/jenkins 8080:8080 -n jenkins完成端口映射,再执行minikube tunnel就可以在浏览器中使用127.0.0.1:8080打开Jenkins界面了,初始密码可以在pod启动的日志中获得。

基于Jenkins插件实现CI任务在K8S上的运行

完成Jenkins在K8S上的部署后,需要在Jenkins中安装kubernetes插件,配置节点类型为K8S集群。从插件管理中先安装kubernetes插件,然后在节点管理中选择配置集群
首先配置K8S集群的信息,因为在一个K8S集群,服务间都可以通过主机名的方式相互访问,所以“Kubernetes地址”配置只需要输入https://kubernetes.defaults,同时补充配置“Kubernetes命名空间”为jenkins,如下图所示。

同理,对于“Jenkins地址”,只需要填入http://jenkins.jenkins:8080

另一个要配置是pod模板,既任务运行的pod的基础镜像及相关信息配置。要同时运行Java和Python,所以在dockerhub找了一个Java和Python都有的镜像,如下图所示,保存后即可完成配置。

基于Pipeline as Code实现Jenkins的流水线配置管理

我们的最后一步是基于Jenkins的流水线即代码功能完成CI/CD流水线搭建,按照设计,它应该包含如下任务:

  • 持续集成流水线
    • 代码检查:数据处理代码、模型代码、推理代码以及脚本代码规范检查任务
    • 单元测试:数据处理逻辑、模型代码逻辑、推理代码逻辑的单元测试任务
    • API测试:推理接口功能测试
    • 训练触发:如果修改了训练代码,触发Argo的训练流水线
  • 部署

使用Jenkins流水线即代码功能,对应的配置如下:

  1. pipeline {
  2. agent {
  3. kubernetes {
  4. containerTemplate {
  5. name 'python'
  6. image 'bitnami/java:1.8'
  7. command 'sleep'
  8. args 'infinity'
  9. }
  10. defaultContainer 'python'
  11. }
  12. }
  13. stages {
  14. stage('Code Check ') {
  15. steps("Code Check") {
  16. echo 'checking python code.'
  17. }
  18. }
  19. stage('Unit Testing') {
  20. steps("Unit Testing") {
  21. echo "running unit tests"
  22. }
  23. }
  24. stage('API Testing') {
  25. steps {
  26. echo 'running inference API Testing'
  27. }
  28. }
  29. stage('Training Trigger') {
  30. when {
  31. changeset "src/train/*.py"
  32. }
  33. steps("trigger training") {
  34. echo 'trigger new round of training'
  35. }
  36. }
  37. }
  38. }

部署流水线的pipeline脚本如下:

  1. pipeline {
  2. agent any
  3. stages {
  4. stage('Packaging') {
  5. steps("Packaging") {
  6. echo 'packaging with model and inference code'
  7. }
  8. }
  9. stage('Continuous Deployment') {
  10. steps("deploying") {
  11. echo 'deploy new version of model'
  12. }
  13. }
  14. }
  15. }

配置文件中每个step先置空,是为了方便调试。在Jenkins基于上面的配置文件创建一个流水线后的测试结果如下:

4. 基于K8S+Argo持续训练流水线

Argo是一个基于K8S的开源的工作流管理工具,也支持机器学习的工作流。MindSpore DX Sig已经在先前的社区机器人项目中使用了该工具,所以这里我们复用了工具和配置。Argo Workflow的安装配置如下:

  1. 在K8S上安装Argo;
  2. 基于Argo Workflow 配置机器学习流水线;
  3. 运行机器学习流水线。

1. 在K8S上安装Argo

首先,我们执行kubectl create -n argo为Argo创建新的命名空间。然后,基于配置文件,执行kubect apply -f install.yml -n argo完成安装。最后,执行kubect apply -f manifests/create_serviceaccount.yaml -n argo完成权限配置。

和前面的Jenkins配置类似,Argo Server需要设置为LoadBalancer类型。

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: argo-server
  5. spec:
  6. ports:
  7. - name: web
  8. port: 2746
  9. targetPort: 2746
  10. type: LoadBalancer
  11. sessionAffinity: None
  12. externalTrafficPolicy: Cluster
  13. selector:
  14. app: argo-server

执行kubectl get svc -n argo可以看到:

  1. ~$ kubectl get svc -n argo
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. argo-server LoadBalancer 10.97.145.232 127.0.0.1 2746:30001/TCP 19d
  4. workflow-controller-metrics ClusterIP 10.99.196.47 <none> 9090/TCP 19d

如果要在Windows的浏览器上访问Argo的Web界面,则还需要把argo-server的端口暴露出来,同上使用kubectl port-forward svc/argo-server 2746:2746 -n argo完成端口映射。然后浏览器上访问https://127.0.0.1:2746,通过下面的脚本获得密码,登录后就可以正常使用Argo的Web管理界面了。

  1. #!/bin/bash
  2. SECRET=$(kubectl get sa argo-server -n argo -o=jsonpath='{.secrets[0].name}')
  3. ARGO_TOKEN="Bearer $(kubectl get secret $SECRET -n argo -o=jsonpath='{.data.token}' | base64 --decode)"
  4. echo $ARGO_TOKEN

2. 基于Argo Workflow 配置机器学习流水线

我们期望训练的工作流可以完成以下任务:

  1. 数据处理
  2. 训练
  3. 评估
    1. 质量评估:基于测试集数据评估模型,预测性能需要高于基线值
    2. 可解释性评估
    3. 可靠性评估
  4. 总结

基于工作流的设计以及Argo工作流语法,可以得出基础的配置:

  1. apiVersion: Page Not Found
  2. kind: Workflow
  3. metadata:
  4. generateName: robot-train-eval-
  5. spec:
  6. serviceAccountName: robot-sa
  7. entrypoint: robot-controller
  8. onExit: summary
  9. templates:
  10. - name: robot-controller
  11. steps:
  12. - - name: data-process
  13. template: process
  14. - - name: robot-train
  15. template: train
  16. - - name: robot-eval
  17. template: eval
  18. - name: robot-interpretability
  19. template: interpretability
  20. - name: robot-reliability
  21. template: reliability
  22. - - name: summary
  23. template: summary

而后,展开每个任务需要的配置,如训练的配置代码:

  1. - name: train
  2. container:
  3. image: ubuntu
  4. imagePullPolicy: Always
  5. env:
  6. - name: IS_TRAIN
  7. value: "True"
  8. - name: NUM_STEPS
  9. value: "10"
  10. command: ['echo']
  11. args: ["trainning"]
  12. ...

把每个阶段的任务汇总在一起就完成了整个的工作流。接下来,我们尝试使用Argo运行下训练流水线。

3. 运行机器学习流水线

可以使用Argo CLI的客户端完成工作流任务的提交,首先安装客户端:

  1. #!/bin/bash
  2. # Download the binary
  3. curl -sLO https://github.com/argoproj/argo-workflows/releases/download/v3.3.5/argo-linux-amd64.gz
  4. # Unzip
  5. gunzip argo-linux-amd64.gz
  6. # Make binary executable
  7. chmod +x argo-linux-amd64
  8. # Move binary to path
  9. mv ./argo-linux-amd64 /usr/local/bin/argo

然后通过argo cli提交工作流argo submit -n robot --watch robot-train-eval.yaml,执行结果如下,和我们期望的流水线步骤一致。

总结

本篇文章总结了如何在本地完成MLOps环境的搭建,基于Minikube、Argo等工具可以让我们很好的在本地展开开发验证工作,不用依赖复杂的基础设施,也不用有额外的开销。在配置文件中和脚本中,我们没有加真实的实现,是为了先打通流程,然后再将调试好内容逐步补充进去,始终都可以从端到端的角度来完成验证。

说明:严禁转载本文内容,否则视为侵权。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号