欢迎关注我的大众号 [极智视界],获取我的更多经历共享

大家好,我是极智视界,本文来谈谈 AI推理结构,是谈谈AI开展系列的第二篇。

本文是我写的谈谈 AI 开展系列的第二篇,别的篇章能够自行查阅:

  • 谈谈 AI 开展第一篇:AI 练习结构 ==> 拜访方法:链接;
  • 谈谈 AI 开展第三篇:AI 练习算力 ==> 敬请期待;
  • 谈谈 AI 开展第四篇:AI 推理算力 ==> 敬请期待;
  • 谈谈 AI 开展第五篇:AI 编译结构 ==> 敬请期待;

时光斗转星移,AI 飞速开展。

满打满算,我真实进入到 AI 这个行业差不多五年的样子,这段时间其实是正处于 AI 结构和 AI 算法自身快速开展的黄金阶段。也很有幸见证了一些 “古早” 的结构、算法,以及从 “古早” 到 “现代” 快速进化的进程,感慨良多。我决定在这几篇文章中谈谈我这个阶段关于 AI 的一些基础设施,如结构、算力、算法等的思考、感触和想法,作为一种输出,也作为一种记录,或许几年后回过头再来看,会别有一番滋味。

本文所评论的推理结构或许会触及英伟达的 TensorRT、NCNN、Tengine 以及一些国产硬件厂商的配套推理引擎。在许多的推理引擎中,英伟达的 TensorRT 可谓是俊彦中的俊彦,标杆中的标杆。标杆到什么程度呢,举个比方,我们国产 AI 芯片厂商的新贵天数智芯、登临,他们的推理引擎都是完全对标 TensorRT 的,意思是一些接口、推理流程的安排方法都是力求和 TensorRT 保持共同,目的是为了借用英伟达的生态,下降用户层的迁移成本。

和练习结构相同,推理结构同样生态繁多,但当你接触过的结构较多之后,就应该能够发现他们之间的一些共同点:推理流程都是共同的。我画了下面这个图来进行展现和阐明,这里的每一个模块的重要性都很高。拿前端解析来说就很难,由于练习结构太多了,同一个模型或许会用不同的结构进行练习,那就需求支撑从不同的结构往 ONNX 或许往你自界说的模型结构进行转换和收敛,这个进程是杂乱的。这个杂乱性一方面来自于不同结构之间的差异,算子粒度、算子描述、算子参数等或许都会有所差异;另一方面来自于 ONNX 自身,ONNX 自身具有一些问题,比方 ONNX opset 版别之间的不一致,比方胶水算子比较多导致对部署不友好等。接着是模型优化,模型优化是推理引擎中最重要的模块,里边的内容也为最多。关于模型优化,我觉得大致能够分为上层优化和底层优化两个部分。上层优化或许又可称为图优化、IR 优化,包括像耳熟能详的量化、算子融合、部署不友好算子的替换等都归于这个层级;而底层优化会愈加多的触及软硬件协同的优化,比方会凭借指令集的加速做一些向量化的实现,比方会更多考虑访存方面的问题来调理算子的调度,比方采用循环拆分来更好地运用并行核算等。正是由于模型优化这一块过于杂乱,过于博大精深,所以衍生出了编译结构来对专门对这一块进行优化,关于编译结构后边我会专门写文章进行评论。一个推理结构的功能怎么样,往往在于它模型优化这一块做的怎么样,如果模型优化这一块做的足够好,那么整个推理结构的功能也会比较突出。在完成了前端模型解析和模型优化后,会进入到惯例的模型推理流程,即 前处理 -> 模型推理 -> 后处理。在实践事务中,关于推理结构来说,并不会在前处理和后处理中做太丰厚的支撑,前处理和后处理模块大多会由用户来主导,比方会运用一些如 OpenCV、npp 之类的通用库来进行处理。一些急于推广的推理结构,为了下降适配难度以及进步整体 pipeline 的功能,另有些情况是需求自己实现一些常用算子以适配自家的芯片,这样或许会在自己的推理引擎中以自界说算子 plugin 的方法集成一些前后处理的典型算子,比方 yolo、比方 resize。

极智AI | 谈谈AI发展第二篇:AI推理框架

推理结构按运用场景、运用类型来说,大致能够分为两类,一类是自用的,一类是通用的。显着,自用的大多其实是芯片厂商的推理结构,为了让自家的芯片可用,所以推出了适配自家芯片的推理结构。自用的推理结构在市场上的占用率应该是占主导的,其间为代表的肯定仍是 TensorRT,别的还有像英特尔的 OpenVino 以及我国各国产芯片厂商的 sdk。自用推理结构的特色非常显着,即在自家的芯片上适配的很好并且效率很高,但不同芯片之间不能通用。自用推理结构的这个毛病让用户很是苦楚,拿我来说,我至少接触和开发过 TensorRT、Openvino、昇腾的推理结构、寒武纪的推理结构、算能的推理结构、登临的推理结构、曙光的推理结构、昆仑的推理结构、海思的推理结构、全志的推理结构等,许多时分都会觉得麻烦。而通用的推理结构就是为了处理这个痛点,通用的推理结构中,NCNN 主要仍是面向移动端,掩盖的通用范畴并不行算广;而 Tengine 则显着后劲不足,推理结构大一统方面或许最有期望的仍是如 TVM 的编译结构了。所以从某种视点来说,关于 TVM 的期望,其实跟对 ONNX 的期望是相同的。

极智AI | 谈谈AI发展第二篇:AI推理框架

关于 TensorRT 来说,许多同学或许会有这种观念,由于 TensorRT 和英伟达 GPU 的强绑定,由于英伟达 GPU 的盛行,所以 TensorRT 自然也就盛行。我倒觉得这种观念有点以偏概全,以 TensorRT 为代表的软件栈和 GPU 硬件之间的关系更像是相辅相成,相互成果。有一种愈加科学的说法,叫做软硬件协同,意思是单飞并不好,组团价更高。TensorRT 是推理结构中的神,在我多年的运用进程中,并没有发现它显着的缺陷,反而是越用越好用。在 TensorRT 中,构建模型的方法主要有三种,分别是 ONNX Parser、TF Parser、API (Python or C++),而我会习惯用 C++ API 的方法来构建模型。和大多数推理结构相同,TensorRT 的模型支撑序列化和反序列化,序列化的意思是将 TensorRT 的 IR 保存为一个称为 Plan 的离线模型,便于实践工程部署,而反序列化的意思是加载这个 Plan 离线模型并还原为 TensorRT IR 的进程,所以模型的序列化和反序列化在流程上要有则必定成对呈现。当然,TensorRT 完全能够跳过序列化和反序列化的进程,直接运用 TensorRT IR 来进行推理。这一点在曙光 DCU 的推理引擎 MIGraphX 中的示例工程中也有所体现,它的做法就是直接加载 ONNX 模型,然后就做推理了,当然这并不是好的做法或许说并不是正常的做法。

关于英伟达来说,它在推理范畴愈加强的原因不止于 TensorRT。配套 TensorRT,往下还有愈加成熟的 CUDA,往上还有考虑整体 Pipeline 功能优化的 DeepStream,合作 NvProfiler、Nsight 功能剖析东西等,这里的每一个拿出来都很能打,况且都是互相合作着的,一整套东西自成系统。

国产的推理引擎在市场上的许多推理结构中必定占据着重要戏份,国产推理引擎的繁荣很大程度上得益于芯片热。国产推理结构的上手难度其实遍及较高,上手难度以华为昇腾最甚,这一点接触过昇腾的同学应该有所了解。昇腾的开发难度高很大程度上是由于昇腾把愈加多底层优化开放出来所导致,你能够很轻松地在网上搜到许多关于昇腾 CANN 的教育教程。提到 CANN 就不得不说昇腾的算子开发,昇腾的算子开发方法主要有 DSL 和 TIK,由于整个推理系统是基于 TVM 的,所以算子开发的方法也和 TVM 的相似,做了核算和调度的分离。所以不管是 DSL 仍是 TIK,都会有核算和调度的概念,差异在于在 DSL 中只需求关注核算而把调度隐藏,而在 TIK 中既要关心核算也要关心调度。调度触及硬件特性,所以比较难写,这也是为什么说 DSL 归于入门级的,TIK 归于高手级的。提到昇腾参阅 TVM,其实这个现象不止于昇腾,我们国产推理引擎的设计大多都会有个自己的参阅,下面列出了一些我的了解。

极智AI | 谈谈AI发展第二篇:AI推理框架

关于寒武纪,比较有特色的或许是 BANG C,它的定位就跟英伟达的 CUDA C 相似。所以在寒武纪中你要自界说算子的话,一般就需求用 BANG C 来实现,这一点很像在 TensorRT 中自界说 Plugin 的时分需求去写 CUDA (当然这不是绝对,TensorRT 中还能够运用组合基础算子的方法来自界说 Plugin)。寒武纪做的比较好的当地在于,寒武纪的产品有卡有盒子,它的推理结构是通的,这关于不同场景的之间的推理掩盖切换成本很低。

在移动端,NCNN 应该算适当出色。NCNN 的模型转换做的很好,模型结构的设计遵从清晰、易于修改的准则,不像 ONNX 那样必须要用代码才能去修改网络的节点,而是比方运用一个文档编辑器就能方便地修改网络的参数,这一点我觉得做的很好。NCNN 的模型转换之所以好,是由于它一方面关于前端练习结构支撑的够全,另一方面关于模型也支撑的够全。特别的,关于模型解析的老大难问题 – Pytorch 的模型解析来说,NCNN 就供给了两套计划:(1) Pytorch -> ONNX (惯例款);(2) PNNX。PNNX 是 NCNN 新供给的代替 Pytorch 导出 ONNX 的针对 Pytorch 模型解析的东西,做法是经过 Torch 来做桥梁,经过解析 Torch 转换到 NCNN IR。很有特色的当地在于整套东西采用 C++ 来实现,这在许多的模型解析东西中也是比较少见,由于练习结构大多仍是用 Python 的。当然,NCNN 也有一些显着的局限性,正是 NCNN 致力于服务移动端,而手机一般只有一个摄像头,所以 NCNN 在结构架构设计之初就天然省掉了 Batch 维度,只是保留了 CHW 的三维数据结构,这在一众推理结构中其实比较少见,当然这关于愈加通用一些的多 Batch 场景,NCNN 的适用性就大大下降。Tengine 是基于 NCNN 愈加新一些的推理结构,从前我仍是对 Tengine 抱有一些期望,并也向其仓库贡献了一些代码,但最近来看,显着后劲不足。

还有一些不温不火的推理结构没有提及,比方 MNN、TNN、OpenPPL 等,别的还有一些看起来会比较小众,比方地平线的东西链,东西这些大都不是由于不行优化,而是或许生态不行。还有一些过于碎片化或许只关注某个模块,比方商汤的量化,其实也很优异。还有像 OnnxRuntime、TF-Lite 之类的我就不多说了,实践工程中应该用的人比较少吧。

这些应该就是我现在关于 AI 推理结构的一些了解,如有不切实践之处,还望不吝指正。

好了,以上共享了 谈谈 AI 开展第二篇:AI 推理结构。期望我的共享能对你的学习有一点协助。


后边几篇的预告:

  • 谈谈AI开展第三篇:AI 练习算力
  • 谈谈AI开展第四篇:AI 推理算力
  • 谈谈AI开展第五篇:AI 编译结构


极智AI | 谈谈AI发展第二篇:AI推理框架