啊抱歉,上周得了一周的流感,人才活过来。。本来还想研究下sam它是怎么部署的,但是时间好像有点来不急,就讲个最简单的efficientNet吧。但是会仔细讲下使用模型部署,实际也就是推理引擎的全过程,以及pulsar2作为推理引擎的一些细节。
可以将模型部署细分为以下几个步骤,其实就是和用onnxruntime\openvino\tensorRT这些部署步骤是一样的,只不过主角这次换成了pulsar2:
1、先在服务器上训练好网络模型,并以一个通用的中间形式导出(通常是onnx)
2、根据你要使用的推理引擎进行离线转换,把onnx转换成你的推理引擎能部署的模型格式,如这里就是axmodel
3、在移动端的linux系统安装好推理引擎
4、使用推理引擎运行
下面一步步的细说,并会挑一些觉得有意思的细节说说。以一个简单的mobilenetV2为例.
这里就取了个巧,直接用torch官方库里面预训练好的模型导出来,得到onnx模型。后续还可以进一步转化为-sim.onnx文件,做了一定的简化,不过差别不大。
import torch
model = torch.hub.load('pytorch/vision:v0.10.0', 'mobilenet_v2', pretrained=True)
model.eval()
x = torch.randn(1, 3, 224, 224)
# 指定输入输出节点名称
input_names = ["input"] # 例如,将默认的"input.1"更改为"input"
output_names = ["output"] # 指定输出节点的名称
# 导出模型
torch.onnx.export(model, x, "mobilenetv2.onnx", export_params = True, verbose=True, opset_version=11,
input_names=input_names,
output_names=output_names)
一句话概括:
安装pulsar2,这里就是用docker安装,他要干的是在你的电脑上,把onnx模型转换为他能跑的模型,也就是axmodel模型
这里面的docker安装什么的具体可以参照这个网站,他们都讲得很详细,我不赘述了:
部署模型到 Maix-III(M3) 系列 AXera-Pi 开发板 - Sipeed Wiki
在docker里面,根据这个指令进行转换:
pulsar2 build --input model/mobilenetv2-sim.onnx --output_dir output --config config/mobilenet_config.js
其实就是根据config.json进行转换,可以具体看看config.json干了什么:
config.json:
{
"model_type": "ONNX",
"npu_mode": "NPU1",
"quant": {
"input_configs": [
{
"tensor_name": "input",
"calibration_dataset": "./dataset/imagenet-1k-images-rgb.tar",
"calibration_size": 256,
"calibration_mean": [103.939, 116.779, 123.68],
"calibration_std": [58.0, 58.0, 58.0]
}
],
"calibration_method": "MinMax",
"precision_analysis": false
},
"input_processors": [
{
"tensor_name": "input",
"tensor_format": "BGR",
"src_format": "BGR",
"src_dtype": "U8",
"src_layout": "NHWC",
"csc_mode": "NoCSC"
}
],
"compiler": {
"check": 0
}
}
主要两点:
1、进行了训练后量化的方式进行量化(PTQ),你要提供一个校准数据集
2、你要指定输入、输出数据tensor
这里对量化方式做一个简要的介绍,量化方式现在主要分为两种,分别是感知量化训练(QAT)、训练后量化(PTQ),其中量化后训练又分为静态和动态两种。一般来说感知量化训练效果最好,但同样算力开销不小,量化后训练中静态效果比动态好,因为动态是在推理时去估计算子的数据范围,误差较大。
这里采用的是静态的训练后量化方式,通过提供一个和训练集同分布的校准数据集,将算子的权重从FP32量化到INT8
一些细节:仔细看看axmodel量化的模型结构和onnx有什么区别,这里可以用netron网站打开:
在最开头,有一个quantize和dequantize,把输入量化,输出反量化,从float转为uint8,再在结束从uint8转为float
在转化时还会自动的进行算子的融合,最常见的就是conv+relu融合在一起(这里是relu6),conv+bn+relu融合在一起,详细远离可以看量化的白皮书论文
在板子上面的debian系统中执行如下指令:
git clone [https://github.com/AXERA-TECH/ax-samples.git](https://github.com/AXERA-TECH/ax-samples.git)
cd ax-samples
mkdir build && cd build
cmake -DBSP_MSP_DIR=/soc/ -DAXERA_TARGET_CHIP=ax650 ..
make -j6
make install
这个代码本质上就是对cmakelists.txt进行编译运行
其实就是用cmakelists.txt进行编译。真正有用的是这一句:
# src files
add_subdirectory(examples)
它编译 examples子目录下的示例代码
examples的cmakelist:其实就是把这些代码编译成可执行文件:
比如classification.cc编译成一个可执行的classification文件,就能在命令行调用了。
仔细看一下这些文件,发现这些文件通常只用了很少的代码调用了模型,大部分是用于pre_process和post_process,也就是定义了怎么调用模型,以及对模型的输出怎么处理的。
在后续如果要调用新的模型,需要自己编写代码文件,这里先简单学习一下。
浅浅记录一下运行的结果:
root@maixbox:~/Desktop/ax-samples/build/install/ax650#
./ax_classification -m mobilenetv2.axmodel -i cat.jpg
--------------------------------------
model file :
mobilenetv2.axmodel
image file : cat.jpg
img_h, img_w : 224 224
--------------------------------------
WARN,Func(__is_valid_file),NOT find file = '/etc/ax_syslog.conf'
ERROR,Func(__syslog_parma_cfg_get),NOT find = '/etc/ax_syslog.conf'
Engine creating handle is done.
Engine creating context is done.
Engine get io info is done.
Engine alloc io is done.
Engine push input is done.
--------------------------------------
topk cost time:0.07 ms
9.0340, 285
9.0340, 283
8.6931, 282
8.5227, 281
7.6704, 463
--------------------------------------
Repeat 1 times, avg time 0.57 ms, max_time 0.57 ms, min_time 0.57 ms
--------------------------------------
更多回帖