网易易盾深度学习模型工程化实践

深度学习大热以后受到大量关注,大部分刚接触深度学习的同窗,注意力大都集中在如何调整参数/数据/网络结构,如何达到预期的精度/召回率/准确率等。nginx

然而,深度学习模型应用的整个流程里面还有一个重要的环节,就是模型部署上线。一个模型只有部署上线了,这个模型的价值才能获得体现。git

因此咱们今天不讨论如何训练模型,咱们关注一下如何将训练好的模型部署上线。
640.webp.jpg
模型生命周期github

模型部署上线,就是将模型封装成一个在线服务,并分配相应的资源,将在线服务运行在服务器上,实时接收请求,返回predict结果。封装在线服务的方式有不少,能够选择一些成熟的框架好比http / thrift / gRPC等,选择一款适合本身项目的便可,咱们重点关注怎么部署。web

模型部署 v0.1 - 裸机部署docker

顾名思义,就是直接在物理服务器上安装配置好相应的环境,直接将工程代码/模型文件部署到物理服务器上运行,看起来好像很简单直接,可是实际操做起来问题不少。实际服务器可能会有2块GPU甚至4块GPU,因此一台服务器一般须要部署多个模型应用,而在同一台服务器上部署多个应用碰到的最多见的问题,就是环境问题。
环境问题的复杂性表如今如下几个方面:segmentfault

  • 依赖管理复杂:因为各类缘由,线上服务器的操做系统版本可能会不一致,好比系统有CentOS6/七、Debian8/9,甚至内核版本也会有一些差别,依赖包管理工做变得很是复杂;
  • 容易产生依赖冲突:各个模型应用依赖的包版本很容易产生冲突,好比一个应用依赖了opencv2,另外一个应用依赖了opencv3,在没有很好的隔离的状况下,会出现各类兼容性问题;
  • 配置/部署效率低下:某一台服务器部署了A应用,某一天A应用下线了,想要部署B应用,可能会面临遗留环境冲突问题,甚至须要重装系统从零开始。碰上线上服务须要紧急扩容的状况,这种环境问题更是容易让人手忙脚乱。

641.webp.jpg
模型部署复杂的环境/依赖api

模型部署v0.2 - 容器技术安全

为了将开发运维从复杂的环境管理工做中解放出来,咱们引入了容器技术。容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序能够在几乎任何地方以相同的方式运行。
简单的说,容器包含两部分:服务器

  • 程序
  • 程序依赖的环境

每一个程序都自带依赖环境,而且相互隔离,这很好的解决了裸机部署带来的各个应用之间的依赖冲突问题,对宿主机的环境依赖很小,真正实现了 “Build Once, Run Anywhere” 的口号。借助nvidia官方提供的 nvidia-docker 组件,将nvidia设备映射到容器内部,咱们能够很容易的实现快速的模型应用部署上线。
642.webp.jpg
容器化环境隔离网络

但容器技术并无解决全部问题,其中一个问题就是资源管理和调度问题,因为一台服务器须要部署多个应用,每一个应用都须要分配1块GPU,这就要求咱们手动维护好分配记录,例如:

  • 应用 A 部署在 Server0 服务器上,分配了第0块GPU
  • 应用B部署在Server0 / Server1服务器上,分配了第1块GPU
  • ...

这种管理工做在集群规模小的时候能够手动管理,可是在集群规模大了以后就很混乱、很复杂了,并且也容易错——尤为是当今天易盾日均请求量达到十亿量级以上的时候,仅靠手动管理已没法想象。

更为严峻的是,由于没有对应用的资源作隔离,经过这种方式部署的应用,相互之间会产生资源竞争问题。例如一台服务器上运行了 A / B / C 应用,此时A应用因为程序Bug将CPU资源耗尽,此时在同一台服务器上的B / C应用也会受到牵连影响。

模型部署v0.3 - Kubernetes

为了解决资源调度问题,咱们引入了Kubernetes。Kubernetes 是一个开源系统,用于容器化应用的自动部署、扩缩和管理。在Kubernetes里有一个“资源”的概念,好比CPU和内存都是资源类型,咱们能够经过Kubernetes对运行的容器进行资源管理,例如:

​apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:

  • name: nginx

image: nginx
resources:
requests:
memory: "64Mi"
cpu: "1"
limits:
memory: "128Mi"
cpu: "2"

咱们对运行的nginx容器申请了64M内存和1核CPU,而且限制这个容器最多只能使用128M内存和2核CPU,若是nginx程序尝试申请超过128M内存,就会被kubernetes系统kill掉从新拉起来,确保不会影响其余应用。借助nvidia官方提供的 k8s-device-plugin 插件,nvidia GPU也被抽象成一种资源类型,这时候咱们就能够像申请CPU/内存同样申请GPU资源。

apiVersion: v1
kind: Pod
metadata:
name: model-app
spec:
containers:

  • name: model-app

image: model-app:v0.3
resources: requests:
cpu: 4
memory: "8Gi"
nvidia.com/gpu: "1"
limits:
cpu: 4
memory: "10Gi"
nvidia.com/gpu: "1"

上述示例中咱们为 model-app这个应用申请了4核CPU、8G内存、1块GPU,申请提交以后,Kubernetes会分配好对应的资源,并自动调度。开发运维人员的视角从“某台服务部署了xx应用”转换为“这个kubenetes集群的资源使用状况”,这极大的简化了运维管理工做。

Kubernetes自带了dashboard组件,监控方案能够用prometheus+grafana,基本的运维和监控管理均可以实现,但毕竟是开源版本,部分功能还不能知足咱们的运维开发需求,通过一番定制开发,咱们基于Kubernetes开发出了适合本身的集开发运维于一体的一站式管理平台。
643.webp.jpg
易盾某项目的资源汇总信息

总结
因为易盾业务发展迅猛,网易安所有商业化易盾仅仅三年多一点的时间,网易易盾就已拥有超过26万的开发者,服务客户达数千家。这也使得这块技术,从最先的裸机手动部署,到半自动的容器部署,再到全自动的kubernetes部署。

每一次进步都伴随着效率的提高,解放了大量的开发运维人员精力,让开发运维人员能够投入更多的精力到值得关注的产品功能上。与此同时,也使得易盾的机器学习模型,从训练完成到上线应用,仅须要数分钟就能够实现落地,从而及时帮助某些有紧急需求的客户。

参考资料

https://www.docker.com/
https://github.com/NVIDIA/nvi...
rhttps://github.com/NVIDIA/k8s...
https://kubernetes.io/zh/

点击免费体验网易易盾安全服务。

相关文章
相关标签/搜索