SS928V100(Hi3403V100)----ATC模型转换工具----SVP_NNN 和 NNN 踩坑记载(LINUX版)

[复制链接]
发表于 2025-9-7 20:23:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
        由于官方SDK比力冗余且经常跨文档讲解且SDK整理的乱七八糟,对于新手来说全部看完上手成本较高,本文旨在以简短的方式先容 CAFFE / ONNX 模型转 om 模型,并进行推理的全流程。盼望能够资助到第一次接触华为海思框架的道友们。大佬们就没必要看这种底子文章啦!
          注:本文全部操纵均在 WSL (Windows 虚拟子系统)上操纵的,默认 root 环境,默认开发板系统为LINUX,全部环境变量均写入 bashrc ,非虚拟机用户谨慎写入。全部用到的工具以及示例代码,均在文末。
  

1. 简介

          ATC 是海思芯片的模型转换工具,用于将开源框架网络模型(caffe,onnx,tensorflow)转化为 .om 格式并使用 AscendCL进行推理(由于笔者比力熟悉瑞芯微系列,分别雷同于雷同瑞芯微系列的RKNNToolkit工具, .rknn 模型,RKNNToolkitLite板端推理工具)。           起首在进行下面这篇文章之前,先来相识一下 SS928V100(Hi3403V100) 这款芯片,该芯片有两颗 NPU,分别是 NNN 和SVP_NNN,其中 NNN 支持4.8Tops算力,支持 INT4/INT8/FP16;SVP_NNN 支持5.6Tops算力,支持 INT8/INT16。         简单阐明:         

  • NNN和SVP_NNN 进行模型转换时,用到的 ATC 工具链以及环境变量不一样
  • NNN和SVP_NNN 进行推理时,推理接口以及依赖的环境变量也不一样
  • NNN和SVP_NNN是能够并利用用的,但是测试过程中发现,如果并利用用,两颗NPU的平均算力利用率会下降10%-15%
            因此本文的安装内容也会分成两部分,分别是 NNN 和 SVP_NNN    1.1 通用交织编译工具链安装

  1. chmod +x Ascend-cann-toolkit_5.20.t6.2.b060_linux-x86_64.run
  2. # 校验安装包是否完整, 校验成功会显示 Verifying archive integrity...  100%
  3. ./Ascend-cann-toolkit_5.20.t6.2.b060_linux-x86_64.run --check
  4. # 安装,安装过程中有协议确认,按 Y 即可,安装成功会显示 <...> install success
  5. # 安装路径:root用户:“/usr/local/Ascend”,非root用户:“${HOME}/Ascend”
  6. ./Ascend-cann-toolkit_5.20.t6.2.b060_linux-x86_64.run --install
  7. # 配置环境变量,以 root 用户为例(WSL默认sudo权限)
  8. source /usr/local/Ascend/ascend-toolkit/latest/x86_64-linux/x86_64-linux/bin/setenv.bash
  9. vi ~/.bahsrc
  10. export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/x86_64-linux/x86_64-linux/devlib/:$LD_LIBRARY_PATH
  11. source ~/.bashrc
复制代码
1.2 安装openssh(有的话可跳过,没有也可以通过 NFS 共享目录办理文件传输问题)

          说实话,挺烦这种精简 linux 系统的,要啥没啥,不知道精减的意义是啥,每次都要重复这种安装编译环境的过程。
          参考,注意本文使用的交织编译工具链的名字和文中的不一样:【MindStudio】【OpenSSH】海思SOC环境准备(linux + android)-云社区-华为云
          真是令人抓狂,海思SS928这款开发板,连adb都莫得,交织编译好的文件甚至都没办法传到开发板上,太恶心啦!!!
          NFS 共享目录方法如下:
   
  1. # 1. 以 root 用户登录 Linux 服务器(Ubuntu 操作系统),安装 NFS 服务并配置共享目录。
  2. apt-get install nfs-kernel-server
  3. # 2. 在“/etc/exports”文件中配置共享目录
  4. vi /etc/exports
  5. # 在末尾添加 <服务器共享目录绝对路径> *(rw,sync,root_squash), 如
  6. /userdata/share *(rw,sync,root_squash)  
  7. # 3. 重启 nfs 服务
  8. /etc/init.d/nfs-kernel-server restart
  9. # 4. 开发板板端挂载,mount -t nfs -o nolock,tcp NFS <服务器IP地址:服务器绝对路径path>,如
  10. mount -t nfs -o nolock,tcp NFS 192.168.1.2:/userdata/share
复制代码
2. NNN 引擎下的模型转换与推理

  2.1 安装CANN ToolKit(以python3.9为例)

     

  • 编译python3.9
            坑:各 python 必须严格按照下述版本,否则实行模型转换时会报错 :Python3.7.x(3.7.5~3.7.11)、Python3.8.x(3.8.0~3.8.11)、Python3.9.x(3.9.0~3.9.2)保举使用Python3.9.2
  1. # 安装python3.9
  2. sudo apt update
  3. sudo apt install -y build-essential libssl-dev zlib1g-dev \
  4.   libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
  5.   libncurses5-dev libncursesw5-dev xz-utils tk-dev \
  6.   libffi-dev libxslt1-dev liblzma-dev python3-openssl cmake Pillow git
  7. wget https://www.python.org/ftp/python/3.9.2/Python-3.9.2.tgz
  8. tar -zxvf Python-3.9.2.tgz
  9. cd Python-3.9.2
  10. ./configure --prefix=/usr/local/python3.9.2 --with-ssl-default-suites=openssl --enable-shared CFLAGS=-fPIC
  11. make -j8
  12. make install
  13. vi ~/.bashrc
  14. export LD_LIBRARY_PATH=/usr/local/python3.9.2/lib:$LD_LIBRARY_PATH
  15. export PATH=/usr/local/python3.9.2/bin:$PATH
  16. source ~/.bashrc
  17. # 安装 cann 所需 python 环境
  18. # 注意,WSL默认sudo权限,此处如果用sudo,后续执行 ./Ascend-cann-toolkit_8.1.RC1_linux-x86_64.run --install 也要加sudo
  19. pip3 install attrs cython numpy==1.24.0 decorator sympy cffi pyyaml pathlib2 psutil protobuf==3.20 scipy requests absl-py -i https://pypi.tuna.tsinghua.edu.cn/simple
复制代码
   

  • 在昇腾官网下载 cann 安装包, 并传到WSL中:社区版资源下载-资源下载中心-昇腾社区
              注:我用的是SDK中提供的   Ascend-cann-toolkit_5.20.t6.2.b060_linux-x86_64.run            

  • 实行如下命令安装
    1. chmod +x Ascend-cann-toolkit_5.20.t6.2.b060_linux-x86_64.run
    2. # 校验安装包是否完整, 校验成功会显示 Verifying archive integrity...  100%
    3. ./Ascend-cann-toolkit_5.20.t6.2.b060_linux-x86_64.run --check
    4. # 安装,安装过程中有协议确认,按 Y 即可,安装成功会显示 <...> install success
    5. # 安装路径:root用户:“/usr/local/Ascend”,非root用户:“${HOME}/Ascend”
    6. ./Ascend-cann-toolkit_5.20.t6.2.b060_linux-x86_64.run --install
    7. # 配置环境变量,以 root 用户为例(WSL默认sudo权限)
    8. source /usr/local/Ascend/ascend-toolkit/latest/x86_64-linux/x86_64-linux/bin/setenv.bash
    9. vi ~/.bahsrc
    10. export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/x86_64-linux/x86_64-linux/devlib/:$LD_LIBRARY_PATH
    11. source ~/.bashrc
    复制代码
    安装完成后,模型转换工具 atc 在 " ${HOME}Ascend/ascend-toolkit/latest/bin " 目录下。
        2.2 caffe/onnx 转 om(以resnet50为例)



  • 转换示例:
  
  1. # 模型转换(类似RKNNToolKit),注意每次重启后都需要再次 source /usr/local/Ascend/ascend-toolkit/latest/x86_64-linux/x86_64-linux/bin/setenv.bash
  2. # caffe 转 om
  3. atc --model=./caffe_model/resnet50.prototxt --weight=./caffe_model/resnet50.caffemodel --framework=0 --output=./model/caffe_resnet50 --soc_version=OPTG --input_fp16_nodes="data" --enable_single_stream=true
  4. # onnx 转 om
  5. atc --model=./caffe_model/resnet50_official.onnx --framework=5 --output=./model/resnet50_bs64 --input_format=NCHW --soc_version=OPTG --input_fp16_nodes="data" --enable_single_stream=true
  6. # sample 编译
  7. vi ~/.bashrc
  8. export DDK_PATH=/usr/local/Ascend/ascend-toolkit/latest/arm64-lmixlinux200
  9. export NPU_HOST_LIB=/usr/local/Ascend/ascend-toolkit/latest/arm64-lmixlinux200/aarch64-linux/devlib
  10. source ~/.bashrc
  11. mkdir -p build/intermediates/soc
  12. cd build/intermediates/soc
  13. cmake ../../../src -DCMAKE_CXX_COMPILER=aarch64-mix210-linux-g++ -DCMAKE_SKIP_RPATH=TRUE
  14. make
复制代码


  • 参数讲解:
   
参数阐明
--weight
仅caffe模型必要,指定 .caffemodel 路径
--framewowrk
0:Caffe,1:MindSpore,2:TensorFlow ,5:ONNX (opset v11)
--model 模型文件
--input_format
输入数据格式 (Caffe、ONNX 默认为 NCHW;TensorFlow 默认为 NHWC)
--enable_single_stream
是否使能一个模型推理时只能使用一条 Stream (由于 SoC 的 Stream 资源有限,在 SoC 场景下必要用户打开此开关,SOC 广义上讲其实就是我们常用的开发板啦)
--input_fp16_nodes模型输入范例: FP32、FP16通过指定该参数设置,UINT8 必要结合 AIPP 预处置处罚文件设置
    2.3 om 模型推理流程(雷同RKNNToolKitLite)

  

  • 基本概念:
          Device 表示板端环境上的 NNN(Neural-Network Processing Unit),提供 NN 计算本领。
          Context 作为一个容器,管理了全部对象(包括 Stream、Event、设备内存等)的生命周期。
          Stream 用于维护一些异步操纵的实行次序,确保按照应用程序中的代码调用次序在 Device 上实行。
     坑1:
           如果开发板没有相干的 NPU 驱动 "dev/xiaoyaozi0", 切换到 " /smp/a55_linux/mpp/out/ko " 目录下实行 " ./load_ss928v100 -a "。等等,先不要惊讶,这个 NNN 的 NPU 驱动就叫 xiaoyaozi0,哈哈哈哈,看得出来,编这个驱动的程序猿很清闲......
   坑2:
           板端实行需设置环境变量 , {PATH} 替换成实际目录地点:
   export LD_LIBRARY_PATH={PATH}/smp/a55_linux/mpp/out/lib/npuLD_LIBRARY_PATH
     

  •  板端推理代码示例:
  1. #include "acl/acl.h"
  2. #include <iostream>
  3. #include <fstream>
  4. #include <cstring>
  5. #include <map>
  6. #include <math.h>
  7. using namespace std;
  8. int32_t deviceId = 0;
  9. uint32_t modelId;
  10. size_t pictureDataSize = 0;
  11. void *pictureHostData;
  12. void *pictureDeviceData;
  13. aclmdlDataset *inputDataSet;
  14. aclDataBuffer *inputDataBuffer;
  15. aclmdlDataset *outputDataSet;
  16. aclDataBuffer *outputDataBuffer;
  17. aclmdlDesc *modelDesc;
  18. size_t outputDataSize = 0;
  19. void *outputDeviceData;
  20. void *outputHostData;
  21. void ReadPictureTotHost(const char *picturePath)
  22. {
  23.         string fileName = picturePath;
  24.         ifstream binFile(fileName, ifstream::binary);
  25.         binFile.seekg(0, binFile.end);
  26.         pictureDataSize = binFile.tellg();
  27.         binFile.seekg(0, binFile.beg);
  28.         aclError ret = aclrtMallocHost(&pictureHostData, pictureDataSize);
  29.         binFile.read((char*)pictureHostData, pictureDataSize);
  30.         binFile.close();
  31. }
  32. int main()
  33. {
  34.         printf("==== 这是测试代码123 ==== \n");
  35.         // ===== step1 : 初始化 acl =====
  36.         aclError ret = aclInit(nullptr);
  37.         if (ret != ACL_SUCCESS) cerr << "aclInit failed with ret: " << ret << "\n" << endl;
  38.         ret = aclrtSetDevice(deviceId);            // 默认创建了 context 和 stream
  39.         if (ret != ACL_SUCCESS) cerr << "aclrtSetDevice failed with ret: " << ret << "\n" << endl;
  40.         
  41.         // ===== step2 : 加载模型 =====
  42.         const char *modelPath = "../model/resnet50.om";
  43.         ret = aclmdlLoadFromFile(modelPath, &modelId);  
  44.         if (ret != ACL_SUCCESS) cerr << "aclmdlLoadFromFile failed with ret: " << ret << "\n" << endl;
  45.         // ===== setp3 : 加载 bin 类型的图片 =====
  46.         const char *picturePath = "../data/dog1_1024_683.bin";
  47.         ReadPictureTotHost(picturePath);
  48.         ret = aclrtMalloc(&pictureDeviceData, pictureDataSize, ACL_MEM_MALLOC_HUGE_FIRST);
  49.         if (ret != ACL_SUCCESS) cerr << "aclrtMalloc failed with ret: " << ret << "\n" << endl;
  50.         ret = aclrtMemcpy(pictureDeviceData, pictureDataSize, pictureHostData, pictureDataSize, ACL_MEMCPY_HOST_TO_DEVICE);
  51.         if (ret != ACL_SUCCESS) cerr << "aclrtInputMemcpy failed with ret: " << ret << "\n" << endl;
  52.         // ===== step4 :执行推理 =====
  53.         // === step4.1 :   创建aclmdlDataset类型的数据,描述模型推理的输入 ===
  54.         inputDataSet = aclmdlCreateDataset();
  55.         inputDataBuffer = aclCreateDataBuffer(pictureDeviceData, pictureDataSize);
  56.         ret = aclmdlAddDatasetBuffer(inputDataSet, inputDataBuffer);
  57.         if (ret != ACL_SUCCESS) cerr << "aclmdlAddDatasetBuffer failed with ret: " << ret << "\n" << endl;
  58.         // === step4.2 :   创建aclmdlDataset类型的数据,描述模型推理的输出 ===
  59.         // 创建模型描述信息
  60.         modelDesc =  aclmdlCreateDesc();
  61.         ret = aclmdlGetDesc(modelDesc, modelId);
  62.         if (ret != ACL_SUCCESS) cerr << "aclmdlGetDesc failed with ret: " << ret << "\n" << endl;
  63.         outputDataSet = aclmdlCreateDataset();
  64.         outputDataSize = aclmdlGetOutputSizeByIndex(modelDesc, 0);
  65.         // 申请输出内存
  66.         ret = aclrtMalloc(&outputDeviceData, outputDataSize, ACL_MEM_MALLOC_HUGE_FIRST);
  67.         if (ret != ACL_SUCCESS) cerr << "aclrtMalloc failed with ret: " << ret << "\n" << endl;
  68.         outputDataBuffer = aclCreateDataBuffer(outputDeviceData, outputDataSize);
  69.         ret = aclmdlAddDatasetBuffer(outputDataSet, outputDataBuffer);
  70.         if (ret != ACL_SUCCESS) cerr << "aclmdlAddDatasetBuffer failed with ret: " << ret << "\n" << endl;
  71.         // === step 4.3 : 推理 ===
  72.         ret = aclmdlExecute(modelId, inputDataSet, outputDataSet);
  73.         if (ret != ACL_SUCCESS) cerr << "aclmdlExecute failed with ret: " << ret << "\n" << endl;
  74.         // ===== step5:获取推理结果数据 =====
  75.         // === step5.1 : copy 推理结果到 outputHostData
  76.         ret = aclrtMallocHost(&outputHostData, outputDataSize);
  77.         if (ret != ACL_SUCCESS) cerr << "aclrtMallocHost failed with ret: " << ret << "\n" << endl;
  78.         ret = aclrtMemcpy(outputHostData, outputDataSize, outputDeviceData, outputDataSize, ACL_MEMCPY_DEVICE_TO_HOST);
  79.         if (ret != ACL_SUCCESS) cerr << "aclrtOutputMemcpy failed with ret: " << ret << "\n" << endl;
  80.         // === step5.2 :后处理部分
  81.         float* outFloatData = reinterpret_cast<float *>(outputHostData);
  82.         // 屏显测试图片的top5置信度的类别编号
  83.         map<float, unsigned int, greater<float>> resultMap;
  84.         for (unsigned int j = 0; j < outputDataSize / sizeof(float); ++j)
  85.         {
  86.                 resultMap[*outFloatData] = j;
  87.                 outFloatData++;
  88.         }
  89.         double totalValue=0.0;
  90.         for (auto it = resultMap.begin(); it != resultMap.end(); ++it)
  91.         {
  92.                 totalValue += exp(it->first);
  93.         }
  94.         int cnt = 0;
  95.         for (auto it = resultMap.begin();it != resultMap.end();++it)
  96.         {
  97.                 if(++cnt > 5) break;
  98.                 printf("top %d: index[%d] value[%lf] \n", cnt, it->second, it->first);
  99.         }
  100.         // ===== step6 : 释放资源 =====
  101.         // === 6.1 释放模型描述信息并卸载模型 ===
  102.         aclmdlDestroyDesc(modelDesc);
  103.         aclmdlUnload(modelId);  
  104.         // === 6.2 释放加载的测试图片 ===
  105.         ret = aclrtFreeHost(pictureHostData);
  106.         pictureHostData = nullptr;
  107.         ret = aclrtFree(pictureDeviceData);
  108.         pictureDeviceData = nullptr;
  109.         aclDestroyDataBuffer(inputDataBuffer);
  110.         inputDataBuffer = nullptr;
  111.         aclmdlDestroyDataset(inputDataSet);
  112.         inputDataSet = nullptr;
  113.         ret = aclrtFreeHost(outputHostData);
  114.         outputHostData = nullptr;
  115.         ret = aclrtFree(outputDeviceData);
  116.         outputDeviceData = nullptr;
  117.         aclDestroyDataBuffer(outputDataBuffer);
  118.         outputDataBuffer = nullptr;
  119.         aclmdlDestroyDataset(outputDataSet);
  120.         outputDataSet = nullptr;   
  121.         // === 6.3 释放计算资源 ===
  122.         ret = aclrtResetDevice(deviceId);
  123.         aclFinalize();   
  124. }
复制代码
3. SVP_NNN 引擎下的模型转换与推理

3.1 安装 CANN ToolKit(以python3.9为例)

        注意,此处用的SDK是"Ascend-cann-toolkit_6.10.t01spc030b270_linux.x86_64.run",写到这里,不得不吐槽一下,我不知道是我拿到手的SDK有问题,还是整理这个SDK的人有问题,喵的,整个SDK没有一篇文档有说过 SVP_NNN 和 NNN 用的ATC工具不是同一个。也没有一篇文档讲了 SVP_NNN 的 ATC 工具进行转换时参数应该怎么写......
        不外幸亏,安装过程和 NNN 的 ATC 工具差别不大,只必要注意环境变量即可
  1. chmod +x Ascend-cann-toolkit_6.10.t01spc030b270_linux.x86_64.run
  2. ./Ascend-cann-toolkit_6.10.t01spc030b270_linux.x86_64.run --install
  3. # install 成功后,终端会打印如下 export 环境变量信息
  4. vi ~/.bashrc
  5. export DDK_PATH=/usr/local/Ascend/ascend-toolkit/svp_latest/x86_64-linux
  6. export NPU_HOST_LIB=/usr/local/Ascend/ascend-toolkit/svp_latest/x86_64-linux/acllib/lib64/stub
  7. export PATH=/usr/local/Ascend/ascend-toolkit/svp_latest/toolkit/bin:$PATH
  8. export PATH=/usr/local/Ascend/ascend-toolkit/svp_latest/atc/bin:$PATH
  9. export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/svp_latest/toolkit/tools/sim/lib:$LD_LIBRARY_PATH
  10. export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/svp_latest/atc/lib64:$LD_LIBRARY_PATH
  11. export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/svp_latest/atc/third_party_lib:$LD_LIBRARY_PATH
  12. source ~/.bashrc
复制代码
3.2 caffe 转 om

        我个人觉得 SVP_NNN 的 ATC 比力好用,可能由于 SVP_NNN 只支持 INT8/INT16 ,所以就量化而言,要比 NNN 下使用 AMCT 工具来的轻松友好的多,转换示例:
  1. atc \
  2.   --weight="./caffe_model/resnet50.caffemodel" \
  3.   --model="./caffe_model/resnet50.prototxt" \
  4.   --framework=0 \
  5.   --log_level=0 \
  6.   --dump_data=0 \
  7.   --online_model_type=0 \
  8.   --batch_num=256 \
  9.   --input_shape="data:1,3,224,224" \
  10.   --input_type="data:UINT8" \
  11.   --input_format=NCHW \
  12.   --output="./model/resnet50" \
  13.   --soc_version=SS928V100 \
  14.   --insert_op_conf=./insert_op.cfg \
  15.   --compile_mode=0 \
  16.   --save_original_model=false \
  17.   --image_list="data:./data/image_ref_list.txt"
复制代码
        具体参数信息,安装完 ATC 环境后,可通过 atc --hlep 查看,以下仅对常用底子参数进行阐明:
参数阐明
           
--batch_num

      
批处置处罚层的批次数,[0, 256],默认值为 256
--compile_mode
量化数据范例,0:低精度(8位量化),1:高精度(16位量化)
--framework
输入模型的框架,0:caffe,5:onnx,默认 0
--image_list
量化校准使用的图像列表文件
--input_shape
输入数据的形状
--input_format
输入数据的格式,{NCHW},默认:NCHW
--input_type
支持的输入数据范例:{FP16, FP32, INT16, INT8, S16, S8, U16, U8, UINT16, UINT8},默认 FP32
--insert_op_conf
AIPP 配置文件路径
--model
输入模型文件路径
--weight
权重文件路径
--output
输出 om 路径及文件名
--output_type
支持的输出数据范例:{FP16, FP32, INT16, INT8, S16, S8, U16, U8, UINT16, UINT8},默认 FP32
--soc_version
SoC 版本,{SS626V100, SS928V100},默认 SS626V100(注意,次数和 NNN 下的 ATC 有一定区别,不支持 OPTG)
--save_original_model
是否生存原始模型,默认 false
3.3 om 推理流程

   坑1:
          如果开发板没有相干的 NPU 驱动 "dev/svp_npu",切换到 " /smp/a55_linux/mpp/out/ko " 目录下,修改 " ./load_ss928v100" 这个可实行程序,搜索加载 " pqp.ko "的代码,然后将其解释掉,然后关闭解释或添加如下内容:"insmod svp_npu/ot_svp_npu.ko svp_npu_save_power=1 svp_npu_max_task_node_num=512", 由于 "ot_svp_npu.ko" 和 "pqp.ko" 不能同时加载
  坑2:
          板端实行需设置环境变量,{PATH} 替换成实际目录地点 :
  export LD_LIBRARY_PATH={PATH}/smp/a55_linux/mpp/out/lib/svp_npuLD_LIBRARY_PATH
          SVP_NNN 下的推理流程和 NNN 雷同,区别在于引用的头文件名称以及接口都添加了 svp 的前缀,且接口风格由驼峰变成了下划线分割,下列代码仅贴出和 NNN 不同的代码段以供理解,完备代码见文末: 
  1. #include "acl/svp_acl.h"
  2. # 1. 初始化 svp_acl
  3. svp_acl_error ret = svp_acl_init(aclConfigPath);
  4. svp_acl_error ret = svp_acl_rt_set_device(deviceId_);
  5. # 2. 加载模型
  6. svp_acl_error ret = svp_acl_mdl_load_from_mem(static_cast<uint8_t* >(modelMemPtr_), modelMemSize_, &modelId_);
  7. # 3. 创建模型描述信息
  8. modelDesc_ = svp_acl_mdl_create_desc();
  9. svp_acl_error ret = svp_acl_mdl_get_desc(modelDesc_, modelId_);
  10. # 4. 创建输入
  11. Result ret = GetInputStrideParam(0, devSize, stride, inputDims);
  12. size_t dataSize = GetInputDataSize(0);
  13. void *picDevBuffer = Utils::GetDeviceBufferOfFile(filePath, inputDims, stride, dataSize);
  14. Result ret = InitInput();
  15. Result ret = CreateInput(picDevBuffer, devSize, stride);
  16. # 4. 创建输出
  17. output_ = svp_acl_mdl_create_dataset();
  18. size_t outputSize = svp_acl_mdl_get_num_outputs(modelDesc_);
  19. # 5. 执行推理
  20. svp_acl_error ret = svp_acl_mdl_execute(modelId_, input_, output_);
复制代码
4. 其他

4.1 om 模型信息查看

        通过 netron 可以直接查看NNN ATC 工具转换的模型信息(SVP_NNN ATC 工具转换的 om 模型无法直接使用 netron 查看),或者实行如下命令,将 .om 模型转化为 json 文件查看模型信息:
  1. atc --mode=1 --om={oem_model_path.oem} --json={oem_json_path.json}
复制代码
4.2 查看 NPU 利用率

        看团体的NPU资源占用,分两个核看
  1. # SVP_NNN, 执行命令后查看 hw_utilization
  2. watch -n 1 cat /proc/umap/svp_npu
  3. # NNN, 执行命令后查看 utilizaiton rate
  4. watch -n 1 cat /proc/umap/tsfw的utilizaiton rate
复制代码
4.3 源码传送门

SS928V100_NNN&SVP_NNN_TOOLS 提取码: 2jdc
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表