链接:https://www.zhihu.com/question/428800593
编辑:深度学习与计算机视觉
声明:仅做学术分享,侵删
如题,本人21届渣渣研三硕士,实习、项目和应聘方向都是图像算法,cv算法岗内卷程度有目共睹,看了不少业内前辈的建议,说转算法部署落地方向比较好(个人在实习期间也感觉到算法模型部署和落地的重要性),本想趁着春招还没来赶紧学习下,可苦于实际中接触不到这方面的前辈或者系统的知识,自学起来如无头苍蝇,无从下手。所以想问问前辈们,如何学习这方面的技能知识,需要掌握那哪些工具技能?
作者:ybai62868
https://www.zhihu.com/question/428800593/answer/1560594742
2017年: 比你大一届,本人也是20届的渣渣硕士,刚刚上研的时候,和大多数“内卷儿”一样,我也很幸运被老板安排了“计算机视觉&图像处理&模式识别”的研究方向。屁颠屁颠的开始看cvpr,iccv的paper。
回想起过去,那时的我年幼无知,在地平线的一台四卡服务器上非root权限一步一步的装好了caffe,开始跑起来了openpose的训练,原本以为我的炼丹生涯就这样正式开始了,没想到怎么都复现不到paper上的精度,当时对multi-scale的测试看半天还不懂怎么回事。经常被leader push进度,真心觉得自己菜得扣脚,很多时候都想放弃炼丹。
一步一步,在工业界,从单帧图像上的目标检测,语义分割,实例分割,到人体姿态估计。再迁移到视频上的目标检测,语义分割,关键点检测。以及最后毕业论文的多目标跟踪。算是把整个工业界能用的cv模型都摸了一遍,领域内的经典paper也能做到信手拈来?起码,各种开源的检测框架(商汤的mmdet, Facebook 最早的mask rcnn,detectron1 (caffe2), detectron2 (pytorch), gluonCV)都用过并完成了自定义的项目,其中的源码也都是“随心”看过一遍,但是自己太蠢了,写不到这个水平的python和cuda代码,以及每次用完,对很多细节的设计只能感慨作者的牛逼。
2018年:一个偶然的机会,我开始看mxnet的源码(当时还是使用的symbol接口),看着看着,觉得这玩意和caffe代码好像,很多地方都是从caffe那里复用的,设计也比caffe灵活不少,毕竟粒度更细,安装也更加友好。我一步一步的学习mxnet官网上放出来的所有有关framework设计的知识,包括从“怎样设计一个高效的data loader”,“怎么样设计一个engine把框架中的所有组件schedule起来”,“以及怎么样更好的优化memory和减少数据IO”,“包括怎么样设计一套面向任何等级用户都友好的API”。
原本以为自己掌握了设计DL framework的大体奥义,发现还是想太多了,在面对让自己从头实现一个框架的时候,我也只会用python定义class 包来包去,性能什么的就别说了,我的菜还是没办法改变,最终还是想自己的愚蠢低下了头。。。
2019年:又一个偶然的机会,我开始在大洋彼岸某个村的CSL做summer research,项目的需求是为他们实验室的一款深度学习编译器(target为fpga)去写一套opencl的backend。
什么是编译器?什么是backend?什么是fpga?什么是opencl?一连串的问题对傻逼的我来说,一切都是未知。扒开这套编译器的codebase,我发现大部分代码都是从tvm那里借鉴来的, 于是,我又走上了tvm的学习之路,从tvm的design到完整的编译flow,包括底层的c++到与上层的python交互,以及autoTVM(那会Ansor还没出来)全部走了一遍。
对于一个根本没玩过硬件开发板的我,这一切在当时来看是非常困难的,还好实验室有给力的Ph.D.们,在他们的配合下,我也成功把基于xilinx和intel fpga的opencl backend全部添加了上去。那会的我,觉得自己算是掌握了 编译器的大体奥义。可最终我还是想自己的傻逼低下了头,涉及到传统编译器中的llvm的设计,codegen的很多细节,我还是一无所知。。。
回国后,又加入了某条的mlsys组继续做编译器,我随后又在glow的基础上,为硬件组的自研芯片MVP开发profile-guided的quantization工具链以及针对网络的每个layer开发了方便debug的可视化工具。
2020年:又又一个偶然的机会,被安排到了一家创业公司做intern,刚刚入职第一天就要求在2080ti上去优化一个超分4k视频。对于一行cuda代码都没写过的我来说,那是不敢想象的,项目负责人每两天催一次进度,连给我配tensorRT,学习如何写高性能cuda代码的机会都不给。我每天都活在自责与痛苦中,为什么我这么菜?这么垃圾啊?待我整完了从pytorch模型到onnx模型转换,再到trt的编译,以及为各种不支持的operator写完tensorRT的plugin,再到关于image的前后处理全部手写cuda kernel去和opencv硬碰硬。
遗憾的是,整个inference还是没有跑起来,当我用尽了我当时力所能及的cuda的debug工具(cuda-gdb,cuda-memcheck,...)最终发现还是败在了模型的多张帧输入没办法做到CPU和GPU上的memory 对齐。就这次偶然的机会,我竟然学会了tensorRT的部署。仗着这个经验,我又把组里其他模型:OCR,简化版超清视频到TX2,NX,AGX,智能相机等设备上,用尽了各种能优化的框架ncnn,mnn (其中包括针对工业级的二阶段的OCR模型,det用tensorRT,reg用mnn的vulkan后端联合开多线程优化在TX2上达到real-time)也熟悉了很多不同的backend和指令集架构。
原本以为,我已经掌握了深度学习CV模型落地的要领,直到这几天接到了要在华为的atlas 500板子上部署算法团队自己整的一套faster rcnn的二阶段检测模型以及tracking,几乎所有套件都要从头开始手写c++(借助FFmpeg对RTSP拉流,解码,udp报文传送,前处理,rpn生成proposals,proposal变anchor,anchor到bbox,kalman filter, hungary, track ID筛选 ...),我才发现自己的无知,模型部署真的是个大坑。
以上内容吹逼归吹逼,且当个故事听听就好。
其实我想表达的是 视觉算法的工业部署和落地是没有你想得那么容易的,dirty work(手写c++, cuda各种前后处理) 全靠你对于上层模型算法的理解,以及不同hardware backend设计的深刻认知。如果要利用编译技术,你又得对深度学习编译器中如何在design space中搜optim的值和手写template来达到半自动优化有很好的掌握,你才能真正把一个paper里吹的“天花乱坠”的model部署到一个理论算力能跟得上的设备上( 当然,real-time和power是很重要的指标)
从工业界的角度想要快速出活,真正要自学的话:
深度学习框架方面,读一读caffe的源码和设计理念,看看其中的cpu/gpu上的op是怎么写的。
深度学习编译器方面,读一读tvm的源码和设计理念,看看编译器是怎么把一个dl model经过relay IR 再到 tvm IR,再到不同backend的codegen。以及编译器对计算图的常见优化(算子融合,data layout等)
深度学习模型部署方面,针对nvidia的gpu,看看cuda,tensorRT的document,自己尝试着把一个检测或者分割的模型部署到实验室的机器上。针对移动端的cpu,gpu,看看mnn,学习下mnn的code design。很多非常好的profiling,可视化工具。针对fpga设备,可以看看hls,opencl,verilog。毕竟直接拿现成的tool把model中的op翻译成hls,opencl代码还不是非常高效,很多东西还是直接写HDL所带来的speed up才更直接。这就和很多时候在arm架构的cpu上去优化算法,直接手写汇编所带来的提升更加直接。
从提升自己内功的角度来看,认真啃好:“编译器,计算机体系结构,并行计算,
编程语言设计,计算机系统,计算机网络,C++程序设计” 来说是更好不过了。
当然,一切的一切都得来源于你对上层DL算法都有了深入了解,知道每个layer是怎么跑的,输入的feature和输出的feature都是怎么存的,软件和算法层面都经历过怎样的加速,还有哪些加速是需要结合hardware来进行co-design的,你才能更好地把模型中的不同layer合理高效地部署到不同的hardware上。
给个结论:如果要真正想习得视觉算法的部署和落地,最快捷的方法,首先你需要有一个极为严格经常push你并且还活跃在代码一线的leader,然后还得有一个特定的业务场景和急迫的ddl。
作者:Rand Xie
https://www.zhihu.com/question/428800593/answer/1559994521
算是有过部署图像算法到嵌入式设备的经验吧. 个人经验来看, 需要建立起两个方面的能力, 一个是图像算法的能力, 另一个则是工程能力 (看着很像废话).
图像算法方面, 需要知道可以怎么优化算法去减少运算量, 或者在latency budget不够的情况下, 如何在算法performance和latency之间取舍. 这就要求对传统图像算法和深度学习算法都有理解.
工程方面, 需要掌握一门compiled language, 最好是C++, 因为你需要去榨干硬件的性能. 这里说的掌握C++, 不是说去掌握所有的奇技淫巧, 而是能深入底层原理, 更精确得控制每一行代码的执行. 展开点来说, 这就涉及到计算机科学最基础的操作系统, compiler, 体系结构等等.
当然, 单纯学这些知识很难坚持, 最好是边做项目边深入了解. 如果能联系到学校的教授, 参与相关的课题, 这就最好了. 如果没有这样的机会, 也可以考虑参与一些开源项目, 比如TVM之类的.
作者:机器学习入坑者
https://www.zhihu.com/question/428800593/answer/1564651870
拿到过高通的终端侧人工智能创新奖,主要做的是手机端的APP。
大规模的工业部署我暂时没接触过,只做过简单的落地应用。
既然说到怎么学,我觉得首先是在自己的服务器上打好基础。如果在训练模型的时候不知道模型的每一层是什么操作,那么部署的时候肯定会出现很多问题,比如端侧不支持某个算子。
其次,需要学习一些模型压缩和量化的知识。在部署的时候需要考虑模型的计算量是否满足部署平台的限制,目前很多针对mobile的论文提到了降低计算量的网络设计。
最后,需要学习Java或者c++之类的语言,一般训练模型用python,而部署的时候需要采用别的语言。pytorch和tensorflow都含有好几种语言的版本,可以多逛逛官网学习一下。
作者:韩天啸
https://www.zhihu.com/question/428800593/answer/1566173600
视觉算法的部署和落地,最一般考虑的"速度"和"精度"的权衡。下面的部署流程中简单介绍一些。
其次,通常的实际系统具体的情况,比如输入输出(摄像头的分辨率、摄象头角度变换),是否要处理遮挡,网络条件(需不需要本地做控制,还是只需要传结果)。
还有是解决一些bad case,比如过曝、失焦。
数据处理 有无标注好的数据,如果有标注数据,数据增广之后是否可以让模型很好的收敛;如果没有标注数据,找一找公开带标注的数据集里面有没有可以迁移学习的。
高效训练 因为之后模型压缩损失精度,就要提前在训练时尽可能把精度达到更高、缩短训练时间。比如大batch size和Linear scaling、warm up、Zero γ 、no bias decay等的方法。同时优先考虑mobilenet等backbone,看精度是否在要求内。听说,有条件的会搜索一下网络结构。
推理引擎优化 使用推理引擎来进行优化,TVM、Nccn、tensorRT、Tensorflow-lite、Tengine、Xilinx vitis 、Huawei ruyi。各家的流程主要有一些 剪枝、量化、蒸馏等。量化中也会重新训练一部分矫正数据集,达到更好的效果。但量化训练(量化感知训练)之后的网络权重就和推理引擎耦合起来了,所以放在了推理引擎优化来讲。但其实训练后量化不管有没有经过矫正损失精度还是蛮多的。所以知识蒸馏看起来还是蛮不错的,看到paddle放出来过一个结果,8位定点数量化的学生模型不仅参数来下降了70%+,精度还提了1%。
加速硬件选取 可以看看roofline模型,软件优化的trick之后,硬件的加速也很重要。使用并行加速硬件(GPU、FPGA)或者异构计算(CPU+FPGA、CPU+加速器)可以有效提高推理速度,但成本也增加的比较多。比较实际的办法,是复用这些加速器,一拖多、但带宽的限制也比较大。看到一些文章在offloading或model partition,希望早日有好的工具release。
5 .上线前测试评估 Fuzz测试工具
在实际使用过程中因为一些原因,譬如使用图像分类应用时,当镜头模糊、光照不足、下雨大雾、拍摄角度等等情况下,实际输入的数据与训练模型时的标准数据集有一些不同。在这种情况下,模型可能出现模型精度答复下降。而在某些极端情况下,可能出现未知的推理失误,引入安全性问题。对模型的评估和鲁棒性测试,可以有效减少未知的安全风险,测试工具通过对数据集进行增强,如色差、翻转、模糊等,自动化产生测试样例。评估图像的覆盖率指标以及精度下降。测试模型出现扰动的情况下,模型精度(Accuracy)下降程度以及神经元激活程度(Coverage Rate)
FPGA LOW POWER OBJECT DETECTION
DAC会议每年会举办一个system design contest,分为两个赛道,分别在FPGA和embedded GPU上处理无人机拍摄的小目标检测数据集。比赛通过分析实际下板运行的速度、精度和功耗三个指标来衡量最后的得分。
其中的一个开源项目SpooNN值得一看。SpooNN的作者是由ETH(苏黎世联邦理工学院)系统组。使用软硬件联合优化的方式在FPGA上优化了squeezeNet,分别在2018、2019比赛上获得第二名、第三名。在网络结构方面,SpooNN将squeezeNet的fire 模块改成half fire模块,少使用一层的卷积层。
thanks to:DREU at Brown University
Thanks to:DAC 2019低功耗目标检测系统设计挑战赛:GPU、FPGA组双冠军方案解读
给出一个gihub链接,大伙可以先自行去看看,由于代码都是release的,而且可以重新训练,所以相对有参考价值。照着我上面讲的流程梳理一下~
作者:范沅
https://www.zhihu.com/question/428800593/answer/1563707806
就这么点时间,看看c++吧,不用学的太好,知道怎么样高效处理数据流,写写前后置处理,指针啊矩阵计算啊啥的。
再看看tfx之类的东西吧,看看怎么调度的。
优化算子啥的,常见模型都跑不好是库有问题吧,看看老黄的tensorrt吧,大概了解了解。
看看招啥人吧,有啥要求,面向面试编程。
☆ END ☆
如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 mthler」,每日朋友圈更新一篇高质量博文。
↓扫描二维码添加小编↓