diff --git a/deploy/paddle2onnx/readme.md b/deploy/paddle2onnx/readme.md index 02c069b7ac69110b63c53cd88e6ab5a223174972..782cffce9e5611b38da5bc002670a8282c08cc19 100644 --- a/deploy/paddle2onnx/readme.md +++ b/deploy/paddle2onnx/readme.md @@ -7,6 +7,7 @@ 需要准备 Paddle2ONNX 模型转化环境,和 ONNX 模型预测环境 ### Paddle2ONNX + Paddle2ONNX 支持将 PaddlePaddle 模型格式转化到 ONNX 模型格式,算子目前稳定支持导出 ONNX Opset 9~11,部分Paddle算子支持更低的ONNX Opset转换。 更多细节可参考 [Paddle2ONNX](https://github.com/PaddlePaddle/Paddle2ONNX/blob/develop/README_zh.md) @@ -51,6 +52,9 @@ paddle2onnx --model_dir=./inference/ch_ppocr_mobile_v2.0_det_infer/ \ 执行完毕后,ONNX 模型会被保存在 `./inference/det_mobile_onnx/` 路径下 +* 注意:以下几个模型暂不支持转换为 ONNX 模型: +NRTR、SAR、RARE、SRN + ## 3. onnx 预测 以检测模型为例,使用 ONNX 预测可执行如下命令: @@ -69,4 +73,4 @@ The predict time of ../../doc/imgs/1.jpg: 0.06162881851196289 The visualized image saved in ./inference_results/det_res_1.jpg ``` -* 注意:ONNX暂时不支持变长预测,因为需要将输入resize到固定输入,预测结果可能与直接使用Paddle预测有细微不同。 +* 注意:ONNX暂时不支持变长预测,需要将输入resize到固定输入,预测结果可能与直接使用Paddle预测有细微不同。 diff --git a/doc/doc_ch/detection.md b/doc/doc_ch/detection.md index 166e15fb03b604b63f47b95304ac06c1f4ae9dd2..8db64664f6ff560450a5ee99d708313c931989fc 100644 --- a/doc/doc_ch/detection.md +++ b/doc/doc_ch/detection.md @@ -98,7 +98,7 @@ python3 -m paddle.distributed.launch --gpus '0,1,2,3' tools/train.py -c configs/ -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained # 多机多卡训练,通过 --ips 参数设置使用的机器IP地址,通过 --gpus 参数设置使用的GPU ID -python3 -m paddle.distributed.launch --ips="10.21.226.181,10.21.226.133" --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml \ +python3 -m paddle.distributed.launch --ips="xx.xx.xx.xx,xx.xx.xx.xx" --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml \ -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained ``` diff --git a/doc/doc_en/detection_en.md b/doc/doc_en/detection_en.md index 68c5691cda9f78c7f805c0f0ecdf82f00534de72..948733e16cebea2ce819367a863948434ece5ae5 100644 --- a/doc/doc_en/detection_en.md +++ b/doc/doc_en/detection_en.md @@ -101,7 +101,7 @@ python3 -m paddle.distributed.launch --gpus '0,1,2,3' tools/train.py -c configs # multi-Node, multi-GPU training # Set the IPs of your nodes used by the '--ips' parameter. Set the GPU ID used by the '--gpus' parameter. -python3 -m paddle.distributed.launch --ips="10.21.226.181,10.21.226.133" --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml \ +python3 -m paddle.distributed.launch --ips="xx.xx.xx.xx,xx.xx.xx.xx" --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml \ -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained ``` **Note:** For multi-Node multi-GPU training, you need to replace the `ips` value in the preceding command with the address of your machine, and the machines must be able to ping each other. The command for viewing the IP address of the machine is `ifconfig`. diff --git a/requirements.txt b/requirements.txt index 6758a59bad20f6ffa271766fc4d0df5ebf4c7a4b..0c87c5c95069a2699f5a3a50320c883c6118ffe7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ shapely -scikit-image==0.18.3 +scikit-image imgaug==0.4.0 pyclipper lmdb diff --git a/test_tipc/configs/jeston_ppocr_det_mobile_params.txt b/test_tipc/configs/jeston_ppocr_det_mobile_params.txt index e79d6283f0c4e160f40bdf0f43c44985a4cf7d52..7e2bba2462bc4517f13da35a6a3bb527275bb85f 100644 --- a/test_tipc/configs/jeston_ppocr_det_mobile_params.txt +++ b/test_tipc/configs/jeston_ppocr_det_mobile_params.txt @@ -2,7 +2,7 @@ model_name:ocr_det python:python gpu_list:null -Global.use_gpu:False +Global.use_gpu:null Global.auto_cast:null Global.epoch_num:null Global.save_model_dir:null @@ -38,9 +38,9 @@ train_model:./inference/ch_ppocr_mobile_v2.0_det_infer infer_export:null infer_quant:False inference:tools/infer/predict_det.py ---use_gpu:True +--use_gpu:True|False --enable_mkldnn:False ---cpu_threads:6 +--cpu_threads:1|6 --rec_batch_num:1 --use_tensorrt:False|True --precision:fp16|fp32 diff --git a/test_tipc/docs/jeston_test_train_inference_python.md b/test_tipc/docs/jeston_test_train_inference_python.md new file mode 100644 index 0000000000000000000000000000000000000000..3c0524df21df84fefdbbfd8e691766c9c542dff5 --- /dev/null +++ b/test_tipc/docs/jeston_test_train_inference_python.md @@ -0,0 +1,118 @@ +# Jeston端基础训练预测功能测试 + +Jeston端基础训练预测功能测试的主程序为`test_train_inference_python.sh`,由于Jeston端CPU较差,Jeston只需要测试TIPC关于GPU和TensorRT预测推理的部分即可。 + +## 1. 测试结论汇总 + +- 预测相关:基于训练是否使用量化,可以将训练产出的模型可以分为`正常模型`和`量化模型`,这两类模型对应的预测功能汇总如下: + +| 模型类型 |device | batchsize | tensorrt | mkldnn | cpu多线程 | +| ---- | ---- | ---- | :----: | :----: | :----: | +| 正常模型 | GPU | 1/6 | fp32/fp16 | - | - | +| 量化模型 | GPU | 1/6 | int8 | - | - | + + +## 2. 测试流程 + +环境准备只需要Python环境即可,安装PaddlePaddle等依赖参考下述文档。 + +### 2.1 安装依赖 +- 安装PaddlePaddle >= 2.0 +- 安装PaddleOCR依赖 + ``` + pip install -r ../requirements.txt + ``` +- 安装autolog(规范化日志输出工具) + ``` + git clone https://github.com/LDOUBLEV/AutoLog + cd AutoLog + pip install -r requirements.txt + python setup.py bdist_wheel + pip install ./dist/auto_log-1.0.0-py3-none-any.whl + cd ../ + ``` +- 安装PaddleSlim (可选) + ``` + # 如果要测试量化、裁剪等功能,需要安装PaddleSlim + pip install paddleslim + ``` + + +### 2.2 功能测试 + +先运行`prepare.sh`准备数据和模型,然后运行`test_train_inference_python.sh`进行测试,最终在```test_tipc/output```目录下生成`python_infer_*.log`格式的日志文件。 + +`test_train_inference_python.sh`包含5种[运行模式](./test_train_inference_python.md),在Jeston端,仅需要测试预测推理的模式即可: + +``` +- 模式3:whole_infer,不训练,全量数据预测,走通开源模型评估、动转静,检查inference model预测时间和精度; +```shell +bash test_tipc/prepare.sh ./test_tipc/configs/mac_ppocr_det_mobile_params.txt 'whole_infer' +# 用法1: +bash test_tipc/test_train_inference_python.sh ./test_tipc/configs/jeston_ppocr_det_mobile_params.txt 'whole_infer' +# 用法2: 指定GPU卡预测,第三个传入参数为GPU卡号 +bash test_tipc/test_train_inference_python.sh ./test_tipc/configs/jeston_ppocr_det_mobile_params.txt 'whole_infer' '1' +``` + +运行相应指令后,在`test_tipc/output`文件夹下自动会保存运行日志。如`lite_train_lite_infer`模式下,会运行训练+inference的链条,因此,在`test_tipc/output`文件夹有以下文件: +``` +test_tipc/output/ +|- results_python.log # 运行指令状态的日志 +|- python_infer_gpu_usetensorrt_True_precision_fp32_batchsize_1.log # GPU上开启TensorRT,batch_size=1条件下的预测运行日志 +...... +``` + +其中`results_python.log`中包含了每条指令的运行状态,如果运行成功会输出: +``` +Run successfully with command - python tools/infer/predict_det.py --use_gpu=True --use_tensorrt=False --precision=fp32 --det_model_dir=./inference/ch_ppocr_mobile_v2.0_det_infer/ --rec_batch_num=1 --image_dir=./inference/ch_det_data_50/all-sum-510/ --benchmark=True > ./test_tipc/output/python_infer_gpu_usetrt_False_precision_fp32_batchsize_1.log 2>&1 ! +Run successfully with command - python tools/infer/predict_det.py --use_gpu=True --use_tensorrt=True --precision=fp32 --det_model_dir=./inference/ch_ppocr_mobile_v2.0_det_infer/ --rec_batch_num=1 --image_dir=./inference/ch_det_data_50/all-sum-510/ --benchmark=True > ./test_tipc/output/python_infer_gpu_usetrt_True_precision_fp32_batchsize_1.log 2>&1 ! +Run successfully with command - python tools/infer/predict_det.py --use_gpu=True --use_tensorrt=True --precision=fp16 --det_model_dir=./inference/ch_ppocr_mobile_v2.0_det_infer/ --rec_batch_num=1 --image_dir=./inference/ch_det_data_50/all-sum-510/ --benchmark=True > ./test_tipc/output/python_infer_gpu_usetrt_True_precision_fp16_batchsize_1.log 2>&1 ! +``` +如果运行失败,会输出: +``` +Run failed with command - python tools/infer/predict_det.py --use_gpu=True --use_tensorrt=False --precision=fp32 --det_model_dir=./inference/ch_ppocr_mobile_v2.0_det_infer/ --rec_batch_num=1 --image_dir=./inference/ch_det_data_50/all-sum-510/ --benchmark=True > ./test_tipc/output/python_infer_gpu_usetrt_False_precision_fp32_batchsize_1.log 2>&1 ! +Run failed with command - python tools/infer/predict_det.py --use_gpu=True --use_tensorrt=True --precision=fp32 --det_model_dir=./inference/ch_ppocr_mobile_v2.0_det_infer/ --rec_batch_num=1 --image_dir=./inference/ch_det_data_50/all-sum-510/ --benchmark=True > ./test_tipc/output/python_infer_gpu_usetrt_True_precision_fp32_batchsize_1.log 2>&1 ! +Run failed with command - python tools/infer/predict_det.py --use_gpu=True --use_tensorrt=True --precision=fp16 --det_model_dir=./inference/ch_ppocr_mobile_v2.0_det_infer/ --rec_batch_num=1 --image_dir=./inference/ch_det_data_50/all-sum-510/ --benchmark=True > ./test_tipc/output/python_infer_gpu_usetrt_True_precision_fp16_batchsize_1.log 2>&1 ! +``` +可以很方便的根据`results_python.log`中的内容判定哪一个指令运行错误。 + +### 2.3 精度测试 + +使用compare_results.py脚本比较模型预测的结果是否符合预期,主要步骤包括: +- 提取日志中的预测坐标; +- 从本地文件中提取保存好的坐标结果; +- 比较上述两个结果是否符合精度预期,误差大于设置阈值时会报错。 + +#### 使用方式 +运行命令: +```shell +python test_tipc/compare_results.py --gt_file=./test_tipc/results/python_*.txt --log_file=./test_tipc/output/python_*.log --atol=1e-3 --rtol=1e-3 +``` + +参数介绍: +- gt_file: 指向事先保存好的预测结果路径,支持*.txt 结尾,会自动索引*.txt格式的文件,文件默认保存在test_tipc/result/ 文件夹下 +- log_file: 指向运行test_tipc/test_train_inference_python.sh 脚本的infer模式保存的预测日志,预测日志中打印的有预测结果,比如:文本框,预测文本,类别等等,同样支持python_infer_*.log格式传入 +- atol: 设置的绝对误差 +- rtol: 设置的相对误差 + +#### 运行结果 + +正常运行效果如下: +``` +Assert allclose passed! The results of python_infer_gpu_usetrt_True_precision_fp32_batchsize_1.log and ./test_tipc/results/python_ppocr_det_mobile_results_fp32.txt are consistent! +``` + +出现不一致结果时的运行输出: +``` +...... +Traceback (most recent call last): + File "test_tipc/compare_results.py", line 140, in + format(filename, gt_filename)) +ValueError: The results of python_infer_gpu_usetrt_True_precision_fp32_batchsize_1.log and the results of ./test_tipc/results/python_ppocr_det_mobile_results_fp32.txt are inconsistent! +``` + + +## 3. 更多教程 +本文档为功能测试用,更丰富的训练预测使用教程请参考: +[模型训练](https://github.com/PaddlePaddle/PaddleOCR/blob/dygraph/doc/doc_ch/training.md) +[基于Python预测引擎推理](https://github.com/PaddlePaddle/PaddleOCR/blob/dygraph/doc/doc_ch/inference.md) diff --git a/tools/infer/predict_e2e.py b/tools/infer/predict_e2e.py index 5029d6059346a00062418d8d1b6cb029b0110643..08b87f36b0670e98e54c3f38c9328fe9462a6d0f 100755 --- a/tools/infer/predict_e2e.py +++ b/tools/infer/predict_e2e.py @@ -38,6 +38,7 @@ class TextE2E(object): def __init__(self, args): self.args = args self.e2e_algorithm = args.e2e_algorithm + self.use_onnx = args.use_onnx pre_process_list = [{ 'E2EResizeForTest': {} }, { @@ -106,21 +107,31 @@ class TextE2E(object): img = img.copy() starttime = time.time() - self.input_tensor.copy_from_cpu(img) - self.predictor.run() - outputs = [] - for output_tensor in self.output_tensors: - output = output_tensor.copy_to_cpu() - outputs.append(output) - - preds = {} - if self.e2e_algorithm == 'PGNet': + if self.use_onnx: + input_dict = {} + input_dict[self.input_tensor.name] = img + outputs = self.predictor.run(self.output_tensors, input_dict) + preds = {} preds['f_border'] = outputs[0] preds['f_char'] = outputs[1] preds['f_direction'] = outputs[2] preds['f_score'] = outputs[3] else: - raise NotImplementedError + self.input_tensor.copy_from_cpu(img) + self.predictor.run() + outputs = [] + for output_tensor in self.output_tensors: + output = output_tensor.copy_to_cpu() + outputs.append(output) + + preds = {} + if self.e2e_algorithm == 'PGNet': + preds['f_border'] = outputs[0] + preds['f_char'] = outputs[1] + preds['f_direction'] = outputs[2] + preds['f_score'] = outputs[3] + else: + raise NotImplementedError post_result = self.postprocess_op(preds, shape_list) points, strs = post_result['points'], post_result['texts'] dt_boxes = self.filter_tag_det_res_only_clip(points, ori_im.shape) diff --git a/tools/infer/utility.py b/tools/infer/utility.py index b6ba50544d4eb431c73f57a6870224f3f9378e39..98bf0362f6842cb70490e6817ef53fe39109f406 100755 --- a/tools/infer/utility.py +++ b/tools/infer/utility.py @@ -179,8 +179,8 @@ def create_predictor(args, mode, logger): if args.use_gpu: gpu_id = get_infer_gpuid() if gpu_id is None: - raise ValueError( - "Not found GPU in current device. Please check your device or set args.use_gpu as False" + logger.warning( + "GPU is not found in current device by nvidia-smi. Please check your device or ignore it if run on jeston." ) config.enable_use_gpu(args.gpu_mem, 0) if args.use_tensorrt: