以目标检测算法YOLOX为例,记录模型从权重文件转换为ONNX,再使用TIDL(Importer/Tools)编译为可执行文件,最后于SK板运行及评估的开发流程。
接上一篇:TDA4②:环境搭建、模型转换、Demo及Tools
下一篇:TDA4④:部署自定义深度学习模型
YOLOX部署TDA4VM-SK流程
TI官方在 ModelZOO 中提供了一系列预训练模型可以直接拿来转换,也提供了 edgeai-YOLOv5 与 edgeai-YOLOX 等优化的开源项目,可以直接下载提供的YOLOX_s的 onnx文件 和 prototxt文件 ,也可以在官方项目上训练自己的模型后再导入。
这里尝试跑通全流程,在 edgeai-YOLOX 项目中训练,得到 .pth
权重文件,使用 export_onnx.py 文件转换为 .onnx
模型文件和 .prototxt
架构配置文件,并导入TIDL,得到部署用的 .bin
文件。
主要参考 edgeai-YOLOX文档 以及 YOLOX模型训练结果导入及平台移植应用
1. 使用edgeai-yolox训练模型
目标检测文档:edgeai-yolox-2d_od
修改后源码见:Arrowes/DMS-YOLOv8/tree/main/TI/edgeai-yolox
1 | git clone https://github.com/TexasInstruments/edgeai-yolox.git |
2. 模型文件转ONNX
ONNX(Open Neural Network Exchange)是用于在各种深度学习训练和推理框架转 换的一个中间表示格式。ONNX 定义了一组和环境,平台均无关的标准格式,来增强各种 AI 模型的可交互性,开放性较强。 TIDL 对 ONNX 模型有很好的支持,因此,将训练得到的pth模型文件转换为onnx文件,并利用tidl importer实现模型的编译与量化,具体步骤如下:
pycharm进入edgeai-yolox项目,根据提示额外安装requirements
Window中配置该环境需要安装visual studio build tools,而且很多包报错,因此转ubuntu用vscode搭pytorch环境,非常顺利(vscode插件离线安装:如装python插件,直接进 marketplace 下好拖到扩展位置)拓展设置中把Python Default Path改成创建的环境 /home/wyj/anaconda3/envs/pytorch/bin/python
,最后用vscode打开项目,F5运行py程序,将.pth转为 .onnx, .prototxt
文件。
1 | pip3 install -U pip && pip3 install -r requirements.txt |
yolox_s_ti_lite.prototxt
1 | name: "yolox" |
1 | cd <YOLOX_HOME> |
3. 模型转换
对于模型转换,硬件不同,使用的工具也不同:
- EVM:使用TIDL Importer,这是RTOS SDK中提供的工具,有很多例程(SDK8.6中例程文件缺失,copy 8.5的),见a.
- SK板:使用TIDL Tools(Edge AI Studio/Edge AI Tools),见edgeai-tidl-tools,灵活度高,不支持的算子分配到ARM核,支持的会使用TIDL加速运行,增加了深度学习模型开发和运行的效率。但要求平台有onnx运行环境, 适用于SK板, 见b/c.
a. 使用TIDL Importer (in RTOS SDK)
- 模型文件配置:拷贝 .onnx, .prototxt 文件至/ti_dl/test/testvecs/models/public/onnx/,yolox_s_ti_lite.prototxt中改in_width&height,根据情况改nms_threshold: 0.4,confidence_threshold: 0.4
- 编写转换配置文件:在/testvecs/config/import/public/onnx下新建(或复制参考目录下yolov3例程)tidl_import_yolox_s.txt,参数配置见文档, 元架构类型见 Object detection meta architectures,
inData
处修改自定义的数据输入
转换配置文件tidl_import_yolox_s.txt
1 | modelType = 2 #模型类型,0: Caffe, 1: TensorFlow, 2: ONNX, 3: tfLite |
模型导入
使用TIDL import tool,得到可执行文件.bin
1
2
3
4
5
6
7
8
9
10
11
12cd ${TIDL_INSTALL_PATH}/ti_dl/utils/tidlModelImport
./out/tidl_model_import.out ${TIDL_INSTALL_PATH}/ti_dl/test/testvecs/config/import/public/onnx/tidl_import_yolox.txt
#successful Memory allocation
#../../test/testvecs/config/tidl_models/onnx/生成的文件分析:
tidl_net_yolox_s.bin #Compiled network file 网络模型数据
tidl_io_yolox_s_1.bin #Compiled I/O file 网络输入配置文件
tidl_net_yolox_s.bin.svg #tidlModelGraphviz tool生成的网络图
tidl_out.png, tidl_out.txt #执行的目标检测测试结果,与第三步TIDL运行效果一致 txt:[class, source, confidence, Lower left point(x,y), upper right point(x,y) ]
#Debug,本来使用官方的yolox_s.pth转成onnx后导入,发现报错:
Step != 1 is NOT supported for Slice Operator -- /backbone/backbone/stem/Slice_3
#因为"the slice operations in Focus layer are not embedded friendly",因此ti提供yolox-s-ti-lite,优化后的才能直接导入TIDL运行(PC inference)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#在文件ti_dl/test/testvecs/config/config_list.txt顶部加入:
1 testvecs/config/infer/public/onnx/tidl_infer_yolox.txt
0
#新建tidl_infer_yolox.txt:
inFileFormat = 2
numFrames = 1
netBinFile = "testvecs/config/tidl_models/onnx/yolo/tidl_net_yolox_s.bin"
ioConfigFile = "testvecs/config/tidl_models/onnx/yolo/tidl_io_yolox_s_1.bin"
inData = testvecs/config/detection_list.txt
outData = testvecs/output/tidl_yolox_od.bin
inResizeMode = 0
debugTraceLevel = 0
writeTraceLevel = 0
postProcType = 2
#运行,结果在ti_dl/test/testvecs/output/
cd ${TIDL_INSTALL_PATH}/ti_dl/test
./PC_dsp_test_dl_algo.out
b. 使用Edge AI Studio
参考他人实例:YOLOX-Yoga
使用Edge AI Studio > Model Analyzer > Custom models > ONNX runtime > custom-model-onnx.ipynb
例程, 并结合 OD.ipynb
例程进行修改
YOLOX.ipynb
1 | import os |
其中scripts.utils中的代码细节在/notebooks/scripts/utils.py
1 | #预处理 |
图片的预处理十分重要,调试时注意print图片数据,避免处理出错
1 | #配置 |
object_detection:meta_arch_type、meta_layers_names_list两个参数在OD任务中必须配置,否则内核直接奔溃,参数配置文档中也有说明:object-detection-model-specific-options
1 | #模型转换 |
打印输入输出信息,运行编译
1 | #画框 |
画框,引入了缩放比例,否则框的位置不对
1 | #Subgraphs visualization |
生成两个.svg网络可视化图的链接
1 | #模型推理 |
推理,注意TIDLCompilationProvider
和TIDLExecutionProvider
的区别
Statistics :
Inferences Per Second : 104.44 fps
Inference Time Per Image : 9.57 ms
DDR BW Per Image : 16.22 MB
Debug:
- 将custom-model-onnx 替换为自己的模型后报错,且内核经常挂掉,这不是服务器的问题,而是代码中有错误引发 Jupyter 中的某种内存分配问题并kill内核.(如,索引路径错误,模型不存在,config参数配置错误)—— E2E:Kills Kernel in Edge AI Studio
- 在My Workspace中, 右上角
New > Terminal
可以打开终端,便于进一步的调试 - prebuilt-models中的预训练模型每次重启EVM都要先重新解压:
cd notebooks/prebuilt-models/8bits/
find . -name "*.tar.gz" -exec tar --one-top-level -zxvf "{}" \;
- 内核频繁挂掉:重启EVM
c. 使用EdgeAI-TIDL-Tools
此处仅简单介绍YOLOX的最简部署流程,详见:TDA4VM4_EdgeAI-TIDL-Tools
TI部署相关修改代码:DMS-YOLOv8: TI
EdgeAI-TIDL-Tools版本:08_06_00_05
1 | #运行训练: |
4. 板端运行(TDA4VM-SK)
SK板环境搭建见:TDA4VM2_TDA4VM-SK-配置
注意SK的镜像版本需要与EdgeAI-TIDL-Tools版本一致,此处均为08_06_00_05
连接SK板进入minicom串口通讯传输模型文件(失败)(若能连网线通过jupyternotebook配置更方便,这里网络有限制所以配置都通过SD卡进行)
通过SD卡配置编译生成的模型,配置模型文件夹yolox放入modelzoo文件夹:
1 | model_zoo/yolox/ |
通过SD卡配置object_detection.yaml,在model参数中索引上面建立的模型文件夹
1 | #通过minicom连接串口 |
修改app_edgeai(optional)
在opt\edgeai-gst-apps\apps_cpp\
完成修改后重新make:
1 | #Regular builds (Build_Instructions.txt) |
5. 性能评估
Docs: Performance Visualization Tool
运行实例时,会在运行文件的上一级../perf_Logs/
中生成 .md
格式的Performance Logs,最多15个,运行时会不断覆写
也可以使用Perfstats tool, 把运行状态在terminal print:
1 | #构建工具 |
此外,使用官方提供的可视化工具Visualization tool是最佳选择,但是要装Docker
Performance Logs
Summary of CPU load
CPU | TOTAL LOAD % |
---|---|
mpu1_0 | 40.83 |
mcu2_0 | 7. 0 |
mcu2_1 | 1. 0 |
c6x_1 | 0. 0 |
c6x_2 | 1. 0 |
c7x_1 | 32. 0 |
HWA performance statistics
HWA(Hardware Accelerator) | LOAD(Million Operations per second) |
---|---|
MSC0(Multiply and Accumulate) | 6.94 % ( 42 MP/s ) |
MSC1 | 6.74 % ( 55 MP/s ) |
DDR performance statistics
DDR BW | AVG | PEAK |
---|---|---|
READ BW | 1509 MB/s | 5713 MB/s |
WRITE BW | 721 MB/s | 3643 MB/s |
TOTAL BW | 2230 MB/s | 9356 MB/s |
Detailed CPU performance/memory statistics
CPU: mcu2_0
TASK | TASK LOAD |
---|---|
IPC_RX | 0.34 % |
REMOTE_SRV | 0.30 % |
LOAD_TEST | 0. 0 % |
TIVX_CPU_0 | 0. 0 % |
TIVX_V1NF | 0. 0 % |
TIVX_V1LDC1 | 0. 0 % |
TIVX_V1SC1 | 3. 9 % |
TIVX_V1MSC2 | 3.24 % |
TIVXVVISS1 | 0. 0 % |
TIVX_CAPT1 | 0. 0 % |
TIVX_CAPT2 | 0. 0 % |
TIVX_DISP1 | 0. 0 % |
TIVX_DISP2 | 0. 0 % |
TIVX_CSITX | 0. 0 % |
TIVX_CAPT3 | 0. 0 % |
TIVX_CAPT4 | 0. 0 % |
TIVX_CAPT5 | 0. 0 % |
TIVX_CAPT6 | 0. 0 % |
TIVX_CAPT7 | 0. 0 % |
TIVX_CAPT8 | 0. 0 % |
TIVX_DPM2M1 | 0. 0 % |
TIVX_DPM2M2 | 0. 0 % |
TIVX_DPM2M3 | 0. 0 % |
TIVX_DPM2M4 | 0. 0 % |
CPU Heap Table
HEAP | Size | Free | Unused |
---|---|---|---|
DDR_LOCAL_MEM | 16777216 B | 16768256 B | 99 % |
L3_MEM | 262144 B | 261888 B | 99 % |
CPU: mcu2_1
CPU: mcu2_1
TASK | TASK LOAD |
---|---|
IPC_RX | 0. 0 % |
REMOTE_SRV | 0.18 % |
LOAD_TEST | 0. 0 % |
TIVX_CPU_1 | 0. 0 % |
TIVX_SDE | 0. 0 % |
TIVX_DOF | 0. 0 % |
IPC_TEST_RX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
CPU Heap Table
HEAP | Size | Free | Unused |
---|---|---|---|
DDR_LOCAL_MEM | 16777216 B | 16773376 B | 99 % |
L3_MEM | 262144 B | 262144 B | 100 % |
CPU: c6x_1
CPU: c6x_1
TASK | TASK LOAD |
---|---|
IPC_RX | 0. 0 % |
REMOTE_SRV | 0. 0 % |
LOAD_TEST | 0. 0 % |
TIVX_CPU | 0. 0 % |
IPC_TEST_RX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
CPU Heap Table
HEAP | Size | Free | Unused |
---|---|---|---|
DDR_LOCAL_MEM | 16777216 B | 16773376 B | 99 % |
L2_MEM | 229376 B | 229376 B | 100 % |
DDR_SCRATCH_MEM | 50331648 B | 50331648 B | 100 % |
CPU: c6x_2
CPU: c6x_2
TASK | TASK LOAD |
---|---|
IPC_RX | 0. 0 % |
REMOTE_SRV | 0. 0 % |
LOAD_TEST | 0. 0 % |
TIVX_CPU | 0. 0 % |
IPC_TEST_RX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
CPU Heap Table
HEAP | Size | Free | Unused |
---|---|---|---|
DDR_LOCAL_MEM | 16777216 B | 16773376 B | 99 % |
L2_MEM | 229376 B | 229376 B | 100 % |
DDR_SCRATCH_MEM | 50331648 B | 50331648 B | 100 % |
CPU: c7x_1
TASK | TASK LOAD |
---|---|
IPC_RX | 0. 5 % |
REMOTE_SRV | 0. 1 % |
LOAD_TEST | 0. 0 % |
TIVX_C71_P1 | 31.38 % |
TIVX_C71_P2 | 0. 0 % |
TIVX_C71_P3 | 0. 0 % |
TIVX_C71_P4 | 0. 0 % |
TIVX_C71_P5 | 0. 0 % |
TIVX_C71_P6 | 0. 0 % |
TIVX_C71_P7 | 0. 0 % |
TIVX_C71_P8 | 0. 0 % |
IPC_TEST_RX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
IPC_TEST_TX | 0. 0 % |
CPU Heap Table
HEAP | Size | Free | Unused |
---|---|---|---|
DDR_LOCAL_MEM | 268435456 B | 232984320 B | 86 % |
L3_MEM | 8159232 B | 0 B | 0 % |
L2_MEM | 458752 B | 458752 B | 100 % |
L1_MEM | 16384 B | 0 B | 0 % |
DDR_SCRATCH_MEM | 385875968 B | 367400145 B | 95 % |
Performance point statistics
Performance
PERF | avg (usecs) | min/max (usecs) | number of executions |
---|---|---|---|
33352 | 0 / 412578 | 9556 |
FPS
PERF | Frames per sec (FPS) |
---|---|
29.98 |
Temperature statistics
ZONE | TEMPERATURE |
---|---|
CPU | 50.93 Celsius |
WKUP | 49.52 Celsius |
C7X | 51.86 Celsius |
GPU | 51.63 Celsius |
R5F | 50.93 Celsius |
TDA4系列文章:
TDA4①:SDK, TIDL, OpenVX
TDA4②:环境搭建、模型转换、Demo及Tools
TDA4③:YOLOX的模型转换与SK板端运行
TDA4④:部署自定义模型