深度学习网络模型部署——知识储备Docker(一)

欢迎关注公众号:七只的Coding日志,[更多链接](https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=Mzk0ODA5NTc5MQ==&uin=&key=&devicetype=Windows+10+x64&version=6302019c&lang=zh_CN&a8scene=7&fontgear=2)

实现从项目调研、数据收集、数据预处理、深度卷积神经网络训练再到服务器部署的人脸表情识别小项目

一、需求

1、简单的demo演示,只要看看效果的,像是学校里面的demo展示这种

caffe、tf、pytorch等框架随便选一个,切到test模式,拿python跑一跑就好,顺手写个简单的GUI展示结果

高级一点,可以用CPython包一层接口,然后用C++工程去调用

2、要放到服务器上去跑,但一不要求吞吐二不要求时延的那种,说白了还是有点玩玩的意思

caffe、tf、pytorch等框架随便选一个,按照官方的部署教程,老老实实用C++部署,例如pytorch模型用工具导到libtorch下跑(官方有教程,很简单)

这种还是没有脱离框架,有很多为训练方便保留的特性没有去除,性能并不是最优的;

另外,这些框架要么CPU,要么NVIDIA GPU,对硬件平台有要求,不灵活;

还有,框架是真心大,占内存(tf还占显存),占磁盘

3、放到服务器上跑,要求吞吐和时延(重点是吞吐)

这种应用在互联网企业居多,一般是互联网产品的后端AI计算,例如人脸验证、语音服务、应用了深度学习的智能推荐等。

由于一般是大规模部署,这时不仅仅要考虑吞吐和时延,还要考虑功耗和成本。所以除了软件外,硬件也会下功夫,比如使用推理专用的NVIDIA P4、寒武纪MLU100等。这些推理卡比桌面级显卡功耗低,单位能耗下计算效率更高,且硬件结构更适合高吞吐量的情况

软件上,一般都不会直接上深度学习框架。对于NVIDIA的产品,一般都会使用TensorRT来加速(我记得NVIDIA好像还有TensorRT inference server什么的,名字记不清了,反正是不仅可以加速前传,还顺手帮忙调度了)。TensorRT用了CUDA、CUDNN,而且还有图优化、fp16、int8量化等。反正用NVIDIA的一套硬软件就对了

4、放在NVIDIA嵌入式平台上跑,注重时延

比如PX2、TX2、Xavier等,参考上面(用全家桶就对了),也就是贵一点嘛

5、放在其他嵌入式平台上跑,注重时延

硬件方面,要根据模型计算量和时延要求,结合成本和功耗要求,选合适的嵌入式平台。

比如模型计算量大的,可能就要选择带GPU的SoC,用opencl/opengl/vulkan编程;也可以试试NPU,不过现在NPU支持的算子不多,一些自定义Op多的网络可能部署不上去

对于小模型,或者帧率要求不高的,可能用CPU就够了,不过一般需要做点优化(剪枝、量化、SIMD、汇编、Winograd等)

顺带一提,在手机上部署深度学习模型也可以归在此列,只不过硬件没得选,用户用什么手机你就得部署在什么手机上23333。为老旧手机部署才是最为头疼的

上述部署和优化的软件工作,在一些移动端开源框架都有人做掉了,一般拿来改改就可以用了,性能都不错。

6、上述部署方案不满足我的需求

比如开源移动端框架速度不够——自己写一套。比如像商汤、旷世、Momenta都有自己的前传框架,性能应该都比开源框架好。只不过自己写一套比较费时费力,且如果没有经验的话,很有可能费半天劲写不好。

就目前来说,我打算将需求定位到2,后期在2的基础上考虑吞吐和延迟问题,从而能够进一步达到需求3和5(位于手机端部署)

二、部署方面问题

模型部署就是在某一框架内训练好的模型(权重文件),通过具体框架进行模型转化或者直接使用对应语言所提供的API接口,load、get一系列操作,使得训练好的“黑箱”能得到实际应用。这种方式可能是简单的pyinstaller库进行简单的封装、也可以是pyqt进行界面集成、接口调用,或者使用flask或者Django框架进行前端和后台服务器的嵌入,这些总体来说,都算是模型部署。

1、首先,不得不提Docker部署模型

Docker的前生是LXC,全名Linux Container,是一种轻量级的虚拟化手段,以便隔离进程和资源。容器是指将单个系统管理的资源划分到孤立的组中,有效地安排资源使用需求。总之,LXC是一种操作系统层次上的资源虚拟化,提供了一个自己的进程和网络空间的虚拟环境。

什么是Docker呢?  Docker底层使用了LXC实现,在此基础上,增添了更多强大的功能。Docker属于一种开源应用容器引擎,是基于go语言开发并遵循apache2.0协议开源。

优点: 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的linux服务器,也可以实现虚拟化。

Docker总体架构:

架构

由于本次轻量化网络结构部署,因此采用Docker作为容器。

2、Docker基本概念

Docker包括三个基本概念:

    ——镜像(Image)

    ——容器(Container)

    ——仓库(Repository)

整个生命周期

2.1 镜像(Image)——一个特殊的文件系统

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。 镜像不包含任何动态数据,其内容在构建之后也不会被改变。

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

2.2 容器(Container)——镜像运行时的实体

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等 。

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于自己的独立的命名空间。前面讲过镜像使用的是分层存储,容器也是如此。

容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。

按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据 ,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此, 使用数据卷后,容器可以随意删除、重新 run ,数据却不会丢失。

2.3 仓库(Repository)——集中存放镜像文件的地方

镜像构建完成后,可以很容易的在当前宿主上运行,但是, 如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。

一个 Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。所以说:镜像仓库是Docker用来集中存放镜像文件的地方类似于我们之前常用的代码仓库。

3、“Docker - Build, Ship, and Run Any App, Anywhere”

操作

——Build(构建镜像) : 镜像就像是集装箱包括文件以及运行环境等等资源。

——Ship(运输镜像) :主机和仓库间运输,这里的仓库就像是超级码头一样。

——Run (运行镜像) :运行的镜像就是一个容器,容器就是运行程序的地方。

4、Docker安装

Docker也是支持其他如CentOS, Mac OS X, Windows等平台。Docker运行对内核要求比较高,一般建议直接在Ubuntu平台运行。

CentOS中安装docker教程,Windows10中安装docker教程,Windows10中docker的安装与使用,Mac系统docker安装

你可能感兴趣的:(深度学习网络模型部署——知识储备Docker(一))