diff --git a/cmake/ascend.cmake b/cmake/ascend.cmake index 01582d4186..ed5aa5d933 100644 --- a/cmake/ascend.cmake +++ b/cmake/ascend.cmake @@ -16,13 +16,4 @@ else () if(NOT PADDLELITE_URL) set(PADDLELITE_URL "https://bj.bcebos.com/fastdeploy/test/lite-linux_arm64_huawei_ascend_npu_python_1207.tgz") endif() - execute_process(COMMAND sh -c "ls *.so*" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/third_libs/install/paddlelite/lib - COMMAND sh -c "xargs ${PATCHELF_EXE} --set-rpath '$ORIGIN'" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/third_libs/install/paddlelite/lib - RESULT_VARIABLE result - OUTPUT_VARIABLE curr_out - ERROR_VARIABLE curr_out) - if(ret EQUAL "1") - message(FATAL_ERROR "Failed to patchelf Paddle Lite libraries when using Ascend.") - endif() - message(STATUS "result:${result} out:${curr_out}") endif() diff --git a/cmake/paddlelite.cmake b/cmake/paddlelite.cmake index 74525b7a9d..7e4fd7ac66 100755 --- a/cmake/paddlelite.cmake +++ b/cmake/paddlelite.cmake @@ -114,6 +114,10 @@ else() BUILD_BYPRODUCTS ${PADDLELITE_LIB}) endif() +if(UNIX AND (NOT APPLE) AND (NOT ANDROID)) + add_custom_target(patchelf_paddle_lite ALL COMMAND bash -c "PATCHELF_EXE=${PATCHELF_EXE} python ${PROJECT_SOURCE_DIR}/scripts/patch_paddle_lite.py ${PADDLELITE_INSTALL_DIR}/lib/" DEPENDS ${LIBRARY_NAME}) +endif() + add_library(external_paddle_lite STATIC IMPORTED GLOBAL) set_property(TARGET external_paddle_lite PROPERTY IMPORTED_LOCATION ${PADDLELITE_LIB}) add_dependencies(external_paddle_lite ${PADDLELITE_PROJECT}) diff --git a/docs/cn/build_and_install/huawei_ascend.md b/docs/cn/build_and_install/huawei_ascend.md index b2a6b2ea40..ce0c802115 100644 --- a/docs/cn/build_and_install/huawei_ascend.md +++ b/docs/cn/build_and_install/huawei_ascend.md @@ -94,6 +94,12 @@ python setup.py bdist_wheel #编译完成后,请用户自行安装当前目录的dist文件夹内的whl包. ``` +## 五.昇腾部署时开启FlyCV +[FlyCV](https://github.com/PaddlePaddle/FlyCV) 是一款高性能计算机图像处理库, 针对ARM架构做了很多优化, 相比其他图像处理库性能更为出色. +FastDeploy现在已经集成FlyCV, 用户可以在支持的硬件平台上使用FlyCV, 实现模型端到端推理性能的加速. +模型端到端推理中, 预处理和后处理阶段为CPU计算, 当用户使用ARM CPU + 昇腾的硬件平台时, 我们推荐用户使用FlyCV, 可以实现端到端的推理性能加速, 详见[FLyCV使用文档](./boost_cv_by_flycv.md). -- 华为昇腾NPU 上使用C++部署 PaddleClas 分类模型请参考:[PaddleClas 华为升腾NPU C++ 部署示例](../../../examples/vision/classification/paddleclas/ascend/cpp/README.md) -- 华为昇腾NPU 上使用Python部署 PaddleClas 分类模型请参考:[PaddleClas 华为升腾NPU Python 部署示例](../../../examples/vision/classification/paddleclas/ascend/python/README.md) + +## 六.昇腾部署Demo参考 +- 华为昇腾NPU 上使用C++部署 PaddleClas 分类模型请参考:[PaddleClas 华为升腾NPU C++ 部署示例](../../../examples/vision/classification/paddleclas/cpp/README.md) +- 华为昇腾NPU 上使用Python部署 PaddleClas 分类模型请参考:[PaddleClas 华为升腾NPU Python 部署示例](../../../examples/vision/classification/paddleclas/python/README.md) diff --git a/docs/cn/faq/boost_cv_by_flycv.md b/docs/cn/faq/boost_cv_by_flycv.md new file mode 100644 index 0000000000..591a5fa0a7 --- /dev/null +++ b/docs/cn/faq/boost_cv_by_flycv.md @@ -0,0 +1,68 @@ +[English](../../en/faq/boost_cv_by_flycv.md) | 中文 + + +# 使用FlyCV加速端到端推理性能 + +[FlyCV](https://github.com/PaddlePaddle/FlyCV) 是一款高性能计算机图像处理库, 针对ARM架构做了很多优化, 相比其他图像处理库性能更为出色. +FastDeploy现在已经集成FlyCV, 用户可以在支持的硬件平台上使用FlyCV, 实现模型端到端推理性能的加速. + +## 已支持的系统与硬件架构 + +| 系统 | 硬件架构 | +| :-----------| :-------- | +| Android | armeabi-v7a, arm64-v8a | +| Linux | aarch64, armhf, x86_64| + + +## 使用方式 +使用FlyCV,首先需要在编译时开启FlyCV编译选项,之后在部署时新增一行代码即可开启. +本文以Linux系统为例,说明如何开启FlyCV编译选项, 之后在部署时, 新增一行代码使用FlyCV. + +用户可以按照如下方式,在编译预测库时,开启FlyCV编译选项. +```bash +# 编译C++预测库时, 开启FlyCV编译选项. +-DENABLE_VISION=ON \ + +# 在编译Python预测库时, 开启FlyCV编译选项 +export ENABLE_FLYCV=ON +``` + +用户可以按照如下方式,在部署代码中新增一行代码启用FlyCV. +```bash +# C++部署代码. +# 新增一行代码启用FlyCV +fastdeploy::vision::EnableFlyCV(); +# 其他部署代码...(以昇腾部署为例) +fastdeploy::RuntimeOption option; +option.UseAscend(); +... + + +# Python部署代码 +# 新增一行代码启用FlyCV +fastdeploy.vision.enable_flycv() +# 其他部署代码...(以昇腾部署为例) +runtime_option = build_option() +option.use_ascend() +... +``` + +## 部分平台FlyCV 端到端性能数据 + +鲲鹏920 CPU + Atlas 300I Pro 推理卡. +| 模型 | OpenCV 端到端性能(ms) | FlyCV 端到端性能(ms) | +| :-----------| :-------- | :-------- | +| ResNet50 | 2.78 | 1.63 | +| PP-LCNetV2 | 2.50 | 1.39 | +| YOLOv7 | 27.00 | 21.36 | +| PP_HumanSegV2_Lite | 2.76 | 2.10 | + + +瑞芯微RV1126. + +| 模型 | OpenCV 端到端性能(ms) | FlyCV 端到端性能(ms) | +| :-----------| :-------- | :-------- | +| ResNet50 | 9.23 | 6.01 | +| mobilenetv1_ssld_量化模型 | 9.23 | 6.01 | +| yolov5s_量化模型 | 28.33 | 14.25 | +| PP_LiteSeg_量化模型 | 132.25 | 60.31 | diff --git a/docs/cn/faq/use_sdk_on_ascend.md b/docs/cn/faq/use_sdk_on_ascend.md index 8f87d5a229..fc0ccc45e3 100644 --- a/docs/cn/faq/use_sdk_on_ascend.md +++ b/docs/cn/faq/use_sdk_on_ascend.md @@ -1,4 +1,4 @@ -[English](../../en/faq/use_sdk_on_linux.md) | 中文 +[English](../../en/faq/use_sdk_on_ascend.md) | 中文 # Linux上使用C++在华为昇腾部署 diff --git a/docs/en/build_and_install/huawei_ascend.md b/docs/en/build_and_install/huawei_ascend.md index 3a0bd8911f..48653939d5 100644 --- a/docs/en/build_and_install/huawei_ascend.md +++ b/docs/en/build_and_install/huawei_ascend.md @@ -93,6 +93,14 @@ python setup.py bdist_wheel #After the compilation is complete, please install the whl package in the dist folder of the current directory. ``` -Deploying PaddleClas Classification Model on Huawei Ascend NPU using C++ please refer to: [PaddleClas Huawei Ascend NPU C++ Deployment Example](../../../examples/vision/classification/paddleclas/ascend/cpp/README.md) +## Enable FlyCV for Ascend deployment -Deploying PaddleClas classification model on Huawei Ascend NPU using Python please refer to: [PaddleClas Huawei Ascend NPU Python Deployment Example](../../../examples/vision/classification/paddleclas/ascend/python/README.md) +[FlyCV](https://github.com/PaddlePaddle/FlyCV) is a high performance computer image processing library, providing better performance than other image processing libraries, especially in the ARM architecture. +FastDeploy is now integrated with FlyCV, allowing users to use FlyCV on supported hardware platforms to accelerate model end-to-end inference performance. +In end-to-end model inference, the pre-processing and post-processing phases are CPU computation, we recommend using FlyCV for end-to-end inference performance acceleration when you are using ARM CPU + Ascend hardware platform. See [Enable FlyCV](./boost_cv_by_flycv.md) documentation for details. + + +## Deployment demo reference +- Deploying PaddleClas Classification Model on Huawei Ascend NPU using C++ please refer to: [PaddleClas Huawei Ascend NPU C++ Deployment Example](../../../examples/vision/classification/paddleclas/cpp/README.md) + +- Deploying PaddleClas classification model on Huawei Ascend NPU using Python please refer to: [PaddleClas Huawei Ascend NPU Python Deployment Example](../../../examples/vision/classification/paddleclas/python/README.md) diff --git a/docs/en/faq/boost_cv_by_flycv.md b/docs/en/faq/boost_cv_by_flycv.md new file mode 100644 index 0000000000..2a06a36293 --- /dev/null +++ b/docs/en/faq/boost_cv_by_flycv.md @@ -0,0 +1,66 @@ +[简体中文](../../cn/faq/boost_cv_by_flycv.md) | English + + +# Accelerate end-to-end inference performance using FlyCV + +[FlyCV](https://github.com/PaddlePaddle/FlyCV) is a high performance computer image processing library, providing better performance than other image processing libraries, especially in the ARM architecture. +FastDeploy is now integrated with FlyCV, allowing users to use FlyCV on supported hardware platforms to accelerate model end-to-end inference performance. + +## Supported OS and Architectures + +| OS | Architectures | +| :-----------| :-------- | +| Android | armeabi-v7a, arm64-v8a | +| Linux | aarch64, armhf, x86_64| + + +## Usage +To use FlyCV, you first need to turn on the FlyCV compile option at compile time, and then add a new line of code to turn it on. +This article uses Linux as an example to show how to enable the FlyCV compile option, and then add a new line of code to use FlyCV during deployment. + +You can turn on the FlyCV compile option when compiling the FastDeploy library as follows. +```bash +# When compiling C++ libraries +-DENABLE_VISION=ON + +# When compiling Python libraries +export ENABLE_FLYCV=ON +``` + +You can enable FlyCV by adding a new line of code to the deployment code as follows. +```bash +# C++ code +fastdeploy::vision::EnableFlyCV(); +# Other..(e.g. With Huawei Ascend) +fastdeploy::RuntimeOption option; +option.UseAscend(); +... + + +# Python code +fastdeploy.vision.enable_flycv() +# Other..(e.g. With Huawei Ascend) +runtime_option = build_option() +option.use_ascend() +... +``` + +## Some Platforms FlyCV End-to-End Inference Performance + +KunPeng 920 CPU + Atlas 300I Pro. +| Model | OpenCV E2E Performance(ms) | FlyCV E2E Performance(ms) | +| :-----------| :-------- | :-------- | +| ResNet50 | 2.78 | 1.63 | +| PP-LCNetV2 | 2.50 | 1.39 | +| YOLOv7 | 27.00 | 21.36 | +| PP_HumanSegV2_Lite | 2.76 | 2.10 | + + +Rockchip RV1126. + +| Model | OpenCV E2E Performance(ms) | FlyCV E2E Performance(ms) | +| :-----------| :-------- | :-------- | +| ResNet50 | 9.23 | 6.01 | +| mobilenetv1_ssld_量化模型 | 9.23 | 6.01 | +| yolov5s_量化模型 | 28.33 | 14.25 | +| PP_LiteSeg_量化模型 | 132.25 | 60.31 | diff --git a/docs/en/faq/use_sdk_on_ascend.md b/docs/en/faq/use_sdk_on_ascend.md index e3cd55b40c..c1ac864b85 100644 --- a/docs/en/faq/use_sdk_on_ascend.md +++ b/docs/en/faq/use_sdk_on_ascend.md @@ -1,4 +1,4 @@ -[简体中文](../../cn/faq/use_sdk_on_linux.md) | English +[简体中文](../../cn/faq/use_sdk_on_ascend.md) | English # # Linux deployment with C++ on Huawei Ascend diff --git a/examples/vision/detection/paddledetection/cpp/README.md b/examples/vision/detection/paddledetection/cpp/README.md index 5dbee5bf2d..f716675ad1 100755 --- a/examples/vision/detection/paddledetection/cpp/README.md +++ b/examples/vision/detection/paddledetection/cpp/README.md @@ -34,6 +34,8 @@ tar xvf ppyoloe_crn_l_300e_coco.tgz ./infer_ppyoloe_demo ./ppyoloe_crn_l_300e_coco 000000014439.jpg 2 # 昆仑芯XPU推理 ./infer_ppyoloe_demo ./ppyoloe_crn_l_300e_coco 000000014439.jpg 3 +# 华为昇腾推理 +./infer_ppyoloe_demo ./ppyoloe_crn_l_300e_coco 000000014439.jpg 4 ``` 以上命令只适用于Linux或MacOS, Windows下SDK的使用方式请参考: diff --git a/examples/vision/detection/paddledetection/cpp/infer_ppyolo.cc b/examples/vision/detection/paddledetection/cpp/infer_ppyolo.cc index 088e984027..6db82aaca7 100755 --- a/examples/vision/detection/paddledetection/cpp/infer_ppyolo.cc +++ b/examples/vision/detection/paddledetection/cpp/infer_ppyolo.cc @@ -102,6 +102,33 @@ void GpuInfer(const std::string& model_dir, const std::string& image_file) { std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; } +void AscendInfer(const std::string& model_dir, const std::string& image_file) { + auto model_file = model_dir + sep + "model.pdmodel"; + auto params_file = model_dir + sep + "model.pdiparams"; + auto config_file = model_dir + sep + "infer_cfg.yml"; + auto option = fastdeploy::RuntimeOption(); + option.UseAscend(); + auto model = fastdeploy::vision::detection::PPYOLO(model_file, params_file, + config_file, option); + if (!model.Initialized()) { + std::cerr << "Failed to initialize." << std::endl; + return; + } + + auto im = cv::imread(image_file); + + fastdeploy::vision::DetectionResult res; + if (!model.Predict(im, &res)) { + std::cerr << "Failed to predict." << std::endl; + return; + } + + std::cout << res.Str() << std::endl; + auto vis_im = fastdeploy::vision::VisDetection(im, res, 0.5); + cv::imwrite("vis_result.jpg", vis_im); + std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; +} + int main(int argc, char* argv[]) { if (argc < 4) { std::cout @@ -120,6 +147,8 @@ int main(int argc, char* argv[]) { GpuInfer(argv[1], argv[2]); } else if (std::atoi(argv[3]) == 2) { KunlunXinInfer(argv[1], argv[2]); + } else if (std::atoi(argv[3]) == 3) { + AscendInfer(argv[1], argv[2]); } return 0; } diff --git a/examples/vision/detection/paddledetection/cpp/infer_ppyoloe.cc b/examples/vision/detection/paddledetection/cpp/infer_ppyoloe.cc index 99922e22a9..c7efaa7c5b 100755 --- a/examples/vision/detection/paddledetection/cpp/infer_ppyoloe.cc +++ b/examples/vision/detection/paddledetection/cpp/infer_ppyoloe.cc @@ -131,6 +131,33 @@ void TrtInfer(const std::string& model_dir, const std::string& image_file) { std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; } +void AscendInfer(const std::string& model_dir, const std::string& image_file) { + auto model_file = model_dir + sep + "model.pdmodel"; + auto params_file = model_dir + sep + "model.pdiparams"; + auto config_file = model_dir + sep + "infer_cfg.yml"; + auto option = fastdeploy::RuntimeOption(); + option.UseAscend(); + auto model = fastdeploy::vision::detection::PPYOLOE(model_file, params_file, + config_file, option); + if (!model.Initialized()) { + std::cerr << "Failed to initialize." << std::endl; + return; + } + + auto im = cv::imread(image_file); + + fastdeploy::vision::DetectionResult res; + if (!model.Predict(im, &res)) { + std::cerr << "Failed to predict." << std::endl; + return; + } + + std::cout << res.Str() << std::endl; + auto vis_im = fastdeploy::vision::VisDetection(im, res, 0.5); + cv::imwrite("vis_result.jpg", vis_im); + std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; +} + int main(int argc, char* argv[]) { if (argc < 4) { std::cout @@ -151,6 +178,8 @@ int main(int argc, char* argv[]) { TrtInfer(argv[1], argv[2]); } else if (std::atoi(argv[3]) == 3) { KunlunXinInfer(argv[1], argv[2]); + } else if (std::atoi(argv[3]) == 4) { + AscendInfer(argv[1], argv[2]); } return 0; } diff --git a/examples/vision/detection/paddledetection/cpp/infer_ssd.cc b/examples/vision/detection/paddledetection/cpp/infer_ssd.cc index b71bf266cf..6c050da7f6 100755 --- a/examples/vision/detection/paddledetection/cpp/infer_ssd.cc +++ b/examples/vision/detection/paddledetection/cpp/infer_ssd.cc @@ -104,6 +104,33 @@ void GpuInfer(const std::string& model_dir, const std::string& image_file) { std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; } +void AscendInfer(const std::string& model_dir, const std::string& image_file) { + auto model_file = model_dir + sep + "model.pdmodel"; + auto params_file = model_dir + sep + "model.pdiparams"; + auto config_file = model_dir + sep + "infer_cfg.yml"; + auto option = fastdeploy::RuntimeOption(); + option.UseAscend(); + auto model = fastdeploy::vision::detection::SSD(model_file, params_file, + config_file, option); + if (!model.Initialized()) { + std::cerr << "Failed to initialize." << std::endl; + return; + } + + auto im = cv::imread(image_file); + + fastdeploy::vision::DetectionResult res; + if (!model.Predict(im, &res)) { + std::cerr << "Failed to predict." << std::endl; + return; + } + + std::cout << res.Str() << std::endl; + auto vis_im = fastdeploy::vision::VisDetection(im, res, 0.5); + cv::imwrite("vis_result.jpg", vis_im); + std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; +} + int main(int argc, char* argv[]) { if (argc < 4) { std::cout @@ -122,6 +149,8 @@ int main(int argc, char* argv[]) { GpuInfer(argv[1], argv[2]); } else if (std::atoi(argv[3]) == 2) { KunlunXinInfer(argv[1], argv[2]); + } else if (std::atoi(argv[3]) == 3) { + AscendInfer(argv[1], argv[2]); } return 0; } diff --git a/examples/vision/detection/paddledetection/cpp/infer_yolov3.cc b/examples/vision/detection/paddledetection/cpp/infer_yolov3.cc index 3ec4410146..2f866bf5e5 100755 --- a/examples/vision/detection/paddledetection/cpp/infer_yolov3.cc +++ b/examples/vision/detection/paddledetection/cpp/infer_yolov3.cc @@ -102,6 +102,34 @@ void GpuInfer(const std::string& model_dir, const std::string& image_file) { std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; } + +void AscendInfer(const std::string& model_dir, const std::string& image_file) { + auto model_file = model_dir + sep + "model.pdmodel"; + auto params_file = model_dir + sep + "model.pdiparams"; + auto config_file = model_dir + sep + "infer_cfg.yml"; + auto option = fastdeploy::RuntimeOption(); + option.UseAscend(); + auto model = fastdeploy::vision::detection::YOLOv3(model_file, params_file, + config_file, option); + if (!model.Initialized()) { + std::cerr << "Failed to initialize." << std::endl; + return; + } + + auto im = cv::imread(image_file); + + fastdeploy::vision::DetectionResult res; + if (!model.Predict(im, &res)) { + std::cerr << "Failed to predict." << std::endl; + return; + } + + std::cout << res.Str() << std::endl; + auto vis_im = fastdeploy::vision::VisDetection(im, res, 0.5); + cv::imwrite("vis_result.jpg", vis_im); + std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; +} + int main(int argc, char* argv[]) { if (argc < 4) { std::cout @@ -120,6 +148,8 @@ int main(int argc, char* argv[]) { GpuInfer(argv[1], argv[2]); } else if (std::atoi(argv[3]) == 2) { KunlunXinInfer(argv[1], argv[2]); + } else if (std::atoi(argv[3]) == 3) { + AscendInfer(argv[1], argv[2]); } return 0; } diff --git a/examples/vision/detection/paddledetection/python/README.md b/examples/vision/detection/paddledetection/python/README.md index b926dd9eea..227bc4efce 100755 --- a/examples/vision/detection/paddledetection/python/README.md +++ b/examples/vision/detection/paddledetection/python/README.md @@ -25,6 +25,8 @@ python infer_ppyoloe.py --model_dir ppyoloe_crn_l_300e_coco --image 000000014439 python infer_ppyoloe.py --model_dir ppyoloe_crn_l_300e_coco --image 000000014439.jpg --device gpu --use_trt True # 昆仑芯XPU推理 python infer_ppyoloe.py --model_dir ppyoloe_crn_l_300e_coco --image 000000014439.jpg --device kunlunxin +# 华为昇腾推理 +python infer_ppyoloe.py --model_dir ppyoloe_crn_l_300e_coco --image 000000014439.jpg --device ascend ``` 运行完成可视化结果如下图所示 diff --git a/examples/vision/detection/paddledetection/python/infer_ppyolo.py b/examples/vision/detection/paddledetection/python/infer_ppyolo.py index 279c5bb9fc..77feb8072f 100755 --- a/examples/vision/detection/paddledetection/python/infer_ppyolo.py +++ b/examples/vision/detection/paddledetection/python/infer_ppyolo.py @@ -32,6 +32,9 @@ def build_option(args): if args.device.lower() == "kunlunxin": option.use_kunlunxin() + if args.device.lower() == "ascend": + option.use_ascend() + if args.device.lower() == "gpu": option.use_gpu() diff --git a/examples/vision/detection/paddledetection/python/infer_ppyoloe.py b/examples/vision/detection/paddledetection/python/infer_ppyoloe.py index 2b0971f128..9f3f628326 100755 --- a/examples/vision/detection/paddledetection/python/infer_ppyoloe.py +++ b/examples/vision/detection/paddledetection/python/infer_ppyoloe.py @@ -33,6 +33,9 @@ def build_option(args): if args.device.lower() == "kunlunxin": option.use_kunlunxin() + if args.device.lower() == "ascend": + option.use_ascend() + if args.device.lower() == "gpu": option.use_gpu() diff --git a/examples/vision/detection/paddledetection/python/infer_ssd.py b/examples/vision/detection/paddledetection/python/infer_ssd.py index 536bf59447..410f469dd7 100755 --- a/examples/vision/detection/paddledetection/python/infer_ssd.py +++ b/examples/vision/detection/paddledetection/python/infer_ssd.py @@ -26,6 +26,9 @@ def build_option(args): if args.device.lower() == "kunlunxin": option.use_kunlunxin() + if args.device.lower() == "ascend": + option.use_ascend() + if args.device.lower() == "gpu": option.use_gpu() return option diff --git a/examples/vision/detection/paddledetection/python/infer_yolov3.py b/examples/vision/detection/paddledetection/python/infer_yolov3.py index 8f6b509f98..26c12f7f2f 100755 --- a/examples/vision/detection/paddledetection/python/infer_yolov3.py +++ b/examples/vision/detection/paddledetection/python/infer_yolov3.py @@ -32,6 +32,9 @@ def build_option(args): if args.device.lower() == "kunlunxin": option.use_kunlunxin() + if args.device.lower() == "ascend": + option.use_ascend() + if args.device.lower() == "gpu": option.use_gpu() diff --git a/examples/vision/detection/yolov5/cpp/README.md b/examples/vision/detection/yolov5/cpp/README.md index 8f03a39ad0..61abe32751 100755 --- a/examples/vision/detection/yolov5/cpp/README.md +++ b/examples/vision/detection/yolov5/cpp/README.md @@ -31,6 +31,8 @@ wget https://gitee.com/paddlepaddle/PaddleDetection/raw/release/2.4/demo/0000000 ./infer_paddle_demo yolov5s_infer 000000014439.jpg 2 # 昆仑芯XPU推理 ./infer_paddle_demo yolov5s_infer 000000014439.jpg 3 +# 华为昇腾推理 +./infer_paddle_demo yolov5s_infer 000000014439.jpg 4 ``` 上述的模型为 Paddle 模型的推理,如果想要做 ONNX 模型的推理,可以按照如下步骤: diff --git a/examples/vision/detection/yolov5/cpp/infer_paddle_model.cc b/examples/vision/detection/yolov5/cpp/infer_paddle_model.cc index e4c02af8ad..e5302eca20 100755 --- a/examples/vision/detection/yolov5/cpp/infer_paddle_model.cc +++ b/examples/vision/detection/yolov5/cpp/infer_paddle_model.cc @@ -130,6 +130,35 @@ void KunlunXinInfer(const std::string& model_dir, const std::string& image_file) std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; } +void AscendInfer(const std::string& model_dir, const std::string& image_file) { + auto model_file = model_dir + sep + "model.pdmodel"; + auto params_file = model_dir + sep + "model.pdiparams"; + fastdeploy::RuntimeOption option; + option.UseAscend(); + auto model = fastdeploy::vision::detection::YOLOv5( + model_file, params_file, option, fastdeploy::ModelFormat::PADDLE); + + if (!model.Initialized()) { + std::cerr << "Failed to initialize." << std::endl; + return; + } + + auto im = cv::imread(image_file); + + fastdeploy::vision::DetectionResult res; + if (!model.Predict(im, &res)) { + std::cerr << "Failed to predict." << std::endl; + return; + } + std::cout << res.Str() << std::endl; + + auto vis_im = fastdeploy::vision::VisDetection(im, res); + + cv::imwrite("vis_result.jpg", vis_im); + std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; +} + + int main(int argc, char* argv[]) { if (argc < 4) { std::cout << "Usage: infer_demo path/to/model path/to/image run_option, " @@ -149,6 +178,8 @@ int main(int argc, char* argv[]) { TrtInfer(argv[1], argv[2]); } else if (std::atoi(argv[3]) == 3) { KunlunXinInfer(argv[1], argv[2]); - } + } else if (std::atoi(argv[3]) == 4) { + AscendInfer(argv[1], argv[2]); + } return 0; } diff --git a/examples/vision/detection/yolov5/python/README.md b/examples/vision/detection/yolov5/python/README.md index 77f9027d58..de93ef0ecb 100755 --- a/examples/vision/detection/yolov5/python/README.md +++ b/examples/vision/detection/yolov5/python/README.md @@ -25,6 +25,8 @@ python infer.py --model yolov5s_infer --image 000000014439.jpg --device gpu python infer.py --model yolov5s_infer --image 000000014439.jpg --device gpu --use_trt True # 昆仑芯XPU推理 python infer.py --model yolov5s_infer --image 000000014439.jpg --device kunlunxin +# 华为昇腾推理 +python infer.py --model yolov5s_infer --image 000000014439.jpg --device ascend ``` 运行完成可视化结果如下图所示 diff --git a/examples/vision/detection/yolov5/python/infer.py b/examples/vision/detection/yolov5/python/infer.py index 7f0823d8ab..74fd96e6c9 100755 --- a/examples/vision/detection/yolov5/python/infer.py +++ b/examples/vision/detection/yolov5/python/infer.py @@ -31,6 +31,9 @@ def build_option(args): if args.device.lower() == "gpu": option.use_gpu() + if args.device.lower() == "ascend": + option.use_ascend() + if args.use_trt: option.use_trt_backend() option.set_trt_input_shape("images", [1, 3, 640, 640]) diff --git a/examples/vision/detection/yolov6/cpp/README.md b/examples/vision/detection/yolov6/cpp/README.md index 973b6a5469..765dde84c1 100755 --- a/examples/vision/detection/yolov6/cpp/README.md +++ b/examples/vision/detection/yolov6/cpp/README.md @@ -29,6 +29,8 @@ wget https://gitee.com/paddlepaddle/PaddleDetection/raw/release/2.4/demo/0000000 ./infer_paddle_demo yolov6s_infer 000000014439.jpg 1 # 昆仑芯XPU推理 ./infer_paddle_demo yolov6s_infer 000000014439.jpg 2 +# 华为昇腾推理 +./infer_paddle_demo yolov6s_infer 000000014439.jpg 3 ``` 如果想要验证ONNX模型的推理,可以参考如下命令: diff --git a/examples/vision/detection/yolov6/cpp/infer_paddle_model.cc b/examples/vision/detection/yolov6/cpp/infer_paddle_model.cc index fc43ee0ae6..bd5d0b0a6b 100755 --- a/examples/vision/detection/yolov6/cpp/infer_paddle_model.cc +++ b/examples/vision/detection/yolov6/cpp/infer_paddle_model.cc @@ -96,6 +96,32 @@ void GpuInfer(const std::string& model_dir, const std::string& image_file) { std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; } +void AscendInfer(const std::string& model_dir, const std::string& image_file) { + auto model_file = model_dir + sep + "model.pdmodel"; + auto params_file = model_dir + sep + "model.pdiparams"; + fastdeploy::RuntimeOption option; + option.UseAscend(); + auto model = fastdeploy::vision::detection::YOLOv6( + model_file, params_file, option, fastdeploy::ModelFormat::PADDLE); + + if (!model.Initialized()) { + std::cerr << "Failed to initialize." << std::endl; + return; + } + + auto im = cv::imread(image_file); + + fastdeploy::vision::DetectionResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Failed to predict." << std::endl; + return; + } + std::cout << res.Str() << std::endl; + + auto vis_im = fastdeploy::vision::VisDetection(im, res); + cv::imwrite("vis_result.jpg", vis_im); + std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; +} int main(int argc, char* argv[]) { if (argc < 4) { @@ -114,6 +140,8 @@ int main(int argc, char* argv[]) { GpuInfer(argv[1], argv[2]); } else if (std::atoi(argv[3]) == 2) { KunlunXinInfer(argv[1], argv[2]); - } + } else if (std::atoi(argv[3]) == 3) { + AscendInfer(argv[1], argv[2]); + } return 0; } diff --git a/examples/vision/detection/yolov6/python/README.md b/examples/vision/detection/yolov6/python/README.md index a12bb90208..37a06fd5ce 100755 --- a/examples/vision/detection/yolov6/python/README.md +++ b/examples/vision/detection/yolov6/python/README.md @@ -22,6 +22,8 @@ python infer_paddle_model.py --model yolov6s_infer --image 000000014439.jpg --d python infer_paddle_model.py --model yolov6s_infer --image 000000014439.jpg --device gpu # 昆仑芯XPU推理 python infer_paddle_model.py --model yolov6s_infer --image 000000014439.jpg --device kunlunxin +# 华为昇腾推理 +python infer_paddle_model.py --model yolov6s_infer --image 000000014439.jpg --device ascend ``` 如果想要验证ONNX模型的推理,可以参考如下命令: ```bash diff --git a/examples/vision/detection/yolov6/python/infer_paddle_model.py b/examples/vision/detection/yolov6/python/infer_paddle_model.py index 2504862011..9fd1c38263 100755 --- a/examples/vision/detection/yolov6/python/infer_paddle_model.py +++ b/examples/vision/detection/yolov6/python/infer_paddle_model.py @@ -28,6 +28,9 @@ def build_option(args): if args.device.lower() == "kunlunxin": option.use_kunlunxin() + if args.device.lower() == "ascend": + option.use_ascend() + return option diff --git a/examples/vision/detection/yolov7/cpp/README.md b/examples/vision/detection/yolov7/cpp/README.md index 8fc7928a8d..5cab3cc955 100755 --- a/examples/vision/detection/yolov7/cpp/README.md +++ b/examples/vision/detection/yolov7/cpp/README.md @@ -28,6 +28,8 @@ wget https://gitee.com/paddlepaddle/PaddleDetection/raw/release/2.4/demo/0000000 ./infer_paddle_model_demo yolov7_infer 000000014439.jpg 1 # 昆仑芯XPU推理 ./infer_paddle_model_demo yolov7_infer 000000014439.jpg 2 +# 华为昇腾推理 +./infer_paddle_model_demo yolov7_infer 000000014439.jpg 3 ``` 如果想要验证ONNX模型的推理,可以参考如下命令: ```bash diff --git a/examples/vision/detection/yolov7/cpp/infer_paddle_model.cc b/examples/vision/detection/yolov7/cpp/infer_paddle_model.cc index f88f0d3a0f..baed4acce4 100755 --- a/examples/vision/detection/yolov7/cpp/infer_paddle_model.cc +++ b/examples/vision/detection/yolov7/cpp/infer_paddle_model.cc @@ -31,7 +31,7 @@ void InitAndInfer(const std::string& model_dir, const std::string& image_file, auto im = cv::imread(image_file); fastdeploy::vision::DetectionResult res; - if (!model.Predict(&im, &res)) { + if (!model.Predict(im, &res)) { std::cerr << "Failed to predict." << std::endl; return; } @@ -68,7 +68,9 @@ int main(int argc, char* argv[]) { option.UseTrtBackend(); } else if (flag == 2) { option.UseKunlunXin(); - } + } else if (flag == 3) { + option.UseAscend(); + } std::string model_dir = argv[1]; std::string test_image = argv[2]; diff --git a/examples/vision/detection/yolov7/python/README.md b/examples/vision/detection/yolov7/python/README.md index c0aa78337a..a925e78efa 100755 --- a/examples/vision/detection/yolov7/python/README.md +++ b/examples/vision/detection/yolov7/python/README.md @@ -24,6 +24,8 @@ python infer_paddle_model.py --model yolov7_infer --image 000000014439.jpg --dev python infer_paddle_model.py --model yolov7_infer --image 000000014439.jpg --device gpu # 昆仑芯XPU推理 python infer_paddle_model.py --model yolov7_infer --image 000000014439.jpg --device kunlunxin +# 华为昇腾推理 +python infer_paddle_model.py --model yolov7_infer --image 000000014439.jpg --device ascend ``` 如果想要验证ONNX模型的推理,可以参考如下命令: ```bash diff --git a/examples/vision/detection/yolov7/python/README_EN.md b/examples/vision/detection/yolov7/python/README_EN.md index 64b6fcc98d..ee7b486b3c 100755 --- a/examples/vision/detection/yolov7/python/README_EN.md +++ b/examples/vision/detection/yolov7/python/README_EN.md @@ -24,6 +24,8 @@ python infer_paddle_model.py --model yolov7_infer --image 000000014439.jpg --dev python infer_paddle_model.py --model yolov7_infer --image 000000014439.jpg --device gpu # KunlunXin XPU python infer_paddle_model.py --model yolov7_infer --image 000000014439.jpg --device kunlunxin +# Huawei Ascend +python infer_paddle_model.py --model yolov7_infer --image 000000014439.jpg --device ascend ``` If you want to test ONNX model: ```bash diff --git a/examples/vision/detection/yolov7/python/infer_paddle_model.py b/examples/vision/detection/yolov7/python/infer_paddle_model.py index 2a3351e595..28f1b747a4 100755 --- a/examples/vision/detection/yolov7/python/infer_paddle_model.py +++ b/examples/vision/detection/yolov7/python/infer_paddle_model.py @@ -28,6 +28,9 @@ def build_option(args): if args.device.lower() == "kunlunxin": option.use_kunlunxin() + if args.device.lower() == "ascend": + option.use_ascend() + return option diff --git a/examples/vision/ocr/PP-OCRv2/cpp/README.md b/examples/vision/ocr/PP-OCRv2/cpp/README.md index fbde53fffc..e30d886d1e 100755 --- a/examples/vision/ocr/PP-OCRv2/cpp/README.md +++ b/examples/vision/ocr/PP-OCRv2/cpp/README.md @@ -43,6 +43,8 @@ wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_ ./infer_demo ./ch_PP-OCRv2_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv2_rec_infer ./ppocr_keys_v1.txt ./12.jpg 3 # 昆仑芯XPU推理 ./infer_demo ./ch_PP-OCRv2_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv2_rec_infer ./ppocr_keys_v1.txt ./12.jpg 4 +# 华为昇腾推理 +./infer_demo ./ch_PP-OCRv2_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv2_rec_infer ./ppocr_keys_v1.txt ./12.jpg 5 ``` 以上命令只适用于Linux或MacOS, Windows下SDK的使用方式请参考: diff --git a/examples/vision/ocr/PP-OCRv2/cpp/infer.cc b/examples/vision/ocr/PP-OCRv2/cpp/infer.cc index 3406246aae..0248367cc7 100755 --- a/examples/vision/ocr/PP-OCRv2/cpp/infer.cc +++ b/examples/vision/ocr/PP-OCRv2/cpp/infer.cc @@ -55,6 +55,10 @@ void InitAndInfer(const std::string& det_model_dir, const std::string& cls_model auto cls_model = fastdeploy::vision::ocr::Classifier(cls_model_file, cls_params_file, cls_option); auto rec_model = fastdeploy::vision::ocr::Recognizer(rec_model_file, rec_params_file, rec_label_file, rec_option); + // Users could enable static shape infer for rec model when deploy PP-OCR on hardware + // which can not support dynamic shape infer well, like Huawei Ascend series. + // rec_model.GetPreprocessor().SetStaticShapeInfer(true); + assert(det_model.Initialized()); assert(cls_model.Initialized()); assert(rec_model.Initialized()); @@ -65,9 +69,12 @@ void InitAndInfer(const std::string& det_model_dir, const std::string& cls_model // Set inference batch size for cls model and rec model, the value could be -1 and 1 to positive infinity. // When inference batch size is set to -1, it means that the inference batch size - // of the cls and rec models will be the same as the number of boxes detected by the det model. + // of the cls and rec models will be the same as the number of boxes detected by the det model. + // When users enable static shape infer for rec model, the batch size of cls and rec model needs to be set to 1. + // ppocr_v2.SetClsBatchSize(1); + // ppocr_v2.SetRecBatchSize(1); ppocr_v2.SetClsBatchSize(cls_batch_size); - ppocr_v2.SetRecBatchSize(rec_batch_size); + ppocr_v2.SetRecBatchSize(rec_batch_size); if(!ppocr_v2.Initialized()){ std::cerr << "Failed to initialize PP-OCR." << std::endl; @@ -122,6 +129,8 @@ int main(int argc, char* argv[]) { option.EnablePaddleToTrt(); } else if (flag == 4) { option.UseKunlunXin(); + } else if (flag == 5) { + option.UseAscend(); } std::string det_model_dir = argv[1]; diff --git a/examples/vision/ocr/PP-OCRv2/python/README.md b/examples/vision/ocr/PP-OCRv2/python/README.md index 66bba9e5bf..270225ab7d 100755 --- a/examples/vision/ocr/PP-OCRv2/python/README.md +++ b/examples/vision/ocr/PP-OCRv2/python/README.md @@ -36,6 +36,8 @@ python infer.py --det_model ch_PP-OCRv2_det_infer --cls_model ch_ppocr_mobile_v2 python infer.py --det_model ch_PP-OCRv2_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv2_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend trt # 昆仑芯XPU推理 python infer.py --det_model ch_PP-OCRv2_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv2_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device kunlunxin +# 华为昇腾推理 +python infer.py --det_model ch_PP-OCRv2_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv2_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device ascend ``` 运行完成可视化结果如下图所示 diff --git a/examples/vision/ocr/PP-OCRv2/python/infer.py b/examples/vision/ocr/PP-OCRv2/python/infer.py index b8c731ef36..f7373b4c28 100755 --- a/examples/vision/ocr/PP-OCRv2/python/infer.py +++ b/examples/vision/ocr/PP-OCRv2/python/infer.py @@ -72,6 +72,10 @@ def build_option(args): option.use_kunlunxin() return option + if args.device.lower() == "ascend": + option.use_ascend() + return option + if args.backend.lower() == "trt": assert args.device.lower( ) == "gpu", "TensorRT backend require inference on device GPU." @@ -112,6 +116,8 @@ def build_option(args): # PPOCR的cls和rec模型现在已经支持推理一个Batch的数据 # 定义下面两个变量后, 可用于设置trt输入shape, 并在PPOCR模型初始化后, 完成Batch推理设置 +# 当用户要把PP-OCR部署在对动态shape推理支持有限的设备上时,(例如华为昇腾) +# 需要把cls_batch_size和rec_batch_size都设置为1. cls_batch_size = 1 rec_batch_size = 6 @@ -144,6 +150,10 @@ def build_option(args): rec_model = fd.vision.ocr.Recognizer( rec_model_file, rec_params_file, rec_label_file, runtime_option=rec_option) +# 当用户要把PP-OCR部署在对动态shape推理支持有限的设备上时,(例如华为昇腾) +# 需要使用下行代码, 来启用rec模型的静态shape推理. +# rec_model.preprocessor.static_shape_infer = True + # 创建PP-OCR,串联3个模型,其中cls_model可选,如无需求,可设置为None ppocr_v2 = fd.vision.ocr.PPOCRv2( det_model=det_model, cls_model=cls_model, rec_model=rec_model) diff --git a/examples/vision/ocr/PP-OCRv3/cpp/README.md b/examples/vision/ocr/PP-OCRv3/cpp/README.md index 9c5eff4ef5..6f48a69ac7 100755 --- a/examples/vision/ocr/PP-OCRv3/cpp/README.md +++ b/examples/vision/ocr/PP-OCRv3/cpp/README.md @@ -43,6 +43,8 @@ wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_ ./infer_demo ./ch_PP-OCRv3_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv3_rec_infer ./ppocr_keys_v1.txt ./12.jpg 3 # 昆仑芯XPU推理 ./infer_demo ./ch_PP-OCRv3_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv3_rec_infer ./ppocr_keys_v1.txt ./12.jpg 4 +# 华为昇腾推理, 请用户在代码里正确开启Rec模型的静态shape推理,并设置分类模型和识别模型的推理batch size为1. +./infer_demo ./ch_PP-OCRv3_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv3_rec_infer ./ppocr_keys_v1.txt ./12.jpg 5 ``` 以上命令只适用于Linux或MacOS, Windows下SDK的使用方式请参考: diff --git a/examples/vision/ocr/PP-OCRv3/cpp/infer.cc b/examples/vision/ocr/PP-OCRv3/cpp/infer.cc index fd25eca7e0..7fbcf835e1 100755 --- a/examples/vision/ocr/PP-OCRv3/cpp/infer.cc +++ b/examples/vision/ocr/PP-OCRv3/cpp/infer.cc @@ -34,7 +34,7 @@ void InitAndInfer(const std::string& det_model_dir, const std::string& cls_model auto rec_option = option; // The cls and rec model can inference a batch of images now. - // User could initialize the inference batch size and set them after create PPOCR model. + // User could initialize the inference batch size and set them after create PP-OCR model. int cls_batch_size = 1; int rec_batch_size = 6; @@ -56,6 +56,10 @@ void InitAndInfer(const std::string& det_model_dir, const std::string& cls_model auto cls_model = fastdeploy::vision::ocr::Classifier(cls_model_file, cls_params_file, cls_option); auto rec_model = fastdeploy::vision::ocr::Recognizer(rec_model_file, rec_params_file, rec_label_file, rec_option); + // Users could enable static shape infer for rec model when deploy PP-OCR on hardware + // which can not support dynamic shape infer well, like Huawei Ascend series. + // rec_model.GetPreprocessor().SetStaticShapeInfer(true); + assert(det_model.Initialized()); assert(cls_model.Initialized()); assert(rec_model.Initialized()); @@ -66,9 +70,12 @@ void InitAndInfer(const std::string& det_model_dir, const std::string& cls_model // Set inference batch size for cls model and rec model, the value could be -1 and 1 to positive infinity. // When inference batch size is set to -1, it means that the inference batch size - // of the cls and rec models will be the same as the number of boxes detected by the det model. + // of the cls and rec models will be the same as the number of boxes detected by the det model. + // When users enable static shape infer for rec model, the batch size of cls and rec model needs to be set to 1. + // ppocr_v3.SetClsBatchSize(1); + // ppocr_v3.SetRecBatchSize(1); ppocr_v3.SetClsBatchSize(cls_batch_size); - ppocr_v3.SetRecBatchSize(rec_batch_size); + ppocr_v3.SetRecBatchSize(rec_batch_size); if(!ppocr_v3.Initialized()){ std::cerr << "Failed to initialize PP-OCR." << std::endl; @@ -123,6 +130,8 @@ int main(int argc, char* argv[]) { option.EnablePaddleToTrt(); } else if (flag == 4) { option.UseKunlunXin(); + } else if (flag == 5) { + option.UseAscend(); } std::string det_model_dir = argv[1]; diff --git a/examples/vision/ocr/PP-OCRv3/python/README.md b/examples/vision/ocr/PP-OCRv3/python/README.md index e87729353d..dd5965d338 100755 --- a/examples/vision/ocr/PP-OCRv3/python/README.md +++ b/examples/vision/ocr/PP-OCRv3/python/README.md @@ -35,6 +35,8 @@ python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2 python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend trt # 昆仑芯XPU推理 python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device kunlunxin +# 华为昇腾推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device ascend ``` 运行完成可视化结果如下图所示 diff --git a/examples/vision/ocr/PP-OCRv3/python/infer.py b/examples/vision/ocr/PP-OCRv3/python/infer.py index 97ee1d0703..f6da98bdb5 100755 --- a/examples/vision/ocr/PP-OCRv3/python/infer.py +++ b/examples/vision/ocr/PP-OCRv3/python/infer.py @@ -72,6 +72,10 @@ def build_option(args): option.use_kunlunxin() return option + if args.device.lower() == "ascend": + option.use_ascend() + return option + if args.backend.lower() == "trt": assert args.device.lower( ) == "gpu", "TensorRT backend require inference on device GPU." @@ -112,6 +116,8 @@ def build_option(args): # PPOCR的cls和rec模型现在已经支持推理一个Batch的数据 # 定义下面两个变量后, 可用于设置trt输入shape, 并在PPOCR模型初始化后, 完成Batch推理设置 +# 当用户要把PP-OCR部署在对动态shape推理支持有限的设备上时,(例如华为昇腾) +# 需要把cls_batch_size和rec_batch_size都设置为1. cls_batch_size = 1 rec_batch_size = 6 @@ -144,6 +150,10 @@ def build_option(args): rec_model = fd.vision.ocr.Recognizer( rec_model_file, rec_params_file, rec_label_file, runtime_option=rec_option) +# 当用户要把PP-OCR部署在对动态shape推理支持有限的设备上时,(例如华为昇腾) +# 需要使用下行代码, 来启用rec模型的静态shape推理. +# rec_model.preprocessor.static_shape_infer = True + # 创建PP-OCR,串联3个模型,其中cls_model可选,如无需求,可设置为None ppocr_v3 = fd.vision.ocr.PPOCRv3( det_model=det_model, cls_model=cls_model, rec_model=rec_model) diff --git a/examples/vision/segmentation/paddleseg/cpp/README.md b/examples/vision/segmentation/paddleseg/cpp/README.md index 35d288ba49..6b1be6e5bd 100755 --- a/examples/vision/segmentation/paddleseg/cpp/README.md +++ b/examples/vision/segmentation/paddleseg/cpp/README.md @@ -34,6 +34,8 @@ wget https://paddleseg.bj.bcebos.com/dygraph/demo/cityscapes_demo.png ./infer_demo Unet_cityscapes_without_argmax_infer cityscapes_demo.png 2 # 昆仑芯XPU推理 ./infer_demo Unet_cityscapes_without_argmax_infer cityscapes_demo.png 3 +# 华为昇腾推理 +./infer_demo Unet_cityscapes_without_argmax_infer cityscapes_demo.png 4 ``` 运行完成可视化结果如下图所示 diff --git a/examples/vision/segmentation/paddleseg/cpp/infer.cc b/examples/vision/segmentation/paddleseg/cpp/infer.cc index 389699a512..ae97c0406e 100755 --- a/examples/vision/segmentation/paddleseg/cpp/infer.cc +++ b/examples/vision/segmentation/paddleseg/cpp/infer.cc @@ -135,6 +135,34 @@ void TrtInfer(const std::string& model_dir, const std::string& image_file) { std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; } +void AscendInfer(const std::string& model_dir, const std::string& image_file) { + auto model_file = model_dir + sep + "model.pdmodel"; + auto params_file = model_dir + sep + "model.pdiparams"; + auto config_file = model_dir + sep + "deploy.yaml"; + auto option = fastdeploy::RuntimeOption(); + option.UseAscend(); + auto model = fastdeploy::vision::segmentation::PaddleSegModel( + model_file, params_file, config_file, option); + + if (!model.Initialized()) { + std::cerr << "Failed to initialize." << std::endl; + return; + } + + auto im = cv::imread(image_file); + + fastdeploy::vision::SegmentationResult res; + if (!model.Predict(im, &res)) { + std::cerr << "Failed to predict." << std::endl; + return; + } + + std::cout << res.Str() << std::endl; + auto vis_im = fastdeploy::vision::VisSegmentation(im, res, 0.5); + cv::imwrite("vis_result.jpg", vis_im); + std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; +} + int main(int argc, char* argv[]) { if (argc < 4) { std::cout @@ -155,6 +183,8 @@ int main(int argc, char* argv[]) { TrtInfer(argv[1], argv[2]); } else if (std::atoi(argv[3]) == 3) { KunlunXinInfer(argv[1], argv[2]); + } else if (std::atoi(argv[3]) == 4) { + AscendInfer(argv[1], argv[2]); } return 0; } diff --git a/examples/vision/segmentation/paddleseg/python/README.md b/examples/vision/segmentation/paddleseg/python/README.md index 9b5163bdfe..02b2e6ab5f 100755 --- a/examples/vision/segmentation/paddleseg/python/README.md +++ b/examples/vision/segmentation/paddleseg/python/README.md @@ -27,6 +27,8 @@ python infer.py --model Unet_cityscapes_without_argmax_infer --image cityscapes_ python infer.py --model Unet_cityscapes_without_argmax_infer --image cityscapes_demo.png --device gpu --use_trt True # 昆仑芯XPU推理 python infer.py --model Unet_cityscapes_without_argmax_infer --image cityscapes_demo.png --device kunlunxin +# 华为昇腾推理 +python infer.py --model Unet_cityscapes_without_argmax_infer --image cityscapes_demo.png --device ascend ``` 运行完成可视化结果如下图所示 diff --git a/examples/vision/segmentation/paddleseg/python/infer.py b/examples/vision/segmentation/paddleseg/python/infer.py index 0b19fedc2f..6862330ed6 100755 --- a/examples/vision/segmentation/paddleseg/python/infer.py +++ b/examples/vision/segmentation/paddleseg/python/infer.py @@ -33,6 +33,9 @@ def build_option(args): if args.device.lower() == "kunlunxin": option.use_kunlunxin() + if args.device.lower() == "ascend": + option.use_ascend() + if args.use_trt: option.use_trt_backend() option.set_trt_input_shape("x", [1, 3, 256, 256], [1, 3, 1024, 1024], diff --git a/fastdeploy/vision/ocr/ppocr/classifier.h b/fastdeploy/vision/ocr/ppocr/classifier.h index cd035e2693..824d9c3be1 100755 --- a/fastdeploy/vision/ocr/ppocr/classifier.h +++ b/fastdeploy/vision/ocr/ppocr/classifier.h @@ -68,11 +68,20 @@ class FASTDEPLOY_DECL Classifier : public FastDeployModel { std::vector* cls_scores, size_t start_index, size_t end_index); - ClassifierPreprocessor preprocessor_; - ClassifierPostprocessor postprocessor_; + /// Get preprocessor reference of ClassifierPreprocessor + virtual ClassifierPreprocessor& GetPreprocessor() { + return preprocessor_; + } + + /// Get postprocessor reference of ClassifierPostprocessor + virtual ClassifierPostprocessor& GetPostprocessor() { + return postprocessor_; + } private: bool Initialize(); + ClassifierPreprocessor preprocessor_; + ClassifierPostprocessor postprocessor_; }; } // namespace ocr diff --git a/fastdeploy/vision/ocr/ppocr/cls_postprocessor.h b/fastdeploy/vision/ocr/ppocr/cls_postprocessor.h index d9702e1a15..e596db71d2 100644 --- a/fastdeploy/vision/ocr/ppocr/cls_postprocessor.h +++ b/fastdeploy/vision/ocr/ppocr/cls_postprocessor.h @@ -39,6 +39,12 @@ class FASTDEPLOY_DECL ClassifierPostprocessor { std::vector* cls_labels, std::vector* cls_scores, size_t start_index, size_t total_size); + /// Set threshold for the classification postprocess, default is 0.9 + void SetClsThresh(float cls_thresh) { cls_thresh_ = cls_thresh; } + + /// Get threshold value of the classification postprocess. + float GetClsThresh() const { return cls_thresh_; } + float cls_thresh_ = 0.9; }; diff --git a/fastdeploy/vision/ocr/ppocr/cls_preprocessor.h b/fastdeploy/vision/ocr/ppocr/cls_preprocessor.h index 8c1c816111..8d42f3d31d 100644 --- a/fastdeploy/vision/ocr/ppocr/cls_preprocessor.h +++ b/fastdeploy/vision/ocr/ppocr/cls_preprocessor.h @@ -34,6 +34,27 @@ class FASTDEPLOY_DECL ClassifierPreprocessor { bool Run(std::vector* images, std::vector* outputs, size_t start_index, size_t end_index); + /// Set mean value for the image normalization in classification preprocess + void SetMean(std::vector mean) { mean_ = mean; } + /// Get mean value of the image normalization in classification preprocess + std::vector GetMean() const { return mean_; } + + /// Set scale value for the image normalization in classification preprocess + void SetScale(std::vector scale) { scale_ = scale; } + /// Get scale value of the image normalization in classification preprocess + std::vector GetScale() const { return scale_; } + + /// Set is_scale for the image normalization in classification preprocess + void SetIsScale(bool is_scale) { is_scale_ = is_scale; } + /// Get is_scale of the image normalization in classification preprocess + bool GetIsScale() const { return is_scale_; } + + /// Set cls_image_shape for the classification preprocess + void SetClsImageShape(std::vector cls_image_shape) + { cls_image_shape_ = cls_image_shape; } + /// Get cls_image_shape for the classification preprocess + std::vector GetClsImageShape() const { return cls_image_shape_; } + std::vector mean_ = {0.5f, 0.5f, 0.5f}; std::vector scale_ = {0.5f, 0.5f, 0.5f}; bool is_scale_ = true; diff --git a/fastdeploy/vision/ocr/ppocr/dbdetector.h b/fastdeploy/vision/ocr/ppocr/dbdetector.h index d2305abd7c..ec1ef028df 100755 --- a/fastdeploy/vision/ocr/ppocr/dbdetector.h +++ b/fastdeploy/vision/ocr/ppocr/dbdetector.h @@ -61,11 +61,20 @@ class FASTDEPLOY_DECL DBDetector : public FastDeployModel { virtual bool BatchPredict(const std::vector& images, std::vector>>* det_results); - DBDetectorPreprocessor preprocessor_; - DBDetectorPostprocessor postprocessor_; + /// Get preprocessor reference of DBDetectorPreprocessor + virtual DBDetectorPreprocessor& GetPreprocessor() { + return preprocessor_; + } + + /// Get postprocessor reference of DBDetectorPostprocessor + virtual DBDetectorPostprocessor& GetPostprocessor() { + return postprocessor_; + } private: bool Initialize(); + DBDetectorPreprocessor preprocessor_; + DBDetectorPostprocessor postprocessor_; }; } // namespace ocr diff --git a/fastdeploy/vision/ocr/ppocr/det_postprocessor.h b/fastdeploy/vision/ocr/ppocr/det_postprocessor.h index 1152288439..129ca62581 100644 --- a/fastdeploy/vision/ocr/ppocr/det_postprocessor.h +++ b/fastdeploy/vision/ocr/ppocr/det_postprocessor.h @@ -36,6 +36,34 @@ class FASTDEPLOY_DECL DBDetectorPostprocessor { std::vector>>* results, const std::vector>& batch_det_img_info); + /// Set det_db_thresh for the detection postprocess, default is 0.3 + void SetDetDBThresh(double det_db_thresh) { det_db_thresh_ = det_db_thresh; } + /// Get det_db_thresh of the detection postprocess + double GetDetDBThresh() const { return det_db_thresh_; } + + /// Set det_db_box_thresh for the detection postprocess, default is 0.6 + void SetDetDBBoxThresh(double det_db_box_thresh) + { det_db_box_thresh_ = det_db_box_thresh; } + /// Get det_db_box_thresh of the detection postprocess + double GetDetDBBoxThresh() const { return det_db_box_thresh_; } + + /// Set det_db_unclip_ratio for the detection postprocess, default is 1.5 + void SetDetDBUnclipRatio(double det_db_unclip_ratio) + { det_db_unclip_ratio_ = det_db_unclip_ratio; } + /// Get det_db_unclip_ratio_ of the detection postprocess + double GetDetDBUnclipRatio() const { return det_db_unclip_ratio_; } + + /// Set det_db_score_mode for the detection postprocess, default is 'slow' + void SetDetDBScoreMode(std::string det_db_score_mode) + { det_db_score_mode_ = det_db_score_mode; } + /// Get det_db_score_mode_ of the detection postprocess + std::string GetDetDBScoreMode() const { return det_db_score_mode_; } + + /// Set use_dilation for the detection postprocess, default is fasle + void SetUseDilation(int use_dilation) { use_dilation_ = use_dilation; } + /// Get use_dilation of the detection postprocess + int GetUseDilation() const { return use_dilation_; } + double det_db_thresh_ = 0.3; double det_db_box_thresh_ = 0.6; double det_db_unclip_ratio_ = 1.5; diff --git a/fastdeploy/vision/ocr/ppocr/det_preprocessor.h b/fastdeploy/vision/ocr/ppocr/det_preprocessor.h index 705f19c7bd..bf496079f2 100644 --- a/fastdeploy/vision/ocr/ppocr/det_preprocessor.h +++ b/fastdeploy/vision/ocr/ppocr/det_preprocessor.h @@ -35,6 +35,26 @@ class FASTDEPLOY_DECL DBDetectorPreprocessor { std::vector* outputs, std::vector>* batch_det_img_info_ptr); + /// Set max_side_len for the detection preprocess, default is 960 + void SetMaxSideLen(int max_side_len) { max_side_len_ = max_side_len; } + /// Get max_side_len of the detection preprocess + int GetMaxSideLen() const { return max_side_len_; } + + /// Set mean value for the image normalization in detection preprocess + void SetMean(std::vector mean) { mean_ = mean; } + /// Get mean value of the image normalization in detection preprocess + std::vector GetMean() const { return mean_; } + + /// Set scale value for the image normalization in detection preprocess + void SetScale(std::vector scale) { scale_ = scale; } + /// Get scale value of the image normalization in detection preprocess + std::vector GetScale() const { return scale_; } + + /// Set is_scale for the image normalization in detection preprocess + void SetIsScale(bool is_scale) { is_scale_ = is_scale; } + /// Get is_scale of the image normalization in detection preprocess + bool GetIsScale() const { return is_scale_; } + int max_side_len_ = 960; std::vector mean_ = {0.485f, 0.456f, 0.406f}; std::vector scale_ = {0.229f, 0.224f, 0.225f}; diff --git a/fastdeploy/vision/ocr/ppocr/ocrmodel_pybind.cc b/fastdeploy/vision/ocr/ppocr/ocrmodel_pybind.cc index acc73c57d4..2bcb697a80 100755 --- a/fastdeploy/vision/ocr/ppocr/ocrmodel_pybind.cc +++ b/fastdeploy/vision/ocr/ppocr/ocrmodel_pybind.cc @@ -24,10 +24,10 @@ void BindPPOCRModel(pybind11::module& m) { // DBDetector pybind11::class_(m, "DBDetectorPreprocessor") .def(pybind11::init<>()) - .def_readwrite("max_side_len", &vision::ocr::DBDetectorPreprocessor::max_side_len_) - .def_readwrite("mean", &vision::ocr::DBDetectorPreprocessor::mean_) - .def_readwrite("scale", &vision::ocr::DBDetectorPreprocessor::scale_) - .def_readwrite("is_scale", &vision::ocr::DBDetectorPreprocessor::is_scale_) + .def_property("max_side_len", &vision::ocr::DBDetectorPreprocessor::GetMaxSideLen, &vision::ocr::DBDetectorPreprocessor::SetMaxSideLen) + .def_property("mean", &vision::ocr::DBDetectorPreprocessor::GetMean, &vision::ocr::DBDetectorPreprocessor::SetMean) + .def_property("scale", &vision::ocr::DBDetectorPreprocessor::GetScale, &vision::ocr::DBDetectorPreprocessor::SetScale) + .def_property("is_scale", &vision::ocr::DBDetectorPreprocessor::GetIsScale, &vision::ocr::DBDetectorPreprocessor::SetIsScale) .def("run", [](vision::ocr::DBDetectorPreprocessor& self, std::vector& im_list) { std::vector images; for (size_t i = 0; i < im_list.size(); ++i) { @@ -44,11 +44,12 @@ void BindPPOCRModel(pybind11::module& m) { pybind11::class_(m, "DBDetectorPostprocessor") .def(pybind11::init<>()) - .def_readwrite("det_db_thresh", &vision::ocr::DBDetectorPostprocessor::det_db_thresh_) - .def_readwrite("det_db_box_thresh", &vision::ocr::DBDetectorPostprocessor::det_db_box_thresh_) - .def_readwrite("det_db_unclip_ratio", &vision::ocr::DBDetectorPostprocessor::det_db_unclip_ratio_) - .def_readwrite("det_db_score_mode", &vision::ocr::DBDetectorPostprocessor::det_db_score_mode_) - .def_readwrite("use_dilation", &vision::ocr::DBDetectorPostprocessor::use_dilation_) + .def_property("det_db_thresh", &vision::ocr::DBDetectorPostprocessor::GetDetDBThresh, &vision::ocr::DBDetectorPostprocessor::SetDetDBThresh) + .def_property("det_db_box_thresh", &vision::ocr::DBDetectorPostprocessor::GetDetDBBoxThresh, &vision::ocr::DBDetectorPostprocessor::SetDetDBBoxThresh) + .def_property("det_db_unclip_ratio", &vision::ocr::DBDetectorPostprocessor::GetDetDBUnclipRatio, &vision::ocr::DBDetectorPostprocessor::SetDetDBUnclipRatio) + .def_property("det_db_score_mode", &vision::ocr::DBDetectorPostprocessor::GetDetDBScoreMode, &vision::ocr::DBDetectorPostprocessor::SetDetDBScoreMode) + .def_property("use_dilation", &vision::ocr::DBDetectorPostprocessor::GetUseDilation, &vision::ocr::DBDetectorPostprocessor::SetUseDilation) + .def("run", [](vision::ocr::DBDetectorPostprocessor& self, std::vector& inputs, const std::vector>& batch_det_img_info) { @@ -75,8 +76,8 @@ void BindPPOCRModel(pybind11::module& m) { .def(pybind11::init()) .def(pybind11::init<>()) - .def_readwrite("preprocessor", &vision::ocr::DBDetector::preprocessor_) - .def_readwrite("postprocessor", &vision::ocr::DBDetector::postprocessor_) + .def_property_readonly("preprocessor", &vision::ocr::DBDetector::GetPreprocessor) + .def_property_readonly("postprocessor", &vision::ocr::DBDetector::GetPostprocessor) .def("predict", [](vision::ocr::DBDetector& self, pybind11::array& data) { auto mat = PyArrayToCvMat(data); @@ -97,10 +98,10 @@ void BindPPOCRModel(pybind11::module& m) { // Classifier pybind11::class_(m, "ClassifierPreprocessor") .def(pybind11::init<>()) - .def_readwrite("cls_image_shape", &vision::ocr::ClassifierPreprocessor::cls_image_shape_) - .def_readwrite("mean", &vision::ocr::ClassifierPreprocessor::mean_) - .def_readwrite("scale", &vision::ocr::ClassifierPreprocessor::scale_) - .def_readwrite("is_scale", &vision::ocr::ClassifierPreprocessor::is_scale_) + .def_property("cls_image_shape", &vision::ocr::ClassifierPreprocessor::GetClsImageShape, &vision::ocr::ClassifierPreprocessor::SetClsImageShape) + .def_property("mean", &vision::ocr::ClassifierPreprocessor::GetMean, &vision::ocr::ClassifierPreprocessor::SetMean) + .def_property("scale", &vision::ocr::ClassifierPreprocessor::GetScale, &vision::ocr::ClassifierPreprocessor::SetScale) + .def_property("is_scale", &vision::ocr::ClassifierPreprocessor::GetIsScale, &vision::ocr::ClassifierPreprocessor::SetIsScale) .def("run", [](vision::ocr::ClassifierPreprocessor& self, std::vector& im_list) { std::vector images; for (size_t i = 0; i < im_list.size(); ++i) { @@ -118,7 +119,7 @@ void BindPPOCRModel(pybind11::module& m) { pybind11::class_(m, "ClassifierPostprocessor") .def(pybind11::init<>()) - .def_readwrite("cls_thresh", &vision::ocr::ClassifierPostprocessor::cls_thresh_) + .def_property("cls_thresh", &vision::ocr::ClassifierPostprocessor::GetClsThresh, &vision::ocr::ClassifierPostprocessor::SetClsThresh) .def("run", [](vision::ocr::ClassifierPostprocessor& self, std::vector& inputs) { std::vector cls_labels; @@ -144,8 +145,8 @@ void BindPPOCRModel(pybind11::module& m) { .def(pybind11::init()) .def(pybind11::init<>()) - .def_readwrite("preprocessor", &vision::ocr::Classifier::preprocessor_) - .def_readwrite("postprocessor", &vision::ocr::Classifier::postprocessor_) + .def_property_readonly("preprocessor", &vision::ocr::Classifier::GetPreprocessor) + .def_property_readonly("postprocessor", &vision::ocr::Classifier::GetPostprocessor) .def("predict", [](vision::ocr::Classifier& self, pybind11::array& data) { auto mat = PyArrayToCvMat(data); @@ -168,11 +169,11 @@ void BindPPOCRModel(pybind11::module& m) { // Recognizer pybind11::class_(m, "RecognizerPreprocessor") .def(pybind11::init<>()) - .def_readwrite("rec_image_shape", &vision::ocr::RecognizerPreprocessor::rec_image_shape_) - .def_readwrite("mean", &vision::ocr::RecognizerPreprocessor::mean_) - .def_readwrite("scale", &vision::ocr::RecognizerPreprocessor::scale_) - .def_readwrite("is_scale", &vision::ocr::RecognizerPreprocessor::is_scale_) - .def_readwrite("static_shape", &vision::ocr::RecognizerPreprocessor::static_shape_) + .def_property("static_shape_infer", &vision::ocr::RecognizerPreprocessor::GetStaticShapeInfer, &vision::ocr::RecognizerPreprocessor::SetStaticShapeInfer) + .def_property("rec_image_shape", &vision::ocr::RecognizerPreprocessor::GetRecImageShape, &vision::ocr::RecognizerPreprocessor::SetRecImageShape) + .def_property("mean", &vision::ocr::RecognizerPreprocessor::GetMean, &vision::ocr::RecognizerPreprocessor::SetMean) + .def_property("scale", &vision::ocr::RecognizerPreprocessor::GetScale, &vision::ocr::RecognizerPreprocessor::SetScale) + .def_property("is_scale", &vision::ocr::RecognizerPreprocessor::GetIsScale, &vision::ocr::RecognizerPreprocessor::SetIsScale) .def("run", [](vision::ocr::RecognizerPreprocessor& self, std::vector& im_list) { std::vector images; for (size_t i = 0; i < im_list.size(); ++i) { @@ -215,8 +216,8 @@ void BindPPOCRModel(pybind11::module& m) { .def(pybind11::init()) .def(pybind11::init<>()) - .def_readwrite("preprocessor", &vision::ocr::Recognizer::preprocessor_) - .def_readwrite("postprocessor", &vision::ocr::Recognizer::postprocessor_) + .def_property_readonly("preprocessor", &vision::ocr::Recognizer::GetPreprocessor) + .def_property_readonly("postprocessor", &vision::ocr::Recognizer::GetPostprocessor) .def("predict", [](vision::ocr::Recognizer& self, pybind11::array& data) { auto mat = PyArrayToCvMat(data); diff --git a/fastdeploy/vision/ocr/ppocr/ppocr_v2.cc b/fastdeploy/vision/ocr/ppocr/ppocr_v2.cc index 756604dde8..622fe41c08 100755 --- a/fastdeploy/vision/ocr/ppocr/ppocr_v2.cc +++ b/fastdeploy/vision/ocr/ppocr/ppocr_v2.cc @@ -23,14 +23,14 @@ PPOCRv2::PPOCRv2(fastdeploy::vision::ocr::DBDetector* det_model, fastdeploy::vision::ocr::Recognizer* rec_model) : detector_(det_model), classifier_(cls_model), recognizer_(rec_model) { Initialized(); - recognizer_->preprocessor_.rec_image_shape_[1] = 32; + recognizer_->GetPreprocessor().rec_image_shape_[1] = 32; } PPOCRv2::PPOCRv2(fastdeploy::vision::ocr::DBDetector* det_model, fastdeploy::vision::ocr::Recognizer* rec_model) : detector_(det_model), recognizer_(rec_model) { Initialized(); - recognizer_->preprocessor_.rec_image_shape_[1] = 32; + recognizer_->GetPreprocessor().rec_image_shape_[1] = 32; } bool PPOCRv2::SetClsBatchSize(int cls_batch_size) { @@ -134,7 +134,7 @@ bool PPOCRv2::BatchPredict(const std::vector& images, return false; }else{ for (size_t i_img = start_index; i_img < end_index; ++i_img) { - if(cls_labels_ptr->at(i_img) % 2 == 1 && cls_scores_ptr->at(i_img) > classifier_->postprocessor_.cls_thresh_) { + if(cls_labels_ptr->at(i_img) % 2 == 1 && cls_scores_ptr->at(i_img) > classifier_->GetPostprocessor().cls_thresh_) { cv::rotate(image_list[i_img], image_list[i_img], 1); } } diff --git a/fastdeploy/vision/ocr/ppocr/ppocr_v3.h b/fastdeploy/vision/ocr/ppocr/ppocr_v3.h index ed9177d923..fa46fdb2c6 100755 --- a/fastdeploy/vision/ocr/ppocr/ppocr_v3.h +++ b/fastdeploy/vision/ocr/ppocr/ppocr_v3.h @@ -36,7 +36,7 @@ class FASTDEPLOY_DECL PPOCRv3 : public PPOCRv2 { fastdeploy::vision::ocr::Recognizer* rec_model) : PPOCRv2(det_model, cls_model, rec_model) { // The only difference between v2 and v3 - recognizer_->preprocessor_.rec_image_shape_[1] = 48; + recognizer_->GetPreprocessor().rec_image_shape_[1] = 48; } /** \brief Classification model is optional, so this function is set up the detection model path and recognition model path respectively. * @@ -47,7 +47,7 @@ class FASTDEPLOY_DECL PPOCRv3 : public PPOCRv2 { fastdeploy::vision::ocr::Recognizer* rec_model) : PPOCRv2(det_model, rec_model) { // The only difference between v2 and v3 - recognizer_->preprocessor_.rec_image_shape_[1] = 48; + recognizer_->GetPreprocessor().rec_image_shape_[1] = 48; } }; diff --git a/fastdeploy/vision/ocr/ppocr/rec_preprocessor.cc b/fastdeploy/vision/ocr/ppocr/rec_preprocessor.cc index 8ed4e0c53f..ad049fdcec 100644 --- a/fastdeploy/vision/ocr/ppocr/rec_preprocessor.cc +++ b/fastdeploy/vision/ocr/ppocr/rec_preprocessor.cc @@ -22,12 +22,12 @@ namespace vision { namespace ocr { void OcrRecognizerResizeImage(FDMat* mat, float max_wh_ratio, - const std::vector& rec_image_shape, bool static_shape) { + const std::vector& rec_image_shape, bool static_shape_infer) { int img_h, img_w; img_h = rec_image_shape[1]; img_w = rec_image_shape[2]; - if (!static_shape) { + if (!static_shape_infer) { img_w = int(img_h * max_wh_ratio); float ratio = float(mat->Width()) / float(mat->Height()); @@ -52,23 +52,6 @@ void OcrRecognizerResizeImage(FDMat* mat, float max_wh_ratio, } } -void OcrRecognizerResizeImageOnAscend(FDMat* mat, - const std::vector& rec_image_shape) { - - int img_h, img_w; - img_h = rec_image_shape[1]; - img_w = rec_image_shape[2]; - - if (mat->Width() >= img_w) { - Resize::Run(mat, img_w, img_h); // Reszie W to 320 - } else { - Resize::Run(mat, mat->Width(), img_h); - Pad::Run(mat, 0, 0, 0, int(img_w - mat->Width()), {0,0,0}); - // Pad to 320 - } -} - - bool RecognizerPreprocessor::Run(std::vector* images, std::vector* outputs) { return Run(images, outputs, 0, images->size(), {}); } @@ -101,7 +84,7 @@ bool RecognizerPreprocessor::Run(std::vector* images, std::vectorat(real_index)); - OcrRecognizerResizeImage(mat, max_wh_ratio, rec_image_shape_, static_shape_); + OcrRecognizerResizeImage(mat, max_wh_ratio, rec_image_shape_, static_shape_infer_); NormalizeAndPermute::Run(mat, mean_, scale_, is_scale_); } // Only have 1 output Tensor. diff --git a/fastdeploy/vision/ocr/ppocr/rec_preprocessor.h b/fastdeploy/vision/ocr/ppocr/rec_preprocessor.h index ee21c73625..c50711588d 100644 --- a/fastdeploy/vision/ocr/ppocr/rec_preprocessor.h +++ b/fastdeploy/vision/ocr/ppocr/rec_preprocessor.h @@ -35,11 +35,40 @@ class FASTDEPLOY_DECL RecognizerPreprocessor { size_t start_index, size_t end_index, const std::vector& indices); + /// Set static_shape_infer is true or not. When deploy PP-OCR + /// on hardware which can not support dynamic input shape very well, + /// like Huawei Ascned, static_shape_infer needs to to be true. + void SetStaticShapeInfer(bool static_shape_infer) + { static_shape_infer_ = static_shape_infer; } + /// Get static_shape_infer of the recognition preprocess + bool GetStaticShapeInfer() const { return static_shape_infer_; } + + /// Set mean value for the image normalization in recognition preprocess + void SetMean(std::vector mean) { mean_ = mean; } + /// Get mean value of the image normalization in recognition preprocess + std::vector GetMean() const { return mean_; } + + /// Set scale value for the image normalization in recognition preprocess + void SetScale(std::vector scale) { scale_ = scale; } + /// Get scale value of the image normalization in recognition preprocess + std::vector GetScale() const { return scale_; } + + /// Set is_scale for the image normalization in recognition preprocess + void SetIsScale(bool is_scale) { is_scale_ = is_scale; } + /// Get is_scale of the image normalization in recognition preprocess + bool GetIsScale() const { return is_scale_; } + + /// Set rec_image_shape for the recognition preprocess + void SetRecImageShape(std::vector rec_image_shape) + { rec_image_shape_ = rec_image_shape; } + /// Get rec_image_shape for the recognition preprocess + std::vector GetRecImageShape() const { return rec_image_shape_; } + std::vector rec_image_shape_ = {3, 48, 320}; std::vector mean_ = {0.5f, 0.5f, 0.5f}; std::vector scale_ = {0.5f, 0.5f, 0.5f}; bool is_scale_ = true; - bool static_shape_ = false; + bool static_shape_infer_ = false; }; } // namespace ocr diff --git a/fastdeploy/vision/ocr/ppocr/recognizer.h b/fastdeploy/vision/ocr/ppocr/recognizer.h index bba8a44477..60ffdcd10d 100755 --- a/fastdeploy/vision/ocr/ppocr/recognizer.h +++ b/fastdeploy/vision/ocr/ppocr/recognizer.h @@ -67,11 +67,20 @@ class FASTDEPLOY_DECL Recognizer : public FastDeployModel { size_t start_index, size_t end_index, const std::vector& indices); - RecognizerPreprocessor preprocessor_; - RecognizerPostprocessor postprocessor_; + /// Get preprocessor reference of DBDetectorPreprocessor + virtual RecognizerPreprocessor& GetPreprocessor() { + return preprocessor_; + } + + /// Get postprocessor reference of DBDetectorPostprocessor + virtual RecognizerPostprocessor& GetPostprocessor() { + return postprocessor_; + } private: bool Initialize(); + RecognizerPreprocessor preprocessor_; + RecognizerPostprocessor postprocessor_; }; } // namespace ocr diff --git a/python/fastdeploy/vision/ocr/ppocr/__init__.py b/python/fastdeploy/vision/ocr/ppocr/__init__.py index a357547fde..41bb279a59 100755 --- a/python/fastdeploy/vision/ocr/ppocr/__init__.py +++ b/python/fastdeploy/vision/ocr/ppocr/__init__.py @@ -509,15 +509,15 @@ def run(self, input_ims): return self._preprocessor.run(input_ims) @property - def static_shape(self): - return self._preprocessor.static_shape + def static_shape_infer(self): + return self._preprocessor.static_shape_infer - @static_shape.setter - def static_shape(self, value): + @static_shape_infer.setter + def static_shape_infer(self, value): assert isinstance( value, - bool), "The value to set `static_shape` must be type of bool." - self._preprocessor.static_shape = value + bool), "The value to set `static_shape_infer` must be type of bool." + self._preprocessor.static_shape_infer = value @property def is_scale(self): @@ -638,15 +638,15 @@ def postprocessor(self, value): self._model.postprocessor = value @property - def static_shape(self): - return self._model.preprocessor.static_shape + def static_shape_infer(self): + return self._model.preprocessor.static_shape_infer - @static_shape.setter - def static_shape(self, value): + @static_shape_infer.setter + def static_shape_infer(self, value): assert isinstance( value, - bool), "The value to set `static_shape` must be type of bool." - self._model.preprocessor.static_shape = value + bool), "The value to set `static_shape_infer` must be type of bool." + self._model.preprocessor.static_shape_infer = value @property def is_scale(self): diff --git a/scripts/patch_paddle_lite.py b/scripts/patch_paddle_lite.py new file mode 100644 index 0000000000..96dea4bf17 --- /dev/null +++ b/scripts/patch_paddle_lite.py @@ -0,0 +1,43 @@ +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import sys +import shutil +import subprocess +import platform +import sys + + +def process_paddle_lite(paddle_lite_so_path): + if platform.system().lower() != "linux": + return + rpaths = ["$ORIGIN"] + patchelf_exe = os.getenv("PATCHELF_EXE", "patchelf") + + for paddle_lite_so_file in os.listdir(paddle_lite_so_path): + paddle_lite_so_file = os.path.join(paddle_lite_so_path, + paddle_lite_so_file) + if '.so' in paddle_lite_so_file: + command = "{} --set-rpath '{}' {}".format( + patchelf_exe, ":".join(rpaths), paddle_lite_so_file) + if platform.machine() != 'sw_64' and platform.machine( + ) != 'mips64': + assert os.system( + command) == 0, "patchelf {} failed, the command: {}".format( + paddle_lite_so_file, command) + + +if __name__ == "__main__": + process_paddle_lite(sys.argv[1])