Skip to main content

10.模型层和算力层

2.1 模型推理框架-nnaces

​ 嘉楠K510芯片中内置有神经网络加速器KPU,其使用的推理框架为nncase。本章节主要介绍nncase是什么?nncase神经网络编译器的功能有哪些?该如何使用nncase神经网络加速器的功能?

​ 下面我们先介绍nncase神经网络编译器的基础概念,nncase是一个为 AI 加速器设计的神经网络编译器, 目前支持的 target有cpu/K210/K510/k230等。nncase提供的功能:

  • 支持多输入多输出网络,支持多分支结构
  • 静态内存分配,不需要堆内存
  • 算子合并和优化
  • 支持 float 和uint8/int8量化推理
  • 支持训练后量化,使用浮点模型和量化校准集
  • 平坦模型,支持零拷贝加载

2.1.1 nncase功能详细介绍

​ 单输入单输出的网络可如下所示:

image=

​ 多输入单输出的网络课如下所示:

image=

​ 多输入多输出的网络如下所示:

image=

多输入多输出的网络它具有多个输入和多个输出。这种网络结构可以处理具有复杂关系的问题,并且能够从多个不同的数据源中学习并提取有用的特征。

在多输入多输出神经网络中,每个输入都可以被视为一个独立的特征,并且每个输出可以对应于一个特定的任务或目标。这种网络结构可以利用多个输入之间的关系来学习更复杂的特征表示,从而更好地处理具有多个相关任务的问题。

多输入多输出神经网络通常由多个神经元组成,这些神经元被组织成不同的层。每个神经元都接收来自其他神经元的输入,并根据其权重和偏差计算输出。这种网络结构可以学习从输入到输出的映射,从而实现对数据的分类、回归或其他任务。

多分支结构通过采用多分支结构,网络能够更好地处理输入的复杂信息,从而实现更准确、更高效的学习和分类。多分支神经网络通常由多个神经元组成,这些神经元被组织成不同的层。每个神经元都接收来自其他神经元的输入,并根据其权重和偏差计算输出。

在图像分类任务中,多分支神经网络可以通过对图像的不同特征进行提取和处理,从而得到更丰富的特征表示。这种网络结构可以学习从输入到输出的映射,从而实现对图像的分类和识别。如下图Fast-SCNN所示:

image-20231216152032938

静态内存分配在nncase中,静态内存分配主要用于分配模型权重和偏置等静态数据。这些数据在程序执行期间是固定的,不需要在运行时动态分配。通过使用静态内存分配,nncase可以确保这些数据在程序执行期间始终位于固定的内存位置,从而提高了程序的稳定性和可靠性。静态内存分配还可以提高模型的执行效率。由于不需要在运行时动态分配内存,因此可以减少内存分配和释放的开销,从而提高模型的推理速度。

算子合并是深度学习编译器中的一种重要技术,主要用于优化神经网络的计算和内存访问。算子合并的主要目的是减少内存访问,让数据更快地被复用。一般而言,被合并的算子之间需要有数据依赖,才有可能能够起到减少内存访问的效果。

在深度学习编译器中,算子合并技术可以应用于多个场景。例如,可以将多个卷积层和池化层融合为一个大的卷积层,以减少内存访问和计算的开销。也可以将多个卷积层和批归一化层融合为一个大的卷积层,以减少内存访问和计算的开销。此外,还可以将多个卷积层和激活函数层融合为一个大的卷积层,以减少内存访问和计算的开销。

算子优化不仅包括算子合并,还包括其他优化技术。例如,可以使用常量折叠技术将常量值折叠到模型中,以减少模型大小和计算量。也可以使用矩阵化技术将模型中的某些操作转换为矩阵运算,以提高计算效率。此外,还可以使用其他优化技术,如向量化、融合计算等,以进一步提高模型的性能和效率。

**支持float和uint8/int8量化推理:**使用float类型进行推理时,nncase会将输入数据和模型权重都转换为float类型,然后进行推理计算。这种推理方式可以提供较高的精度和灵活性,但同时也需要更多的内存和计算资源。使用uint8或int8类型进行推理时,nncase会将输入数据和模型权重都转换为相应的量化类型,然后进行推理计算。这种推理方式可以减少内存占用和计算资源消耗,但同时也可能会引入一定的精度损失。

**训练后量化,使用浮点模型和量化校准集。**在nncase中,量化校准集用于校准量化模型,以确保量化模型的精度和稳定性。量化校准集通常由一组浮点模型和相应的量化模型组成,用于比较量化模型和浮点模型的性能。在训练后量化过程中,nncase会将浮点模型转换为量化模型,然后使用量化校准集进行校准。通过比较量化模型和浮点模型的性能,可以调整量化模型的参数,以获得更好的精度和稳定性。

量化校准集是指一组用于校准量化模型的浮点模型和相应的量化模型。这些模型在相同的输入数据上运行,并比较其输出结果,以评估量化模型的精度和稳定性。

平坦模型是指将神经网络的模型参数以二进制文件的形式存储,并直接加载到内存中。这种方式可以避免在运行时进行内存分配和拷贝操作,从而提高了程序的执行效率。

零拷贝加载是指将模型参数从磁盘加载到内存时,不需要进行任何数据拷贝操作。这种方式可以减少CPU和内存之间的数据传输开销,进一步提高程序的执行效率。

2.1.2 支持的神经网络框架

nncase支持的神经网络框架包括TensorFlow Lite(tflite)、ONNX和Caffe。

  1. TensorFlow Lite(tflite):nncase支持TensorFlow Lite模型,可以加载和运行在嵌入式设备上。通过使用tflite模型转换为kmodel,nncase可以在各种不同的硬件平台上运行神经网络推理,包括CPU、KPU神经网络加速器。

  2. ONNX(Open Neural Network Exchange):nncase也支持ONNX模型,这是一种用于表示深度学习模型的开放标准。ONNX模型可以在不同的深度学习框架之间互操作,包括TensorFlow、PyTorch、Keras等。通过使用ONNX模型转换为kmodel,nncase可以加载和运行各种不同的深度学习模型,从而扩展了其应用范围。

  3. Caffe:Caffe是一种深度学习框架,由Berkeley Vision and Learning Center开发。nncase也支持加载和运行Caffe模型。通过使用Caffe模型转换为kmodel,nncase可以在嵌入式设备上进行图像分类、目标检测等计算机视觉任务。

image-20231216155020588

2.2 nncase模块-编译模型

Compiler: 用于在PC上编译神经网络模型,最终生成kmodel文件。主要包括importer, IR, Evaluator, Quantize, Transform优化, Tiling, Partition, Schedule, Codegen等模块。

2.2.1 importer模块

Importer是一个用于加载和转换模型的工具。它可以从各种不同的格式中导入模型,并将其转换为nncase可以使用的格式。具体来说,nncase的Importer可以从TensorFlow Lite、ONNX和Caffe等格式中导入模型。导入后,模型会被转换为nncase可以使用的内部格式,以便在嵌入式设备上进行推理。使用nncase的Importer,可以方便地将训练好的模型转换为nncase可以使用的格式,从而在嵌入式设备上部署和运行模型。同时,Importer还支持对模型进行优化和压缩,以减少模型的大小和推理时间,提高模型的性能和效率。

2.2.2 IR模块

nncase的IR(中间表示)确实分为两个部分:Importer导入的Neutral IR(设备无关)和Neutral IR经lowering转换生成的Target IR(设备相关)。

  1. Importer导入的Neutral IR(设备无关):
    • 这是nncase的IR的第一层,也称为设备无关层。它表示的是从外部模型格式(如TensorFlow Lite、ONNX等)导入的原始模型。
    • 在这一层,模型的结构和计算逻辑被完整地保留,但与特定的硬件平台无关。这意味着无论是在CPU、GPU还是其他类型的硬件上,都可以使用相同的Importer导入相同的Neutral IR。
    • 这为nncase提供了一个统一的、通用的模型表示,使得它可以轻松地支持各种不同的神经网络框架和模型格式。
  2. Neutral IR经lowering转换生成的Target IR(设备相关):
    • 当Importer导入的Neutral IR被加载后,nncase会进行lowering转换,将其转换为与特定硬件平台相关的Target IR。
    • Target IR是nncase的IR的第二层,也称为设备相关层。在这一层,模型的结构和计算逻辑会根据目标硬件平台的特点进行优化和调整。
    • 通过lowering转换,nncase可以对模型进行一系列的优化操作,如算子融合、常量折叠、内存优化等,以提高模型的性能和效率。
    • 这一层的设计使得nncase可以针对不同的硬件平台进行优化,从而在各种不同的嵌入式设备上实现高效的神经网络推理。

nncase的IR通过Importer导入的Neutral IR和经lowering转换生成的Target IR两个层次,实现了对神经网络模型的统一表示和针对不同硬件平台的优化。这使得nncase成为一种高效、灵活的神经网络推理引擎,适用于各种嵌入式系统。

2.2.3 Evaluator模块

nncase的Evaluator模块提供了IR的解释执行能力。Evaluator模块可以加载和执行nncase的IR,对模型进行评估和推断。

在Constant Folding和PTQ Calibration等场景中,Evaluator模块可以用于对模型进行验证和校准。Constant Folding是一种在模型训练过程中将常量值折叠到模型中的技术,可以减少模型的大小和计算量。而PTQ Calibration则是一种对模型进行校准的技术,以提高模型的精度和稳定性。

通过使用Evaluator模块,可以对nncase的IR进行解释执行,从而对模型进行评估和推断。这可以帮助开发者验证模型的正确性和性能,并进行必要的调整和优化。

需要注意的是,使用Evaluator模块时,需要确保IR的正确性和完整性,以避免出现错误或异常情况。同时,也需要根据实际情况选择合适的解释执行方式和参数配置,以获得最佳的性能和效率。

2.2.4 Transform模块

nncase的Transform模块用于IR转换和图的遍历优化等操作。

在nncase中,IR转换是指将模型的IR从一种格式转换为另一种格式,以便在不同的平台或框架之间进行模型推理。Transform模块提供了转换功能,可以将Importer导入的Neutral IR转换为Target IR,也可以将Target IR转换为其他格式。

除了IR转换外,Transform模块还支持对图的遍历进行优化。在神经网络模型中,图的遍历是指按照一定的顺序访问模型中的节点和边。遍历优化是一种常见的优化技术,可以减少计算量和内存占用,提高模型的性能和效率。

Transform模块可以对模型图进行遍历优化,例如对相邻节点进行合并、消除冗余的计算等操作。这些优化可以显著提高模型的推理速度和效率,特别是在嵌入式系统中。

nncase的Transform模块用于IR转换和图的遍历优化等操作,可以帮助开发者对模型进行必要的调整和优化,提高模型的性能和效率。

2.2.5 Quantize模块

nncase的Quantize模块用于训练后量化,对要量化的tensor加入量化标记,并根据输入的校正集调用Evaluator进行解释执行,收集tensor的数据范围,插入量化/反量化结点,最后优化消除不必要的量化/反量化结点等。

在nncase中,量化是一种将浮点数转换为低精度整数的过程,以减少模型的大小和计算量。Quantize模块提供了训练后量化的功能,可以在模型训练完成后对模型进行量化操作。

在Quantize模块中,首先会对要量化的tensor加入量化标记,以便后续识别和处理。然后,根据输入的校正集调用Evaluator进行解释执行,收集tensor的数据范围。接下来,根据收集到的数据范围插入量化/反量化结点,将浮点数转换为低精度整数或从低精度整数转换回浮点数。

最后,Quantize模块会对插入的量化/反量化结点进行优化,消除不必要的结点。这样可以减少模型的计算量和内存占用,提高模型的性能和效率。

需要注意的是,使用Quantize模块时,需要确保输入的校正集的正确性和完整性,以避免出现错误或异常情况。同时,也需要根据实际情况选择合适的量化参数和配置,以获得最佳的性能和效率。

2.2.6 Tiling模块

nncase的Tiling模块用于将大块计算进行拆分,以适应NPU较低的存储器容量。

在深度学习模型中,尤其是在嵌入式设备上,NPU(神经网络处理单元)的存储器容量通常是有限的。为了充分利用NPU的计算能力,同时避免存储器溢出,需要对大块计算进行拆分。

Tiling模块的作用是将大块计算拆分成较小的小块,然后将这些小块逐个进行处理。这种拆分的方式可以减少单个操作的数据量,从而降低存储器的使用量。

然而,选择Tiling参数会对时延和带宽产生影响。如果Tiling参数设置不当,可能会导致计算时间增加或带宽占用过多。因此,在使用Tiling模块时,需要根据实际情况选择合适的Tiling参数和配置,以平衡计算效率和存储器使用量。

nncase的Tiling模块用于将大块计算进行拆分,以适应NPU较低的存储器容量。选择合适的Tiling参数和配置对于优化深度学习模型的性能和效率至关重要。

2.2.7 Partition模块

nncase的Partition模块用于将模型图按照ModuleType进行切分,将切分后的每个子图映射到对应的RuntimeModule。不同类型的RuntimeModule可以对应不同的设备(如CPU、K510等)。

在nncase中,模型图由一系列的节点和边组成,每个节点表示一个操作或计算,边表示数据的传递。Partition模块根据ModuleType对模型图进行切分,将不同的子图映射到不同的RuntimeModule中。

在切分过程中,Partition模块会考虑每个子图中的节点和边的计算复杂度和数据依赖关系。每个子图对应一个RuntimeModule,而RuntimeModule是与设备相关的执行单元,可以运行在不同的设备上。

通过将模型图切分为不同的子图并映射到不同的RuntimeModule中,Partition模块可以实现模型的并行计算和分布式执行。在不同的设备上运行不同的RuntimeModule,可以充分利用设备的计算资源和并行处理能力,提高模型的推理速度和效率。

需要注意的是,使用Partition模块时,需要考虑到不同子图的计算复杂度和数据依赖关系,以及不同设备的计算能力和内存限制。选择合适的切分方式和配置参数,可以平衡模型的计算效率和设备的资源利用率,以实现最佳的性能和效率。

2.2.8 Schedule模块

nncase的Schedule模块根据优化后图中的数据依赖关系生成计算顺序并分配Buffer。

在深度学习模型中,计算顺序和Buffer分配是影响模型性能和效率的重要因素。计算顺序决定了模型中各个操作的执行顺序,而Buffer分配则决定了数据在内存中的存储和访问方式。

Schedule模块的作用是根据优化后的图中的数据依赖关系生成计算顺序。它考虑了节点之间的数据依赖关系和计算复杂度,以确定最佳的计算顺序。这样可以减少计算过程中的数据依赖冲突,提高计算的并行性和效率。

在计算顺序确定之后,Schedule模块还需要分配Buffer。Buffer是用于存储模型中的数据和中间结果的内存区域。通过合理的Buffer分配,可以减少内存访问的开销,提高数据的访问速度和效率。

在nncase中,Schedule模块会根据优化后的图的结构和数据依赖关系,为每个节点分配一个或多个Buffer。这些Buffer可以用于存储节点的输入数据、中间结果和输出数据。通过优化Buffer的分配和管理,可以减少内存的占用和提高数据的访问效率。

nncase的Schedule模块根据优化后图中的数据依赖关系生成计算顺序并分配Buffer,以优化模型的计算过程和提高性能和效率。

2.2.9 Codegen模块

nncase的Codegen模块会对每个子图分别调用ModuleType对应的codegen方法,生成对应的RuntimeModule。

在nncase中,模型图被切分为不同的子图,每个子图对应一个RuntimeModule。每个RuntimeModule是由一系列计算节点组成的,每个计算节点对应一个操作或计算。

Codegen模块会根据每个子图的ModuleType调用相应的codegen方法,生成对应的RuntimeModule。不同的ModuleType可能具有不同的计算特性和优化方法,因此需要使用相应的codegen方法来生成对应的RuntimeModule。

在生成RuntimeModule的过程中,Codegen模块会考虑设备的特性和限制,对生成的代码进行优化和调整。例如,针对特定的CPU或NPU,Codegen模块可能会生成相应的汇编代码或中间表示,以充分利用硬件的特性。

生成的RuntimeModule可以作为可执行代码的一部分,与其他代码和库一起编译和链接,最终生成可执行文件。通过将模型图切分为不同的子图并生成对应的RuntimeModule,nncase可以实现模型的并行计算和分布式执行,提高模型的推理速度和效率。

需要注意的是,Codegen模块的具体实现和功能可能会因不同的硬件平台和nncase版本而有所不同。因此,在使用Codegen模块时,建议参考相关的文档和示例,以了解其具体的使用方法和要求。

2.3 nncase模块-推理模型

nncase的神经网络编译器Runtime模块是集成于用户的应用程序中,提供了加载kmodel、设置输入数据、KPU执行和获取输出数据等功能。

  • 提供了加载kmodel的功能。kmodel是nncase中用于表示神经网络模型的文件格式。通过使用Runtime模块的API,用户可以在应用程序中加载kmodel文件,并将其加载到内存中。这样,用户就可以在应用程序中使用加载的模型进行推理和计算。

  • 提供了设置输入数据的功能。在神经网络模型推理过程中,需要将输入数据传递给模型进行计算。Runtime模块提供了API来设置输入数据,用户可以通过这些API将数据传递给模型进行推理。

  • 提供了KPU执行的功能。KPU是nncase中用于执行神经网络计算的内核处理器。通过使用Runtime模块的API,用户可以调用KPU来执行模型的推理计算。KPU可以充分利用硬件的并行计算能力和高效执行神经网络计算的能力,从而提高模型的推理速度和效率。

  • 提供了获取输出数据的功能。在模型推理完成后,输出数据会被计算并存储在内存中。通过使用Runtime模块的API,用户可以获取模型的输出数据。这些数据可以用于后续的处理或分析。

nncase的神经网络编译器Runtime模块为应用程序提供了加载kmodel、设置输入数据、KPU执行和获取输出数据等功能,使得用户可以在自己的应用程序中轻松地集成和运行神经网络模型。这些功能使得nncase成为一种高效、灵活的神经网络编译器,适用于各种应用场景。