docs/performance/benchmark_tools.md
当我们已经有一个 Paddle 格式的模型后,我们可以使用 Benchmark 工具对该模型进行性能测试。Benchmark 工具可以输出的性能指标包括但不限于:
Benchmark 工具的详细功能包括但不限于:
Benchmark 工具可方便快捷地评测给定模型在如下硬件上运行时的性能:
根据源码编译准备编译环境,建议使用 Docker 配置交叉编译环境。 拉取 Paddle Lite 代码,切换到特定分支,然后在 Paddle Lite 根目录下执行编译命令:
./lite/tools/build_android.sh --toolchain=clang --with_benchmark=ON full_publish
可选参数:
| 参数 | 说明 | 可选值 | 默认值 |
|---|---|---|---|
| arch | 目标 ARM 架构 | armv7hf / armv7 / armv8 | armv8 |
| toolchain | 工具链 | gcc / clang | gcc |
| with_profile | 逐层时间 profile | ON / OFF | OFF |
| with_precision_profile | 逐层精度 profile | ON / OFF | OFF |
编译完成后,会生成build.lite.*./lite/api/tools/benchmark/benchmark_bin二进制文件。
需要将如下文件通过adb上传至手机:
opt工具离线优化后的.nb文件benchmark_bin在 Host 端机器上操作例子如下:
# 获取模型文件
wget https://paddle-inference-dist.bj.bcebos.com/AI-Rank/mobile/MobileNetV1.tar.gz
tar zxvf MobileNetV1.tar.gz
# 上传文件
adb shell mkdir /data/local/tmp/benchmark
adb push MobileNetV1 /data/local/tmp/benchmark
adb push build.lite.android.armv8.clang/lite/api/tools/benchmark/benchmark_bin /data/local/tmp/benchmark
# 执行性能测试
adb shell "cd /data/local/tmp/benchmark;
./benchmark_bin \
--model_file=MobileNetV1/inference.pdmodel \
--param_file=MobileNetV1/inference.pdiparams \
--input_shape=1,3,224,224 \
--warmup=10 \
--repeats=20 \
--backend=arm"
会输出如下信息:
======= Opt Info =======
Load paddle model from inference.pdmodel and inference.pdiparams
Save optimized model to .nb
======= Device Info =======
Brand: Xiaomi
Device: cepheus
Model: MI 9
Android Version: 10
Android API Level: 29
======= Model Info =======
optimized_model_file: .nb
input_data_path:
input_shape: 1,3,224,224
output tensor num: 1
--- output tensor 0 ---
output shape(NCHW): 1 1000
output tensor 0 elem num: 1000
output tensor 0 mean value: 0.001
output tensor 0 standard deviation: 0.00219647
======= Runtime Info =======
benchmark_bin version: acf6614
threads: 1
power_mode: 0
warmup: 10
repeats: 20
result_path:
======= Backend Info =======
backend: arm
cpu precision: fp32
======= Perf Info =======
Time(unit: ms):
init = 15.305
first = 43.670
min = 32.577
max = 32.895
avg = 32.723
根据源码编译准备编译环境,建议使用 Docker 配置交叉编译环境。 拉取 Paddle Lite 代码,切换到特定分支,然后在 Paddle Lite 根目录下执行编译命令:
./lite/tools/build_linux.sh --arch=armv8 --with_benchmark=ON full_publish
可选参数:
| 参数 | 说明 | 可选值 | 默认值 |
|---|---|---|---|
| arch | 目标 ARM 架构 | armv7 / armv8 | armv8 |
| toolchain | 工具链 | gcc / clang | gcc |
| with_profile | 逐层时间 profile | ON / OFF | OFF |
| with_precision_profile | 逐层精度 profile | ON / OFF | OFF |
编译完成后,会生成build.lite.*./lite/api/tools/benchmark/benchmark_bin二进制文件。
需要将如下文件通过scp或其他方式上传至 ARM Linux 设备:
opt工具离线优化后的.nb文件benchmark_bin在 Host 端机器上操作例子如下:
# 获取模型文件
wget https://paddle-inference-dist.bj.bcebos.com/AI-Rank/mobile/MobileNetV1.tar.gz
tar zxvf MobileNetV1.tar.gz
# 上传文件到 ARM Linux 设备
然后通过ssh登录到 ARM Linux 设备,执行:
# 性能测试
cd /path/to/benchmark_bin; \
./benchmark_bin \
--model_file=MobileNetV1/inference.pdmodel \
--param_file=MobileNetV1/inference.pdiparams \
--input_shape=1,3,224,224 \
--warmup=10 \
--repeats=20 \
--backend=arm
会输出如下信息:
======= Opt Info =======
Load paddle model from inference.pdmodel and inference.pdiparams
Save optimized model to .nb
======= Model Info =======
optimized_model_file: .nb
input_data_path:
input_shape: 1,3,224,224
output tensor num: 1
--- output tensor 0 ---
output shape(NCHW): 1 1000
output tensor 0 elem num: 1000
output tensor 0 mean value: 0.001
output tensor 0 standard deviation: 0.00219647
======= Runtime Info =======
benchmark_bin version: acf6614
threads: 1
power_mode: 0
warmup: 10
repeats: 20
result_path:
======= Backend Info =======
backend: arm
cpu precision: fp32
======= Perf Info =======
Time(unit: ms):
init = 15.305
first = 43.670
min = 32.577
max = 32.895
avg = 32.723
根据源码编译准备编译环境,建议使用 Docker 配置环境。 拉取 Paddle Lite 代码,切换到特定分支,然后在 Paddle Lite 根目录下执行编译命令:
./lite/tools/build_linux.sh --arch=x86 --with_benchmark=ON full_publish
可选参数:
| 参数 | 说明 | 可选值 | 默认值 |
|---|---|---|---|
| toolchain | 工具链 | gcc / clang | gcc |
| with_profile | 逐层时间 profile | ON / OFF | OFF |
| with_precision_profile | 逐层精度 profile | ON / OFF | OFF |
编译完成后,会生成build.lite.*./lite/api/tools/benchmark/benchmark_bin二进制文件。
运行所需文件:
opt工具离线优化后的.nb文件benchmark_binlibmklml_intel.so在待测试的 Linux 机器上操作例子如下:
# 获取模型文件
wget https://paddle-inference-dist.bj.bcebos.com/AI-Rank/mobile/MobileNetV1.tar.gz
tar zxvf MobileNetV1.tar.gz
# 设置环境变量
export LD_LIBRARY_PATH=build.lite.x86.gcc/third_party/install/mklml/lib/:$LD_LIBRARY_PATH
# 执行性能测试
./build.lite.linux.x86.gcc/lite/api/tools/benchmark/benchmark_bin \
--model_file=MobileNetV1/inference.pdmodel \
--param_file=MobileNetV1/inference.pdiparams \
--input_shape=1,3,224,224 \
--warmup=10 \
--repeats=20 \
--backend=x86
会输出如下信息:
======= Opt Info =======
Load paddle model from MobileNetV1/inference.pdmodel and MobileNetV1/inference.pdiparams
Save optimized model to .nb
======= Model Info =======
optimized_model_file: .nb
input_data_path: All 1.f
input_shape: 1,3,224,224
output tensor num: 1
--- output tensor 0 ---
output shape(NCHW): 1 1000
output tensor 0 elem num: 1000
output tensor 0 mean value: 0.001
output tensor 0 standard deviation: 0.00219647
======= Runtime Info =======
benchmark_bin version: 380d8d0
threads: 1
power_mode: 0
warmup: 10
repeats: 20
result_path:
======= Backend Info =======
backend: x86
cpu precision: fp32
======= Perf Info =======
Time(unit: ms):
init = 18.135
first = 80.052
min = 31.982
max = 38.947
avg = 33.918
根据源码编译准备编译环境,可以使用 Docker 配置环境,也可以使用系统原生开发环境。 拉取 Paddle Lite 代码,切换到特定分支,然后在 Paddle Lite 根目录下执行编译命令:
# 芯片为 x86 架构时,执行:
./lite/tools/build_macos.sh --with_benchmark=ON x86
# 芯片为 ARM 架构时,执行:
./lite/tools/build_macos.sh --with_benchmark=ON arm64
可选参数:
| 参数 | 说明 | 可选值 | 默认值 |
|---|---|---|---|
| toolchain | 工具链 | gcc / clang | gcc |
| with_profile | 逐层时间 profile | ON / OFF | OFF |
| with_precision_profile | 逐层精度 profile | ON / OFF | OFF |
编译完成后,会生成build.lite.*./lite/api/tools/benchmark/benchmark_bin二进制文件。
运行所需文件:
opt工具离线优化后的.nb文件benchmark_binlibmklml.dylib在 macOS 机器上操作例子如下:
# 获取模型文件
wget https://paddle-inference-dist.bj.bcebos.com/AI-Rank/mobile/MobileNetV1.tar.gz
tar zxvf MobileNetV1.tar.gz
# 设置环境变量
export LD_LIBRARY_PATH=build.lite.x86.opencl/third_party/install/mklml/lib/:$LD_LIBRARY_PATH
# 执行性能测试
./build.lite.x86.opencl/lite/api/tools/benchmark/benchmark_bin \
--model_file=MobileNetV1/inference.pdmodel \
--param_file=MobileNetV1/inference.pdiparams \
--input_shape=1,3,224,224 \
--warmup=10 \
--repeats=20 \
--backend=x86
会输出如下信息:
======= Opt Info =======
Load paddle model from MobileNetV1/inference.pdmodel and MobileNetV1/inference.pdiparams
Save optimized model to MobileNetV1/opt.nb
======= Model Info =======
optimized_model_file: MobileNetV1/opt.nb
input_data_path: All 1.f
input_shape: 1,3,224,224
output tensor num: 1
--- output tensor 0 ---
output shape(NCHW): 1 1000
output tensor 0 elem num: 1000
output tensor 0 mean value: 0.001
output tensor 0 standard deviation: 0.00219646
======= Runtime Info =======
benchmark_bin version: 380d8d004
threads: 1
power_mode: 0
warmup: 0
repeats: 1
result_path:
======= Backend Info =======
backend: x86
cpu precision: fp32
======= Perf Info =======
Time(unit: ms):
init = 11.410
first = 53.964
min = 53.964
max = 53.964
avg = 53.964
Benchnark 工具提供了丰富的运行时选项,来满足不同的运行时参数设置。用户可以通过在目标设备上执行./benchmark_bin --help获取所有选项介绍。
--backend=arm来实现--backend=x86来实现--backend=opencl,arm来实现--backend=opencl,arm来实现, 只支持精度为fp32,需设置--gpu_precision=fp32--backend=opencl,x86来实现说明:
--opencl_cache_dir:设置 opencl cache 文件的存放路径,当显式设置该选项后,会开启 opencl kernel 预编译 和 auto-tune 功能--opencl_kernel_cache_file:设置 opencl kernel cache 文件名字--opencl_tuned_file:设置 opencl auto-tune 文件名字--opencl_tune_mode:设置 opencl auto-tune 模式比如在 Android 设备上使用 GPU 运行模型时,推荐使用:
adb shell "cd /data/local/tmp/benchmark;
./benchmark_bin \
--model_file=MobileNetV1/inference.pdmodel \
--param_file=MobileNetV1/inference.pdiparams \
--input_shape=1,3,224,224 \
--warmup=10 \
--repeats=20 \
--backend=opencl,arm \
--opencl_cache_dir=/data/local/tmp \
--opencl_kernel_cache_file=MobileNetV1_kernel.bin \
--opencl_tuned_file=MobileNetV1_tuned.bin"
在 NNAdapter 上运行模型,需配置三个重要参数:
--backend:设置模型运行时的后端,支持 NNAdapter 与 x86、ARM 组合进行异构计算--nnadapter_device_names:设置 NNAdapter 的实际新硬件后端--nnadapter_context_properties:设置新硬件硬件资源(目前仅在 Huawei Ascend NPU 上使用)编译完成后,会生成build.lite.*./lite/api/tools/benchmark/benchmark_bin二进制文件。
请参考下表编译指南,编译 NNAdapter 运行时库及 NNAdapter Device HAL 库
| No. | 新硬件名称 | Device HAL 库名称 | 编译指南 |
|---|---|---|---|
| 1 | Huawei Kirin NPU | libhuawei_kirin_npu.so | 点击进入 |
| 2 | Huawei Ascend NPU | libhuawei_ascend_npu.so | 点击进入 |
| 3 | Imagination NNA | libimagination_nna.so | 点击进入 |
| 4 | Mediatek APU | libmediatek_apu.so | 点击进入 |
编译完成后,NNAdapter 运行时库和 Device HAL 库将会生成在build.lite*/inference_lite_lib*/cxx/lib/目录下。
请下载 Paddle Lite 通用示例程序,并参照下表路径,获取新硬件所需的 DDK。
| No. | 新硬件名称 | DDK 路径 |
|---|---|---|
| 1 | Huawei Kirin NPU | PaddleLite-generic-demo/libs/PaddleLite/android/arm64-v8a/lib/huawei_kirin_npu |
| PaddleLite-generic-demo/libs/PaddleLite/android/armeabi-v7a/lib/huawei_kirin_npu | ||
| 2 | Huawei Ascend NPU | PaddleLite-generic-demo/libs/PaddleLite/linux/amd64/lib/huawei_ascend_npu |
| PaddleLite-generic-demo/libs/PaddleLite/linux/arm64/lib/huawei_ascend_npu | ||
| 3 | Imagination NNA | PaddleLite-generic-demo/libs/PaddleLite/linux/arm64/lib/imagination_nna |
| 4 | Mediatek APU | PaddleLite-generic-demo/libs/PaddleLite/android/armeabi-v7a/lib/mediatek_apu |
将 benchmark_bin 及所需动态库全部拷入新硬件设备后,即可开始运行模型并获得性能数据。
/data/local/tmp/benchmark目录下~/benchmark目录下为方便后续命令的表示,我们做以下约定:
~/benchmark路径下归档好包含 benchmark_bin、NNAdapter 运行时库、NNAdapter Device HAL 库、新硬件 DDK、Paddle 模型文件在内的全部数据。# 拷贝 benchmark 文件夹到新硬件
adb shell "rm -rf /data/local/tmp/benchmark"
adb shell "mkdir /data/local/tmp/benchmark"
adb push ~/benchmark/* /data/local/tmp/benchmark
# 设置环境变量并运行模型
adb shell "cd /data/local/tmp/benchmark;
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH;
./benchmark_bin \
--model_file=MobileNetV1/inference.pdmodel \
--param_file=MobileNetV1/inference.pdiparams \
--input_shape=1,3,224,224 \
--warmup=10 \
--repeats=20 \
--backend=nnadapter,arm \
--nnadapter_device_names=huawei_kirin_npu"
# Host 侧为 x86 CPU 时
# 拷贝 benchmark 文件夹到新硬件
ssh name@ip "rm -rf ~/benchmark"
scp -r ~/benchmark name@ip:~
ssh name@ip
cd ~/benchmark
# 设置环境变量
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
# 运行模型
./benchmark_bin \
--model_file=MobileNetV1/inference.pdmodel \
--param_file=MobileNetV1/inference.pdiparams \
--input_shape=1,3,224,224 \
--warmup=10 \
--repeats=20 \
--backend=nnadapter,x86 \
--nnadapter_device_names=huawei_ascend_npu \
--nnadapter_context_properties="HUAWEI_ASCEND_NPU_SELECTED_DEVICE_IDS=0"
# Host 侧为 ARM CPU 时
# 拷贝 benchmark 文件夹到新硬件
ssh name@ip "rm -rf ~/benchmark"
scp -r ~/benchmark name@ip:~
ssh name@ip
cd ~/benchmark
# 设置环境变量
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
# 运行模型
./benchmark_bin \
--model_file=MobileNetV1/inference.pdmodel \
--param_file=MobileNetV1/inference.pdiparams \
--input_shape=1,3,224,224 \
--warmup=10 \
--repeats=20 \
--backend=nnadapter,arm \
--nnadapter_device_names=huawei_ascend_npu \
--nnadapter_context_properties="HUAWEI_ASCEND_NPU_SELECTED_DEVICE_IDS=0"
# 拷贝 benchmark 文件夹到新硬件
ssh name@ip "rm -rf ~/benchmark"
scp -r ~/benchmark name@ip:~
ssh name@ip
cd ~/benchmark
# 设置环境变量
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
# 运行模型
./benchmark_bin \
--uncombined_model_dir=./mobilenet_v1_int8_224_per_layer \
--input_shape=1,3,224,224 \
--warmup=10 \
--repeats=20 \
--backend=nnadapter,arm \
--nnadapter_device_names=imagination_nna
# 拷贝 benchmark 文件夹到新硬件
adb shell "rm -rf /data/local/tmp/benchmark"
adb shell "mkdir /data/local/tmp/benchmark"
adb push ~/benchmark/* /data/local/tmp/benchmark
# 设置环境变量并运行模型
adb shell "cd /data/local/tmp/benchmark;
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH;
./benchmark_bin \
--uncombined_model_dir=./mobilenet_v1_int8_224_per_layer \
--input_shape=1,3,224,224 \
--warmup=10 \
--repeats=20 \
--backend=nnadapter,arm \
--nnadapter_device_names=mediatek_apu"
当在编译时设置--with_profile=ON时,运行benchmark_bin时会输出模型每层的耗时信息;
当在编译时设置--with_precision_profile=ON时,运行benchmark_bin时会输出模型每层的精度信息。具体可以参见 Profiler 工具。