跳转至

Memory

Memory

TensorFlow Lite for Microcontrollers(TFLM)以及其他轻量级推理引擎(如 Arm’s CMSIS-NN、uTensor、MicroTVM)在内存控制方面有许多关键策略,专门为资源受限的设备(如微控制器)优化。以下是它们如何控制内存的主要方式:

  1. 静态内存分配 预先分配内存池:TFLM 和其他轻量推理引擎通常会在初始化时分配一个固定大小的内存池,而不是在推理过程中动态分配内存。这样可以避免内存碎片化问题,同时减少实时计算的内存压力。 模型所需的内存静态计算:在模型部署之前,推理引擎会分析每层操作的需求,确定最小的内存池大小。然后,模型初始化时就会为所有中间激活值分配足够的内存,从而确保整个推理过程不需要额外的内存分配。
  2. 层级内存复用 复用中间张量:在前向传播中,TFLM 会复用不再需要的中间激活值的内存。例如,当某一层的输出张量在后续层不再需要时,它的内存空间会被复用。这样可以有效减少中间激活张量所占用的内存。 时间调度和内存复用表:TFLM 会构建内存复用表,确保在推理的每个阶段中,层与层之间合理复用内存资源。这种内存复用方法在大多数轻量化推理引擎中是标配技术,尤其在神经网络中间层数较多时尤为有效。
  3. 支持 int8 量化 量化模型的权重和激活:为了减少内存和存储占用,TFLM 支持 int8 量化。量化模型将权重和激活值从浮点数(如 float32)转换为低比特精度(如 int8),从而减少约 75% 的内存占用。 量化后的操作优化:量化不仅减少了内存占用,还加快了推理速度。引擎中的算子(如卷积、全连接)通常会专门优化以支持 int8 运算,这进一步减少了计算时间和内存需求。
  4. 以 Arena Allocator 控制内存 TFLM 中采用了 Arena Allocator 管理内存池,Arena Allocator 提供了一块固定大小的内存区域,用于所有的模型权重、中间激活张量等。 Arena Allocator 不会进行复杂的动态内存分配,而是像栈一样分配和释放内存,以减少内存碎片化的问题。
  5. 模型结构优化和操作融合 算子融合:一些推理引擎会将多个操作合并为一个操作,例如将卷积和激活函数或卷积和批量归一化(BatchNorm)融合成单一操作。这种融合可以减少数据在不同层之间的中间存储需求,从而节省内存。 模型优化:在部署之前,模型通常会使用优化工具进行图级优化,以减少不必要的计算和内存使用。例如,常见的优化包括移除冗余层、常量折叠、剪枝和算子替换等。
  6. 最小化模型和参数存储 模型存储压缩:TFLM 支持通过模型压缩技术,如权重剪枝和稀疏化,将模型存储占用降到最低。 参数分片加载:对于较大的模型,一些推理引擎可以分段加载权重,只在需要时加载到内存中。例如,将模型分片,并在推理过程中按需加载以避免占用过多内存。
  7. 延迟加载和惰性计算 延迟加载:有些推理引擎会在推理时根据需求动态加载模型的权重或部分网络,从而避免模型加载时的一次性大内存占用。 惰性计算:惰性计算可以确保只在需要时进行计算,从而避免不必要的内存分配。例如,只有当某些中间结果确实需要时,才会进行计算和存储。
  8. 支持裁剪模型 稀疏矩阵存储:模型中通过权重剪枝或稀疏化后,推理引擎可以存储和计算稀疏矩阵结构,仅对非零部分进行计算,从而减少内存需求。 稀疏张量格式:一些推理引擎会支持稀疏张量格式,以避免存储和计算零值部分的数据,进一步优化内存使用。 总结 在资源受限的 TinyML 环境中,TFLM 和其他推理引擎通过以下方法控制内存:

使用 静态内存分配,避免运行时的内存分配和碎片化。 利用 层级内存复用 和 量化,显著减少内存占用。 采用 Arena Allocator 管理内存池,避免复杂的内存管理开销。 支持 模型结构优化、操作融合 和 稀疏化技术,以减少模型的存储和中间激活的内存需求。 这些技术确保了推理引擎在微控制器等资源受限的设备上高效运行,实现了在极低内存条件下的实时推理。

内存静态分配算法(CSP, Meta-CSP, MixedILP, TelaMalloc, MiniMalloc)主要用于深度学习推理中的内存管理。它们的目标是通过有效地分配和管理内存资源,减少内存占用和提高执行效率。以下是这些算法的原理和区别的详细介绍:

  1. CSP (Conflict-free Space Placement) CSP算法,即无冲突空间分配算法,通过减少内存碎片和避免内存冲突来优化内存利用率。其关键思想是使用图模型来描述操作符(如卷积、全连接等)之间的依赖关系,并根据这些依赖关系分配内存。CSP的工作流程如下:

构建依赖图:对所有操作符构建一个依赖图,节点表示操作符,边表示数据依赖。 分配内存空间:在分配时,尽可能避免不同操作符间的内存区域重叠,以防止冲突。 回收和复用:当操作符执行完后,回收其内存空间并用于接下来的操作符。 CSP适合较为简单的神经网络结构,但在复杂结构中,其内存冲突控制较弱,导致分配效率有限。

  1. Meta-CSP Meta-CSP是对CSP的改进版本,主要通过在图模型上应用更复杂的搜索算法来改进内存分配的效率。Meta-CSP的改进之处在于使用了更细粒度的约束处理:

元约束添加:添加额外的约束条件,使内存分配更适应复杂的网络结构,如循环神经网络(RNN)和卷积神经网络(CNN)。 动态调整分配策略:基于实际负载情况调整分配策略,减少不必要的冲突。 通过改进的算法设计,Meta-CSP可以在处理大型复杂模型时提供更好的内存利用率和更低的延迟。

  1. MixedILP (Mixed Integer Linear Programming) MixedILP是一种使用混合整数线性规划(ILP)进行内存分配的算法,它通过数学优化方法来实现最优内存分配。MixedILP将内存分配问题建模为整数线性规划问题,并求解内存的最优解。主要流程如下:

数学建模:将每个操作符和数据块定义为一个变量,并对这些变量施加线性约束,以确保分配的内存满足所有操作需求。 线性求解器优化:使用线性求解器优化目标函数(通常是最小化内存总量),找到最优内存分配方案。 求解和分配:根据求解结果进行内存块的分配和复用。 MixedILP因使用数学优化方法,可以获得接近全局最优的分配结果,但在大型网络上求解时间较长,适合偏静态的内存需求场景。

  1. TelaMalloc TelaMalloc是一种专门为深度学习设计的内存分配器,它以高效地满足推理过程中频繁的内存请求为目标。TelaMalloc的关键在于:

分块与复用:将内存分块为不同大小的小块,以便快速分配和复用。 自动内存释放:当某个内存块使用完毕后立即释放,从而在推理过程中动态释放和复用内存。 分配策略优化:根据操作符的需求动态调整分配策略,例如优先分配较小块,减少大块分配的频率。 TelaMalloc在深度学习推理中表现出色,适合需要频繁小块内存请求的推理场景,特别适合模型层次较多且频繁交替使用内存的网络。

  1. MiniMalloc MiniMalloc是一个轻量级的内存分配算法,设计上更倾向于内存高效性。MiniMalloc的核心思路是:

预分配池:将内存划分为多个预定义大小的池,每个池包含固定大小的内存块,避免动态申请和释放带来的额外开销。 小块复用:小块内存块的复用率高,对于固定大小的小数据请求可以快速响应。 分配策略简化:MiniMalloc仅对少数几种大小进行分配,减少了复杂的分配管理逻辑。 MiniMalloc对内存的空间利用率高,适合内存需求简单且数据请求大小固定的推理场景,尤其适合在资源受限的嵌入式系统中使用。

总结对比 |算法| 原理| 优势| 适用场景| |:--:|:--:|:--:|:--:| |CSP |无冲突内存分配 |适合较简单网络结构,避免内存冲突 |简单模型、依赖关系明确的网络| |Meta-CSP |增强CSP,增加约束条件 |适合复杂网络,减少冲突,优化利用率 |复杂模型、循环结构较多的网络| |MixedILP |使用整数线性规划进行内存分配 |全局最优分配结果 |偏静态分配需求的大型网络| |TelaMalloc |动态块分配与复用 |高效满足小块请求,自动释放与复用 |频繁小块请求的推理过程| |MiniMalloc |轻量级内存池分配 |高复用率,简化管理逻辑 |嵌入式系统、小请求固定场景|

每种算法都有其独特的优势和适用场景,在深度学习推理中可以根据需求选择合适的内存分配方案,以获得最佳的性能和内存利用效率。