未验证 提交 f5f3f473 编写于 作者: B Bin Lu 提交者: GitHub

Merge pull request #1648 from Intsigstephon/develop

support cls inference for onnx mode
# paddle2onnx 模型转化与预测
本章节介绍 ResNet50_vd 模型如何转化为 ONNX 模型,并基于 ONNX 引擎预测。
## 1. 环境准备
需要准备 Paddle2ONNX 模型转化环境,和 ONNX 模型预测环境。
Paddle2ONNX 支持将 PaddlePaddle 模型格式转化到 ONNX 模型格式,算子目前稳定支持导出 ONNX Opset 9~11,部分Paddle算子支持更低的ONNX Opset转换。
更多细节可参考 [Paddle2ONNX](https://github.com/PaddlePaddle/Paddle2ONNX/blob/develop/README_zh.md)
- 安装 Paddle2ONNX
```
python3.7 -m pip install paddle2onnx
```
- 安装 ONNX 运行时
```
python3.7 -m pip install onnxruntime
```
## 2. 模型转换
- ResNet50_vd inference模型下载
```
cd deploy
mkdir models && cd models
wget -nc https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/inference/ResNet50_vd_infer.tar && tar xf ResNet50_vd_infer.tar
cd ..
```
- 模型转换
使用 Paddle2ONNX 将 Paddle 静态图模型转换为 ONNX 模型格式:
```
paddle2onnx --model_dir=./models/ResNet50_vd_infer/ \
--model_filename=inference.pdmodel \
--params_filename=inference.pdiparams \
--save_file=./models/ResNet50_vd_infer/inference.onnx \
--opset_version=10 \
--enable_onnx_checker=True
```
执行完毕后,ONNX 模型 `inference.onnx` 会被保存在 `./models/ResNet50_vd_infer/` 路径下
## 3. onnx 预测
执行如下命令:
```
python3.7 python/predict_cls.py \
-c configs/inference_cls.yaml \
-o Global.use_onnx=True \
-o Global.use_gpu=False \
-o Global.inference_model_dir=./models/ResNet50_vd_infer \
```
结果如下:
```
ILSVRC2012_val_00000010.jpeg: class id(s): [153, 204, 229, 332, 155], score(s): [0.69, 0.10, 0.02, 0.01, 0.01], label_name(s): ['Maltese dog, Maltese terrier, Maltese', 'Lhasa, Lhasa apso', 'Old English sheepdog, bobtail', 'Angora, Angora rabbit', 'Shih-Tzu']
```
...@@ -67,12 +67,17 @@ class ClsPredictor(Predictor): ...@@ -67,12 +67,17 @@ class ClsPredictor(Predictor):
warmup=2) warmup=2)
def predict(self, images): def predict(self, images):
input_names = self.paddle_predictor.get_input_names() use_onnx = self.args.get("use_onnx", False)
input_tensor = self.paddle_predictor.get_input_handle(input_names[0]) if not use_onnx:
input_names = self.predictor.get_input_names()
input_tensor = self.predictor.get_input_handle(input_names[0])
output_names = self.predictor.get_output_names()
output_tensor = self.predictor.get_output_handle(output_names[0])
else:
input_names = self.predictor.get_inputs()[0].name
output_names = self.predictor.get_outputs()[0].name
output_names = self.paddle_predictor.get_output_names()
output_tensor = self.paddle_predictor.get_output_handle(output_names[
0])
if self.benchmark: if self.benchmark:
self.auto_logger.times.start() self.auto_logger.times.start()
if not isinstance(images, (list, )): if not isinstance(images, (list, )):
...@@ -84,9 +89,15 @@ class ClsPredictor(Predictor): ...@@ -84,9 +89,15 @@ class ClsPredictor(Predictor):
if self.benchmark: if self.benchmark:
self.auto_logger.times.stamp() self.auto_logger.times.stamp()
if not use_onnx:
input_tensor.copy_from_cpu(image) input_tensor.copy_from_cpu(image)
self.paddle_predictor.run() self.predictor.run()
batch_output = output_tensor.copy_to_cpu() batch_output = output_tensor.copy_to_cpu()
else:
batch_output = self.predictor.run(
output_names=[output_names],
input_feed={input_names: image})[0]
if self.benchmark: if self.benchmark:
self.auto_logger.times.stamp() self.auto_logger.times.stamp()
if self.postprocess is not None: if self.postprocess is not None:
......
...@@ -109,17 +109,16 @@ class DetPredictor(Predictor): ...@@ -109,17 +109,16 @@ class DetPredictor(Predictor):
''' '''
inputs = self.preprocess(image) inputs = self.preprocess(image)
np_boxes = None np_boxes = None
input_names = self.paddle_predictor.get_input_names() input_names = self.predictor.get_input_names()
for i in range(len(input_names)): for i in range(len(input_names)):
input_tensor = self.paddle_predictor.get_input_handle(input_names[ input_tensor = self.predictor.get_input_handle(input_names[i])
i])
input_tensor.copy_from_cpu(inputs[input_names[i]]) input_tensor.copy_from_cpu(inputs[input_names[i]])
t1 = time.time() t1 = time.time()
self.paddle_predictor.run() self.predictor.run()
output_names = self.paddle_predictor.get_output_names() output_names = self.predictor.get_output_names()
boxes_tensor = self.paddle_predictor.get_output_handle(output_names[0]) boxes_tensor = self.predictor.get_output_handle(output_names[0])
np_boxes = boxes_tensor.copy_to_cpu() np_boxes = boxes_tensor.copy_to_cpu()
t2 = time.time() t2 = time.time()
......
...@@ -58,12 +58,16 @@ class RecPredictor(Predictor): ...@@ -58,12 +58,16 @@ class RecPredictor(Predictor):
warmup=2) warmup=2)
def predict(self, images, feature_normalize=True): def predict(self, images, feature_normalize=True):
input_names = self.paddle_predictor.get_input_names() use_onnx = self.args.get("use_onnx", False)
input_tensor = self.paddle_predictor.get_input_handle(input_names[0]) if not use_onnx:
input_names = self.predictor.get_input_names()
input_tensor = self.predictor.get_input_handle(input_names[0])
output_names = self.paddle_predictor.get_output_names() output_names = self.predictor.get_output_names()
output_tensor = self.paddle_predictor.get_output_handle(output_names[ output_tensor = self.predictor.get_output_handle(output_names[0])
0]) else:
input_names = self.predictor.get_inputs()[0].name
output_names = self.predictor.get_outputs()[0].name
if self.benchmark: if self.benchmark:
self.auto_logger.times.start() self.auto_logger.times.start()
...@@ -76,9 +80,15 @@ class RecPredictor(Predictor): ...@@ -76,9 +80,15 @@ class RecPredictor(Predictor):
if self.benchmark: if self.benchmark:
self.auto_logger.times.stamp() self.auto_logger.times.stamp()
if not use_onnx:
input_tensor.copy_from_cpu(image) input_tensor.copy_from_cpu(image)
self.paddle_predictor.run() self.predictor.run()
batch_output = output_tensor.copy_to_cpu() batch_output = output_tensor.copy_to_cpu()
else:
batch_output = self.predictor.run(
output_names=[output_names],
input_feed={input_names: image})[0]
if self.benchmark: if self.benchmark:
self.auto_logger.times.stamp() self.auto_logger.times.stamp()
......
...@@ -28,7 +28,11 @@ class Predictor(object): ...@@ -28,7 +28,11 @@ class Predictor(object):
if args.use_fp16 is True: if args.use_fp16 is True:
assert args.use_tensorrt is True assert args.use_tensorrt is True
self.args = args self.args = args
self.paddle_predictor, self.config = self.create_paddle_predictor( if self.args.get("use_onnx", False):
self.predictor, self.config = self.create_onnx_predictor(
args, inference_model_dir)
else:
self.predictor, self.config = self.create_paddle_predictor(
args, inference_model_dir) args, inference_model_dir)
def predict(self, image): def predict(self, image):
...@@ -69,3 +73,20 @@ class Predictor(object): ...@@ -69,3 +73,20 @@ class Predictor(object):
predictor = create_predictor(config) predictor = create_predictor(config)
return predictor, config return predictor, config
def create_onnx_predictor(self, args, inference_model_dir=None):
import onnxruntime as ort
if inference_model_dir is None:
inference_model_dir = args.inference_model_dir
model_file = os.path.join(inference_model_dir, "inference.onnx")
config = ort.SessionOptions()
if args.use_gpu:
raise ValueError(
"onnx inference now only supports cpu! please specify use_gpu false."
)
else:
config.intra_op_num_threads = args.cpu_num_threads
if args.ir_optim:
config.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
predictor = ort.InferenceSession(model_file, sess_options=config)
return predictor, config
===========================paddle2onnx_params===========================
model_name:ResNet50_vd
python:python3.7
2onnx: paddle2onnx
--model_dir:./deploy/models/ResNet50_vd_infer/
--model_filename:inference.pdmodel
--params_filename:inference.pdiparams
--save_file:./deploy/models/ResNet50_vd_infer/inference.onnx
--opset_version:10
--enable_onnx_checker:True
inference: python/predict_cls.py -c configs/inference_cls.yaml
Global.use_onnx:True
Global.inference_model_dir:models/ResNet50_vd_infer/
Global.use_gpu:False
...@@ -165,3 +165,15 @@ if [ ${MODE} = "serving_infer" ];then ...@@ -165,3 +165,15 @@ if [ ${MODE} = "serving_infer" ];then
cd ./deploy/paddleserving cd ./deploy/paddleserving
wget -nc https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/inference/ResNet50_vd_infer.tar && tar xf ResNet50_vd_infer.tar wget -nc https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/inference/ResNet50_vd_infer.tar && tar xf ResNet50_vd_infer.tar
fi fi
if [ ${MODE} = "paddle2onnx_infer" ];then
# prepare paddle2onnx env
python_name=$(func_parser_value "${lines[2]}")
${python_name} -m pip install install paddle2onnx
${python_name} -m pip install onnxruntime
# wget model
cd deploy && mkdir models && cd models
wget -nc https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/inference/ResNet50_vd_infer.tar && tar xf ResNet50_vd_infer.tar
cd ../../
fi
...@@ -11,7 +11,7 @@ python=$(func_parser_value "${lines[2]}") ...@@ -11,7 +11,7 @@ python=$(func_parser_value "${lines[2]}")
# parser params # parser params
dataline=$(awk 'NR==1, NR==12{print}' $FILENAME) dataline=$(awk 'NR==1, NR==14{print}' $FILENAME)
IFS=$'\n' IFS=$'\n'
lines=(${dataline}) lines=(${dataline})
...@@ -33,12 +33,12 @@ enable_onnx_checker_key=$(func_parser_key "${lines[9]}") ...@@ -33,12 +33,12 @@ enable_onnx_checker_key=$(func_parser_key "${lines[9]}")
enable_onnx_checker_value=$(func_parser_value "${lines[9]}") enable_onnx_checker_value=$(func_parser_value "${lines[9]}")
# parser onnx inference # parser onnx inference
inference_py=$(func_parser_value "${lines[10]}") inference_py=$(func_parser_value "${lines[10]}")
use_gpu_key=$(func_parser_key "${lines[11]}") use_onnx_key=$(func_parser_key "${lines[11]}")
use_gpu_value=$(func_parser_value "${lines[11]}") use_onnx_value=$(func_parser_value "${lines[11]}")
det_model_key=$(func_parser_key "${lines[12]}") inference_model_dir_key=$(func_parser_key "${lines[12]}")
image_dir_key=$(func_parser_key "${lines[13]}") inference_model_dir_value=$(func_parser_value "${lines[12]}")
image_dir_value=$(func_parser_value "${lines[13]}") inference_hardware_key=$(func_parser_key "${lines[13]}")
inference_hardware_value=$(func_parser_value "${lines[13]}")
LOG_PATH="./test_tipc/output" LOG_PATH="./test_tipc/output"
mkdir -p ./test_tipc/output mkdir -p ./test_tipc/output
...@@ -50,7 +50,7 @@ function func_paddle2onnx(){ ...@@ -50,7 +50,7 @@ function func_paddle2onnx(){
_script=$1 _script=$1
# paddle2onnx # paddle2onnx
_save_log_path="${LOG_PATH}/paddle2onnx_infer_cpu.log" _save_log_path=".${LOG_PATH}/paddle2onnx_infer_cpu.log"
set_dirname=$(func_set_params "${infer_model_dir_key}" "${infer_model_dir_value}") set_dirname=$(func_set_params "${infer_model_dir_key}" "${infer_model_dir_value}")
set_model_filename=$(func_set_params "${model_filename_key}" "${model_filename_value}") set_model_filename=$(func_set_params "${model_filename_key}" "${model_filename_value}")
set_params_filename=$(func_set_params "${params_filename_key}" "${params_filename_value}") set_params_filename=$(func_set_params "${params_filename_key}" "${params_filename_value}")
...@@ -62,10 +62,10 @@ function func_paddle2onnx(){ ...@@ -62,10 +62,10 @@ function func_paddle2onnx(){
last_status=${PIPESTATUS[0]} last_status=${PIPESTATUS[0]}
status_check $last_status "${trans_model_cmd}" "${status_log}" status_check $last_status "${trans_model_cmd}" "${status_log}"
# python inference # python inference
set_gpu=$(func_set_params "${use_gpu_key}" "${use_gpu_value}") set_model_dir=$(func_set_params "${inference_model_dir_key}" "${inference_model_dir_value}")
set_model_dir=$(func_set_params "${det_model_key}" "${save_file_value}") set_use_onnx=$(func_set_params "${use_onnx_key}" "${use_onnx_value}")
set_img_dir=$(func_set_params "${image_dir_key}" "${image_dir_value}") set_hardware=$(func_set_params "${inference_hardware_key}" "${inference_hardware_value}")
infer_model_cmd="${python} ${inference_py} ${set_gpu} ${set_img_dir} ${set_model_dir} --use_onnx=True > ${_save_log_path} 2>&1 " infer_model_cmd="cd deploy && ${python} ${inference_py} -o ${set_model_dir} -o ${set_use_onnx} -o ${set_hardware} >${_save_log_path} 2>&1 && cd ../"
eval $infer_model_cmd eval $infer_model_cmd
status_check $last_status "${infer_model_cmd}" "${status_log}" status_check $last_status "${infer_model_cmd}" "${status_log}"
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册