# OpenPose 部署示例

该示例来自 [pytorch-openpose](https://github.com/Hzzone/pytorch-openpose) 项目, 权重使用的是 [body_pose_model.pth](https://www.dropbox.com/scl/fo/kuq364n2mz721u7nlwy0a/ACC5RMZv8Qp8IV_0M9YVCX4?rlkey=pbkgp7zmp7384v98z6smc76d3&e=1&dl=0)。

整体步骤如下：

1. 把 ONNX 模型转换成 SG-IR(以下简称 sg 文件)，用于后续步骤的量化和编译。
2. 准备量化校准数据集，使用 rbcc 量化 sg 得到量化后的 sg。
3. 使用 rbcc 对量化后的 sg 进行编译，生成可在 CAISA 芯片上执行的 rbo 文件。
4. 对 rbo 进行性能测试和精度测试。

**目录**

- [OpenPose 部署示例](#openpose-部署示例)
  - [0. 模型与数据集下载](#0-模型与数据集下载)
  - [1. 模型转换](#1-模型转换)
  - [2. 模型量化](#2-模型量化)
  - [3. 模型编译](#3-模型编译)
  - [4. 模型测试](#4-模型测试)
    - [4.1 精度测试](#41-精度测试)
    - [4.2 性能测试](#42-性能测试)

## 0. 模型与数据集下载

为了快速体验 CAISA 430 芯片，我们预先提供了预编译好的 sg、onnx 和 rbo 文件，您可选择快速从任一步骤开始。

1. [量化校准数据集](https://modelzoo.oss-cn-shenzhen.aliyuncs.com/COCO2017_Quantization_256.zip)
2. [测试数据集](https://modelzoo.oss-cn-shenzhen.aliyuncs.com/COCO2017.zip)
3. [测试标签数据](https://modelzoo.oss-cn-shenzhen.aliyuncs.com/datasets/openpose_val_data.zip)
4. [onnx 模型](https://modelzoo.oss-cn-shenzhen.aliyuncs.com/onnxs/openpose.onnx)
5. [量化后的 sg](https://modelzoo.oss-cn-shenzhen.aliyuncs.com/sgs/openpose_8bit.sg)
6. [rbo](https://modelzoo.oss-cn-shenzhen.aliyuncs.com/rbos/openpose.rbo)

## 1. 模型转换

导出 onnx 模型：

```shell
$ mkdir outputs
$ git clone https://github.com/Hzzone/pytorch-openpose
$ cd pytorch-openpose
$ # 请按项目要求安装好上述项目，并提前下载好权重文件 (body_pose_model.pth) 到当前目录下。
$ cp ../export_onnx.py ./
$ python export_onnx.py ./body_pose_model.pth ../outputs/openpose.onnx
$ cd ..
```

把 onnx 模型转换成 sg：

```shell
$ rbcc parse --onnx outputs/openpose.onnx --sg outputs/openpose.sg 
The version of rbcc installed is 1.2.0
2025-04-28 12:35:06 - RBCC - INFO - Start parse 'outputs/openpose.onnx' onnx model.
2025-04-28 12:35:11 - RBCC - INFO - ONNX model parsed successfully.
2025-04-28 12:35:11 - RBCC - INFO - Model's input  0: name=input_1, shape=[1, 224, 224, 3], dtype=float32.
2025-04-28 12:35:11 - RBCC - INFO - Model's output 0: name=351, shape=[1, 28, 28, 38], dtype=float32.
2025-04-28 12:35:11 - RBCC - INFO - Model's output 1: name=365, shape=[1, 28, 28, 19], dtype=float32.
SG IR saved in outputs/openpose.sg
```

> 注：rbcc parse 命令行默认会对输入 [Batch, Channel, Height, Width] 转换成 [Batch, Height, Width, Channel] 格式。

## 2. 模型量化

在量化操作之前，我们需要从训练数据集中选择 256 个样本，作为量化校准数据集。在进行量化前请先在[模型与数据集下载](#0-模型与数据集下载)中下载量化校准数据集。

对数据集 `COCO2017_Quantization_256.zip` 和解压，然后对 sg 进行量化：

```shell
$ python quantize_sg.py outputs/openpose.sg ./COCO2017_Quantization_256
Quantize Calibration - Histogram: 256sample [00:04, 2.56sample/s]
```

## 3. 模型编译

获得量化后的 sg 后，使用 `rbcc gen` 即可快速完成 rbo 编译：

```shell
$ rbcc gen --sg ./outputs/openpose_8bit.sg --rbo ./outputs/openpose.rbo
The version of rbcc installed is 1.2.0
2025-04-28 14:07:34 - RBCC - INFO - Start loading './outputs/openpose_8bit.sg'.
2025-04-28 14:07:34 - RBCC - INFO - Loading sg end.
2025-04-28 14:07:34 - RBCC - INFO - Start compiling the model and generate rbo.
2025-04-28 14:07:42 - RBCC - INFO - Compilation is completed, rbo has been saved to './outputs/openpose.rbo'.
```

## 4. 模型测试

成功编译生成 rbo 后，我们需要在 CAISA 430 芯片上进行精度测试和性能测试。以下精度评估使用了远程调用的方式，环境准备参考 [rbo 远程调用](../rbo_exe.md)。

### 4.1 精度测试

| Model       | DataSet          |  fp32@AP      |  sg-int8@AP   | rbo-int8@AP      |
| ----------- | ---------------- | ------------- | ------------- | ---------------- |
| OpenPose    | COCO2017         |  34.7/45.3    |  35.3/45.9    | 35.3/45.9        |

该模型使用 COCO2017 和 openpose_val_data 数据集进行精度评估，请先在[模型与数据集下载](#0-模型与数据集下载)中下载测试数据集和测试标签数据，测试集结构如下：

```shell
└── COCO2017
    ├── annotations  # COCO2017 标签      
    └── val2017      # COCO2017 图像
└── openpose_val_data
    ├── val2017.txt  # 参与测试的 COCO2017 图像名称      
    └── valcoco.json # 参与测试的 COCO2017 图像标签
```

评估方式如下：

```shell
# scp rbo 到硬件设备上
$ scp outputs/openpose.rbo root@192.168.12.169:/data
python eval_acc.py /data/openpose.rbo --data ./COCO2017 --label ./openpose_val_data --device-id 0 --eval-nums 2198
```

> 评估前，确保 openpose.rbo 已经 scp 到 430 系列盒子上，并且容器是可以访问到的路径。

参数介绍：

- `--data`：COCO2017 数据集文件夹路径。
- `--label`：openpose_val_data 数据集文件夹路径。
- `--device-id`：输入为 rbo 时，表示指定 CAISA 430 芯片引擎 id，它默认有 2 个引擎，分别使用 0 和 1 表示。输入为 sg 时，表示指定 GPU 设备 id，cpu 推理请指定 -1。
- `--eval-nums`：指定数据集的大小(默认大小为 2198)。

若 rbo 精度相比原浮点模型精度下降过多，无法确定具体原因时，我们建议先测试 sg，它作为 rbo 的编译输入，它的结果也至关重要，sg 精度测试方式如下：

```shell
python eval_acc.py outputs/openpose_8bit.sg --data ./COCO2017 --label ./openpose_val_data --device-id 0 --eval-nums 2198
```

> sg 使用 Pytorch 作为运行后端，并模拟量化计算过程，故其精度和 rbo 精度会有些许区别，这属于正常现象。

### 4.2 性能测试

参考 [rbo 性能测试](../rbo_perf.md)
