算法在嵌入式端的部署与优化

算法在嵌入式端的部署与优化

    • 前言
    • 理论
      • 1.参考资源
      • 2.其他
        • 1.将深度学习模型移植到嵌入式端时,提高推理速度的方法
        • 2.深度学习模型移植到嵌入式端的主要流程
        • 3.假设将已经训练好的目标检测模型(比如YOLOv3)移植到树莓派4B这样一款嵌入式设备上,并且需要保证推理速度达到实时。具体流程如下
        • 4.在树莓派上使用ncnn推理引擎,可以采取以下措施提高推理速度
        • 5.先进行模型压缩再用推理模型部署是一种常见的深度学习模型部署方式,可以有效地减小模型大小并提高推理性能。
        • 6.量化实际上发生在模型压缩阶段,是独立于推理引擎之外的一步。它的作用是生成更小更快的量化模型。推理引擎只是基于此量化模型进行推理。但是推理引擎转化模型过程中支持量化,例如tensorRT INT8、tensorflow lite等等。
        • 7.在多核CPU中,可以使用线程并发来加速推理过程。将推理任务分配给多个线程同时处理,可以利用CPU的多核能力,加速推理速度。
        • 8.硬件以及推荐的推理引擎
    • Python加速方案
      • 1.参考资源
      • 2.其他
        • 1.numba 数值计算加速 上百倍提升 性价比最高的优化方案
        • 2.Numpy 使用ndarray代替Python自带的list 支持大型多维数组和矩阵计算 10倍以上提升
        • 3.Cython 麻烦 优先找已有C库或者numba加速或者撰写C库 比numba快几倍
        • 4.使用C库
        • 5.多线程
        • 6.PyPy 比Cpython更快的解释器 也就是换个解释器运行 5-10倍提升 CPython 是 Python 官方的标准解释器
        • 7.学习如何降低算法复杂度和编写更高效的算法——最有效但最麻烦
        • 8.其他

前言

我创作这篇博客的目的是记录学习技术过程中的笔记。希望通过分享自己的学习经历,能够帮助到那些对相关领域感兴趣或者正在学习的人们。

理论

1.参考资源

1.神经网络的压缩算法:6种神经网络的压缩方法

2.深度学习推理架构:主流的深度学习推理架构、AI模型部署落地综述(ONNX/NCNN/TensorRT)

3.TensorFlow 模型优化:TensorFlow 模型优化工具包

2.其他

1.将深度学习模型移植到嵌入式端时,提高推理速度的方法
  1. 硬件加速:使用专用芯片(例如GPU、NPU等)或FPGA进行硬件加速可以大幅提升推理速度。
  2. 模型压缩:对于已经训练好的模型,可以通过减少参数量、降低精度等方式来达到压缩的效果。常见的方法包括剪枝、量化和蒸馏等。
  3. 网络结构优化:优化网络结构也是一种有效地提高推理速度的方式。比如改变网络层数、调整通道数目和内存消耗等。
  4. 编译器优化:针对不同平台开发相应编译器,并且在编译过程中尝试各种技巧以最大限度地利用处理器功能单元和内存带宽,进行代码自动向量化。
2.深度学习模型移植到嵌入式端的主要流程
  1. 对原始模型进行剪枝/压缩/转换等操作以适配嵌入式设备。
  2. 针对特定平台编写底层驱动程序。
  3. 针对特定平台编写适配深度学习模型的推理引擎。
  4. 进行端到端的测试和优化,不断调整以实现最佳性能。
3.假设将已经训练好的目标检测模型(比如YOLOv3)移植到树莓派4B这样一款嵌入式设备上,并且需要保证推理速度达到实时。具体流程如下
  1. 模型压缩:为了适应树莓派4B较低的算力和存储容量,可以使用剪枝、量化等技术对原始模型进行压缩处理。
  2. 硬件加速:由于树莓派4B内置GPU并不强大,因此可以考虑使用外部NPU芯片来提高推理速度。
  3. 软硬件协同优化:针对特定平台编写底层驱动程序和适配深度学习模型的推理引擎。在软硬件协同优化方面,可以借助TensorFlow Lite或ONNX Runtime等工具进行开发。
  4. 端到端测试和优化:通过不断地调整参数、修改网络结构以及采用更高效率的算法来实现最佳性能表现。同时也需要注意内存消耗情况以及功耗限制等因素。
4.在树莓派上使用ncnn推理引擎,可以采取以下措施提高推理速度
  1. 优化ncnn环境配置:确保您的树莓派上已经安装了所有必要的依赖,并且ncnn环境配置正确。
  2. 编译ncnn
  3. 模型转换:使用ncnn提供的工具将YOLO3模型从其原始格式(通常是.cfg和.weights文件)转换为ncnn支持的格式。
  4. 模型优化
  5. 硬件优化
  6. 使用更轻量级的模型
  7. 减少图像分辨率
  8. 并行处理:如果您的应用程序允许,可以在树莓派上使用多线程或多进程来并行处理多个任务,以此来提高整体效率。
5.先进行模型压缩再用推理模型部署是一种常见的深度学习模型部署方式,可以有效地减小模型大小并提高推理性能。
6.量化实际上发生在模型压缩阶段,是独立于推理引擎之外的一步。它的作用是生成更小更快的量化模型。推理引擎只是基于此量化模型进行推理。但是推理引擎转化模型过程中支持量化,例如tensorRT INT8、tensorflow lite等等。
7.在多核CPU中,可以使用线程并发来加速推理过程。将推理任务分配给多个线程同时处理,可以利用CPU的多核能力,加速推理速度。
8.硬件以及推荐的推理引擎
  • 英特尔神经网络棒2代:openvino推理引擎
  • 在 Intel 的 CPU/GPU 上就使用 OpenVINO,在 Arm 的 CPU/GPU 上使用 NCNN/MNN 等,在 Nvidia GPU 上使用 TensorRT。

Python加速方案

1.参考资源

1.Python量化策略的算法性能提升指南

2.其他

1.numba 数值计算加速 上百倍提升 性价比最高的优化方案
  • 用于加速Python数值计算的开源库
  • 使用LLVM编译器将Python代码编译为本地机器码
  • 将处理numpy数组的Python函数JIT编译成机器码执行

在使用Numba加速Python数值计算时,需要注意以下几点:

  1. Numba只能加速一部分Python代码,特别是那些涉及到数值计算的部分。因此,需要仔细分析代码,选择合适的部分进行加速,以获得最大的加速效果。

  2. Numba只支持一部分Python语法和标准库函数,因此需要注意使用的Python语法和函数是否在Numba的支持范围内。一般来说,Numba支持大多数基本数据类型和NumPy数组操作,但是不支持Python标准库中的一些模块和函数,如math模块、random模块等。

  3. 在使用Numba加速函数时,需要使用@jit装饰器将函数标记为JIT(Just-In-Time)编译函数。这样,Numba就会对函数进行编译,从而提高其执行速度。需要注意的是,Numba只能对一部分函数进行加速,因此需要根据实际情况选择要加速的函数。

  4. 在使用Numba加速函数时,需要将函数的参数和返回值类型声明为Numba支持的数据类型。Numba支持大多数基本数据类型和NumPy数组类型,但是不支持Python标准库中的一些类型,如list、tuple等。可以使用numba.types模块中的数据类型来声明函数参数和返回值类型,例如:

    import numba as nb
    @nb.jit(nb.float32(nb.float32, nb.float32))
    def add(x, y):
    	return x + y
    
  5. 在使用Numba加速函数时,需要注意函数内部调用其他模块的情况。如果被调用的模块中的函数不是Numba支持的函数,那么这部分代码将无法被加速。此时,可以将这部分代码提取出来,单独编写一个Numba加速的函数,然后在主函数中调用该函数,从而实现对整个程序的加速。即如果在使用Numba加速的函数中调用了Numba不支持的math模块中的函数,会导致Numba编译错误。因此,如果要使用Numba加速的话,需要使用Numba支持的函数替代math模块中的函数。

2.Numpy 使用ndarray代替Python自带的list 支持大型多维数组和矩阵计算 10倍以上提升
3.Cython 麻烦 优先找已有C库或者numba加速或者撰写C库 比numba快几倍
  • 需要学专门的Cython语言
  • 允许用户以非常接近Python的语法来实现非常接近C的性能。
  • 将Python代码转换为C语言代码的工具
  • 使用了Cython语言编写,其实现方式和C语言非常类似,因为Cython是一种基于Python语言的C扩展语言,它可以将Python代码转换为C语言或C++代码,然后通过编译器进行编译和链接,生成可执行代码。因此,Cython代码可以获得接近于C语言的性能,并且可以与Python语言进行交互。也就是说实现它要用Cpython语言,不能直接使用Python语言。
  • Cython适用于需要高性能的Python代码,并且可以使用C语言的库和工具进行扩展的场景。需要注意的是,使用Cython进行加速需要编写一些额外的类型声明和C语言代码,因此相对于Numba而言,Cython的使用难度较高。
4.使用C库

相关的工具包括ctypes、cffi、Swig、Boost.Python等

python调用C代码方法与加速效果

5.多线程
  • 代码中存在一些可以并行执行的任务。如果您的代码中没有这样的任务,那么多线程并不能给您带来任何性能上的提升。
  • 可以考虑使用多进程来利用多个CPU核心同时处理帧。由于Python的全局解释锁(Global Interpreter Lock,GIL)会限制线程在同一时间只能在一个CPU核心上运行,因此使用多线程并不能真正利用多个CPU核心。这意味着在任何时间点只有一个线程可以处于执行状态。即使在使用多线程的情况下,也只能有一个线程执行 Python 代码,而其他线程将被阻塞。因此,使用多线程来处理 CPU 密集型任务可能不会提高性能,甚至可能会降低性能。而使用多进程可以避开这个限制,实现真正的并行处理。

什么是Python全局解释器锁GIL

Python 多进程、多线程效率比较 - massquantity - 博客园 (cnblogs.com)

6.PyPy 比Cpython更快的解释器 也就是换个解释器运行 5-10倍提升 CPython 是 Python 官方的标准解释器

PyPy是一个Python解释器,它通过即时编译(JIT)技术对Python代码进行加速,从而获得比CPython更高的性能表现。PyPy可以运行大部分的Python代码,而且通常不需要对代码进行修改,因此可以轻松地将现有的Python代码迁移到PyPy上。

7.学习如何降低算法复杂度和编写更高效的算法——最有效但最麻烦

使用8位无符号整型处理图像数据比使用64位浮点型数据要快。这是因为,8位无符号整型数据类型需要的内存和计算资源比64位浮点型数据类型少得多,而且处理8位整型数据的硬件部件也更加普遍和成熟,因此可以实现更快的计算速度。

8.其他

许多第三方模块是使用 C 扩展编写的,这些扩展可以通过 Python 的 C API 与 CPython 解释器进行交互。这些扩展可以提供比纯 Python 代码更高的性能,并且可以访问底层操作系统和硬件的功能。也就是说第三方模块大多已经使用了许多 C 语言库和函数来加速图像处理算法的计算。例如scikit-image (skimage)是一个Python第三方图像处理库,它提供了许多常用的图像处理算法和工具。skimage库是使用Python和Cython编写的,它使用了许多C语言库和函数来加速图像处理算法的计算。

你可能感兴趣的:(硬件,算法,嵌入式硬件)