深度学习最大的坑明明是部署
深度学习最大的坑明明是部署
最近闲得无聊,学弟学妹有一个比赛我就带着做了(说是带着做,其实只有我在写代码,学弟学妹不会·····),基本上是一个在边缘设备上做视频检测的项目。所谓边缘设备其实也是一台x86主机,只不过没有GPU,也是在这个过程中对于深度学习模型的部署有了许多练习,发现这个坑还挺深的。
(多说一句,当时收到设备发现是一台x86主机真是谢天谢地,之前用过某arm架构的专业用途的机器试着做深度学习的开发,机器还挺贵的,但是用起来那个酸爽:很多包没有arm的,开源的话还能源码编译,但是编译地迷之慢,碰到闭源的驱动、包等等基本上可以躺平了·····)
之前其实已经做过深度学习模型的部署了,就是我之前的博文中我做的那个个人项目,用ssd mobilenet,利用tensorflow lite在手机上跑目标检测,但是上次的项目方便就方便在用的是现成的网络,这个网络tensorflow lite是有官方支持的,不涉及到customer layers,文档也比较全,所以做起来还挺顺利。
但是这次不一样,这次我们的模型比较复杂,用Yolo的darknet做了特征提取,之后还加了cnn、双向lstm等等层,这就麻烦了。
- 先试着直接在边缘设备用CPU上跑原始模型,不出意外地,实时性达不到
- 再尝试用Intel的openvino(因为板子上有一个Intel的HDDL推理加速硬件),这个就有意思了:官方给了一个行为检测的demo,和我们的需求差不多。然后我在github也找到了用resnet_vtn\mobilenet_vtn(也有cnn3d等等)来训练的openvino代码,下载预训练模型转换成onnx再转换为openvino格式之后遇到了问题:
- resnet_vtn\mobilenet_vtn推理特别慢,一帧就要500ms左右,那要达到实时的话差不多一秒只能推理两帧,这就从原理上有问题了,帧之间跨度太大了,不好从中推理行为
- 那个HDDL不好使,听起来很厉害:“人工智能加速器”,但是我实际测试下来,只比CPU推理快10%左右,有一次还出现了比CPU慢的情况····亏我搞了半天才把它环境配置好。而且我发现,FP32和FP16的推理速度好像没差很多····FP8之类的openvino还不支持
- 官方demo的模型其实很好用!模型小、速度快、精度也还行,它是基于Kinetic400数据集的,我想迁移到我们自己的数据集和任务上。但是!官方只给了用openvino转换后的模型,没有提供模型代码!因为它是有损转换,所以很难从转换后的模型恢复原始的模型(这个过程和编译差不多),我翻遍了github和intel官方文档也没有找到这个模型的代码·······我也不理解,为啥这个还藏着掖着
- github上resnet_vtn\mobilenet_vtn的README中写着,将模型用openvino转换后用openvino里那个行为检测的demo的代码跑就可以了,但是实测时不知道是不是帧间隔过大的问题,几个模型都出现了只预测某一类的问题,也即是无论输入什么,输出都是那个类,我还没弄清楚是为什么(因为后来就不采用这条路了,所以研究了一晚上之后也没接着研究)
- 再尝试用tensorflow lite,老实说这条路也许是能走通的,但是无奈我自打上手用的基本上就是pytorch,tensorflow确实功夫不到家,主要难点其实就是先要把模型转成pb文件,再转成tflite格式,但是我们的模型比较复杂,而且算是“套娃”网络:网络里面已经套了一个预训练的pb文件了,而且还用到了双向LSTM。据说tensorflow lite已经支持lstm了(虽然官方demo里面好像没有?),但是确实很难,尝试了好几次都没成功,一部分是因为我对tensorflow不太熟悉,一部分是因为tensorflow api实在太tm复杂了,另外就是tensorflow lite对自定义模型的兼容性还是不太好,有很多时候需要自定义customer layers,尤其像网络复杂一点定义起来就更麻烦了。这个不得不说,弄得我很头大,那几天睡觉做梦都是这些
- 又尝试换模型,既然我们自定义的模型支持不好,那就试试那些支持好的网络吧。向同学打听到视频检测也有用纯cnn网络的,那这个我就太熟了,用pytorch搞了个resnet(openvino也支持pytorch模型转换的,需要先把模型转换成onnx通用格式,这里要吐槽下intel openvino的文档,列出了tensorflow和caffe,就是没在一级目录列出来pytorch,我一开始还以为不支持),结果训练不收敛·····好吧,从原理上我也觉得不太靠谱,纯靠图像信息来检测行为确实不太可能
再回头看看github上面关于tensorflow lite和openvino等技术的项目,基本上都是基于demo开发的,也就是“demo提供了什么模型,换个场景开发下”,踩深坑并且踩坑成功的确实不多,主要还是这些工具用起来都太坑了(这里再吐槽下openvino的代码,要把支持的应用的api写全啊,只提供了几个应用的执行代码文件,其他模型转换过去了不知道找谁执行,文档说的也可以再详细一点·····)
最后怎么解决的,说来神奇······昨天把边缘设备里的tensorflow-gpu版本卸载了(最一开始装的,后来都没用过),然后用conda重新创建了一个环境,安了一个tensorflow-cpu版本以及一些相关的包,再用原模型一跑,它就突然跑起来了。我坐在那楞了五分钟,吃了个月饼,心里想的是“这tm咋就跑起来了,之前明明跑不了了,这找谁说理去,我这几天忙活了个啥·····"。我猜测了一下原因:
- 之前环境的依赖有问题(但是好像没啥问题啊····)
- cpu版本对cpu的推理有优化?(这个我还没搜到证据)
- 上天被我这几天的折腾感动了,命令板子麻溜地跑起来
我猜是第三个原因····
总体做下来的感觉就是一句话,“带着锁链跳舞”,边缘设备硬件条件受限,但是又要实现比较好的深度学习模型效果,工具也不完善,(也没有人和我一起做····)。还是学术界好混,实现idea就行,卡随便用,不用考虑实际应用。不过我觉得这还挺能反映工业界的深度学习实践和学术界的研究的区别的,抱着几个好用的模型做开发、部署的dirty work就完事了,天天折腾新模型确实吃不消,光是成功部署就是个问题。