课程全程将在SOPHGO(算能)云平台上进行。
本次课程将介绍:
1. SOPHGO(算能)云平台环境搭建
2. CenterNet目标检测算法
3. 通过BMNNSDK进行CenterNet网络模型转换和量化
4. 实现算法的移植
5. 部署和测试
6. 相关链接
注意:申请开通BM1684-PCIE通用云开发空间
参考:https://cloud.sophgo.com/tpu.pdf
1.2.1 进入命令行模式,进去默认在/home/sophgo目录
1.2.2 切换成 root 权限
sudo -i
1.2.3 安装驱动
cd /home/sophgo/bmnnsdk2-bm1684_v2.7.0/scripts
./install_driver_pcie.sh
ls /dev/bm*
如果可以看到以下设备节点,表示驱动安装成功:
1.2.4 加载Docker,并初始化环境
cd /home/sophgo/
apt install unzip
unzip bmnnsdk2-bm1684-ubuntu-docker-py37.zip
cd bmnnsdk2-bm1684-ubuntu-docker-py37/
docker load -i bmnnsdk2-bm1684-ubuntu.docker
1.2.5 通过脚本创建Docker容器
cd /home/sophgo/bmnnsdk2-bm1684_v2.7.0/
# 执行脚本创建Docker容器
./docker_run_bmnnsdk.sh
# 自动进入Docker容器
# 进行环境初始化
cd scripts/
# 更新 pip
/usr/local/bin/python3 -m pip install --upgrade pip
# 安装 nntc
./install_lib.sh nntc
# 执行脚本 envsetup_pcie.sh 设置环境变量
source ./envsetup_pcie.sh
# 安装sophon包
pip3 install /workspace/lib/sail/python3/pcie/py37/sophon-2.7.0-py3-none-any.whl
1.2.6 Docker 常用命令
# 启动 Docker容器
docker start
# 查看正在运行的 Docker容器
docker ps
# 进入 Docker 容器 docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
docker exec -it
1.2.7 通过云空间文件系统拷贝代码到Docker容器中
打开云空间文件系统:
上传文件:文件会被存储在服务器的 /tmp 目录下
拷贝文件到Docker容器中:
Docker容器的workspace目录被映射到 /home/sophgo/bmnnsdk2-bm1684_v2.7.0/
cp /tmp/<待拷贝文件> /home/sophgo/bmnnsdk2-bm1684_v2.7.0/
注意:本教程后续步骤均在Docker容器中进行
论文链接:https://arxiv.org/abs/1904.07850
代码仓库链接:https://github.com/xingyizhou/CenterNet
CenterNet是在2019年论文Objects as points中提出,相比yolo,ssd,faster_rcnn依靠大量anchor的检测网络,CenterNet是一种anchor-free的目标检测网络,在速度和精度上都比较有优势,可以实现:
从Github上获取SOPHON示例项目:git clone -b 2.7.0 https://github.com/sophon-ai-algo/examples.git
3.1.1 获取主干网的预训练模型
运行如下命令下载 dlav0 作为主干网的预训练模型:
apt update
apt install curl
cd ${centernet}/data/scripts
# 下载 ctdet_coco_dlav0_1x.pth 模型文件到路径 ${centernet}/data/bulid 目录下
./download_pt.sh
3.1.2 将训练好的Pytorch模型转换为JIT模型
由于BMNNSDK中的PyTorch模型编译工具BMNETP只接受PyTorch的JIT模型(TorchScript模型),需要用户自行将训练好的Pytorch模型进行转换。
JIT(Just-In-Time)是一组编译工具,用于弥合PyTorch研究与生产之间的差距。它允许创建可以在不依赖Python解释器的情况下运行的模型,并且可以更积极地进行优化。在已有PyTorch的Python模型(基类为torch.nn.Module)的情况下,通过torch.jit.trace就可以得到JIT模型,如torch.jit.trace(python_model, torch.rand(input_shape)).save('jit_model')。BMNETP暂时不支持带有控制流操作(如if语句或循环)的JIT模型,因此不能使用torch.jit.script,而要使用torch.jit.trace,它仅跟踪和记录张量上的操作,不会记录任何控制流操作。
从Github上获取CenterNet源码:git clone https://github.com/xingyizhou/CenterNet.git
其中${centernet}/data/bulid/dlav0.py为修改CenterNet源码的dlav0.py的DLASeg类forward方法的返回值得到的。目的是为了将heatmap, wh, reg三个head的特征图concat到一起,固定bmodel输出顺序:
...
return torch.cat((ret['hm'], ret['wh'], ret['reg']), 1)
...
导出PyTorch的JIT模型(TorchScript)模型
cd ${centernet}/data/bulid
python3 export.py
# 拷贝生成的 ctdet_coco_dlav0_1x.torchscript.pt 到路径 ${centernet}/data/models 下
cp ctdet_coco_dlav0_1x.torchscript.pt ../models
# 输出:
[DEBUG]arch is: dlav0
loaded ctdet_coco_dlav0_1x.pth, epoch 140
ctdet_coco_dlav0_1x.torchscript.pt exported
BMNETP是针对pytorch的模型编译器,可以把pytorch模型直接编译成BMRuntime所需的执行指令。https://doc.sophgo.com/docs/2.7.0/docs_latest_release/nntc/html/usage/bmnetp.html
方式一(推荐):执行以下脚本,使用bmnetp编译生成FP32 BModel:
cd ${centernet}/data/scripts
./1_gen_fp32bmodel.sh
上述脚本会在${centernet}/data/models文件夹下根据ctdet_coco_dlav0_1x.torchscript.pt生成ctdet_coco_dlav0_1output_512_fp32_1batch.bmodel文件,即转换好的FP32 BModel。
方式二:通过以下命令可以实现FP32 BModel模型的直接生成(如需完成后续步骤请将生成的模型拷贝至${centernet}/data/models路径下):
python3 -m bmnetp \
--net_name=ctdet_dlav0 \
--target=BM1684 \
--opt=2 \
--cmp=true \
--enable_profile=true \
--shapes=[1,3,512,512] \
--model=${ctdet_coco_dlav0_1x.torchscript.pt所在路径} \
--outdir=${输出的文件夹路径} \
--dyn=false
不量化模型可跳过本节。
3.3.1 准备量化集
量化集使用COCO Detection 2017的验证集 我们选取其中的200张图片进行量化
通过运行脚本获得数据:
# 进行下载前确保Docker中已安装unzip
apt install unzip
# 下载图片至 ${centernet}/data/image 目录下
cd ${centernet}/data/scripts
./00_prepare.sh
3.3.2 量化生成INT8 BModel
INT8 BModel的生成需要经历中间格式UModel,即:原始模型→FP32 UModel→INT8 UModel→INT8 BModel。
执行以下命令,将依次调用以下步骤中的脚本(参考3.3.3 - 3.3.6),生成INT8 BModel:
./2_gen_int8bmodel.sh
# 转换成功后,模型位于../models/ctdet_coco_dlav0_1output_512_int8_4batch.bmodel
3.3.3 生成LMDB
需要将原始量化数据集转换成lmdb格式,供后续校准量化工具Quantization-tools 使用。更详细信息请参考:[准备LMDB数据集](https://doc.sophgo.com/docs/docs_latest_release/calibration-tools/html/module/chapter4.html#lmdb)。
在docker开发容器中使用ufw.io 工具从数据集图片生成LMDB文件,具体操作参见convert_imageset.py, 相关操作已被封装在 scripts/20_create_lmdb.sh中,执行如下命令即可:
./20_create_lmdb.sh
上述脚本会在${centernet}/data/images/中生成data.mdb的文件
请注意根据模型输入要求修改脚本中convert_imageset命令中的resize_width和resize_height等参数。
3.3.4 生成FP32 UModel
执行以下命令,使用ufw.pt_to_umodel生成FP32 UModel,若不指定-D参数,可以在生成prototxt文件以后修改:
./21_gen_fp32umodel.sh
上述脚本会在`${centernet}/data/build/int8model/`下生成*_bmnetp_test_fp32.prototxt、*_bmnetp.fp32umodel文件,即转换好的FP32 UModel。
3.3.5 修改FP32 UModel
执行以下命令,修改FP32 UModel的prototxt文件即ctdet_coco_dlav0_1x.torchscript_bmnetp_test_fp32.prototxt,将输入层替换为Data层指向LMDB文件位置(若上一步已经指定-D参数,则无需操作),并使用transform_op完成需要进行的预处理;对于CenterNet来说,需要设置scale;如果transform_op无法完成要求的预处理,那么可以使用Python程序来生成LMDB文件:
./22_modify_fp32umodel.sh
3.3.6 生成INT8 UModel
执行以下命令,使用修改后的FP32 UModel文件生成INT8 UModel:
./23_gen_int8umodel.sh
上述脚本会在${centernet}/data/build/int8model/下生成*_bmnetp_deploy_fp32_unique_top.prototxt、*_bmnetp_deploy_int8_unique_top.prototxt和*_bmnetp.int8umodel文件,即转换好的INT8 UModel。
命令:bm_model.bin --info xxxx.bmodel
cd ${centernet}/data/models
# 查看模型信息
bm_model.bin --info ctdet_coco_dlav0_1output_512_fp32_1batch.bmodel
# 得到以下输出
bmodel version: B.2.2
chip: BM1684
create time: Mon Sep 5 06:49:03 2022
==========================================
net 0: [ctdet_dlav0] static
------------
stage 0:
input: input.1, [1, 3, 512, 512], float32, scale: 1
# 其中第二维是84,concat了热力图、宽高、偏移输出
output: 40, [1, 84, 128, 128], float32, scale: 1
device mem size: 113864072 (coeff: 72048648, instruct: 134528, runtime: 41680896)
host mem size: 0 (coeff: 0, runtime: 0)
cd ${centernet}/data/models
# 查看模型信息
bm_model.bin --info ctdet_coco_dlav0_1output_512_int8_4batch.bmodel
# 得到以下输出
bmodel version: B.2.2
chip: BM1684
create time: Tue Sep 6 01:55:48 2022
==========================================
net 0: [ctdet_coco_dlav0_1x.torchscript_bmnetp] static
------------
stage 0:
input: input.1, [4, 3, 512, 512], int8, scale: 71.5776
output: 40, [4, 84, 128, 128], float32, scale: 1
device mem size: 89838272 (coeff: 30114112, instruct: 180608, runtime: 59543552)
host mem size: 0 (coeff: 0, runtime: 0)
目录路径:${centernet}/py_bmcv_sail
目录路径:${centernet}/cpp_bmcv_sail
Python代码无需编译,可以直接运行
由于python例程需要用到sail库:
# 在容器里, 以python3.7的docker为例
cd /workspace/lib/sail/python3/pcie/py37
pip3 install sophon-2.7.0-py3-none-any.whl
注:在Docker容器中注意环境变量的设置(参考1.2.5设置环境变量)
cd ${centernet}/py_bmcv_sail
# 1batch
python3 det_centernet_bmcv_sail_1b_4b.py --bmodel=../data/models/ctdet_coco_dlav0_1output_512_fp32_1batch.bmodel --input=../data/ctdet_test.jpg
# 执行完毕后,在当前目录生成ctdet_result_20xx-xx-xx-xx-xx-xx_b_x.jpg格式的图片
# 图片上检测出11个目标
# 4batch
python3 det_centernet_bmcv_sail_1b_4b.py --bmodel=../data/models/ctdet_coco_dlav0_1output_512_int8_4batch.bmodel --input=../data/ctdet_test.jpg
# 执行完毕后,在当前目录生成ctdet_result_20xx-xx-xx-xx-xx-xx_b_x.jpg格式的图片
# 按照量化结果差异,图片上检测出11-13个目标,均属正常范围
5.2.1 编译
$ cd ${centernet}/cpp_bmcv_sail
# 先手动修改Makefile.pcie里的top_dir地址,指向实际SDK的根路径
# docker容器中,默认为/workspace
$ make -f Makefile.pcie # 生成centernet_bmcv_sail.pcie
5.2.2 运行测试C++程序
# 1batch
$ ./centernet_bmcv_sail.pcie --bmodel=../data/models/ctdet_coco_dlav0_1output_512_fp32_1batch.bmodel --image=../data/ctdet_test.jpg
# 执行完毕后,在当前目录生成ctdet_result_20xx-xx-xx-xx-xx-xx.jpg格式的图片
# 图片上检测出11个目标
# 4batch
$ ./centernet_bmcv_sail.pcie --bmodel=../data/models/ctdet_coco_dlav0_1output_512_int8_4batch.bmodel --image=../data/ctdet_test.jpg
# 执行完毕后,在当前目录生成ctdet_result_20xx-xx-xx-xx-xx-xx-bx.jpg格式的图片
# 按照量化结果差异,图片上检测出11-12个目标,均属正常范围
*注意:由于是在Docker容器中,如果想要看到推理的可视化结果需要退出容器,并打开Docker容器映射的文件夹,在对应位置将图片拷贝到 /tmp 文件夹下后可在云平台文件系统中下载。
# 退出容器
exit
# 进入Docker容器映射的文件夹,即Docker容器中的 workspace/目录
cd /home/sophgo/bmnnsdk2-bm1684_v2.7.0/
# 打开centernet项目, ${centernet}即项目所在路径
# 以python测试结果为例
cd ${centernet}/py_bmcv_sail
# 拷贝需要的推理结果图片
cp ctdet_result_20xx-xx-xx-xx-xx-xx_b_x.jpg /tmp/
云空间文件系统:
样例开源仓库:https://github.com/sophon-ai-algo/examples
BM1684 BMNNSDK文档:https://developer.sophgo.com/site/index/document/6/all.html
编译工具用户开发手册: https://doc.sophgo.com/docs/2.7.0/docs_latest_release/nntc/html/index.html
量化工具用户开发手册: https://doc.sophgo.com/docs/2.7.0/docs_latest_release/calibration-tools/html/index.html
算能量化工具介绍及使用说明:https://www.bilibili.com/video/BV1DA4y1S75p?spm_id_from=333.999.0.0
官网视频教程:https://developer.sophgo.com/site/index/course/all/all.html
官网文档中心:https://developer.sophgo.com/site/index/document/all/all.html
官网下载中心:https://developer.sophgo.com/site/index/material/all/all.html
官网论坛:https://developer.sophgo.com/forum/view/43.html