- 作者:
- 分类:知识&开发->AI->edge_AI
- 阅读:1431
- 点赞:6
- 版权:CC BY-SA 4.0
- 创建:2022-07-19
- 更新:2022-07-29
原文链接(持续更新):https://neucrack.com/p/441
资料
全志在线: 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 足够# for v853
ACUITY_TOOLS_METHOD=acuity-toolkit-binary
export ACUITY_PATH=/home/neucrack/VeriSilicon/$ACUITY_TOOLS_METHOD/bin/
export VIV_SDK=/home/neucrack/VeriSilicon/VivanteIDE5.7.0/cmdtools/
export PATH=$PATH:/home/neucrack/VeriSilicon/$ACUITY_TOOLS_METHOD/bin/:/home/neucrack/VeriSilicon/VivanteIDE5.7.0/ide/
export pegasus=/home/neucrack/VeriSilicon/$ACUITY_TOOLS_METHOD/bin/pegasus
alias pegasus=/home/neucrack/VeriSilicon/$ACUITY_TOOLS_METHOD/bin/pegasus
编译 SDK 和 demo 测试
编译: https://v853.docs.aw-ol.com/study/study_4compile/
需要注意: 必须使用 ubuntu, 其它发行版比如 manjaro,可能无法编译通过! 不然可能编译会遇到各种奇怪错误
/bin/bash
source build/envsetup.sh
lunch
make -j$
编译demo
先make menuconfig
使能Allwinner/yolov3
然后
make packages/allwinner/yolov3/compile
make packages/allwinner/yolov3/clean
或者
cd packages/allwinner/yolov3/src
make
然后把out/v853-perf1/compile_dir/target/yolov3
下的 yolov3
和sdk
目录拷贝到板子, 将sdk/drivers
下面的 so
复制到/usr/lib
目录,同时将yolov3_model.nb
也拷贝到板子(使用adb push
命令传文件)
但是实际跑的时候出错了
root@TinaLinux:/mnt/UDISK# ./yolov3 yolov3_model.nb horses_416x416.jpg
Usage:
nbg_name input_data1 input_data2...
[0xb6f1d560]gcvip_create_network[3769], binary target=0xEE, actually target=0x0
[0xb6f1d560]gcvip_create_network[4002], fail to create network
[0xb6f1d560]gcvip_create_network_from_file[4022], fail to create network
[0xb6f1d560]vip_create_network[752], failed to create network status=-10
Error: main.c: vnn_CreateNeuralNetwork at 117
Error: main.c: main at 233
[0xb6f1d560]vip_finish_network[1199], network object is NULL
Error: vnn_post_process.c: destroy_network at 168
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/ ) :
按照页面代码或
import torch
model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet18', pretrained=True)
# or any of these variants
# model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet34', pretrained=True)
# model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', pretrained=True)
# model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet101', pretrained=True)
# model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet152', pretrained=True)
model.eval()
inputs = torch.randn(1, 3, 224, 224, device="cuda")
torch.onnx.export(model, inputs, "resnet18.onnx", export_params=True, opset_version=13, input_names=["input0"], output_names=["output0"])
然后对 onnx 进行简化
python -m onnxsim resnet18.onnx resnet18.onnx
先创建 dataset.txt, 指定图片路径, 一行一个
./data/1.JPEG
./data/2.JPEG
./data/3.JPEG
./data/4.JPEG
./data/5.JPEG
./data/6.JPEG
./data/7.JPEG
./data/8.JPEG
./data/9.JPEG
./data/10.JPEG
./data/11.JPEG
导入模型
pegasus import onnx --model resnet18.onnx --output-model resnet18.json --output-data resnet18.data
pegasus generate inputmeta --model resnet18.json --input-meta-output resnet18-inputmeta.yml
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 转换脚本,就不用这个命令了,自己写预处理(推荐)
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
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
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
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-sdk
的out
目录下的staging_dir/target/
export STAGING_DIR=/home/neucrack/data/v85x/data/tina-v853/out/v853-perf1/staging_dir/target/
然后删除 components
目录下所有或者只删除components3
, 然后修改 demo1
的Cmakelist.txt
list(APPEND ADD_INCLUDE "include")
list(APPEND ADD_PRIVATE_INCLUDE "")
append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
list(APPEND ADD_DYNAMIC_LIB "libs/libVIPlite.so"
"libs/libVIPuser.so"
)
register_component()
然后编译
python project.py distclean
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
python project.py build
编译后在build
目录得到可执行文件,adb push
到板子,还需要个txt
文件用来描述模型路径和输入以及期望的输出
vpm_run is a framework for testing VIPLite driver.
#You may put comment by starting with a '#'.
#####################################################A separator makes the list clear.
[network]
resnet18.nb
[input]
input_0.dat
[golden]
output0_1000_1.dat
[output]
resnet18_output_tensor.dat
input_0.dat
和output0_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 就宣传得比较实诚了哈哈哈