选中内容(绿色)时除了会搜索文章名,还会搜索文章内容
点击结果中的文章名进入文章界面后可以按Ctrl+F在页面内搜索
  • 版权:CC BY-SA 4.0
  • 创建:2022-07-19
  • 更新:2022-07-29
全志 V853 NPU 实机体验,包括模型量化,模型导出,以及 SDK 编译, 例程编译运行等


资料

全志在线: https://v853.docs.aw-ol.com/ 公开资料, 包括了官方开发板的资料, SDK 下载的方法在里面也有,SDK有公开版本和不公开版本,公开的只是需要注册账号即可下载,不公开的需要授权了的账号下载

下载 SDK 需要用 全志改过的 repo 命令: https://v853.docs.aw-ol.com/study/study_3getsdk/

需要下载 NPU 扩展包(~实际SDK中 package/allwinner/yolov3 已经有了,不需要下载~需要使用里面的 so文件,tina-SDK中的版本太旧): https://www.aw-ol.com/downloads?cat=18

NPU 使用环境准备

  • 安装 IDE Verisilicon_Tool_VivanteIDE(改自eclipse), 需要 license, 使用 acuity toolkit不需要 license,但是在 IDE 中运行程序以及调试都需要 license,否则会报错, 需要申请, 或者在芯原官方申请 https://www.verisilicon.com/cn/VIPAcuityIDELicenseRequest
  • 解压 acuity-toolkit-binary 并设置环境变量使pegasus help可用,按照官方说的解压到 IDE 安装目录, 以防出现啥官方没测过的 bug, 比如 导入包错误

    Vivante_acuity_toolkit_whl或者Vivante_acuity_toolkit_src, 分别是使用 pip 进行安装的 whl 文件或者源码,正常情况直接只用 binary 足够

    1. # for v853
    2. ACUITY_TOOLS_METHOD=acuity-toolkit-binary
    3. export ACUITY_PATH=/home/neucrack/VeriSilicon/$ACUITY_TOOLS_METHOD/bin/
    4. export VIV_SDK=/home/neucrack/VeriSilicon/VivanteIDE5.7.0/cmdtools/
    5. export PATH=$PATH:/home/neucrack/VeriSilicon/$ACUITY_TOOLS_METHOD/bin/:/home/neucrack/VeriSilicon/VivanteIDE5.7.0/ide/
    6. export pegasus=/home/neucrack/VeriSilicon/$ACUITY_TOOLS_METHOD/bin/pegasus
    7. alias pegasus=/home/neucrack/VeriSilicon/$ACUITY_TOOLS_METHOD/bin/pegasus

编译 SDK 和 demo 测试

编译: https://v853.docs.aw-ol.com/study/study_4compile/

需要注意: 必须使用 ubuntu, 其它发行版比如 manjaro,可能无法编译通过! 不然可能编译会遇到各种奇怪错误

  1. /bin/bash
  2. source build/envsetup.sh
  3. lunch
  4. make -j$

编译demo
make menuconfig使能Allwinner/yolov3
然后

  1. make packages/allwinner/yolov3/compile
  2. make packages/allwinner/yolov3/clean

或者

  1. cd packages/allwinner/yolov3/src
  2. make

然后把out/v853-perf1/compile_dir/target/yolov3下的 yolov3sdk目录拷贝到板子, 将sdk/drivers下面的 so复制到/usr/lib目录,同时将yolov3_model.nb也拷贝到板子(使用adb push命令传文件)

但是实际跑的时候出错了

  1. root@TinaLinux:/mnt/UDISK# ./yolov3 yolov3_model.nb horses_416x416.jpg
  2. Usage:
  3. nbg_name input_data1 input_data2...
  4. [0xb6f1d560]gcvip_create_network[3769], binary target=0xEE, actually target=0x0
  5. [0xb6f1d560]gcvip_create_network[4002], fail to create network
  6. [0xb6f1d560]gcvip_create_network_from_file[4022], fail to create network
  7. [0xb6f1d560]vip_create_network[752], failed to create network status=-10
  8. Error: main.c: vnn_CreateNeuralNetwork at 117
  9. Error: main.c: main at 233
  10. [0xb6f1d560]vip_finish_network[1199], network object is NULL
  11. Error: vnn_post_process.c: destroy_network at 168
  12. Error: main.c: vnn_ReleaseNeuralNetwork at 195

查了查.h错误代码-10表示VIP_ERROR_NETWORK_INCOMPATIBLE,版本不兼容,可见这个 vip_lite 的库版本有问题

原因是因为使用了 tina-sdk 中的yolov3例程中的sdk目录下的so文件,版本旧了, 使用另外下载的 NPU 扩展包 里面的 viplite-driver 中的驱动即可, 同时代码也使用其中的

模型转换

词汇:

  • VIP: Vision Image Processing
  • OVX: OpenVX
  • PPU: parallel processing unit

准备个模型, 比如 onnx, 以 resnet18 为例 (https://pytorch.org/hub/pytorch_vision_resnet/ ) :
按照页面代码或

  1. import torch
  2. model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet18', pretrained=True)
  3. # or any of these variants
  4. # model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet34', pretrained=True)
  5. # model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', pretrained=True)
  6. # model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet101', pretrained=True)
  7. # model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet152', pretrained=True)
  8. model.eval()
  1. inputs = torch.randn(1, 3, 224, 224, device="cuda")
  2. torch.onnx.export(model, inputs, "resnet18.onnx", export_params=True, opset_version=13, input_names=["input0"], output_names=["output0"])

然后对 onnx 进行简化

  1. python -m onnxsim resnet18.onnx resnet18.onnx

先创建 dataset.txt, 指定图片路径, 一行一个

  1. ./data/1.JPEG
  2. ./data/2.JPEG
  3. ./data/3.JPEG
  4. ./data/4.JPEG
  5. ./data/5.JPEG
  6. ./data/6.JPEG
  7. ./data/7.JPEG
  8. ./data/8.JPEG
  9. ./data/9.JPEG
  10. ./data/10.JPEG
  11. ./data/11.JPEG

导入模型

  1. pegasus import onnx --model resnet18.onnx --output-model resnet18.json --output-data resnet18.data
  2. pegasus generate inputmeta --model resnet18.json --input-meta-output resnet18-inputmeta.yml
  3. pegasus generate postprocess-file --model resnet18.json --postprocess-file-output resnet18-postprocess.yml

然后修改 resnet18-inputmeta.yml 中的 mean, 这里修改 mean 发现没有 std, 只有一个 scale, 其实就是(输入 - mean ) * scale, 但是这里有点问题就是 mean 可以写多个, 但是貌似 scale 只能写一个值?尝试直接将scale 写成和 mean 一样的三通道格式,会报错,所以应该是不支持,那这里可能实际用起来会遇到坑,训练的模型预处理可能需要改改来满足这个 scale 的做法, 或者 acuity 提供过了 python 调用的方式, 自己写 python 转换脚本,就不用这个命令了,自己写预处理(推荐)

  1. pegasus quantize --model resnet18.json --model-data resnet18.data --batch-size 1 --device CPU --with-input-meta resnet18-inputmeta.yml --rebuild --model-quantize resnet18.quantilize --quantizer asymmetric_affine --qtype uint8
  1. pegasus inference --model resnet18.json --model-data resnet18.data --batch-size 1 --dtype quantized --model-quantize resnet18.quantilize --device CPU --with-input-meta resnet18-inputmeta.yml --postprocess-file resnet18-postprocess.yml --iterations 11
  2. pegasus export ovxlib --model resnet18.json --model-data resnet18.data --batch-size 1 --dtype quantized --model-quantize resnet18.quantilize --save-fused-graph --target-ide-project 'linux64' --with-input-meta resnet18-inputmeta.yml --postprocess-file resnet18-postprocess.yml --output-path ovxlib/resnet18 --pack-nbg-unify --optimize "VIP9000PICO_PID0XEE" --viv-sdk $VIV_SDK
  3. pegasus export ovxlib --model resnet18.json --model-data resnet18.data --batch-size 1 --dtype quantized --model-quantize resnet18.quantilize --save-fused-graph --target-ide-project 'linux64' --with-input-meta resnet18-inputmeta.yml --postprocess-file resnet18-postprocess.yml --output-path ovxlib/resnet18 --pack-nbg-viplite --optimize "VIP9000PICO_PID0XEE" --viv-sdk $VIV_SDK

这里发现--pack-nbg-viplite在提供的工具链中已经被移除了, 只有 --pack-nbg-unify, 但是 SDK 提供给的包都是 vip-lite的库,生成的unify目录下的代码也和提供的vip-lite代码有比较多的区别,不知道是什么情况,提供的使用文档 PDF 让导出模型使用 —pack-nbg-viplite 参数导出 viplite 模型和生成工程,但是实际上提供的转换工具(Verisilicon_Tool_Acuity_Toolkit_6.6.1_Binary_Whl_Src_20220420) 中这个参数已经被废弃了, 只能用生成 —pack-nbg-unify 参数生成,可以得到 nb 模型,但是得到的代码不是使用的 vip_lite 库,所以不知道是不是也意味着 vip_lite 库被废弃了还是怎么回事。

请过询问,只是转换工具不支持导出 viplite 模板工程了,实际上板子上还是要用 viplite 跑的, 用 nbg-unify 生成的 nb 格式模型文件可以直接用 viplite 运行。

模型在板子运行

使用 SDK 里面的 yolov3 例程,好不容易把 tina-sdk 编译过了,运行时(vip_create_network)报错VIP_ERROR_NETWORK_INCOMPATIBLE,即版本不兼容,nb模型来自 NPU 扩展包, 只不过代码直接编译了 tina-sdk 中的yolov3 demo,估计两个的vip-lite 库版本不兼容

感觉在版本管理和发布同步上面做得相当糟糕。。。本来芯原的 NPU ip 以及工具链感觉貌似都还做得挺不错的,可惜经了二道手之后文档和版本管理发布就挺糟糕的,很浪费时间,而且不熟悉tina-sdk的话光是编译就会让你很难受,如果不是公司需要一点都不想继续弄了

所以没办法,继续弄, 因为很明显是版本问题,tina-sdk(0.8) 提供的库版本太低了,而提供了一个 NPU 扩展包,所以我们争取所有的文件都来自这里面:

  • 将 NPU 扩展包 中的 viplite-driver 和 vpm_run 拷贝到 packages/allwinner中,执行make menuconfig发现发错,并不能直接使用hhhh,真牛,看了下是因为 makefile 用的变量问题(可能是那个open-tina 版本用的包?懒得看心累累),稍微按照tina-sdk中的yolov3例程中的makefile改改理论就可以编译过了,实际又报错了,工具链路径又没识别对,,,,算了,心累累,不太熟悉tina,不想用 tina-sdk 编译了。。
  • 用我自己的c_cpp_project_framework这个工程, 将 NPU扩展包中的viplite-driver中的头文件和 so 文件拷贝到 工程里, 然后把vmp_run的代码拷贝到main.c,然后需要设置下工具链需要的STAGING_DIR变量为tina-sdkout目录下的staging_dir/target/
  1. export STAGING_DIR=/home/neucrack/data/v85x/data/tina-v853/out/v853-perf1/staging_dir/target/

然后删除 components 目录下所有或者只删除components3, 然后修改 demo1Cmakelist.txt

  1. list(APPEND ADD_INCLUDE "include")
  2. list(APPEND ADD_PRIVATE_INCLUDE "")
  3. append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
  4. list(APPEND ADD_DYNAMIC_LIB "libs/libVIPlite.so"
  5. "libs/libVIPuser.so"
  6. )
  7. register_component()

然后编译

  1. python project.py distclean
  2. python project.py --toolchain /home/neucrack/data/v85x/data/tina-v853/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-musl/toolchain/bin --toolchain-prefix arm-openwrt-linux- config
  3. python project.py build

编译后在build目录得到可执行文件,adb push到板子,还需要个txt文件用来描述模型路径和输入以及期望的输出

  1. vpm_run is a framework for testing VIPLite driver.
  2. #You may put comment by starting with a '#'.
  3. #####################################################A separator makes the list clear.
  4. [network]
  5. resnet18.nb
  6. [input]
  7. input_0.dat
  8. [golden]
  9. output0_1000_1.dat
  10. [output]
  11. resnet18_output_tensor.dat

input_0.datoutput0_1000_1.dat是 int8 输入和输出,这两个文件可以在 IDE 仿真时生成,然后执行即可看到模型运行时间,以及结果对比等信息,到此算是成功运行起来了,主要的问题还是卡在运行时版本以及 tina-sdk 的使用上

NPU 性能和效率

V853 宣称是 1TOPS 算力, 大致跑了几个常见的简单模型, resnet18 resnet50 mobilenetv2 yolov5s,时间分别为13.4ms 39.3ms 6.4ms 62.3ms, 和 CR182x 的 0.5TOPS 算力几乎时间一样, AX620A 的 1.8TOPS 算力运行时间差不多就是它的 1.4~1.9倍,好像看起来 AX620A和V853在这几个模型上的实际算力和标的倒是挺统一口径的hhhhh, 这样一看 CR182x 就宣传得比较实诚了哈哈哈

文章有误?有想法想讨论?查看或者发起勘误/讨论 主题
(发起评论需要先登录 github)

/wallpaper/wallhaven-rdyewm.jpg