跳到主要内容

DVPP数据处理高性能编程建议

溢出算子数据采集及分析

前提条件

使用ATC工具转换模型时,需在转换命令中增加--status_check参数,并将参数值设置为1,表示在编译算子时添加溢出检测逻辑。

关于ATC工具及其参数的详细说明,请参见《ATC工具使用指南》。

采集溢出算子信息

在调用aclInit接口初始化AscendCL时,在json配置文件中增加溢出算子Dump配置。

json配置文件中的示例内容如下,示例中的dump_path以相对路径为例:

{
"dump":{
"dump_path":"output",
"dump_debug":"on"
}
}

当dump_path配置为相对路径时,您可以在“应用可执行文件的目录/{dump_path}”下查看导出的数据文件,针对每个溢出算子,会导出两个数据文件:

  • 溢出算子的dump文件:命名规则如{op_type}.{op_name}.{taskid}.{stream_id}.{timestamp},如果op_type、op_name出现了“.”、“/”、“\”、空格时,会转换为下划线表示。

    用户可通过该信息知道具体出现溢出错误的算子,并通过解析溢出算子的dump文件获取该算子的输入和输出信息。

  • 算子溢出数据文件:命名规则如OpDebug.Node_Opdebug.{taskid}.{stream_id}.{timestamp},其中taskid不是溢出算子的taskid,用户不需要关注taskid的实际含义。

    用户可通过解析算子溢出数据文件获取溢出相关信息,包括溢出算子所在的模型、AICore的status寄存器状态等。

解析溢出算子的dump文件

  1. 请根据实际情况,将{op_type}.{op_name}.{taskid}.{stream_id}.{timestamp}上传到安装有Toolkit软件包的环境。

  2. 进入解析脚本所在目录,例如Toolkit软件包安装目录为:/home/HwHiAiUser/Ascend/ascend-toolkit/latest。

    cd /home/HwHiAiUser/Ascend/ascend-toolkit/latest/toolkit/tools/operator_cmp/compare

  3. 执行msaccucmp.py脚本,转换dump文件为numpy文件。举例:

    python3 msaccucmp.py convert -d /home/HwHiAiUser/dump -out /home/HwHiAiUser/dumptonumpy -v 2

    :::note 说明 -d参数支持传入单个文件,对单个dump文件进行转换,也支持传入目录,对整个path下所有的dump文件进行转换。 :::

  4. 调用Python,转换numpy文件为txt文件。举例:

    $ python3

    >>> import numpy as np

    >>> a = np.load("/home/HwHiAiUser/dumptonumpy/Pooling.pool1.1147.1589195081588018.output.0.npy")

    >>> b = a.flatten()

    >>> np.savetxt("/home/HwHiAiUser/dumptonumpy/Pooling.pool1.1147.1589195081588018.output.0.txt", b)

    转换为.txt格式文件后,维度信息、Dtype均不存在。详细的使用方法请参考numpy官网介绍。

解析算子溢出数据文件

由于生成的溢出数据是二进制格式,可读性较差,需要通过工具将bin文件解析为用户可读性好的json文件。

  1. 请根据实际情况,将溢出数据文件OpDebug.Node_Opdebug.{taskid}.{timestamp}上传到安装有Toolkit软件包的环境。

  2. 进入解析脚本所在路径,例如Toolkit软件包安装目录为:/home/HwHiAiUser/Ascend/ascend-toolkit/latest。

    cd /home/HwHiAiUser/Ascend/ascend-toolkit/latest/toolkit/tools/operator_cmp/compare

  3. 执行解析命令,例如:

    python3 msaccucmp.py convert -d /home/HwHiAiUser**/opdebug/Opdebug.Node_OpDebug.59.1597922031178434** -out /home/HwHiAiUser/result

    关键参数:

    • -d:溢出数据文件所在目录,包括文件名。
    • -out:解析结果待存储目录,如果不指定,默认生成在当前目录下。
  4. 解析结果文件内容如下所示。

    {
    "DHA Atomic Add": {
    "model_id": 0,
    "stream_id": 0,
    "task_id": 0,
    "task_type": 0,
    "pc_start": "0x0",
    "para_base": "0x0",
    "status": 0
    },
    "L2 Atomic Add": {
    "model_id": 0,
    "stream_id": 0,
    "task_id": 0,
    "task_type": 0,
    "pc_start": "0x0",
    "para_base": "0x0",
    "status": 0
    },
    "AI Core": {
    "model_id": 514,
    "stream_id": 563,
    "task_id": 57,
    "task_type": 0,
    "pc_start": "0x1008005b0000",
    "para_base": "0x100800297000",
    "kernel_code": "0x1008005ae000",
    "block_idx": 1,
    "status": 32
    }
    }

    参数解释:

    • model_id:标识溢出算子所在的模型id。

    • stream_id:标识溢出算子所在的streamid。

    • task_id:标识溢出算子的taskid。

    • task_type:标识溢出算子的task类型。

    • pc_start:标识溢出算子的代码程序的内存起始地址。

    • para_base:标识溢出算子的参数的内存起始地址。

    • kernel_code:标识溢出算子的代码程序的内存起始地址,和pc_start相同。

    • block_idx:标识溢出算子的blockid参数。

    • status:AICore的status寄存器状态,用户可以从status值分析得到具体溢出错误。status为10进制表示,需要转换成16进制,然后定位到具体错误。

      例如:status为272,转换成16进制为0x00000110,则可以判定出可能原因为0x00000010+0x00000100。

      • 0x00000008: 符号整数最小负数NEG符号位取反溢出
      • 0x00000010: 整数加法、减法、乘法或乘加操作计算有溢出
      • 0x00000020: 浮点计算有溢出
      • 0x00000080: 浮点数转无符号数的输入是负数
      • 0x00000100: FP32转FP16或32位符号整数转FP16中出现溢出
      • 0x00000400: CUBE累加出现溢出

父主题: 扩展更多特性

共享Buffer管理

本特性提供了跨进程共享Buffer管理能力,可配合共享队列一起使用。共享Buffer的共享范围由共享队列的授权确定,共享范围包括“一主多从”的这些进程。

接口调用流程

关键接口的调用流程如上图所示,流程说明如下:

  1. AscendCL初始化

    调用aclInit接口实现初始化AscendCL。

  2. 运行管理资源申请

    具体流程,请参见运行管理资源申请与释放

  3. 申请共享Buffer内存

    调用acltdtAllocBuf接口申请共享Buffer内存,此处需根据实际情况选择内存类型。

  4. 向共享Buffer中填充有效数据

    需先调用acltdtGetBufData接口获取共享Buffer的数据区指针和数据区长度,接着调用aclrtMemcpy接口把用户数据复制到共享Buffer中,最后可调用acltdtSetBufDataLen接口设置有效数据长度,以便在多进程场景下调用acltdtGetBufDataLen接口获取有效数据长度,再根据有效数据长度获取共享Buffer中的数据。

  5. 设置共享Buffer的私有数据区数据

    调用acltdtSetBufUserData接口设置共享Buffer的私有数据区数据,以便在多进程场景下调用acltdtGetBufUserData接口获取共享Buffer的私有数据区数据。

  6. 释放共享Buffer内存

    调用acltdtFreeBuf接口来释放共享Buffer。

  7. 运行管理资源释放

    接口调用流程,请参见运行管理资源申请与释放

  8. AscendCL去初始化

    调用aclFinalize接口实现AscendCL去初始化。

示例代码

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>cpp<br>#include "acl/acl.h"<br>// 1. AscendCL初始化<br>// 此处的..表示相对路径,相对可执行文件所在的目录<br>// 例如,编译出来的可执行文件存放在out目录下,此处的..就表示out目录的上一级目录<br>const char *aclConfigPath = "../src/acl.json";<br>aclError ret = aclInit(aclConfigPath);<br>// 2. 运行管理资源申请,指定计算设备,此处以deviceId = 0为例<br>ret = aclrtSetDevice(0);<br>// 3. 申请mbuf内存并进行内存管理,此处以申请DVPP内存、内存大小1024U为例<br>size_t size = 1024U; <br>acltdtBuf buf; <br>ret = acltdtAllocBuf(size, ACL_TDT_DVPP_MEM, &buf);<br>// 4. 向共享Buffer中填充有效数据<br>// 4.1 获取共享Buffer的数据区指针和数据区长度<br>void *dataPtr = nullptr;<br>size_t dataSize = 0U;<br>ret = acltdtGetBufData(buf, &dataPtr, &dataSize);<br>// 4.2 把用户数据拷贝到共享Buffer中<br>size_t len = 512U; // 用户数据长度<br>void *ptr = new (std::nothrow) char_t[len]; // 用户申请自己的内存<br>// 用户对自己申请的数据进行处理<br>//……<br>ret = aclrtMemcpy(dataPtr, size, ptr, len, ACL_MEMCPY_HOST_TO_DEVICE);<br>// 5. 释放内存<br>delete[] ptr;<br>ptr = nullptr;<br>delete[] newPtr;<br>newPtr = nullptr;<br>ret = acltdtFreeBuf(buf);<br>// 6. 运行管理资源释放<br>ret = aclrtResetDevice(0);<br>// 7. AscendCL去初始化<br>ret = aclFinalize();<br>

父主题: 扩展更多特性

应用调试

编译及运行应用

  1. 编译代码

    可参考基于Caffe ResNet-50网络实现图片分类(同步推理)中的说明,主要步骤如下:

    1. 创建编译脚本。

      您可以从该基于Caffe ResNet-50网络实现图片分类(同步推理)样例中获取编译脚本CMakeLists.txt,在该编译脚本的基础上修改如下参数。

      • include_directories:添加头文件所在的目录。依赖的头文件请参见调用接口依赖的头文件和库文件说明

        示例如下:

        include_directories(
        directoryPath1
        directoryPath2
        )
      • link_directories:添加库文件所在的目录。

        示例如下:

        link_directories(
        directoryPath3
        directoryPath4
        )
      • add_executable:修改可执行文件的名称(例如:main)、添加*.cpp文件所在的目录。

        示例如下:

        add_executable(main
        directoryPath5
        directoryPath6)
      • target_link_libraries:修改可执行文件的名称(与add_executable中设置的名称保持一致)、添加可执行文件依赖的库文件。依赖的库文件与接口所在的头文件有关,请参见调用接口依赖的头文件和库文件说明

        示例如下:

        target_link_libraries(main
        ascendcl
        libName1
        libName2)

        :::note 说明 编译基于AscendCL接口的代码逻辑时,请按照include的头文件依赖对应的库文件,如果引用多余的so文件(例如libascendcl.a),可能导致版本功能异常或后续版本升级时存在兼容性问题。 :::

      • 编译选项,修改可执行文件的名称(与与add_executable中设置的名称保持一致),以及可执行文件的安装目录。

        示例如下,表示main安装在${CMAKE_INSTALL_PREFIX}/out目录下,${CMAKE_INSTALL_PREFIX}变量定义的路径是相对路径,相对cmake命令执行的路径:

        set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../../../out")

        install(TARGETS main DESTINATION $&#123;CMAKE_RUNTIME_OUTPUT_DIRECTORY&#125;)
    2. 设置环境变量

      如果基于基于Caffe ResNet-50网络实现图片分类(同步推理)样例中的CMakeLists.txt编译脚本进行修改时,则需要设置DDK_PATH、NPU_HOST_LIB环境变量,分别用于指向AscendCL头文件目录、库文件目录。

      如下为设置环境变量的示例,${INSTALL_DIR}表示CANN软件安装目录,例如,$HOME/Ascend/ascend-toolkit/latest*,**arch表示操作系统架构,{os}*表示操作系统。

      export DDK_PATH=$&#123;INSTALL_DIR&#125;
      export NPU_HOST_LIB=$&#123;INSTALL_DIR&#125;/&#123;arch-os&#125;/devlib
      备注

      须知

      使用“${INSTALL_DIR}/{**arch-os}/devlib”目录下的*.so库,是为了编译基于AscendCL接口的代码逻辑时,不依赖其它组件(例如Driver)的任何*.so库。因此在使用cmake编译命令时,请务必将DCMAKE_SKIP_RPATH设置为TRUE,代表不会将rpath路径(即“${INSTALL_DIR}/{arch-os}/devlib”)添加到编译生成的可执行文件中去。

      编译通过后,运行应用时,通过配置环境变量,应用会链接到运行环境上“lib64”目录下的*.so库,运行时会自动链接到依赖其它组件的*.so库。

    3. 执行cmake命令编译代码。

      示例命令如下,其中,“../../../src”表示CMakeLists.txt文件所在的目录,请根据实际目录层级修改;通过-DCMAKE_CXX_COMPILER参数指定的编译器,请根据实际版本要求修改。

      • 当开发环境与运行环境操作系统架构相同时,执行如下命令编译:

        cmake ../../../src -DCMAKE_CXX_COMPILER=g++ -DCMAKE_SKIP_RPATH=TRUE
      • 当开发环境与运行环境操作系统架构不同时,执行以下命令进行交叉编译:

        例如,当开发环境为X86架构,运行环境为AArch64架构时,执行以下命令进行交叉编译。

        cmake ../../../src -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_SKIP_RPATH=TRUE

      :::note 说明 关于cmake参数的详细介绍,请参见https://cmake.org/cmake/help/latest/guide/tutorial/index.html,选择对应的版本后再查看参数。 :::

    4. 执行make命令生成可执行文件。

      make
  2. 运行可执行文件

    将AscendCL初始化配置文件(acl.json)所在的目录、可执行文件所在的目录、测试图片所在的目录、*.om文件所在的目录都上传到运行环境的同一个目录下,再登录到运行环境,切换到可执行文件所在的目录,运行可执行文件,示例命令如下:

    ./main

    如果在AscendCL初始化阶段,在aclInit接口中传入空指针,则无需将AscendCL初始化配置文件(acl.json)所在的目录上传到运行环境。

问题定位

运行应用时如果出错,您可以参见《日志参考》获取日志文件,以便查看日志文件中详细报错。根据报错初步定位后:

  • 如果是接口约束导致接口调用逻辑不对,需查看总体的使用约束以及各接口本身的约束,再调整接口调用逻辑。
  • 如果是算子在AI Core上运行报错,需要进一步定位算子报错的原因,调用AscendCL提供的接口,获取出错算子的描述信息,用于进一步分析时使用,可参见AI Core异常信息获取,查看原理及调用示例。

DVPP数据处理高性能编程建议

目前在处理图像、视频数据时,可以使用VPC多功能组合接口、VPC批处理接口、合理选择VDEC的输出格式等编码方式,来提升应用的性能,具体编程建议请参见高性能编程建议

父主题: 精度/性能优化

简介

本文介绍整网推理场景下的精度调优流程、相关配置及典型案例等。由于是调优,因此在调优前,请确保已经完成了整网推理功能调测,功能不阻塞,只是推理精度错误,或推理精度与标杆数据存在少量差距。

在整网推理时,可能由于以下原因导致推理精度错误或者推理精度不达标:

  • 推理功能与其它功能之间的串接问题,当前比较典型的是DVPP+AIPP+模型推理串联使用的场景,该场景主要是因为接口中参数的配置问题、模型转换时AIPP的配置问题导致。

    如果存在DVPP、AIPP功能、模型推理串联使用的场景,建议先排查这部分问题;否则,可以跳过该排查,直接排查算子本身的精度问题。

  • 整网中算子本身的精度问题,该类问题可以借助精度比对工具,根据下文中具体的问题定位流程获取各类数据后,再进行比对、分析,确认是配置问题,还是算子实现问题,再逐一解决问题。本文中会结合具体的比对、分析的案例,介绍如何比对、分析。

图1 推理精度问题

:::note 说明

  • 本文中的“推理”,当前限定为使用om离线模型文件进行推理的场景。
  • 本文中的算子精度问题,是指整网中算子的精度问题,对于自定义的TBE算子,运行验证时的发现精度问题,请参见《TBE&AI CPU算子开发指南》。 :::

父主题: 模型推理精度提升建议

问题描述

推理结果不达标,包括以下两种情况:

  • 算子精度导致推理结果错误,是指整网推理的功能已调通,但推理结果错误,例如目标检测网络MAP结果全0、昇腾om模型的推理结果与标杆网络的推理结果比对时余弦相似度为0。
  • 算子精度导致推理精度不达标,是指整网推理的功能已调通,单次昇腾om模型的推理结果与标杆网络的推理结果比对时余弦相似度在95%以上,但数据集推理精度与标杆数据存在少量差距,例如:
    • 分类网络昇腾om模型,Top1/Top5分别为:0.90/0.70,;标杆网络Top1/Top5分别为:0.92/0.71。
    • 检测网络昇腾om模型MAP精度:0.54;标杆网络MAP精度:0.55。

父主题: 算子精度导致推理结果不达标

问题定位流程

图1 定位流程

  1. 推理结果错误,为了后续定位问题,需要重新执行推理,用于获取模型的Dump数据。

    获取模型的Dump数据,需要调用AscendCL接口打开Dump开关,详细描述请参见《精度比对工具使用指南》。

  2. 配置精度模式。

    1. 配置模型高精度模式后推理,获取模型的Dump数据。推理后,如果精度达标,则进行步骤2.b;如果精度不达标,则进行步骤3

      配置模型高精度模式后推理,可能会影响推理性能,如果在精度达标的同时,需要保持性能,则执行2.b~2.d,配置部分算子保持原始网络中的数据类型。

      配置模型高精度模式,请参见配置网络模型的高精度模式

    2. 使用精度比对工具比对高精度模式下的Dump数据与1获取的Dump数据。

      工具的使用请参见《精度比对工具使用指南》。

    3. 根据2.b中的比对结果识别计算有差异的算子。

      一般来说,每次识别一个差异算子(首个余弦相似度较低的算子,例如低于0.95),找到差异算子后,执行2.d推理,推理的同时获取Dump数据,用来与高精度模式下的Dump数据比对,继续找到下一个差异算子。

      需要循环执行该步骤,直至没有差异算子。

    4. 对于有差异的算子,配置该部分算子保持原始网络中的数据类型,再重新推理。

      配置部分算子的高精度模式,请参见配置部分算子保持原始网络中的数据类型

  3. 关闭数据缓存优化功能。

    1. 恢复模型的原有精度模式后,关闭数据缓存优化功能后推理,如果精度达标,则进行步骤3.b;如果精度不达标,则进行步骤4

      当前默认开启数据缓存优化,开启数据缓存优化可提高计算效率、提升性能,但由于部分算子在实现上可能存在未考虑的场景,导致影响精度,因此在出现精度问题时可以尝试关闭数据缓存优化。如果关闭数据缓存优化功能后,精度达标,则还是需要识别出问题算子,反馈给技术支持进一步分析、解决算子问题,解决算子问题后,建议保持开启数据缓存优化。

      关闭数据缓存优化功能,请参见关闭数据缓存优化

    2. 使用精度比对工具比对关闭数据缓存优化功能后的Dump数据与1获取的Dump数据。

      工具的使用请参见《精度比对工具使用指南》。

    3. 根据3.b中的比对结果识别计算有差异的算子。

    4. 联系技术支持(您可以获取日志后单击Link联系技术支持。),提供有差异的算子,进一步分析。

  4. 关闭融合规则功能。

    1. 恢复启用数据缓存优化功能,关闭融合规则功能后推理,如果精度达标,则进行步骤4.b;如果精度不达标,则进行步骤5

      当前默认开启融合规则,开启融合规则可提高计算效率、提升性能,但算子之间可能会融合,融合后的部分算子在实现上可能存在未考虑的场景,导致影响精度,因此在出现精度问题时可以尝试关闭融合规则。如果关闭融合规则功能后,精度达标,则还是需要识别出问题算子,反馈给技术支持进一步分析、解决算子问题,解决算子问题后,建议保持开启融合规则功能。

      关闭融合规则功能,请参见关闭融合规则。关闭某些融合规则可能会导致功能问题,因此在配置关闭融合规则后,系统在不影响功能的前提下关闭部分融合规则,而不是全部融合规则。

    2. 使用精度比对工具比对关闭融合规则后的Dump数据与1获取的Dump数据。

      工具的使用请参见《精度比对工具使用指南》。

    3. 根据4.b中的比对结果识别计算有差异的算子。

    4. 联系技术支持(您可以获取日志后单击Link联系技术支持。),提供有差异的算子,进一步分析。

  5. 检查数据处理或配置。

    推理精度不达标可能是由于数据集、AIPP、后处理方式的差异导致,需逐步进行排查,恢复启用融合规则功能后,请检查数据处理或配置,参见检查数据处理或配置

    如果数据处理逻辑或数据配置有问题,则需修改后重新推理;如果数据处理逻辑或数据配置没有问题,则进行6

  6. 与标杆计算数据比对。

    1. 使用精度比对工具将模型的Dump数据与标杆网络的Dump数据进行对比。

      工具的使用请参见《精度比对工具使用指南》。

    2. 根据6.a中的比对结果识别计算有差异的算子。

    3. 联系技术支持(您可以获取日志后单击Link联系技术支持。),提供有差异的算子,进一步分析。

父主题: 算子精度导致推理结果不达标

配置精度模式

如果在模式转换时不指定网络模型或算子的精度模式,默认采用fp16(float16)数据类型进行计算。

配置模型高精度模式后推理,可提升精度,但可能会影响推理性能,如果在精度达标的同时,需要保持性能,则可以配置部分算子保持原始网络中的数据类型。关于ATC参数的详细说明请参见《ATC工具使用指南》。

配置网络模型的高精度模式

  1. 使用ATC工具转换模型时,增加高级参数--precision_mode,用于指定精度模式。

    参数设置如下所示,表示如果网络模型中算子支持fp32(float32),则使用fp32;如果网络模型中算子不支持fp32,则使用fp16(float16)。

    --precision_mode=allow_fp32_to_fp16
  2. 使用转换后的om模型重新推理。

配置部分算子保持原始网络中的数据类型

  1. 使用ATC工具转换模型时,增加高级参数--keep_dtype(指定部分算子计算时保持原始网络的数据类型)和--precision_mode(指定网络模型的精度模式)。

    参数使用示例如下:

    --keep_dtype=$HOME/execeptionlist.cfg --precision_mode=force_fp16

    配置文件名举例为execeptionlist.cfg,配置文件样例如下,文件中每一行是一个算子的名称,将配置好的execeptionlist.cfg文件上传到ATC工具所在服务器任意目录:

    Opname1
    Opname2

  2. 使用转换后的om模型重新推理。

父主题: 算子精度导致推理结果不达标

在线提单