ソースを参照

Merge branch 'develop' of https://github.com/PaddlePaddle/PaddleX into develop_jf

will-jl944 4 年 前
コミット
81d9c874ef
65 ファイル変更2587 行追加213 行削除
  1. 2 1
      README.md
  2. 36 177
      deploy/cpp/CMakeLists.txt
  3. 21 1
      deploy/cpp/CMakeSettings.json
  4. 157 0
      deploy/cpp/demo/CMakeLists.txt
  5. 48 0
      deploy/cpp/demo/onnx_openvino/CMakeLists.txt
  6. 62 0
      deploy/cpp/demo/onnx_openvino/model_infer.cpp
  7. 2 2
      deploy/cpp/docs/manufacture_sdk/README.md
  8. 1 1
      deploy/cpp/encryption/include/paddle_model_decrypt.h
  9. 1 1
      deploy/cpp/encryption/include/paddle_model_encrypt.h
  10. 1 1
      deploy/cpp/encryption/include/paddle_stream_decrypt.h
  11. 3 1
      deploy/cpp/model_deploy/common/include/base_model.h
  12. 0 0
      deploy/cpp/model_deploy/common/include/deploy_declare.h
  13. 1 1
      deploy/cpp/model_deploy/common/include/multi_gpu_model.h
  14. 1 1
      deploy/cpp/model_deploy/common/include/paddle_deploy.h
  15. 23 3
      deploy/cpp/model_deploy/engine/include/engine_config.h
  16. 44 0
      deploy/cpp/model_deploy/engine/include/openvino_engine.h
  17. 140 0
      deploy/cpp/model_deploy/engine/src/openvino_engine.cpp
  18. 7 0
      deploy/cpp/model_deploy/ppseg/src/seg_postprocess.cpp
  19. 3 3
      deploy/cpp/scripts/build.sh
  20. 64 0
      deploy/cpp/scripts/onnx/openvino_build.sh
  21. 0 0
      deploy/cpp/scripts/onnx/tensorrt_build.sh
  22. 0 0
      deploy/cpp/scripts/onnx/triton_build.sh
  23. 61 0
      docs/FAQ/FAQ.md
  24. BIN
      docs/FAQ/images/FAQ1.png
  25. 144 0
      docs/Resful_API/docs/readme.md
  26. BIN
      docs/Resful_API/images/1.png
  27. BIN
      docs/Resful_API/images/10.png
  28. BIN
      docs/Resful_API/images/2.5.png
  29. BIN
      docs/Resful_API/images/2.6.png
  30. BIN
      docs/Resful_API/images/2.png
  31. BIN
      docs/Resful_API/images/3.png
  32. BIN
      docs/Resful_API/images/4.png
  33. BIN
      docs/Resful_API/images/5.5.png
  34. BIN
      docs/Resful_API/images/5.png
  35. BIN
      docs/Resful_API/images/6.png
  36. BIN
      docs/Resful_API/images/7.png
  37. BIN
      docs/Resful_API/images/8.png
  38. BIN
      docs/Resful_API/images/9.png
  39. 4 4
      docs/apis/datasets.md
  40. 1 1
      docs/apis/prediction.md
  41. 1 1
      docs/apis/transforms/transforms.md
  42. 60 0
      docs/appendix/anaconda_install.md
  43. 34 0
      docs/gui/download.md
  44. 100 0
      docs/gui/how_to_use.md
  45. 191 0
      docs/gui/restful/data_struct.md
  46. BIN
      docs/gui/restful/img/classify_help.jpg
  47. BIN
      docs/gui/restful/img/detect_help.jpg
  48. BIN
      docs/gui/restful/img/framework.png
  49. BIN
      docs/gui/restful/img/gui_use.png
  50. BIN
      docs/gui/restful/img/ins_seg_help.jpg
  51. BIN
      docs/gui/restful/img/restful_api.png
  52. BIN
      docs/gui/restful/img/seg_help.jpg
  53. BIN
      docs/gui/restful/img/start_restful.png
  54. BIN
      docs/gui/restful/img/web_demo.png
  55. 49 0
      docs/gui/restful/index.rst
  56. 89 0
      docs/gui/restful/introduction.md
  57. 222 0
      docs/gui/restful/quick_start.md
  58. 69 0
      docs/gui/restful/restful.md
  59. 871 0
      docs/gui/restful/restful_api.md
  60. 57 0
      docs/gui/restful/tree.md
  61. 4 4
      docs/install.md
  62. 3 2
      examples/meter_reader/README.md
  63. BIN
      examples/meter_reader/images/step5_4.png
  64. 1 1
      paddlex/cv/models/detector.py
  65. 9 7
      static/paddlex/deploy.py

+ 2 - 1
README.md

@@ -1,4 +1,4 @@
-# PaddleX全面升级动态图,2.0.0-rc3发布!
+# PaddleX全面升级动态图,2.0.0-rc4发布!
 
 
 
@@ -38,6 +38,7 @@
   * [PaddleX Restful开发模式安装](./docs/install.md#3-paddlex-restful开发模式安装)
 * [10分钟快速上手使用](./docs/quick_start.md)
 * [AIStudio在线项目示例](https://aistudio.baidu.com/aistudio/projectdetail/2159977)
+* [常见问题汇总](./docs/FAQ/FAQ.md)
 
 
 ### 2. 数据准备

+ 36 - 177
deploy/cpp/CMakeLists.txt

@@ -1,21 +1,29 @@
 cmake_minimum_required(VERSION 3.0)
 project(PaddleDeploy CXX C)
 
-option(WITH_MKL        "Compile demo with MKL/OpenBlas support,defaultuseMKL."          ON)
-option(WITH_GPU        "Compile demo with GPU/CPU, default use CPU."                    OFF)
-if (NOT WIN32)
-    option(WITH_STATIC_LIB "Compile demo with static/shared library, default use static."   OFF)
+if (WIN32)
+  option(WITH_STATIC_LIB "Compile demo with static/shared library, default use static."   ON)
 else()
-    option(WITH_STATIC_LIB "Compile demo with static/shared library, default use static."   ON)
+  option(WITH_STATIC_LIB "Compile demo with static/shared library, default use static."   OFF)
 endif()
-option(WITH_TENSORRT "Compile demo with TensorRT."   OFF)
-option(WITH_ENCRYPTION "Compile demo with ENCRYPTION."   OFF)
+# Paddle
+option(WITH_MKL        "Compile demo with MKL/OpenBlas support,defaultuseMKL."          ON)
+option(WITH_GPU        "Compile demo with GPU/CPU, default use CPU."                    OFF)
+option(WITH_PADDLE_TENSORRT "Compile demo with TensorRT."   OFF)
+#other engine
+option(WITH_OPENVINO "Compile demo with TensorRT."   OFF)
+option(WITH_ONNX_TENSORRT "Compile demo with TensorRT."   OFF)
 
+SET(OPENCV_DIR "" CACHE PATH "Location of libraries")
+SET(DEPS "" CACHE PATH "Location of libraries")
+# Paddle
 SET(TENSORRT_DIR "" CACHE PATH "Location of libraries")
 SET(PADDLE_DIR "" CACHE PATH "Location of libraries")
-SET(OPENCV_DIR "" CACHE PATH "Location of libraries")
 SET(CUDA_LIB "" CACHE PATH "Location of libraries")
-SET(OPENSSL_DIR "" CACHE PATH "Location of libraries")
+#OpenVINO
+SET(GFLAGS_DIR "" CACHE PATH "Location of libraries")
+SET(OPENVINO_DIR "" CACHE PATH "Location of libraries")
+SET(NGRAPH_LIB "" CACHE PATH "Location of libraries")
 
 SET(PROJECT_ROOT_DIR  "." CACHE PATH  "root directory of project.")
 
@@ -30,9 +38,17 @@ else()
     add_definitions(-DPADDLEX_DEPLOY)
 endif()
 
-#source
-include_directories("${CMAKE_SOURCE_DIR}/")
-link_directories("${CMAKE_CURRENT_BINARY_DIR}")
+#project
+include_directories("${PROJECT_SOURCE_DIR}")
+
+# common
+aux_source_directory(${PROJECT_SOURCE_DIR}/model_deploy/common/src SRC)
+
+# det seg clas pdx src
+aux_source_directory(${PROJECT_SOURCE_DIR}/model_deploy/ppdet/src DETECTOR_SRC)
+aux_source_directory(${PROJECT_SOURCE_DIR}/model_deploy/ppseg/src DETECTOR_SRC)
+aux_source_directory(${PROJECT_SOURCE_DIR}/model_deploy/ppclas/src DETECTOR_SRC)
+aux_source_directory(${PROJECT_SOURCE_DIR}/model_deploy/paddlex/src DETECTOR_SRC)
 
 #yaml-cpp
 if(WIN32)
@@ -40,68 +56,10 @@ if(WIN32)
 else()
   SET(YAML_BUILD_SHARED_LIBS ON CACHE BOOL "yaml build shared library.")
 endif(WIN32)
-include(${PROJECT_ROOT_DIR}/cmake/yaml-cpp.cmake)
+include(${PROJECT_SOURCE_DIR}/cmake/yaml-cpp.cmake)
 include_directories("${CMAKE_CURRENT_BINARY_DIR}/ext/yaml-cpp/src/ext-yaml-cpp/include")
 link_directories("${CMAKE_CURRENT_BINARY_DIR}/ext/yaml-cpp/lib")
 
-#paddle inference
-if (NOT DEFINED PADDLE_DIR OR ${PADDLE_DIR} STREQUAL "")
-    message(FATAL_ERROR "please set PADDLE_DIR with -DPADDLE_DIR=/path/paddle_influence_dir")
-endif()
-
-#paddle inference third party
-include_directories("${PADDLE_DIR}")
-include_directories("${PADDLE_DIR}/third_party/install/protobuf/include")
-include_directories("${PADDLE_DIR}/third_party/install/glog/include")
-include_directories("${PADDLE_DIR}/third_party/install/gflags/include")
-include_directories("${PADDLE_DIR}/third_party/install/xxhash/include")
-include_directories("${PADDLE_DIR}/third_party/install/cryptopp/include")
-
-link_directories("${PADDLE_DIR}/paddle/lib/")
-link_directories("${PADDLE_DIR}/third_party/install/protobuf/lib")
-link_directories("${PADDLE_DIR}/third_party/install/glog/lib")
-link_directories("${PADDLE_DIR}/third_party/install/gflags/lib")
-link_directories("${PADDLE_DIR}/third_party/install/xxhash/lib")
-link_directories("${PADDLE_DIR}/third_party/install/cryptopp/lib")
-
-if (WIN32)
-  set(DEPS ${DEPS} ${PADDLE_DIR}/paddle/lib/paddle_inference.lib)
-  set(DEPS ${DEPS} glog gflags_static libprotobuf xxhash cryptopp-static libyaml-cppmt shlwapi)
-else()
-  if (WITH_STATIC_LIB)
-    set(DEPS ${PADDLE_DIR}/paddle/lib/libpaddle_inference${CMAKE_STATIC_LIBRARY_SUFFIX})
-  else()
-    set(DEPS ${PADDLE_DIR}/paddle/lib/libpaddle_inference${CMAKE_SHARED_LIBRARY_SUFFIX})
-  endif()
-  set(DEPS ${DEPS} glog gflags protobuf xxhash cryptopp yaml-cpp)
-endif(WIN32)
-
-#MKL
-if(WITH_MKL)
-  ADD_DEFINITIONS(-DUSE_MKL)
-  set(MKLML_PATH "${PADDLE_DIR}/third_party/install/mklml")
-  include_directories("${MKLML_PATH}/include")
-  if (WIN32)
-    set(MATH_LIB ${MKLML_PATH}/lib/mklml.lib ${MKLML_PATH}/lib/libiomp5md.lib)
-  else ()
-    set(MATH_LIB ${MKLML_PATH}/lib/libmklml_intel${CMAKE_SHARED_LIBRARY_SUFFIX} ${MKLML_PATH}/lib/libiomp5${CMAKE_SHARED_LIBRARY_SUFFIX})
-    execute_process(COMMAND cp -r ${MKLML_PATH}/lib/libmklml_intel${CMAKE_SHARED_LIBRARY_SUFFIX} /usr/lib)
-  endif ()
-  set(MKLDNN_PATH "${PADDLE_DIR}/third_party/install/mkldnn")
-  if(EXISTS ${MKLDNN_PATH})
-    include_directories("${MKLDNN_PATH}/include")
-    if (WIN32)
-      set(MKLDNN_LIB ${MKLDNN_PATH}/lib/mkldnn.lib)
-    else ()
-      set(MKLDNN_LIB ${MKLDNN_PATH}/lib/libmkldnn.so.0)
-    endif ()
-  endif()
-else()
-  set(MATH_LIB ${PADDLE_DIR}/third_party/install/openblas/lib/libopenblas${CMAKE_STATIC_LIBRARY_SUFFIX})
-endif()
-
-set(DEPS ${DEPS} ${MATH_LIB} ${MKLDNN_LIB})
-
 #OPENCV
 if (NOT (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64"))
   if (NOT DEFINED OPENCV_DIR OR ${OPENCV_DIR} STREQUAL "")
@@ -125,62 +83,7 @@ endif ()
 set(DEPS ${DEPS} ${OpenCV_LIBS})
 include_directories(${OpenCV_INCLUDE_DIRS})
 
-
-if (WITH_TENSORRT AND WITH_GPU)
-  include_directories("${TENSORRT_DIR}/include")
-  link_directories("${TENSORRT_DIR}/lib")
-
-  file(READ ${TENSORRT_DIR}/include/NvInfer.h TENSORRT_VERSION_FILE_CONTENTS)
-  string(REGEX MATCH "define NV_TENSORRT_MAJOR +([0-9]+)" TENSORRT_MAJOR_VERSION
-    "${TENSORRT_VERSION_FILE_CONTENTS}")
-  if("${TENSORRT_MAJOR_VERSION}" STREQUAL "")
-    file(READ ${TENSORRT_DIR}/include/NvInferVersion.h TENSORRT_VERSION_FILE_CONTENTS)
-    string(REGEX MATCH "define NV_TENSORRT_MAJOR +([0-9]+)" TENSORRT_MAJOR_VERSION
-      "${TENSORRT_VERSION_FILE_CONTENTS}")
-  endif()
-  if("${TENSORRT_MAJOR_VERSION}" STREQUAL "")
-    message(SEND_ERROR "Failed to detect TensorRT version.")
-  endif()
-  string(REGEX REPLACE "define NV_TENSORRT_MAJOR +([0-9]+)" "\\1"
-    TENSORRT_MAJOR_VERSION "${TENSORRT_MAJOR_VERSION}")
-  message(STATUS "Current TensorRT header is ${TENSORRT_INCLUDE_DIR}/NvInfer.h. "
-    "Current TensorRT version is v${TENSORRT_MAJOR_VERSION}. ")
-endif()
-
-#set GPU
-if(WITH_GPU)
-  if (NOT DEFINED CUDA_LIB OR ${CUDA_LIB} STREQUAL "")
-    message(FATAL_ERROR "please set CUDA_LIB with -DCUDA_LIB=/path/cuda/lib64")
-  endif()
-
-  if(NOT WIN32)
-    if (NOT DEFINED CUDNN_LIB)
-      message(FATAL_ERROR "please set CUDNN_LIB with -DCUDNN_LIB=/path/cudnn/")
-    endif()
-
-    set(DEPS ${DEPS} ${CUDA_LIB}/libcudart${CMAKE_SHARED_LIBRARY_SUFFIX})
-    set(DEPS ${DEPS} ${CUDNN_LIB}/libcudnn${CMAKE_SHARED_LIBRARY_SUFFIX})
-
-    if (WITH_TENSORRT)
-      set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/libnvinfer${CMAKE_SHARED_LIBRARY_SUFFIX})
-      set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/libnvinfer_plugin${CMAKE_SHARED_LIBRARY_SUFFIX})
-    endif()
-
-  else()
-    set(DEPS ${DEPS} ${CUDA_LIB}/cudart${CMAKE_STATIC_LIBRARY_SUFFIX} )
-    set(DEPS ${DEPS} ${CUDA_LIB}/cublas${CMAKE_STATIC_LIBRARY_SUFFIX} )
-    set(DEPS ${DEPS} ${CUDA_LIB}/cudnn${CMAKE_STATIC_LIBRARY_SUFFIX})
-
-    if (WITH_TENSORRT)
-      set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/nvinfer${CMAKE_STATIC_LIBRARY_SUFFIX})
-      set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/nvinfer_plugin${CMAKE_STATIC_LIBRARY_SUFFIX})
-      if(${TENSORRT_MAJOR_VERSION} GREATER_EQUAL 7)
-        set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/myelin64_1${CMAKE_STATIC_LIBRARY_SUFFIX})
-      endif()
-    endif()
-  endif()
-endif()
-
+# MD
 macro(safe_set_static_flag)
     foreach(flag_var
         CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
@@ -216,20 +119,7 @@ else()
     set(DEPS ${DEPS} ${EXTERNAL_LIB})
 endif()
 
-message("-----DEPS = ${DEPS}")
-
-#project
-include_directories("${PROJECT_ROOT_DIR}")
-
-aux_source_directory(${PROJECT_ROOT_DIR}/model_deploy/common/src SRC)
-set(ENGINE_SRC ${PROJECT_ROOT_DIR}/model_deploy/engine/src/ppinference_engine.cpp)
-
-#detector seg
-aux_source_directory(${PROJECT_ROOT_DIR}/model_deploy/ppdet/src DETECTOR_SRC)
-aux_source_directory(${PROJECT_ROOT_DIR}/model_deploy/ppseg/src DETECTOR_SRC)
-aux_source_directory(${PROJECT_ROOT_DIR}/model_deploy/ppclas/src DETECTOR_SRC)
-aux_source_directory(${PROJECT_ROOT_DIR}/model_deploy/paddlex/src DETECTOR_SRC)
-
+# encryption
 set(ENCRYPTION_SRC "")
 if (WITH_ENCRYPTION)
   add_definitions(-DPADDLEX_DEPLOY_ENCRYPTION)
@@ -248,40 +138,9 @@ if (WITH_ENCRYPTION)
   aux_source_directory(${PROJECT_ROOT_DIR}/encryption/util/src/crypto ENCRYPTION_SRC)
 endif()
 
-add_executable(model_infer ${PROJECT_ROOT_DIR}/demo/model_infer.cpp ${SRC} ${ENGINE_SRC} ${DETECTOR_SRC} ${ENCRYPTION_SRC})
-ADD_DEPENDENCIES(model_infer ext-yaml-cpp)
-target_link_libraries(model_infer ${DEPS})
-
-add_executable(batch_infer ${PROJECT_ROOT_DIR}/demo/batch_infer.cpp ${SRC} ${ENGINE_SRC} ${DETECTOR_SRC} ${ENCRYPTION_SRC})
-ADD_DEPENDENCIES(batch_infer ext-yaml-cpp)
-target_link_libraries(batch_infer ${DEPS})
-
-add_executable(multi_gpu_model_infer ${PROJECT_ROOT_DIR}/demo/multi_gpu_model_infer.cpp ${SRC} ${ENGINE_SRC} ${DETECTOR_SRC} ${ENCRYPTION_SRC})
-ADD_DEPENDENCIES(multi_gpu_model_infer ext-yaml-cpp)
-target_link_libraries(multi_gpu_model_infer ${DEPS})
-
-if (WITH_TENSORRT)
-  add_executable(tensorrt_infer ${PROJECT_ROOT_DIR}/demo/tensorrt_infer.cpp ${SRC} ${ENGINE_SRC} ${DETECTOR_SRC} ${ENCRYPTION_SRC})
-  ADD_DEPENDENCIES(tensorrt_infer ext-yaml-cpp)
-  target_link_libraries(tensorrt_infer ${DEPS})
-endif()
-
-if(WIN32)
-  add_custom_command(TARGET model_infer POST_BUILD
-    COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.dll ${CMAKE_BINARY_DIR}/paddle_deploy
-    COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.dll ${CMAKE_BINARY_DIR}/paddle_deploy
-    COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_DIR}/third_party/install/mkldnn/lib/mkldnn.dll  ${CMAKE_BINARY_DIR}/paddle_deploy
-    COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_DIR}/paddle/lib/paddle_inference.dll ${CMAKE_BINARY_DIR}/paddle_deploy
-  )
-  if (WITH_TENSORRT)
-    add_custom_command(TARGET model_infer POST_BUILD
-      COMMAND ${CMAKE_COMMAND} -E copy ${TENSORRT_DIR}/lib/nvinfer.dll ${CMAKE_BINARY_DIR}/paddle_deploy
-      COMMAND ${CMAKE_COMMAND} -E copy ${TENSORRT_DIR}/lib/nvinfer_plugin.dll ${CMAKE_BINARY_DIR}/paddle_deploy
-    )
-    if(${TENSORRT_MAJOR_VERSION} GREATER_EQUAL 7)
-      add_custom_command(TARGET model_infer POST_BUILD
-        COMMAND ${CMAKE_COMMAND} -E copy ${TENSORRT_DIR}/lib/myelin64_1.dll ${CMAKE_BINARY_DIR}/paddle_deploy
-      )
-    endif()
-  endif()
+# select engine
+if(WITH_OPENVINO)
+  add_subdirectory(demo/onnx_openvino)
+else ()
+  add_subdirectory(demo)
 endif()

+ 21 - 1
deploy/cpp/CMakeSettings.json

@@ -44,7 +44,7 @@
           "type": "BOOL"
         },
         {
-          "name": "WITH_TENSORRT",
+          "name": "WITH_PADDLE_TENSORRT",
           "value": "False",
           "type": "BOOL"
         },
@@ -57,6 +57,26 @@
           "name": "OPENSSL_DIR",
           "value": "path\\to\\openssl1.1.0k",
           "type": "PATH"
+        },
+        {
+          "name": "WITH_OPENVINO",
+          "value": "False",
+          "type": "BOOL"
+        },
+        {
+          "name": "GFLAGS_DIR",
+          "value": "path\\to\\gflags",
+          "type": "PATH"
+        },
+        {
+          "name": "OPENVINO_DIR",
+          "value": "path\\to\\inference_engine",
+          "type": "PATH"
+        },
+        {
+          "name": "NGRAPH_LIB",
+          "value": "path\\to\\deployment_tools/ngraph",
+          "type": "PATH"
         }
       ]
     }

+ 157 - 0
deploy/cpp/demo/CMakeLists.txt

@@ -0,0 +1,157 @@
+#paddle inference
+if (NOT DEFINED PADDLE_DIR OR ${PADDLE_DIR} STREQUAL "")
+    message(FATAL_ERROR "please set PADDLE_DIR with -DPADDLE_DIR=/path/paddle_influence_dir")
+endif()
+
+#paddle inference third party
+include_directories("${PADDLE_DIR}")
+include_directories("${PADDLE_DIR}/third_party/install/protobuf/include")
+include_directories("${PADDLE_DIR}/third_party/install/glog/include")
+include_directories("${PADDLE_DIR}/third_party/install/gflags/include")
+include_directories("${PADDLE_DIR}/third_party/install/xxhash/include")
+include_directories("${PADDLE_DIR}/third_party/install/cryptopp/include")
+
+link_directories("${PADDLE_DIR}/paddle/lib/")
+link_directories("${PADDLE_DIR}/third_party/install/protobuf/lib")
+link_directories("${PADDLE_DIR}/third_party/install/glog/lib")
+link_directories("${PADDLE_DIR}/third_party/install/gflags/lib")
+link_directories("${PADDLE_DIR}/third_party/install/xxhash/lib")
+link_directories("${PADDLE_DIR}/third_party/install/cryptopp/lib")
+
+if (WIN32)
+  set(DEPS ${DEPS} ${PADDLE_DIR}/paddle/lib/paddle_inference.lib)
+  set(DEPS ${DEPS} glog gflags_static libprotobuf xxhash cryptopp-static libyaml-cppmt shlwapi)
+else()
+  if (WITH_STATIC_LIB)
+    set(DEPS ${DEPS} ${PADDLE_DIR}/paddle/lib/libpaddle_inference${CMAKE_STATIC_LIBRARY_SUFFIX})
+  else()
+    set(DEPS ${DEPS} ${PADDLE_DIR}/paddle/lib/libpaddle_inference${CMAKE_SHARED_LIBRARY_SUFFIX})
+  endif()
+  set(DEPS ${DEPS} glog gflags protobuf xxhash cryptopp yaml-cpp)
+endif(WIN32)
+
+#MKL
+if(WITH_MKL)
+  ADD_DEFINITIONS(-DUSE_MKL)
+  set(MKLML_PATH "${PADDLE_DIR}/third_party/install/mklml")
+  include_directories("${MKLML_PATH}/include")
+  if (WIN32)
+    set(MATH_LIB ${MKLML_PATH}/lib/mklml.lib ${MKLML_PATH}/lib/libiomp5md.lib)
+  else ()
+    set(MATH_LIB ${MKLML_PATH}/lib/libmklml_intel${CMAKE_SHARED_LIBRARY_SUFFIX} ${MKLML_PATH}/lib/libiomp5${CMAKE_SHARED_LIBRARY_SUFFIX})
+    execute_process(COMMAND cp -r ${MKLML_PATH}/lib/libmklml_intel${CMAKE_SHARED_LIBRARY_SUFFIX} /usr/lib)
+  endif ()
+  set(MKLDNN_PATH "${PADDLE_DIR}/third_party/install/mkldnn")
+  if(EXISTS ${MKLDNN_PATH})
+    include_directories("${MKLDNN_PATH}/include")
+    if (WIN32)
+      set(MKLDNN_LIB ${MKLDNN_PATH}/lib/mkldnn.lib)
+    else ()
+      set(MKLDNN_LIB ${MKLDNN_PATH}/lib/libmkldnn.so.0)
+    endif ()
+  endif()
+else()
+  set(MATH_LIB ${PADDLE_DIR}/third_party/install/openblas/lib/libopenblas${CMAKE_STATIC_LIBRARY_SUFFIX})
+endif()
+
+set(DEPS ${DEPS} ${MATH_LIB} ${MKLDNN_LIB})
+
+#set GPU
+if (WITH_PADDLE_TENSORRT AND WITH_GPU)
+  include_directories("${TENSORRT_DIR}/include")
+  link_directories("${TENSORRT_DIR}/lib")
+
+  file(READ ${TENSORRT_DIR}/include/NvInfer.h TENSORRT_VERSION_FILE_CONTENTS)
+  string(REGEX MATCH "define NV_TENSORRT_MAJOR +([0-9]+)" TENSORRT_MAJOR_VERSION
+    "${TENSORRT_VERSION_FILE_CONTENTS}")
+  if("${TENSORRT_MAJOR_VERSION}" STREQUAL "")
+    file(READ ${TENSORRT_DIR}/include/NvInferVersion.h TENSORRT_VERSION_FILE_CONTENTS)
+    string(REGEX MATCH "define NV_TENSORRT_MAJOR +([0-9]+)" TENSORRT_MAJOR_VERSION
+      "${TENSORRT_VERSION_FILE_CONTENTS}")
+  endif()
+  if("${TENSORRT_MAJOR_VERSION}" STREQUAL "")
+    message(SEND_ERROR "Failed to detect TensorRT version.")
+  endif()
+  string(REGEX REPLACE "define NV_TENSORRT_MAJOR +([0-9]+)" "\\1"
+    TENSORRT_MAJOR_VERSION "${TENSORRT_MAJOR_VERSION}")
+  message(STATUS "Current TensorRT header is ${TENSORRT_INCLUDE_DIR}/NvInfer.h. "
+    "Current TensorRT version is v${TENSORRT_MAJOR_VERSION}. ")
+endif()
+
+if(WITH_GPU)
+  if (NOT DEFINED CUDA_LIB OR ${CUDA_LIB} STREQUAL "")
+    message(FATAL_ERROR "please set CUDA_LIB with -DCUDA_LIB=/path/cuda/lib64")
+  endif()
+
+  
+  if(NOT WIN32)
+    if (NOT DEFINED CUDNN_LIB)
+      message(FATAL_ERROR "please set CUDNN_LIB with -DCUDNN_LIB=/path/cudnn/")
+    endif()
+
+    set(DEPS ${DEPS} ${CUDA_LIB}/libcudart${CMAKE_SHARED_LIBRARY_SUFFIX})
+    set(DEPS ${DEPS} ${CUDNN_LIB}/libcudnn${CMAKE_SHARED_LIBRARY_SUFFIX})
+
+    if (WITH_PADDLE_TENSORRT)
+      set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/libnvinfer${CMAKE_SHARED_LIBRARY_SUFFIX})
+      set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/libnvinfer_plugin${CMAKE_SHARED_LIBRARY_SUFFIX})
+    endif()
+
+  else()
+    set(DEPS ${DEPS} ${CUDA_LIB}/cudart${CMAKE_STATIC_LIBRARY_SUFFIX} )
+    set(DEPS ${DEPS} ${CUDA_LIB}/cublas${CMAKE_STATIC_LIBRARY_SUFFIX} )
+    set(DEPS ${DEPS} ${CUDA_LIB}/cudnn${CMAKE_STATIC_LIBRARY_SUFFIX})
+
+    if (WITH_PADDLE_TENSORRT)
+      set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/nvinfer${CMAKE_STATIC_LIBRARY_SUFFIX})
+      set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/nvinfer_plugin${CMAKE_STATIC_LIBRARY_SUFFIX})
+      if(${TENSORRT_MAJOR_VERSION} GREATER_EQUAL 7)
+        set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/myelin64_1${CMAKE_STATIC_LIBRARY_SUFFIX})
+      endif()
+    endif()
+  endif()
+endif()
+
+message("-----DEPS = ${DEPS}")
+
+# engine src
+set(ENGINE_SRC ${PROJECT_SOURCE_DIR}/model_deploy/engine/src/ppinference_engine.cpp)
+
+
+add_executable(model_infer model_infer.cpp ${SRC} ${ENGINE_SRC} ${DETECTOR_SRC} ${ENCRYPTION_SRC})
+ADD_DEPENDENCIES(model_infer ext-yaml-cpp)
+target_link_libraries(model_infer ${DEPS})
+
+add_executable(batch_infer batch_infer.cpp ${SRC} ${ENGINE_SRC} ${DETECTOR_SRC} ${ENCRYPTION_SRC})
+ADD_DEPENDENCIES(batch_infer ext-yaml-cpp)
+target_link_libraries(batch_infer ${DEPS})
+
+add_executable(multi_gpu_model_infer multi_gpu_model_infer.cpp ${SRC} ${ENGINE_SRC} ${DETECTOR_SRC} ${ENCRYPTION_SRC})
+ADD_DEPENDENCIES(multi_gpu_model_infer ext-yaml-cpp)
+target_link_libraries(multi_gpu_model_infer ${DEPS})
+
+if (WITH_PADDLE_TENSORRT)
+  add_executable(tensorrt_infer tensorrt_infer.cpp ${SRC} ${ENGINE_SRC} ${DETECTOR_SRC} ${ENCRYPTION_SRC})
+  ADD_DEPENDENCIES(tensorrt_infer ext-yaml-cpp)
+  target_link_libraries(tensorrt_infer ${DEPS})
+endif()
+
+if(WIN32)
+  add_custom_command(TARGET model_infer POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.dll ${CMAKE_BINARY_DIR}/paddle_deploy
+    COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.dll ${CMAKE_BINARY_DIR}/paddle_deploy
+    COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_DIR}/third_party/install/mkldnn/lib/mkldnn.dll  ${CMAKE_BINARY_DIR}/paddle_deploy
+    COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_DIR}/paddle/lib/paddle_inference.dll ${CMAKE_BINARY_DIR}/paddle_deploy
+  )
+  if (WITH_PADDLE_TENSORRT)
+    add_custom_command(TARGET model_infer POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy ${TENSORRT_DIR}/lib/nvinfer.dll ${CMAKE_BINARY_DIR}/paddle_deploy
+      COMMAND ${CMAKE_COMMAND} -E copy ${TENSORRT_DIR}/lib/nvinfer_plugin.dll ${CMAKE_BINARY_DIR}/paddle_deploy
+    )
+    if(${TENSORRT_MAJOR_VERSION} GREATER_EQUAL 7)
+      add_custom_command(TARGET model_infer POST_BUILD
+        COMMAND ${CMAKE_COMMAND} -E copy ${TENSORRT_DIR}/lib/myelin64_1.dll ${CMAKE_BINARY_DIR}/paddle_deploy
+      )
+    endif()
+  endif()
+endif()

+ 48 - 0
deploy/cpp/demo/onnx_openvino/CMakeLists.txt

@@ -0,0 +1,48 @@
+# Openvino
+include_directories("${OPENVINO_DIR}")
+include_directories("${OPENVINO_DIR}/include")
+include_directories("${OPENVINO_DIR}/external/tbb/include/tbb")
+link_directories("${OPENVINO_DIR}/lib")
+link_directories("${OPENVINO_DIR}/external/tbb/lib")
+
+link_directories("${NGRAPH_LIB}/lib")
+
+include_directories("${GFLAGS_DIR}/include")
+link_directories("${GFLAGS_DIR}/lib")
+
+if(WIN32)
+    link_directories("${OPENVINO_DIR}/lib/intel64/Release")
+    link_directories("${OPENVINO_DIR}/bin/intel64/Release")
+
+    set(DEPS ${DEPS} ${OPENVINO_DIR}/lib/intel64/Release/inference_engine${CMAKE_STATIC_LIBRARY_SUFFIX})
+    set(DEPS ${DEPS} ${OPENVINO_DIR}/lib/intel64/Release/inference_engine_legacy${CMAKE_STATIC_LIBRARY_SUFFIX})
+    set(DEPS ${DEPS} gflags_static libyaml-cppmt shlwapi)
+else()
+    if (${ARCH} STREQUAL "armv7")
+        if(WITH_STATIC_LIB)
+            set(DEPS ${DEPS} ${OPENVINO_DIR}/lib/armv7l/libinference_engine${CMAKE_STATIC_LIBRARY_SUFFIX})
+            set(DEPS ${DEPS} ${OPENVINO_DIR}/lib/armv7l/libinference_engine_legacy${CMAKE_STATIC_LIBRARY_SUFFIX})
+        else()
+            set(DEPS ${DEPS} ${OPENVINO_DIR}/lib/armv7l/libinference_engine${CMAKE_SHARED_LIBRARY_SUFFIX})
+            set(DEPS ${DEPS} ${OPENVINO_DIR}/lib/armv7l/libinference_engine_legacy${CMAKE_SHARED_LIBRARY_SUFFIX})
+        endif()
+    else()
+        if(WITH_STATIC_LIB)
+            set(DEPS ${DEPS} ${OPENVINO_DIR}/lib/intel64/libinference_engine${CMAKE_STATIC_LIBRARY_SUFFIX})
+            set(DEPS ${DEPS} ${OPENVINO_DIR}/lib/intel64/libinference_engine_legacy${CMAKE_STATIC_LIBRARY_SUFFIX})
+        else()
+            set(DEPS ${DEPS} ${OPENVINO_DIR}/lib/intel64/libinference_engine${CMAKE_SHARED_LIBRARY_SUFFIX})
+            set(DEPS ${DEPS} ${OPENVINO_DIR}/lib/intel64/libinference_engine_legacy${CMAKE_SHARED_LIBRARY_SUFFIX})
+        endif()
+    endif()
+    set(DEPS ${DEPS} gflags yaml-cpp)
+endif(WIN32)
+
+message("-----DEPS = ${DEPS}")
+
+# engine src
+set(ENGINE_SRC ${PROJECT_SOURCE_DIR}/model_deploy/engine/src/openvino_engine.cpp)
+
+add_executable(model_infer model_infer.cpp ${SRC} ${ENGINE_SRC} ${DETECTOR_SRC})
+ADD_DEPENDENCIES(model_infer ext-yaml-cpp)
+target_link_libraries(model_infer ${DEPS})

+ 62 - 0
deploy/cpp/demo/onnx_openvino/model_infer.cpp

@@ -0,0 +1,62 @@
+// Copyright (c) 2021 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.
+
+#include <gflags/gflags.h>
+#include <string>
+#include <vector>
+
+#include <opencv2/core/core.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+
+#include "model_deploy/common/include/paddle_deploy.h"
+
+DEFINE_string(xml_file, "", "Path of model xml file");
+DEFINE_string(bin_file, "", "Path of model bin file");
+DEFINE_string(cfg_file, "", "Path of yaml file");
+DEFINE_string(model_type, "", "model type");
+DEFINE_string(image, "", "Path of test image file");
+DEFINE_string(device, "CPU", "Infering with VPU or CPU");
+
+int main(int argc, char** argv) {
+  // Parsing command-line
+  google::ParseCommandLineFlags(&argc, &argv, true);
+
+  // create model
+  PaddleDeploy::Model* model = PaddleDeploy::CreateModel(FLAGS_model_type);
+
+
+  // model init
+  model->Init(FLAGS_cfg_file);
+
+  // engine init
+  PaddleDeploy::OpenVinoEngineConfig engine_config;
+  engine_config.xml_file_ = FLAGS_xml_file;
+  engine_config.bin_file_ = FLAGS_bin_file;
+  engine_config.batch_size_ = 1;
+  engine_config.device_ = FLAGS_device;
+  model->OpenVinoEngineInit(engine_config);
+
+  // prepare data
+  std::vector<cv::Mat> imgs;
+  imgs.push_back(std::move(cv::imread(FLAGS_image)));
+
+  // predict
+  std::vector<PaddleDeploy::Result> results;
+  model->Predict(imgs, &results, 1);
+
+  std::cout << results[0] << std::endl;
+  delete model;
+  return 0;
+}

+ 2 - 2
deploy/cpp/docs/manufacture_sdk/README.md

@@ -151,7 +151,7 @@ SDK的预处理中使用了OpenCV, 所以需要额外下载链接:
 
 三.编译运行
 
-windows编译可以看[表计读数案例](https://github.com/PaddlePaddle/PaddleX/tree/develop/dygraph/examples/meter_reader#8)
+windows编译可以看[表计读数案例](https://github.com/PaddlePaddle/PaddleX/tree/develop/examples/meter_reader)
 
 linux上需要修改CMakeLists.txt 各个库位置,然后执行一下几行命令:
 
@@ -173,4 +173,4 @@ pipeline_infer --pipeline_cfg /path/pipeline.yaml --image /path/image.png
 
 ## <h2 id="6">多模型串联的工业表计读数部署</h2>
 
-多模型串联可以看我们的[表计读数案例](https://github.com/PaddlePaddle/PaddleX/tree/develop/dygraph/examples/meter_reader#8), 里边有详细的部署介绍。
+多模型串联可以看我们的[表计读数案例](https://github.com/PaddlePaddle/PaddleX/tree/develop/examples/meter_reader), 里边有详细的部署介绍。

+ 1 - 1
deploy/cpp/encryption/include/paddle_model_decrypt.h

@@ -16,7 +16,7 @@
 #include <stdio.h>
 #include <string>
 
-#include "model_deploy/common/include/deploy_delacre.h"
+#include "model_deploy/common/include/deploy_declare.h"
 // #include "paddle/include/paddle_inference_api.h"  // NOLINT
 
 #ifndef PADDLE_MODEL_PROTECT_API_PADDLE_MODEL_DECRYPT_H

+ 1 - 1
deploy/cpp/encryption/include/paddle_model_encrypt.h

@@ -16,7 +16,7 @@
 #include <iostream>
 #include <string>
 
-#include "model_deploy/common/include/deploy_delacre.h"
+#include "model_deploy/common/include/deploy_declare.h"
 
 #ifndef PADDLE_MODEL_PROTECT_API_PADDLE_MODEL_ENCRYPT_H
 #define PADDLE_MODEL_PROTECT_API_PADDLE_MODEL_ENCRYPT_H

+ 1 - 1
deploy/cpp/encryption/include/paddle_stream_decrypt.h

@@ -16,7 +16,7 @@
 #include <stdio.h>
 #include <string>
 
-#include "model_deploy/common/include/deploy_delacre.h"
+#include "model_deploy/common/include/deploy_declare.h"
 
 #ifndef PADDLE_MODEL_PROTECT_API_PADDLE_STREAM_DECRYPT_H
 #define PADDLE_MODEL_PROTECT_API_PADDLE_STREAM_DECRYPT_H

+ 3 - 1
deploy/cpp/model_deploy/common/include/base_model.h

@@ -20,7 +20,7 @@
 
 #include "yaml-cpp/yaml.h"
 
-#include "model_deploy/common/include/deploy_delacre.h"
+#include "model_deploy/common/include/deploy_declare.h"
 #include "model_deploy/common/include/base_postprocess.h"
 #include "model_deploy/common/include/base_preprocess.h"
 #include "model_deploy/common/include/output_struct.h"
@@ -76,6 +76,8 @@ class PD_INFER_DECL Model {
 
   bool TensorRTInit(const TensorRTEngineConfig& engine_config);
 
+  bool OpenVinoEngineInit(const OpenVinoEngineConfig& engine_config);
+
   virtual bool PostprocessInit() {
     postprocess_ = nullptr;
     std::cerr << "model no Postprocess!" << std::endl;

+ 0 - 0
deploy/cpp/model_deploy/common/include/deploy_delacre.h → deploy/cpp/model_deploy/common/include/deploy_declare.h


+ 1 - 1
deploy/cpp/model_deploy/common/include/multi_gpu_model.h

@@ -17,7 +17,7 @@
 #include <thread> // NOLINT
 #include <vector>
 
-#include "model_deploy/common/include/deploy_delacre.h"
+#include "model_deploy/common/include/deploy_declare.h"
 #include "model_deploy/common/include/model_factory.h"
 #include "model_deploy/engine/include/engine.h"
 

+ 1 - 1
deploy/cpp/model_deploy/common/include/paddle_deploy.h

@@ -16,7 +16,7 @@
 #include <memory>
 #include <string>
 
-#include "model_deploy/common/include/deploy_delacre.h"
+#include "model_deploy/common/include/deploy_declare.h"
 #include "model_deploy/common/include/output_struct.h"
 #include "model_deploy/common/include/model_factory.h"
 #include "model_deploy/engine/include/engine.h"

+ 23 - 3
deploy/cpp/model_deploy/engine/include/engine_config.h

@@ -162,12 +162,27 @@ struct TensorRTEngineConfig {
   YAML::Node yaml_config_;
 };
 
+struct OpenVinoEngineConfig {
+  // openvino xml file path
+  std::string xml_file_ = "";
+
+  // openvino bin file path
+  std::string bin_file_ = "";
+
+  //  Set batchsize
+  int batch_size_ = 1;
+
+  //  Set Device {CPU, MYRIAD}
+  std::string device_ = "CPU";
+};
+
 struct InferenceConfig {
   std::string engine_type;
   union {
     PaddleEngineConfig* paddle_config;
     TritonEngineConfig* triton_config;
     TensorRTEngineConfig* tensorrt_config;
+    OpenVinoEngineConfig* openvino_config;
   };
 
   InferenceConfig() {
@@ -182,6 +197,8 @@ struct InferenceConfig {
       triton_config = new TritonEngineConfig();
     } else if ("tensorrt" == engine_type) {
       tensorrt_config = new TensorRTEngineConfig();
+    } else if ("openvino" == engine_type) {
+      openvino_config = new OpenVinoEngineConfig();
     }
   }
 
@@ -196,20 +213,23 @@ struct InferenceConfig {
     } else if ("tensorrt" == engine_type) {
       tensorrt_config = new TensorRTEngineConfig();
       *tensorrt_config = *(config.tensorrt_config);
+    } else if ("openvino" == engine_type) {
+      openvino_config = new OpenVinoEngineConfig();
+      *openvino_config = *(config.openvino_config);
     }
   }
 
   ~InferenceConfig() {
     if ("paddle" == engine_type) {
       delete paddle_config;
-      paddle_config = NULL;
     } else if ("triton" == engine_type) {
       delete triton_config;
-      triton_config = NULL;
     } else if ("tensorrt" == engine_type) {
       delete tensorrt_config;
-      tensorrt_config = NULL;
+    } else if ("openvino" == engine_type) {
+      delete openvino_config;
     }
+    paddle_config = NULL;
   }
 };
 

+ 44 - 0
deploy/cpp/model_deploy/engine/include/openvino_engine.h

@@ -0,0 +1,44 @@
+// Copyright (c) 2021 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.
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <inference_engine.hpp>
+
+#include "model_deploy/common/include/base_model.h"
+#include "model_deploy/common/include/output_struct.h"
+#include "model_deploy/engine/include/engine.h"
+
+namespace PaddleDeploy {
+
+class OpenVinoEngine : public InferEngine {
+ public:
+  virtual bool Init(const InferenceConfig& engine_config);
+
+  virtual bool Infer(const std::vector<DataBlob>& inputs,
+                     std::vector<DataBlob>* outputs);
+
+ private:
+  bool GetDtype(const InferenceEngine::TensorDesc &output_blob,
+                DataBlob *output);
+
+  InferenceEngine::OutputsDataMap out_maps_;
+  InferenceEngine::InputsDataMap inputInfo_;
+  InferenceEngine::ExecutableNetwork executable_network_;
+};
+
+}  // namespace PaddleDeploy

+ 140 - 0
deploy/cpp/model_deploy/engine/src/openvino_engine.cpp

@@ -0,0 +1,140 @@
+// Copyright (c) 2021 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.
+
+#include "model_deploy/engine/include/openvino_engine.h"
+
+namespace PaddleDeploy {
+bool Model::OpenVinoEngineInit(const OpenVinoEngineConfig& engine_config) {
+  infer_engine_ = std::make_shared<OpenVinoEngine>();
+  InferenceConfig config("openvino");
+  *(config.openvino_config) = engine_config;
+  return infer_engine_->Init(config);
+}
+
+bool OpenVinoEngine::Init(const InferenceConfig& infer_config) {
+  const OpenVinoEngineConfig& engine_config = *(infer_config.openvino_config);
+  InferenceEngine::Core ie;
+  InferenceEngine::CNNNetwork network = ie.ReadNetwork(
+                              engine_config.xml_file_,
+                              engine_config.bin_file_);
+  inputInfo_ = network.getInputsInfo();
+  out_maps_ = network.getOutputsInfo();
+  network.setBatchSize(engine_config.batch_size_);
+  if (engine_config.device_ == "MYRIAD") {
+    std::map<std::string, std::string> networkConfig;
+    networkConfig["VPU_HW_STAGES_OPTIMIZATION"] = "NO";
+    executable_network_ = ie.LoadNetwork(
+            network, engine_config.device_, networkConfig);
+  } else {
+    executable_network_ = ie.LoadNetwork(network, engine_config.device_);
+  }
+  return true;
+}
+
+bool OpenVinoEngine::Infer(const std::vector<DataBlob> &inputs,
+                          std::vector<DataBlob> *outputs) {
+  InferenceEngine::InferRequest infer_request =
+        executable_network_.CreateInferRequest();
+  int i = 0;
+  for (const auto & item : inputInfo_) {
+    InferenceEngine::TensorDesc input_tensor;
+    InferenceEngine::Blob::Ptr input_blob =
+        infer_request.GetBlob(item.first);
+    InferenceEngine::MemoryBlob::Ptr input_mem_blob =
+        InferenceEngine::as<InferenceEngine::MemoryBlob>(input_blob);
+    auto mem_blob_holder = input_mem_blob->wmap();
+    int size = std::accumulate(inputs[i].shape.begin(),
+                    inputs[i].shape.end(), 1, std::multiplies<int>());
+    if (inputs[i].dtype == 0) {
+      input_tensor.setPrecision(InferenceEngine::Precision::FP32);
+      float *blob_data = mem_blob_holder.as<float *>();
+      memcpy(blob_data, inputs[i].data.data(), size * sizeof(float));
+    } else if (inputs[i].dtype == 1) {
+      input_tensor.setPrecision(InferenceEngine::Precision::U64);
+      int64_t *blob_data = mem_blob_holder.as<int64_t *>();
+      memcpy(blob_data, inputs[i].data.data(), size * sizeof(int64_t));
+    } else if (inputs[i].dtype == 2) {
+      input_tensor.setPrecision(InferenceEngine::Precision::I32);
+      int *blob_data = mem_blob_holder.as<int *>();
+      memcpy(blob_data, inputs[i].data.data(), size * sizeof(int));
+    } else if (inputs[i].dtype == 3) {
+      input_tensor.setPrecision(InferenceEngine::Precision::U8);
+      uint8_t *blob_data = mem_blob_holder.as<uint8_t *>();
+      memcpy(blob_data, inputs[i].data.data(), size * sizeof(uint8_t));
+      infer_request.SetBlob(inputs[i].name, input_blob);
+    }
+    i += 1;
+  }
+
+  // do inference
+  infer_request.Infer();
+
+  for (const auto & output_map : out_maps_) {
+    DataBlob output;
+    std::string name = output_map.first;
+    output.name = name;
+    InferenceEngine::Blob::Ptr output_ptr = infer_request.GetBlob(name);
+    InferenceEngine::MemoryBlob::CPtr moutput =
+      InferenceEngine::as<InferenceEngine::MemoryBlob>(output_ptr);
+    InferenceEngine::TensorDesc blob_output = moutput->getTensorDesc();
+    InferenceEngine::SizeVector output_shape = blob_output.getDims();
+    int size = 1;
+    output.shape.clear();
+    for (auto& i : output_shape) {
+      size *= i;
+      output.shape.push_back(static_cast<int>(i));
+    }
+    GetDtype(blob_output, &output);
+    auto moutputHolder = moutput->rmap();
+    if (output.dtype == 0) {
+      output.data.resize(size * sizeof(float));
+      float* data = moutputHolder.as<float *>();
+      memcpy(output.data.data(), data, size * sizeof(float));
+    } else if (output.dtype == 1) {
+      output.data.resize(size * sizeof(int64_t));
+      int64_t* data = moutputHolder.as<int64_t *>();
+      memcpy(output.data.data(), data, size * sizeof(int64_t));
+    } else if (output.dtype == 2) {
+      output.data.resize(size * sizeof(int));
+      int* data = moutputHolder.as<int *>();
+      memcpy(output.data.data(), data, size * sizeof(int));
+    } else if (output.dtype == 3) {
+      output.data.resize(size * sizeof(uint8_t));
+      uint8_t* data = moutputHolder.as<uint8_t *>();
+      memcpy(output.data.data(), data, size * sizeof(uint8_t));
+    }
+    outputs->push_back(std::move(output));
+  }
+  return true;
+}
+
+bool OpenVinoEngine::GetDtype(const InferenceEngine::TensorDesc &output_blob,
+                          DataBlob *output) {
+  InferenceEngine::Precision output_precision = output_blob.getPrecision();
+  if (output_precision == 10) {
+    output->dtype = FLOAT32;
+  } else if (output_precision == 72) {
+    output->dtype = INT64;
+  } else if (output_precision == 70) {
+    output->dtype = INT32;
+  } else if (output_precision == 40) {
+    output->dtype = INT8;
+  } else {
+    std::cout << "can't paser the precision type" << std::endl;
+    return false;
+  }
+  return true;
+}
+
+}  //  namespace PaddleDeploy

+ 7 - 0
deploy/cpp/model_deploy/ppseg/src/seg_postprocess.cpp

@@ -74,6 +74,13 @@ bool SegPostprocess::RunV2(const DataBlob& output,
                    std::back_inserter(label_vector),
                    [](int64_t x) { return (uint8_t)x;});
     label_data = reinterpret_cast<const uint8_t*>(label_vector.data());
+  } else if (output.dtype == INT32) {  // int32
+    const int32_t* output_data =
+          reinterpret_cast<const int32_t*>(output.data.data());
+    std::transform(output_data, output_data + label_map_size * batch_size,
+                   std::back_inserter(label_vector),
+                   [](int32_t x) { return (uint8_t)x;});
+    label_data = reinterpret_cast<const uint8_t*>(label_vector.data());
   } else if (output.dtype == INT8) {  // uint8
     label_data = reinterpret_cast<const uint8_t*>(output.data.data());
   } else {

+ 3 - 3
deploy/cpp/scripts/build.sh

@@ -3,14 +3,14 @@ WITH_GPU=ON
 # 使用MKL or openblas
 WITH_MKL=ON
 # 是否集成 TensorRT(仅WITH_GPU=ON 有效)
-WITH_TENSORRT=OFF
+WITH_PADDLE_TENSORRT=OFF
 # TensorRT 的路径,如果需要集成TensorRT,需修改为您实际安装的TensorRT路径
 TENSORRT_DIR=$(pwd)/TensorRT/
 # Paddle 预测库路径, 请修改为您实际安装的预测库路径
 PADDLE_DIR=$(pwd)/paddle_inference
 # Paddle 的预测库是否使用静态库来编译
 # 使用TensorRT时,Paddle的预测库通常为动态库
-WITH_STATIC_LIB=ON
+WITH_STATIC_LIB=OFF
 # CUDA 的 lib 路径
 CUDA_LIB=/usr/local/cuda/lib64
 # CUDNN 的 lib 路径
@@ -37,7 +37,7 @@ cd build
 cmake .. \
     -DWITH_GPU=${WITH_GPU} \
     -DWITH_MKL=${WITH_MKL} \
-    -DWITH_TENSORRT=${WITH_TENSORRT} \
+    -DWITH_PADDLE_TENSORRT=${WITH_PADDLE_TENSORRT} \
     -DTENSORRT_DIR=${TENSORRT_DIR} \
     -DPADDLE_DIR=${PADDLE_DIR} \
     -DWITH_STATIC_LIB=${WITH_STATIC_LIB} \

+ 64 - 0
deploy/cpp/scripts/onnx/openvino_build.sh

@@ -0,0 +1,64 @@
+# OpenVINO预编译库inference_engine的路径
+OPENVINO_DIR=$INTEL_OPENVINO_DIR/inference_engine
+
+# ngraph lib的路径,编译openvino时通常会生成
+NGRAPH_LIB=$INTEL_OPENVINO_DIR/deployment_tools/ngraph
+
+# gflags预编译库的路径
+GFLAGS_DIR=$(pwd)/deps/gflags
+
+# opencv使用自带预编译版本
+OPENCV_DIR=$(pwd)/deps/opencv/
+
+#cpu架构
+ARCH=x86
+export ARCH
+
+#下载并编译 gflags
+GFLAGS_URL=https://bj.bcebos.com/paddlex/deploy/gflags.tar.gz
+if [ ! -d ${GFLAGS_DIR} ]; then
+    cd deps
+    wget -c ${GFLAGS_URL} -O glog.tar.gz
+    tar -zxvf glog.tar.gz
+    rm -rf glog.tar.gz
+    cd ..
+fi
+
+mkdir -p deps
+# opencv
+if [ "$ARCH" = "x86" ]; then
+    OPENCV_URL=https://bj.bcebos.com/paddlex/deploy/x86opencv/opencv.tar.bz2
+else
+    OPENCV_URL=https://bj.bcebos.com/paddlex/deploy/armlinux/opencv.tar.bz2
+fi
+if [ ! -d "./deps/opencv" ]; then
+    cd deps
+    wget -c ${OPENCV_URL}
+    tar xvfj opencv.tar.bz2
+    rm -rf opencv.tar.bz2
+    cd ..
+fi
+
+rm -rf build
+mkdir -p build
+cd build
+if [ ${ARCH} = "x86" ];then
+  cmake .. \
+      -DWITH_OPENVINO=ON \
+      -DOPENCV_DIR=${OPENCV_DIR} \
+      -DGFLAGS_DIR=${GFLAGS_DIR} \
+      -DOPENVINO_DIR=${OPENVINO_DIR} \
+      -DNGRAPH_LIB=${NGRAPH_LIB} \
+      -DARCH=${ARCH}
+  make -j16
+else
+  cmake .. \
+      -DWITH_OPENVINO=ON \
+      -DOPENCV_DIR=${OPENCV_DIR} \
+      -DGFLAGS_DIR=${GFLAGS_DIR} \
+      -DOPENVINO_DIR=${OPENVINO_DIR} \
+      -DNGRAPH_LIB=${NGRAPH_LIB} \
+      -DARCH=${ARCH} \
+      -DCMAKE_CXX_FLAGS="-march=armv7-a"
+  make
+fi

+ 0 - 0
deploy/cpp/scripts/tensorrt_build.sh → deploy/cpp/scripts/onnx/tensorrt_build.sh


+ 0 - 0
deploy/cpp/scripts/triton_build.sh → deploy/cpp/scripts/onnx/triton_build.sh


+ 61 - 0
docs/FAQ/FAQ.md

@@ -0,0 +1,61 @@
+# FAQ(常见问题)
+
+- [GUI相关问题](#GUI相关问题)
+- [API训练相关问题](#API训练相关问题)
+- [推理部署问题](#推理部署问题)
+
+## GUI相关问题
+**Q:**  GUI卡死后怎么解决?
+
+**A:**  卡死后点击一下这个按钮即可恢复正常。
+<p align="center">
+  <img src="./images/FAQ1.png"  alt="QR" align="middle" />
+</p>
+
+
+**Q:**  GUI训练时报错怎么办?
+
+**A:**  首先打开当前项目的日志文件,查看报错信息。
+
+例如此前将PaddleX GUI的工作空间设置在`D:/work_space`下,则根据在GUI上的项目ID和任务ID找到当前任务的日志文件,例如`D:/work_space/projects/P0001/T0001/err.log/err.log`和`D:/work_space/projects/P0001/T0001/err.log/out.log`
+
+如果无法定位出问题,可进一步查看PaddleX GUI的系统日志:例如在`C:/User/User_name/.paddlex/logs/paddlex.log`
+
+查看上述三个日志文件,基本可以定位出是否是显存不足、或者是数据路径不对等问题。如果是显存不足,请调低batch_size(需同时按比例调低学习率等参数)。其他无法解决的问题,可以前往GitHub[提ISSUE](https://github.com/PaddlePaddle/PaddleX/issues),描述清楚问题会有工程师及时回复。
+
+## API训练相关问题
+**Q:**  loss为nan时怎么办?
+
+**A:**  loss为nan表示梯度爆炸,导致loss为无穷大。这时候,需要将学习率(learning rate)调小,或者增大批大小(batch_size)。
+
+
+**Q:**  YOLO系列为什么要训练这么久?
+
+**A:**  像yolo系列的数据增强比较多,所以训练的epoch要求要多一点,具体在不同的数据集上的时候,训练参数需要调整一下。比如我们先前示例给出ppyolo,ppyolov2的训练参数都是针对COCO数据集换算到单卡上的配置,但是在昆虫这份数据集上的效果并不好,后来我们进行了调整,您可以参考我们调整的参数相应调整自己的参数,具体调了哪些可以看我们之前的[pr](https://github.com/PaddlePaddle/PaddleX/pull/853/files)。
+
+
+**Q:**  用命令行跑 `.\paddlex_inference\detector.exe` 这个指令没有什么提示,也没有输出,怎么回事?
+
+**A:**  可能是缺少dll,双击执行一下out目录下的detector.exe或model_infer.exe,会有提示。
+
+
+## 推理部署问题
+**Q:**  如何在程序中手动释放inference model和占用的显存?
+
+**A:**  在主进程中初始化predictor,然后在线程里完成图片的预测,这样使用是没有问题的。线程退出后显存不会释放,主进程退出才会释放显存。线程退出后,后续显存是可以复用的,不会一直增长。
+
+
+**Q:**  提高预测速度的策略都有哪些?
+
+**A:**  1. 可以考虑使用更加轻量的backbone;看看图像预处理和预测结果后处理有没有优化空间;相比于python推理预测,用C++会更快;同时对批量图片进行预测;可以尝试使用加速库,例如在CPU上部署时可以开启mkdldnn,或者使用用OpenVINO推理引擎加速性能,在Nvidia GPU上部署时可以使用TensorRT加速性能;
+2. 在测试性能时,需要注意给模型进行预热,例如先让模型预测100轮之后,再开始进行性能测试和记录,这样得到的性能指标才准确。
+
+
+**Q:**  预测结果如何可视化?
+
+**A:**  检测结果可以用`pdx.det.visualize`,分割结果可以用`pdx.seg.visualize`,API说明见[文档](https://github.com/PaddlePaddle/PaddleX/blob/develop/docs/apis/prediction.md)
+
+
+**Q:**  如何用旧的部署代码部署新的模型?
+
+**A:**  2.0版本的cpp部署支持新旧版本的paddlex/gui导出的模型进行部署, 但是python不兼容。 GUI新旧版本也不兼容, 新版本只能加载新版本训练的模型。

BIN
docs/FAQ/images/FAQ1.png


+ 144 - 0
docs/Resful_API/docs/readme.md

@@ -0,0 +1,144 @@
+# PaddleX_Restful API --快速搭建私有化训练云服务
+
+* ## 什么是Resetful
+* ## PaddleX_Restful API 说明
+* ## 如何快速使用PaddleX_Restful API 快速搭建私有化训练云平台
+
+
+
+## *什么是Resetful*
+
+RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。RESTFUL适用于移动互联网厂商作为业务接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源。
+
+简单来说就是用户可以起一个远端的服务,客户端通过http形式进行访问。
+
+## *PaddleX_Restful API 说明*
+
+PaddleX RESTful是基于PaddleX开发的RESTful API。对于开发者来说只需要简单的指令便可开启PaddleX RESTful服务。对于哪些有远程训练要求,同时为了数据保密的开发者来说,PaddleX_Restful API简单易用的操作可以很好的满足上述要求。
+
+开启RESTful服务后可以实现如下功能:
+
+* 通过下载基于RESTful API的GUI连接开启RESTful服务的服务端,实现远程深度学习全流程开发。
+* 通过使用web demo连接开启RESTful服务的服务端,实现远程深度学习全流程开发。
+* 根据RESTful API来开发您自己个性化的可视化界面。
+
+
+<div align="center">
+<img src="../images/1.png"  width = "500" />              </div>
+
+## *如何快速使用PaddleX_Restful API 快速搭建私有化训练云平台*
+
+在该示例中PaddleX_Restful运行在一台带GPU的linux服务器下,用户通过其他电脑连接该服务器进行远程的操作。
+### 1  环境准备
+在服务器下载PaddlePaddle和PaddleX及其他依赖
+
+* 下载PaddlePaddle
+
+`pip install paddlepaddle-gpu -i `
+
+* 下载PaddleX
+
+pip install paddlex==1.3.11 -i
+
+* 下载pycuda(如果不使用GPU,该项可不进行下载)
+
+pip install pycuda -i
+
+### 2  启动Restful服务
+
+在服务器上启动如下命令,其中端口号是用户自定义的,`workspace_dir`是用户在服务器创建的
+
+`paddlex_restful --start_restful --port [端口号] --workspace_dir [工作空间地址]`
+
+例如开启一个端口为27000,工作路径在`cv/x/resful_space`的一个服务
+
+`paddlex_restful --start_restful --port 27000 --workspace_dir cv/x/resful_space`
+
+<div align="center">
+<img src="../images/2.png"  width = "800" />              </div>
+
+出现上述图片所示的内容,即为开启服务成功。
+
+### 3 启动客户端进行远程全流程训练
+
+为了方便大家进行远程调试,PaddleX_Restful提供了两张访问形式,一个是Web图形化界面,另一个是客户端的图形化界面
+* ## Web图像化界面
+
+### 3.1 打开Web界面
+当用户启动Restful服务后,在Web界面的导航栏只需要输入IP地址和端口号即可。例如当前案例的IP地址是222.95.100.37 端口号是25001
+
+即在导航栏输入 `http://222.95.100.37:25001/` 即可出现如下界面
+
+<div align="center">
+<img src="../images/2.5.png"  width = "800" />              </div>
+
+### 3.2 服务器设置
+点击界面中内容,在将服务器进行设置
+
+<div align="center">
+<img src="../images/2.6.png"  width = "800" />              </div>
+
+### 3.3 下载示例项目
+
+用户根据自己的需求,选择是否下载示例项目
+
+<div align="center">
+<img src="../images/3.png"  width = "800" />              </div>
+
+最终画面如下图所示
+
+<div align="center">
+<img src="../images/4.png"  width = "800" />              </div>
+
+### 3.4 创建数据集
+用户如果要自定义训练,首先需要去创建用户自身的数据集,
+在此之前,用户首先需要将数据集上传到服务器上。
+
+<div align="center">
+<img src="../images/5.png"  width = "800" />              </div>
+
+输入在服务上数据存储的路径,开始导入数据,在服务器上传的数据集,必须是符合PaddleX训练数据的命名格式要求。
+
+<div align="center">
+<img src="../images/5.5.png"  width = "800" />              </div>
+
+<div align="center">
+<img src="../images/6.png"  width = "800" />              </div>
+
+数据导入成功后,进行数据集划分
+<div align="center">
+<img src="../images/7.png"  width = "800" />              </div>
+
+用户在划分完成数据集后,也可对数据集进行可视化观察
+<div align="center">
+<img src="../images/8.png"  width = "800" />              </div>
+
+### 3.5 开始训练
+
+在数据集创建完成后,用户可创建新项目,并进行训练
+
+<div align="center">
+<img src="../images/9.png"  width = "800" />              </div>
+
+配置好相关参数后,点击开始训练,便开始进行训练。
+<div align="center">
+<img src="../images/10.png"  width = "800" />              </div>
+
+
+* ## 客户端图形化界面
+客户端操作流程和Web界面基本一致,提供了MAC和Windows版本两种,用户可自行下载并操作
+
+- [MAC](https://bj.bcebos.com/paddlex/PaddleX_Remote_GUI/mac/PaddleX_Remote_GUI.zip)
+- [Windows](https://bj.bcebos.com/paddlex/PaddleX_Remote_GUI/windows/PaddleX_Remote_GUI.zip)
+
+### 4  Restful 二次开发说明
+
+开发者可以使用PaddleX RESTful API 进行二次开发,按照自己的需求开发可视化界面,详细请参考以下文档  
+
+[RESTful API 二次开发简介](../..//gui/restful/restful.md)  
+
+[快速开始](../../gui/restful/quick_start.md)  
+
+[API 参考文档](../../gui/restful/restful_api.md)  
+
+[自定义数据结构](../../gui/restful/data_struct.md)

BIN
docs/Resful_API/images/1.png


BIN
docs/Resful_API/images/10.png


BIN
docs/Resful_API/images/2.5.png


BIN
docs/Resful_API/images/2.6.png


BIN
docs/Resful_API/images/2.png


BIN
docs/Resful_API/images/3.png


BIN
docs/Resful_API/images/4.png


BIN
docs/Resful_API/images/5.5.png


BIN
docs/Resful_API/images/5.png


BIN
docs/Resful_API/images/6.png


BIN
docs/Resful_API/images/7.png


BIN
docs/Resful_API/images/8.png


BIN
docs/Resful_API/images/9.png


+ 4 - 4
docs/apis/datasets.md

@@ -16,7 +16,7 @@ paddlex.datasets.ImageNet(data_dir, file_list, label_list, transforms=None, num_
 ```
 读取ImageNet格式的分类数据集,并对样本进行相应的处理。ImageNet数据集格式的介绍可查看文档:[数据集格式说明](../data/format/classification.md)  
 
-示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/dygraph/tutorials/train/image_classification/mobilenetv3_small.py)
+示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/image_classification/mobilenetv3_small.py)
 
 > **参数**
 >
@@ -35,7 +35,7 @@ paddlex.datasets.VOCDetection(data_dir, file_list, label_list, transforms=None,
 
 > 读取PascalVOC格式的检测数据集,并对样本进行相应的处理。PascalVOC数据集格式的介绍可查看文档:[数据集格式说明](../data/format/detection.md)  
 
-> 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/dygraph/tutorials/train/object_detection/yolov3_darknet53.py)
+> 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/object_detection/yolov3_darknet53.py)
 
 > **参数**
 >
@@ -77,7 +77,7 @@ paddlex.datasets.CocoDetection(data_dir, ann_file, transforms=None, num_workers=
 
 > 读取MSCOCO格式的检测数据集,并对样本进行相应的处理,该格式的数据集同样可以应用到实例分割模型的训练中。MSCOCO数据集格式的介绍可查看文档:[数据集格式说明](../data/format/instance_segmentation.md)  
 
-> 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/dygraph/tutorials/train/instance_segmentation/mask_rcnn_r50_fpn.py)
+> 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/instance_segmentation/mask_rcnn_r50_fpn.py)
 
 > **参数**
 >
@@ -118,7 +118,7 @@ paddlex.datasets.SegDataset(data_dir, file_list, label_list=None, transforms=Non
 
 > 读取语义分割任务数据集,并对样本进行相应的处理。语义分割任务数据集格式的介绍可查看文档:[数据集格式说明](../data/format/segmentation.md)  
 
-> 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/dygraph/tutorials/train/semantic_segmentation/unet.py)
+> 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/semantic_segmentation/unet.py)
 
 > **参数**
 >

+ 1 - 1
docs/apis/prediction.md

@@ -58,7 +58,7 @@ result = model.predict(test_jpg)
 pdx.det.visualize(test_jpg, result, threshold=0.5, save_dir='./')
 ```
 - MaskRCNN模型predict接口[说明文档](./apis/models/instance_segmentation.md#predict)
-- 可视化pdx.det.visualize接口[说明文档](https://github.com/PaddlePaddle/PaddleX/blob/develop/dygraph/paddlex/cv/models/utils/visualize.py#L25)
+- 可视化pdx.det.visualize接口[说明文档](https://github.com/PaddlePaddle/PaddleX/blob/develop/paddlex/cv/models/utils/visualize.py#L25)
 
 **注意**:目标检测和实例分割模型在调用`predict`接口得到的结果需用户自行过滤低置信度结果,在`paddlex.det.visualize`接口中,我们提供了`threshold`用于过滤,置信度低于此值的结果将被过滤,不会可视化。
 ![](./images/mask_predict.jpg)

+ 1 - 1
docs/apis/transforms/transforms.md

@@ -27,7 +27,7 @@
 paddlex.transforms.Compose(transforms)
 ```
 
-根据数据预处理/增强算子对输入数据进行操作。  [使用示例](https://github.com/PaddlePaddle/PaddleX/blob/develop/dygraph/tutorials/train/image_classification/mobilenetv3_small.py#L10)
+根据数据预处理/增强算子对输入数据进行操作。  [使用示例](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/image_classification/mobilenetv3_small.py#L10)
 
 > **参数**
 > * **transforms** (List[paddlex.transforms.Transform]): 数据预处理/数据增强列表。

+ 60 - 0
docs/appendix/anaconda_install.md

@@ -0,0 +1,60 @@
+# Anaconda安装使用
+Anaconda是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。使用Anaconda可以通过创建多个独立的Python环境,避免用户的Python环境安装太多不同版本依赖导致冲突。
+
+## Windows安装Anaconda
+### 第一步 下载
+- 在Anaconda官网[(https://www.anaconda.com/products/individual)](https://www.anaconda.com/products/individual)选择下载Windows Python3.7 64-Bit版本
+- 确保已经安装`Visual C++ Build Tools`(可以在开始菜单中找到),如未安装,请[点击下载](https://go.microsoft.com/fwlink/?LinkId=691126)安装。
+
+### 第二步 安装
+运行下载的安装包(以.exe为后辍),根据引导完成安装, 用户可自行修改安装目录(如下图)
+![](images/anaconda_windows.png)
+
+### 第三步 使用
+- 点击Windows系统左下角的Windows图标,打开:所有程序->Anaconda3/2(64-bit)->Anaconda Prompt  
+- 在命令行中执行下述命令
+```cmd
+# 创建名为my_paddlex的环境,指定Python版本为3.7
+conda create -n my_paddlex python=3.7
+# 进入my_paddlex环境
+conda activate my_paddlex
+# 安装git
+conda install git
+# 安装pycocotools
+pip install cython
+pip install git+https://gitee.com/jiangjiajun/philferriere-cocoapi.git#subdirectory=PythonAPI
+# 安装paddlepaddle-gpu
+pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
+# 安装paddlex
+pip install paddlex -i https://mirror.baidu.com/pypi/simple
+```  
+按如上方式配置后,即可在环境中使用PaddleX了,命令行输入`python`回车后,`import paddlex`试试吧,之后再次使用都可以通过打开'所有程序->Anaconda3/2(64-bit)->Anaconda Prompt',再执行`conda activate my_paddlex`进入环境后,即可再次使用paddlex
+
+## Linux/Mac安装
+
+### 第一步 下载
+在Anaconda官网[(https://www.anaconda.com/products/individual)](https://www.anaconda.com/products/individual)选择下载对应系统 Python3.7版本下载(Mac下载Command Line Installer版本即可)
+
+### 第二步 安装
+打开终端,在终端安装Anaconda
+```
+# ~/Downloads/Anaconda3-2019.07-Linux-x86_64.sh即下载的文件
+bash ~/Downloads/Anaconda3-2019.07-Linux-x86_64.sh
+```
+安装过程中一直回车即可,如提示设置安装路径,可根据需求修改,一般默认即可。
+
+### 第三步 使用
+```
+# 创建名为my_paddlex的环境,指定Python版本为3.7
+conda create -n my_paddlex python=3.7
+# 进入paddlex环境
+conda activate my_paddlex
+# 安装pycocotools
+pip install cython
+pip install pycocotools
+# 安装paddlepaddle-gpu
+pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
+# 安装paddlex
+pip install paddlex -i https://mirror.baidu.com/pypi/simple
+```
+按如上方式配置后,即可在环境中使用PaddleX了,终端输入`python`回车后,`import paddlex`试试吧,之后再次使用只需再打开终端,再执行`conda activate my_paddlex`进入环境后,即可使用paddlex

+ 34 - 0
docs/gui/download.md

@@ -0,0 +1,34 @@
+# 下载安装
+
+下载地址:https://www.paddlepaddle.org.cn/paddlex
+
+
+## 安装方式
+
+**注意:安装/解压路径请务必在不包含中文和空格的路径下,否则会导致可能无法正确训练模型**
+
+- Windows下载后双击后选择安装路径即可
+- Mac/Ubuntu下载后解压即可
+
+
+## 安装推荐环境
+
+* **操作系统**:
+  * Windows 10;
+  * Mac OS 10.13+;
+  * Ubuntu 18.04(Ubuntu暂只支持18.04);
+
+***注:处理器需为x86_64架构,支持MKL。***
+
+* **训练硬件**:  
+  * **GPU**(仅Windows及Linux系统):  
+    推荐使用支持CUDA的NVIDIA显卡,例如:GTX 1070+以上性能的显卡;  
+    Windows系统X86_64驱动版本>=411.31;  
+    Linux系统X86_64驱动版本>=410.48;  
+    显存8G以上;  
+  * **CPU**:  
+    PaddleX当前支持您用本地CPU进行训练,但推荐使用GPU以获得更好的开发体验。
+  * **内存**:建议8G以上  
+  * **硬盘空间**:建议SSD剩余空间1T以上(非必须)  
+
+***注:PaddleX在Mac OS系统只支持CPU训练。Windows系统只支持单GPU卡训练。***

+ 100 - 0
docs/gui/how_to_use.md

@@ -0,0 +1,100 @@
+# 使用方法
+
+*注:如果你的系统是 Mac OS 10.15.5及以上,在双击客户端icon后,需要在Terminal中执行 sudo xattr -r -d com.apple.quarantine /Users/username/PaddleX ,并稍等几秒来启动客户端,其中 /Users/username/PaddleX 为您保存PaddleX的文件夹路径*
+
+## 准备和导入数据
+
+**第一步: 准备数据**
+在开始模型训练前,您需要根据不同的任务类型,将数据标注为相应的格式。目前PaddleX支持【图像分类】、【目标检测】、【语义分割】、【实例分割】四种任务类型。  
+开发者可以参考PaddleX使用文档中的[2.数据准备-数据标注](../data/annotations/index.html)来进行数据标注和转换工作。 如若开发者自行准备数据,请注意数据格式与PaddleX支持四种数据格式是否一致。
+
+
+
+**第二步:导入的据集**
+
+①数据标注完成后,您需要根据不同的任务,将数据和标注文件,按照客户端提示更名并保存到正确的文件中。
+
+②在客户端新建数据集,选择与数据集匹配的任务类型,并选择数据集对应的路径,将数据集导入。
+
+![](images/datasets1.jpg)
+
+③选定导入数据集后,客户端会自动校验数据及标注文件是否合规,校验成功后,您可根据实际需求,将数据集按比例划分为训练集、验证集、测试集。
+
+④您可在「数据分析」模块按规则预览您标注的数据集,双击单张图片可放大查看。
+
+![](images/dataset2.jpg)
+
+
+## 创建项目和任务
+
+**第一步:创建项目**
+
+① 在完成数据导入后,您可以点击「新建项目」创建一个项目。
+
+② 您可根据实际任务需求选择项目的任务类型,需要注意项目所采用的数据集也带有任务类型属性,两者需要进行匹配。
+
+![](images/project3.jpg)
+
+
+
+**第二步:项目开发**
+
+① **数据选择**:项目创建完成后,您需要选择已载入客户端并校验后的数据集,并点击下一步,进入参数配置页面。
+
+![](images/project1.jpg)
+
+② **参数配置**:主要分为**模型参数**、**训练参数**、**优化策略**三部分。您可根据实际需求选择模型结构、骨架网络及对应的训练参数、优化策略,使得任务效果最佳。
+
+![](images/project2.jpg)
+
+## 任务模型训练
+
+参数配置完成后,点击启动训练,模型开始训练并进行效果评估。
+
+① **训练可视化**:在训练过程中,您可通过VisualDL查看模型训练过程参数变化、日志详情,及当前最优的训练集和验证集训练指标。模型在训练过程中通过点击"中止训练"随时中止训练过程。
+
+![](images/visualization1.jpg)
+
+模型训练结束后,可选择进入『模型剪裁分析』或者直接进入『模型评估』。
+
+![](images/visualization2.jpg)
+
+> 模型训练是最容易出错的步骤,经常遇到的原因为电脑无法联网下载预训练模型、显存不够。训练检测模型\实例分割模型对于显存要求较高,**建议用户通过在Windows/Mac/Ubuntu的命令行终端(Windows的Cmd命令终端)执行`nvidia-smi`命令**查看显存情况,请不要使用系统自带的任务管理器查看。  
+
+## 任务模型裁剪训练
+
+此步骤可选,模型裁剪训练相对比普通的任务模型训练,需要消耗更多的时间,需要在正常任务模型训练的基础上,增加『**模型裁剪分类**』和『**模型裁剪训练**』两个步骤。  
+
+裁剪过程将对模型各卷积层的敏感度信息进行分析,根据各参数对模型效果的影响进行不同比例的裁剪,再进行精调训练获得最终裁剪后的模型。  
+裁剪训练后的模型体积,计算量都会减少,并且可以提升模型在低性能设备的预测速度,如移动端,边缘设备,CPU。
+
+在可视化客户端上,**用户训练好模型后**,在训练界面,
+- 首先,点击『模型裁剪分析』,此过程将会消耗较长的时间
+- 接着,点击『开始模型裁剪训练』,客户端会创建一个新的任务,无需修改参数,直接再启动训练即可
+
+![](images/visualization3.jpg)
+
+## 模型效果评估
+
+在模型评估页面,您可查看训练后的模型效果。评估方法包括混淆矩阵、精度、召回率等。
+
+![](images/visualization4.jpg)
+
+您还可以选择『数据集切分』时留出的『测试数据集』或从本地文件夹中导入一张/多张图片,将训练后的模型进行测试。根据测试结果,您可决定是否将训练完成的模型保存为预训练模型并进入模型发布页面,或返回先前步骤调整参数配置重新进行训练。
+
+![](images/visualization5.jpg)
+
+## 模型发布
+
+当模型效果满意后,您可根据实际的生产环境需求,选择将模型发布为需要的版本。  
+> 如若要部署到移动端/边缘设备,对于部分支持量化的模型,还可以根据需求选择是否量化。量化可以压缩模型体积,提升预测速度
+
+![](images/publish.jpg)
+
+
+
+
+
+**如果您有任何问题或建议,欢迎以issue的形式,或加入PaddleX官方QQ群(1045148026)直接反馈您的问题和需求**
+
+![](images/QR.jpg)

+ 191 - 0
docs/gui/restful/data_struct.md

@@ -0,0 +1,191 @@
+# 数据结构
+本文档用于说明PaddleX RESTful模块自定义的数据结构
+
+## Protobuf结构化数据
+```
+message Dataset {
+    string id = 1;
+    string name = 2;
+    string desc = 3;
+    // 'classification': 分类数据
+    // 'segmentation': 分割数据
+    // 'detection_voc': 检测数据(仅用于检测)
+    // 'detection_coco': 检测数据(用于检测,分割,实例分割)
+    string type = 4;
+    string path = 5;
+    string create_time = 6;
+}
+
+message Project {
+    string id = 1;
+    string name = 2;
+    string desc = 3;
+    // 'classification'
+    // 'segmentation'
+    // 'segmentation'
+    // 'instance_segmentation'
+    // 'remote_segmentation'
+    string type = 4;
+    string did = 5;
+    string path = 6;
+    string create_time = 7;
+}
+
+message Task {
+    string id = 1;
+    string name = 2;
+    string desc = 3;
+    string pid = 4;
+    string path = 5;
+    string create_time = 6;
+    //裁剪任务id
+    string parent_id = 7;
+}
+
+message PretrainedModel {
+    string id = 1;
+    string name = 2;
+    string model = 3;
+    string type = 4;
+    // 所属项目id
+    string pid = 5;
+    string tid = 6;
+    string create_time = 7;
+    string path = 8;
+}
+
+message ExportedModel {
+    string id = 1;
+    string name = 2;
+    string model = 3;
+    string type = 4;
+    // 所属项目id
+    string pid = 5;
+    string tid = 6;
+    string create_time = 7;
+    string path = 8;
+    int32 exported_type = 9;
+}
+
+message Workspace {
+    string version = 1;
+    string path = 2;
+    map<string, Dataset> datasets = 3;
+    map<string, Project> projects = 4;
+    map<string, Task> tasks = 5;
+    int32 max_dataset_id = 6;
+    int32 max_project_id = 7;
+    int32 max_task_id = 8;
+    string current_time = 9;
+
+    int32 max_pretrained_model_id = 10;
+    map<string, PretrainedModel> pretrained_models = 11;
+
+    int32 max_exported_model_id = 12;
+    map<string, ExportedModel> exported_models = 13;
+}
+
+```
+
+## 状态枚举变量
+### DatasetStatus(数据集状态变量)
+```
+DatasetStatus = Enum('DatasetStatus',  
+('XEMPTY', #空数据集  
+'XCHECKING', #正在验证数据集  
+'XCHECKFAIL', #数据集验证失败  
+'XCOPYING',  #正在导入数据集  
+'XCOPYDONE', #数据集导入成功  
+'XCOPYFAIL', #数据集导入失败  
+'XSPLITED' #数据集已经切分  
+),start=0)
+```
+
+### TaskStatus(任务状态变量)
+```
+TaskStatus = Enum('TaskStatus',
+('XUNINIT',#任务还未初始化
+'XINIT',#任务初始化
+'XDOWNLOADING',#正在下载预训练模型
+'XTRAINING',#任务正在运行中,改状态下任务不能被删除
+'XTRAINDONE',#任务完成运行
+'XEVALUATED',#任务评估完成
+'XEXPORTING',#任务正在导出inference模型
+'XEXPORTED',#任务已经导出模型
+'XTRAINEXIT', #任务运行中止
+'XDOWNLOADFAIL', #任务下载失败
+'XTRAINFAIL', #任务运行失败
+'XEVALUATING',#任务评估中
+'XEVALUATEFAIL', #任务评估失败
+'XEXPORTFAIL', #任务导出模型失败
+'XPRUNEING', #裁剪分析任务运行中
+'XPRUNETRAIN'#裁剪训练任务运行中
+),start=0)
+```
+### ProjectType(项目类型)
+
+```
+ProjectType = Enum('ProjectType',
+('classification',#分类
+'detection',#检测
+'segmentation',#分割
+'instance_segmentation',#实例分割
+'remote_segmentation'#遥感分割
+),start=0)
+```
+
+### DownloadStatus(下载状态变量)
+
+```
+DownloadStatus = Enum('DownloadStatus',
+('XDDOWNLOADING',#下载中
+'XDDOWNLOADFAIL',#下载失败
+'XDDOWNLOADDONE',下载完成
+'XDDECOMPRESSED'解压完成
+),start=0)
+```
+
+
+### PruneStatus(裁剪状态变量)
+
+```
+PruneStatus = Enum('PruneStatus',
+('XSPRUNESTART',#启动裁剪任务
+'XSPRUNEING',#正在裁剪模型
+'XSPRUNEDONE',#已完成裁剪任务
+'XSPRUNEFAIL',#裁剪任务失败
+'XSPRUNEEXIT',#裁剪任务已经停止
+),start=0)
+```
+
+### PredictStatus(预测任务状态变量)
+
+```
+PredictStatus = Enum('PredictStatus',
+('XPRESTART',#预测开始
+'XPREDONE',#预测完成
+'XPREFAIL'#预测失败
+), start=0)
+```
+### PretrainedModelStatus(预训练模型状态变量)
+
+```
+PretrainedModelStatus = Enum('PretrainedModelStatus',
+('XPINIT', #初始化
+'XPSAVING', #正在保存
+'XPSAVEFAIL',#保存失败
+'XPSAVEDONE' #保存完成
+),start=0)
+```
+
+### ExportedModelType(模型导出状态变量)
+```
+ExportedModelType = Enum('ExportedModelType',
+('XQUANTMOBILE',#量化后的lite模型
+'XPRUNEMOBILE', #裁剪后的lite模型
+'XTRAINMOBILE',#lite模型
+'XQUANTSERVER', #量化后的inference模型
+'XPRUNESERVER', #裁剪后的inference模型
+'XTRAINSERVER'#inference模型
+),start=0)
+```

BIN
docs/gui/restful/img/classify_help.jpg


BIN
docs/gui/restful/img/detect_help.jpg


BIN
docs/gui/restful/img/framework.png


BIN
docs/gui/restful/img/gui_use.png


BIN
docs/gui/restful/img/ins_seg_help.jpg


BIN
docs/gui/restful/img/restful_api.png


BIN
docs/gui/restful/img/seg_help.jpg


BIN
docs/gui/restful/img/start_restful.png


BIN
docs/gui/restful/img/web_demo.png


+ 49 - 0
docs/gui/restful/index.rst

@@ -0,0 +1,49 @@
+
+PaddleX RESTful
+=======================================
+
+PaddleX RESTful是基于PaddleX开发的RESTful API。
+
+对于开发者来说通过如下指令启动PaddleX RESTful服务,开启RESTful服务后可以通过下载Remote版本的GUI或者是web demo连接开启RESTful服务的服务端完成深度学习全流程开发。
+
+同样您还可以根据RESTful API来开发自己的可视化界面。
+
+```
+paddlex_restful --start_restful --port 8081 --workspace_dir D:\Workspace
+```
+
+**注意:请确保启动RESTful的端口未被防火墙限制**
+
+支持RESTful版本的GUI
+---------------------------------------
+
+支持RESTful版本的GUI是针对PaddleX RESTful开发的可视化客户端。开发者可以通过客户端连接开启RESTful服务的服务端,通过GUI远程的实现深度学习全流程:**数据处理** 、 **超参配置** 、 **模型训练及优化** 、 **模型发布**,无需开发一行代码,即可得到高性深度学习推理模型。
+
+
+支持RESTful版本Web Demo
+---------------------------------------
+
+支持RESTful版本Web Demo是针对PaddleX RESTful开发的网页版可视化客户端。开发者可以通过Web Demo连接开启RESTful服务的服务端,远程实现深度学习全流程:**数据处理** 、 **超参配置** 、 **模型训练及优化** 、 **模型发布**,无需开发一行代码,即可得到高性深度学习推理模型。
+
+PaddleX RESTful API 二次开发
+---------------------------------------
+
+开发者可以使用PaddleX RESTful API 进行二次开发,按照自己的需求开发可视化界面
+
+
+
+.. toctree::
+   :maxdepth: 1
+   :caption: 文档目录
+   
+   introduction.md
+   restful.md
+   quick_start.md
+   restful_api.md
+   data_struct.md
+   tree.md
+
+
+
+
+

+ 89 - 0
docs/gui/restful/introduction.md

@@ -0,0 +1,89 @@
+# 介绍与使用
+PaddleX RESTful是基于PaddleX开发的RESTful API。  
+
+对于开发者来说可以通过如下指令启动PaddleX RESTful服务  
+
+```
+paddlex_restful --start_restful --port [端口号] --workspace_dir [工作空间地址]  
+```
+
+对于设置workspace在HOME目录的wk文件夹下,RESTful服务端口为8080的命令参考如下:
+![](./img/start_restful.png)  
+
+**注意:请确保启动RESTful的端口未被防火墙限制**
+
+开启RESTful服务后可以实现如下功能:
+
+- 通过下载基于RESTful API的GUI连接开启RESTful服务的服务端,实现远程深度学习全流程开发。
+- 通过使用web demo连接开启RESTful服务的服务端,实现远程深度学习全流程开发。
+- 根据RESTful API来开发您自己个性化的可视化界面。  
+
+
+
+## PaddleX Remote GUI
+PaddleX Remote GUI是针对PaddleX RESTful开发的可视化客户端。开发者可以通过客户端连接开启RESTful服务的服务端,通过GUI实现深度学习全流程:**数据处理** 、 **超参配置** 、 **模型训练及优化** 、 **模型发布**,无需开发一行代码,即可得到高性深度学习推理模型。  
+### 客户端下载地址
+- [MAC](https://bj.bcebos.com/paddlex/PaddleX_Remote_GUI/mac/PaddleX_Remote_GUI.zip)
+- [Windows](https://bj.bcebos.com/paddlex/PaddleX_Remote_GUI/windows/PaddleX_Remote_GUI.zip)
+
+### 客户端使用流程
+
+#### step1:安装PaddleX  
+```
+pip install paddlex
+```  
+**注意**:若需要使用GPU请安装pycuda
+```
+pip install pycuda
+```
+
+#### step2:开启RESTful 服务
+```
+paddlex_restful --start_restful --port [端口号] --workspace_dir [工作空间地址]
+```
+
+#### setp3:根据上面的链接下载支持RESTful版本的GUI
+
+#### step4:运行客户端,如图所示填写开启RESTful后端的ip与端口,点击确定便可正常使用GUI
+![](./img/gui_use.png)
+
+
+## PaddleX Web Demo
+PaddleX Web Demo是针对PaddleX RESTful开发的Web可视化客户端。  
+[Wed demo传送门](https://github.com/PaddlePaddle/PaddleX/blob/develop/paddlex_restful/restful/templates/paddlex_restful_demo.html)
+
+### Web DEMO使用流程
+
+#### step1:安装paddlex  
+```
+pip install paddlex
+```  
+**注意**:若需要使用GPU请安装pycuda
+```
+pip install pycuda
+```
+
+#### step2:开启RESTful 服务
+```
+paddlex_restful --start_restful --port [端口号] --workspace_dir [工作空间地址]
+```
+
+#### step3:
+- 方法1(推荐):在浏览器输入开启RESTful服务的机器与端口号如:10.3.12.4:8080,便可以使用WEB GUI,此方法无需step4操作
+- 方法2:通过浏览器打开[Demo](https://github.com/PaddlePaddle/PaddleX/blob/develop/paddlex_restful/restful/templates/paddlex_restful_demo.html)文件
+
+
+
+#### step4:点击设置服务器信息,填写正确的后端ip与端口
+![](./img/web_demo.png)
+
+## PaddleX RESTful API 二次开发
+开发者可以使用PaddleX RESTful API 进行二次开发,按照自己的需求开发可视化界面,详细请参考以下文档  
+
+[RESTful API 二次开发简介](./restful.md)  
+
+[快速开始](./quick_start.md)  
+
+[API 参考文档](./restful_api.md)  
+
+[自定义数据结构](./data_struct.md)

+ 222 - 0
docs/gui/restful/quick_start.md

@@ -0,0 +1,222 @@
+# 快速开始
+
+## 环境依赖  
+- paddlepaddle-gpu/paddlepaddle  
+- paddlex  
+- pycocotools  
+
+
+## 服务端启动PaddleX RESTful服务
+```
+ paddlex_restful --start_restful --port [端口号] --workspace_dir [工作空间目录]
+```  
+
+## 客户端请求服务端
+```
+import requests
+url = "https://127.0.0.1:5000"
+```
+- url为实际服务端ip与端口
+- 所有的请求,通过ret.status_code是否为200,判断是否正确给Server执行
+- 在status_code为200的前提下,如果ret.json()['status']为-1,则表明出错,出错信息在ret.json()['message']里面,如果执行成功, status是1
+
+## 创建一个PaddleX的训练任务  
+**下面介绍如何通过API完成模型的训练、评估、预测与导出,对于每个RESTful API的详细介绍请参考[API 接口文档](./restful_api.md),对于示例中用到自定的数据结构请参考[数据结构](./data_struct.md)**
+
+### 流程
+对于通过RESTful API创建一个PaddleX的训练任务的主要流程如下
+- 1):创建并导入数据集
+- 2):创建项目并绑定数据集
+- 3):获取参数并创建任务
+- 4):开始训练
+- 5):评估任务
+- 6):导出模型
+
+
+### 数据集操作
+#### 创建数据集
+```
+# dataset_type: 支持"detection"/"classification"/"segmentation"/"instance_segmentation"
+params = {"name": "我的第一个数据集", "desc": "这里是数据集的描述文字", "dataset_type": "detection"}  
+ret = requests.post(url+"/dataset", json=params)  
+#获取数据集id
+did = ret.json()['id']
+```
+
+#### 导入数据集
+
+```
+# 导入数据集
+params = {'did' : did, 'path' : '/path/to/dataset'}
+ret = requests.put(url+"/dataset", json=params)
+
+# 数据集导入是一个异步操作,可以通过不断发送请求,获取导入的状态
+params = {"did": did}
+ret = requests.get(url+"/dataset", json=params)
+#导入状态获取,其中DatasetStatus为自定义枚举标量,用来表示数据集的状态,具体定义请参考数据结构部分
+import_status = DatasetStatus(ret.json['dataset_status'])
+if import_status == DatasetStatus.XCOPYDONE:
+    print("数据集导入成功")
+elif import_status == DatasetStatus.XCOPYING:
+    print("数据集正在导入中")
+elif import_status == DatasetStatus.XCHECKFAIL:
+    print("数据集格式校验未通过,请确定数据集格式是否正确)
+```
+
+#### 切分数据集
+```
+# 当数据集导入成功后,可以对数据集进行切分
+# 切分数据集按照训练集、验证集、测试集为:6:2:2的形式切分
+params = {'did' : did, 'val_split' : 0.2 , 'test_split' : 0.2}
+ret = requests.put(url+"/dataset/split', json=params)
+
+#切分数据集后需要获取具体切分情况
+params = {'did': did}  
+ret = requests.get(url+"/dataset/details', json=params)  
+#获取切分情况
+dataset_details = ret.json()
+```
+
+## 项目操作
+
+### 创建项目
+```
+# project_type: 支持detection/classification/segmentation/instance_segmentation
+params = {'name': '项目名称', 'desc': '项目描述文字', 'project_type' : 'detection'}
+ret = requests.post(url+'/project', json=params)
+# 获取项目id
+pid = ret.json['pid']
+```
+
+### 绑定数据集
+```
+# 修改project中的did属性
+# struct支持 project/dataset/task
+params = {'struct': 'project', 'id': pid, 'attr_dict': {'did':did}}
+ret = requests.put(url+'/workspace', json=params)
+```
+
+### 获取训练默认参数
+```
+params = {"pid", "P0001"}
+ret = requests.get(url+"/project/task/parmas", json=params)
+#获取默认训练参数
+train_params = ret.json()['train']
+```
+
+
+
+## 任务操作
+
+### 创建任务
+```
+#将训练参数json化
+params_json = json.dumps(train_params)
+#创建任务
+params = {'pid': 'P0001', 'train':params_json}
+ret = requests.post(url+'/task', json=params)
+#获取任务id
+tid = ret.json()['tid']
+```
+
+### 启动训练任务
+```
+params = {'tid' : tid}
+ret = requests.post(url+'/project/task/train', json=params)
+
+#训练任务是一个后台异步操作,可通过如下操作,获取任务训练的最新状态
+params = {'tid' : 'T0001', 'type': 'train'}
+ret = requests.get(url+'/project/task/metrics', json=params)
+ret.json()获取返回值:
+{'status': 1, 'train_log': 训练日志}
+```
+
+### 停止训练任务
+通过如下操作,停止正在训练的任务
+```
+params = {'tid': tid, 'act': 'stop'}
+ret = requests.put(url+'/project/task/train', json=params)
+```
+
+### 获取训练任务信息
+```
+params = {'tid': tid, 'type': 'train'}
+ret = requests.get(url+'/project/task/metrics', json=params)
+#任务训练信息
+train_log = ret.json()['train_log']
+```
+
+### 创建一个评估任务,并获取评估结果
+```
+#获取任务状态
+params = {'tid': tid}
+ret = requests.get(url+'/project/task', json=params)
+#判断是否训练完成
+if TaskStatus(ret.json()['task_status']) == TaskStatus.XTRAINDONE:
+    #创建一个评估任务,可以指定score_thresh
+    params = {'tid': tid, 'score_thresh', 0.3}
+    ret = requests.post(url+'/project/task/evaluate', json=params)
+#获取评估任务状态
+import time
+while:
+    params = {'tid': tid}
+    ret = requests.get(url+'/project/task/evaluate', json=params)
+    #判断是否评估完成
+    if TaskStatus(ret.json()['evaluate_status']) == TaskStatus.XEVALUATED:
+        break
+    else:
+        time.sleep(1)
+#获取评估结果
+result = ret.json()['result']
+```
+
+### 使用模型进行预测
+
+```
+import cv2
+import numpy as np
+#预测图片路径
+img_path = '/path/to/img'
+params = dict()
+#base64编码
+with open(img_path, 'rb') as f:
+    base64_data = base64.b64encode(f.read())
+    base64_str = str(base64_data,'utf-8')
+    params['image_data'] = base64_str
+params['tid'] = tid
+#单张推理
+ret = requests.post(url + 'project/task/predict', json=params)
+#获取结果保存地址
+result_path = ret.json()['path']
+#判断是否预测完成
+while:
+    params = {'tid': tid}
+    ret = requests.get(url+'/project/task/predict', json=params)
+    #判断是否评估完成
+    if PredictStatus(ret.json()['predict_status']) == PredictStatus.XPREDONE:
+        break
+    else:
+        time.sleep(1)
+# 获取结果
+params = {'path' : result_path}
+ret = requests.get(url+'/file', json=params)
+#图片based64数据
+img_data = ret.json()['img_data']
+#转换为numpy数据
+img_data = base64.b64decode(img_data)
+img_array = np.frombuffer(img_data, np.uint8)
+img = cv2.imdecode(img_array, cv2.COLOR_RGB2BGR)
+```
+
+### 导出inference模型
+
+```
+#导出inference模型
+#保存地址
+save_dir = '/path/to/save/inference/model'
+params = {'tid': tid ,'type': 'inference', 'save_dir' : save_dir}
+ret = requests.post(url+'/project/task/export', json=params)
+#workspace创建inference模型信息
+params = {'pid' : pid, 'tid': tid, 'name': 'my_inference_model', 'type': 'exported', 'path' : save_dir, 'exported_type': 0}
+ret = requests.post(url+'/model', json=params)
+```

+ 69 - 0
docs/gui/restful/restful.md

@@ -0,0 +1,69 @@
+# 二次开发简介
+如图,PaddleX RESTful主要由数据集(dataset),项目(project),任务(task),模型(model)组成。上述模块数据保存在指定的工作空间(workspace)内,相应的结构化信息通过protobuf保存,[workspace的protobuf消息定义](./data_struct.md)。  
+
+![](./img/framework.png)  
+
+**说明**:后续RESTful API通过`[HTTP request method] url`来表示  
+
+## 流程介绍
+对于通过RESTtful接口来进行二次开发,主要的流程如下:
+- 1):指定工作空间启动restful服务
+- 2):创建、导入并切分数据到数据集
+- 3):创建项目,绑定数据集到该项目,并根据项目类型获取训练的默认参数
+- 4):根据默认参数,在该项目下创建训练任务,调整参数(非必要),开始训练模型
+- 5):对训练好的模型进行裁剪、评估、测试(非必要)
+- 6):保存或者发布训练好的模型
+
+## 工作空间
+
+通过如下命令启动PaddleX的RESTful服务,同时会初始化工作空间,初始化工作空间主要做载入工作空间内已有的数据集、项目等模块的信息。初始化工作空间后就可以正常调用其他的RESTful API,所有新建的数据集、项目等数据都会保存在此工作空间目录下面  
+```
+ paddlex_restful --start_restful --port [端口号] --workspace_dir [工作空间目录]
+```  
+
+
+## 数据集
+可以通过调用["[post] /dataset"](./restful_api.md)接口创建数据集、创建数据集后会在工作空间内创建相应的文件夹,按照workspace protobuf定义的变量保存数据集信息。创建数据集后可以通过["[put] \dataset"](./restful_api.md)接口导入数据集,目前仅支持从路径导入并且数据集需储存在后端服务器。目前支持图像分类、目标检测、语义分割与实例分割四种数据集,具体格式如下  
+### 图像分类
+如图所示
+- 文件夹名为需要分类的类名,输入限定为英文字符,不可包含:空格、中文或特殊字符;
+- 图片格式支持png,jpg,jpeg,bmp格式  
+
+![](./img/classify_help.jpg)
+
+### 目标检测
+如图所示
+- 图片文件名需要为"JPEGImages",标签文件夹命名需要为"Annotations"
+- 图片格式支持png,jpg,jpeg,bmp格式;标签文件格式为.xml  
+
+![](./img/detect_help.jpg)
+
+### 语义分割
+如图所示
+- 图片文件名需要为"JPEGImages",标签文件夹命名需要为"Annotations"
+- 图片格式支持png,jpg,jpeg,bmp格式
+- 标注需要与图片像素严格保持一一对应,格式只可为png。每个像素值需标注为[0,255]区间从0开始依序递增整数ID,除255外,标注ID值的增加不能跳跃。其中255表示模型中需忽略的像素,0为背景类标注。
+- (可选)可以提供一份命名为"labels.txt"的包含所有标注名的清单  
+
+![](./img/seg_help.jpg)
+
+
+### 实例分割
+如图所示
+- 图片文件名需要为"JPEGImages",标签文件名需要为"annotations.json"
+- 图片格式支持png,jpg,jpeg,bmp格式;标签文件格式为.json  
+
+![](./img/ins_seg_help.jpg)
+
+## 项目
+可以通过调用["[post] /project"](./restful_api.md)接口创建项目,目前支持的项目类型有分类(classification)、检测(detection)、语义分割(segmentation)、实例分割(instance_segmentation)。对于新建的项目首先需要绑定项目类型对应的数据集,通过["[post] \workspace"](./restful_api.md)可以实现;然后便可以在项目下创建任务,进行一系列任务相关的操作。  
+
+## 任务
+在创建项目后,首先需要通过["[get] /project/task/params"](./restful_api.md)获得默认的训练参数,可以通过调用["[post] /project/task"](./restful_api.md)接口在项目中创建任务,创建好任务后可以通过API实现以下功能:
+- 训练(train):进行模型的训练
+- 裁剪(prune):对训练好的模型模型进行裁剪
+- 评估(eval):对训练好的模型进行评估
+- 预测(predict):用训练好的模型进行预测,目前仅支持单张图片的预测
+
+## 模型
+目前PaddleX RESTful API支持将训练评估后的模型保存为预训练模型、导出inference模型、导出Padlle-Lite模型、同时能支持模型的量化,可以通过调用["[post] /model](./restful_api.md)接口来完成这些功能

+ 871 - 0
docs/gui/restful/restful_api.md

@@ -0,0 +1,871 @@
+# RestFUL API 参考文档
+## API 总览
+![](./img/restful_api.png)
+图片包含目前PaddleX RESTful模块提供所有的RESTful API:
+
+- /workspace: 工作空间相关
+- /dataset:数据集操作
+- /project: 项目操作
+- /project/task: 任务相关操作
+- /model: 模型相关操作
+- /file: 文件传输
+- /demo: 示例
+
+
+## API 接口文档
+**说明**:
+- 后续例子中HTTP请求通过requests完成,url代表运行PaddleX RESTful服务的主机ip与端口号
+- 所有的请求,通过ret.status_code是否为200,判断是否正确给Server执行
+- 在status_code为200的前提下,如果ret.json()['status']为-1,则表明出错,出错信息在ret.json()['message']里面,如果执行成功, status是1
+
+
+### /workspace [GET,PUT]
+主要是对工作空间的结构化信息进行操作,包括修改合和获取工作空间中数据集、项目、任务的属性
+- GET请求:获取workspace中数据集、项目、任务、模型的属性
+- PUT请求:修改workspace中数据集、项目、任务、模型的属性,对于创建项目之后我们需求通过该接口将数据集与项目绑定才能进行训练任务
+对于可以获取和修改的属性请参考[Protobuf结构化数据](./data_struct.md)  
+
+```
+methods=='GET':获取工作目录中项目、数据集、任务的属性
+	Args:
+		struct(str):结构类型,可以是'dataset', 'project'或'task',
+		id(str):结构类型对应的id
+		attr_list(list):需要获取的属性的列表
+	Return:
+		status
+		if Not Args:
+			'dirname' : RESTful服务初始化时指定的工作目录
+		else:
+			attr(dict):key为属性,value为属性的值
+
+	Example:
+		#获取任务id为'T0001'的任务对应的path的值
+		params = {'struct': 'task', 'id': 'T0001', 'attr_list': ['path']}
+		ret = requests.get(url + '/workspace', json=params)
+		if (ret.json()['status'] == 1):
+			task_path = ret.json()['attr']['path']
+		else:
+			print("failed to get path)
+
+methods=='PUT':修改工作目录中项目、数据集、任务的属性
+	Args:
+		struct(str):结构类型,可以是'dataset', 'project'或'task'
+		id(str):结构类型对应的id
+		attr_dict(dict):key:需要修改的属性,value:需要修改属性的值
+	Return:
+		status
+	Example
+		#为id为'P0001'的项目绑定id为'D0001'的数据集
+		attr_dict = {'did': 'D0001'}
+		params = {'struct': 'project', 'id': 'P0001', 'attr_dict': attr_dict}
+		ret = requests.post(url + '/workspace', json=params)
+```
+
+
+
+
+### /dataset [GET,POST,PUT,DELETE]
+对数据集进行操作,包括创建、导入、查询、删除数据集的功能
+- POST请求:创建数据集,创建时需要指定数据集类型可以是['classification', 'detection', 'segmentation','instance_segmentation']中的一种
+- GET请求:创建好数据集后,可以通过GET请求获取数据集信息,目前支持获取单个或者所有数据集的信息
+- PUT请求:导入数据集,创建数据集后并没有真实的数据与数据集关联,需要通过导入功能,将数据导入到工作空间内,需要导入的数据集必须按照
+- DELETE:删除一个数据集  
+DatasetStatus定义了数据集状态,具体请参考[数据集状态变量](./data_struct.md)  
+
+```
+methods=='GET':获取所有数据集或者单个数据集的信息
+	Args:
+		did(str, optional):数据集id(可选),如果存在就返回数据集id对应数据集的信息
+	Ruturn:
+		status
+		if 'did' in Args:
+			id(str):数据集id,
+			dataset_status(int):数据集状态(DatasetStatus)枚举变量的值
+			message(str):数据集状态信息
+			attr(dict):数据集属性
+		else:
+			datasets(list):所有数据集属性的列表
+    Example1:
+        #获取数据集id为'D0001'数据集的信息
+        params = {'did': 'D0001'}
+        ret = requests.get(url + '/dataset', json=params)
+        #状态码转换为Enum类型
+        ret.json()['dataset_status'] = DatasetStatus(ret.json()['dataset_status'])
+    Example2:
+        #获取所有数据集信息
+        ret = requests.get(url + '/dataset')
+    Ruturn中的自定数据结构:
+		数据集属性attr,为dict对于其中的key包括如下
+		attr{
+			'type'(str): 数据集类型
+			'id'(str): 数据集id
+			'name'(str): 数据集名字
+			'path'(str): 数据集路径
+			'desc'(str): 数据集描述
+			'create_time'(str): 数据集创建时间
+			'pids'(list): 数据集绑定的项目列表
+		}
+		所有数据集属性datasets,为list,dataset_list[idx]包含:
+		dataset_list[idx]{
+			"id": 数据集id
+			"attr": 数据集属性
+		}
+		其中数据集属性attr,为dict对于其中的key包括如下,注意与获取单个数据集的属性区分
+		attr{
+			"type": 数据集类型,
+            "id": 数据集id,
+            "name": 数据集名字,
+            "path": 数据集路径,
+            "desc": 数据集描述,
+            "create_time": 数据集创建时间
+			'dataset_status': 数据集状态(DatasetStatus)枚举变量的值
+            'message' : 数据集状态信息
+
+		}
+
+methods=='POST':创建一个新的数据集
+	Args:
+		name(str):数据集名字
+		desc(str):数据集描述
+		dataset_type(str):数据集类型,可以是['classification', 'detection', 'segmentation','instance_segmentation']
+	Return:
+		did(str):数据集id
+		status
+	Example:
+		#新建一个分类数据集
+		params = {'name' : '我的数据集', 'desc' : '数据集描述', 'dataset_type' : 'classification'}
+		ret = requests.post(url + '/dataset', json=params)
+		#获得数据集id
+		did = ret.json()['did']
+
+methods=='PUT':异步,向数据集导入数据,支持分类、检测、语义分割、实例分割、摇杆分割数据集类型
+	Args:
+		did(str):数据集id
+		path(str):数据集路径
+	Return:
+		status
+	Example:
+		#为id为'D0001'的数据集导入数据集
+		params = {'did':'D0001', 'path':'/path/to/dataset'}
+		ret = requests.put(url + '/dataset', json=params)
+
+methods=='DELETE':删除已有的某个数据集
+	Args:
+		did(str):数据集id
+	Return:
+		status
+	Example:
+		#删除数据集id为'D0001'的数据集
+		params = {'did':'D0001'}
+		ret = requests.delete(url + '/dataset', json=params)
+```
+
+### /dataset/split [PUT]
+按照比例切分一个已经导入数据的数据集  
+
+```
+methods=='PUT':切分某个数据集
+	Args:
+		did(str):数据集id
+		val_split(float): 验证集比例
+		test_split(float): 测试集比例
+	Return:
+		status
+	Example:
+		#按照训练集,验证集,测试集,7:2:1的形式切分D0001数据集
+		params = {'did':'D0001', 'val_split': 0.2, 'test_split': 0.1}
+		ret = requests.put(url + '/dataset/split', json=params)
+```
+
+### /dataset/details [GET]
+获取切分后数据集的具体信息  
+
+```
+methods=='GET':获取某个数据集的详细信息
+	Args:
+		did(str):数据集id
+	Return:
+		details(dict):数据集详细信息,
+		status
+	Example:
+		#获取数据集id为'D0001'的数据集的详细信息
+		params = {'did':'D0001'}
+		ret = requests.get(url + '/dataset/details', json=params)
+	Ruturn中的自定数据结构:
+		数据集详细信息(details),其中的key包括如下:
+		details{
+			'file_info'(dict): 全量数据集文件与标签映射表,key:图片相对于数据集地址的相对路径;value:标签文件相对于数据集地址的相对路径
+			'label_info'(dict): 标签与全量数据集文件映射表,key:标签的类别;value:标签文件相对于数据集地址的相对路径
+			'labels'(list): 标签列表
+			'train_files'(list): 训练集文件列表,相对于据集地址的相对路径
+			'val_files'(list): 验证集文件列表,相对于据集地址的相对路径
+			'test_files'(list): 测试集文件列表,相对于据集地址的相对路径
+			'class_train_file_list(dict)':类别与训练集映射表,key为类别、value为训练图片相对于据集地址的相对路径
+			'class_val_file_list(dict)':类别与评估集映射表,key为类别、value为评估图片相对于据集地址的相对路径
+			'class_test_file_list(dict)':类别与测试集映射表,key为类别、value为测试图片相对于据集地址的相对路径
+		}
+```
+
+### /file [GET]
+#用于文件传输,目前支持图片、xml格式文件、log或者txt格式文件,对于图片文件如果带有did参数则会返回带可视化label的图片数据  
+
+```
+methods=='GET':获取服务端的文件,目前支持图片、xml格式文件、log文件
+	Args:
+		'path'(str):文件在服务端的路径
+		'did'(str, optional):可选,数据集id仅在文件为图片时有效。若存在返回图片带label可视化。注意当前不支持分类数据集数据的标注可视化
+	Return:
+		#数据为图片
+		img_data(str): base64图片数据
+		status
+		#数据为xml文件
+		ret:数据流
+		#数据为log或者txt文件
+		ret:json数据
+	Example1:
+		#获取图片,目前支持的图片格式有:
+		#{'JPEG', 'jpeg', 'JPG', 'jpg', 'BMP', 'bmp', 'PNG', 'png'}
+		#图片通过based64编码
+		params = {'path' : '/path/to/img'}
+		ret = requests.get(url + '/file', json=params)
+		#图片数据
+		img_data = base64.b64decode(ret.json()['img_data'])
+		#图片解码
+		#opencv
+		img_array = np.frombuffer(img_data, np.uint8)
+        img = cv2.imdecode(img_array, cv2.COLOR_RGB2BGR)
+        #PIL
+        img = Image.open(BytesIO(img_data))
+	Example2:
+		#获取xml数据
+		params = {'path' : '/path/to/xml'}
+		ret = requests.get(url + '/file', json=params)
+		#xml数据
+		xml_file = ret.text
+```
+
+### /project [GET,POST,DELETE]
+项目相关操作,包括创建、删除、查询项目
+- POST请求:创建一个项目,支持分类、检测、语义分割、实例分割
+- GET请求:查询已经创建项目中的信息,可以是单个项目或者是所有项目
+- DELETE:删除一个项目,同时会删除项目里面所有task  
+
+```
+methods=='GET':获取指定项目id的信息
+	Args:
+		'id'(str, optional):项目id,可选,如果存在就返回项目id对应项目的信息
+	Return:
+		status,
+		if 'id' in Args:
+			attr(dict):项目属性
+		else:
+			projects(list):所有项目属性
+	Example1:
+		#获取id为P0001项目的信息
+		params = {'id' : 'P0001'}
+		ret = requests.get(url + '/project', json=params)
+	Example2:
+		#获取所有项目信息
+		ret = requests.get(url + '/project', json=params)
+	Ruturn中的自定数据结构:
+		单个项目属性attr(dict){
+			id(str):项目id,
+			name(str):项目名字,
+			desc(str):项目描述,
+			type(str):项目类型,
+			did(str):项目绑定的数据集id,
+			path(str):项目在服务端的路径,
+			create_time(str):项目创建时间,
+			tasks(list):项目中包含所有任务的任务状态变量的int值
+		}
+		多个项目的属性projects(list),对于list里面每一个元素表示了单个项目属性的字典project其数据结构如下
+		project(dict){
+			id(str):项目id,
+			attr(dict):项目属性字典,与单个项目属性一致
+		}
+
+methods=='POST':创建一个项目
+	Args:
+		name(str): 项目名
+		desc(str):项目描述
+		project_type(str):项目类型
+	Return:
+		pid(str):项目id
+		status
+	Example:
+		#创建一个新的项目,project_type支持{'classification', 'detection', 'segmentation', 'instance_segmentation'}
+		params = {'name' : '分类项目','desc': '一个新的项目','project_type' : 'classification'}
+		ret = requests.post(url + '/project', json=params)
+		#获取项目id
+		pid = ret.json()['pid']
+
+methods=='DELETE':删除一个项目,以及项目相关的task
+	Args:
+		pid(str):项目id
+	Return:
+		status
+	Example:
+		#删除id为'P0001'的项目
+		params = {'pid' : 'P0001'}
+		ret = requests.delete(url + '/project', json=params)
+```
+
+### /project/task [GET,POST,DELETE]
+任务相关,创建、获取、删除任务
+- POST请求:创建一个任务可以是训练任务也可以是剪裁任务,剪裁任务需要指定parent_id
+- GET请求: 获取单个任务、单个项目内所有任务、所有任务的信息,当tid存在时返回指定任务的信息,如果任务状态(TaskStatus)显示任务停止可以通过resume查询任务是否可以恢复训练以及保存的最大epoch;当pid存在时返回该项目下面所有任务信息
+- DELETE请求:删除任务  
+TaskStatus定义了任务状态,具体请参考[任务状态变量](./data_struct.md)  
+
+```
+methods=='GET':#获取某个任务的信息或者所有任务的信息
+	Args:
+		tid(str, optional):任务id,可选,若存在即返回id对应任务的信息
+		resume(str, optional):获取是否可以恢复训练的状态,可选,需在存在tid的情况下才生效
+		pid(str, optional):项目id,可选,若存在即返回该项目id下所有任务信息
+	Return:
+		status
+		if 'tid' in Args:
+			task_status(int):任务状态(TaskStatus)枚举变量的值
+			message(str):任务状态信息
+			type(str):任务类型包括{'classification', 'detection', 'segmentation', 'instance_segmentation'}
+			resumable(bool):仅Args中存在resume时返回,任务训练是否可以恢复
+			max_saved_epochs(int):仅Args中存在resume时返回,当前训练模型保存的最大epoch
+		else:
+			tasks(list):所有任务属性
+	Example1:
+		#获取任务id为"T0001"的信息
+		params = {'tid' : 'T0001'}
+		ret = requests.get(url + '/project/task', json=params)
+	Example2:
+		#获取所有任务的信息
+		ret = requests.get(url + '/project/task')
+	Ruturn中的自定数据结构:
+		所有任务属性(tasks),任务属性attr(dict)的list
+		attr{
+			'id'(str): 任务id
+			'name'(str): 任务名字
+			'desc'(str): 任务详细描述
+			'pid'(str): 任务所属的项目id
+			'path'(str): 任务在工作空间的路径
+			'create_time'(str): 任务创建时间
+			'status(int)':任务状态(TaskStatus)枚举变量的值
+			'type(str)':任务类型包括{'classification', 'detection', 'segmentation', 'instance_segmentation'}
+		}
+
+methods=='POST':#创建任务(训练或者裁剪)
+	Args:
+		pid(str):项目id
+		train(dict):训练参数
+		desc(str, optional):任务描述,可选
+		parent_id(str, optional):可选,若存在即表示新建的任务为裁剪任务,parent_id的值为裁剪任务对应的训练任务id
+	Return:
+		tid(str):任务id
+		status
+	Example:
+		#在P0001项目下创建一个任务
+		params = {'pid' : 'POOO1'}
+		ret = requests.post(url + '/project/task')
+		#获取任务id
+		tid = ret.json()['tid']
+
+methods=='DELETE':#删除任务
+	Args:
+		tid(str):任务id
+	Return:
+		status
+	Example:
+		#删除id为T0001的任务
+		params = {'tid' : 'T0001'}
+		ret = requests.delete(url + '/project/task')
+```
+
+### /project/task/params [GET,POST]
+获取和设置训练参数
+- GET请求:获取已有的参数信息或者默认的参数信息,当tid存在时获取该任务已有的参数信息、当pid存在时获取该项目的推荐参数给该任务,在创建任务之前需要先获取默认参数
+- POST请求:设置训练参数,用户修改训练参数后通过该接口设置训练参数,在workspace内会将训练参数保存为params.pkl文件  
+
+```
+methods=='GET':#获取任务id对应的参数,或者获取项目默认参数
+	Args:
+		tid(str, optional):获取任务对应的参数
+		pid(str,optional):获取项目对应的默认参数
+		model_type(str,optional):pid存在下有效,对应项目下获取指定模型的默认参数
+		gpu_list(list,optional):pid存在下有效,默认值为[0],使用指定的gpu并获取相应的默认参数
+	Return:
+		train(dict):训练或者裁剪的参数
+		status
+	Example1:
+		获取任务id为T0001的任务对应的参数
+		params = {'tid' : 'T0001'}
+		ret = requests.get(url + '/project/task/params',json=params)
+	Example2:
+		获取项目id为P0001的检测项目,PPYOLO模型的默认参数
+		params = {'pid' : 'P0001', 'model_type' : 'PPYOLO'}
+		ret = requests.get(url + '/project/task/params',json=params)
+		#获取参数dict
+		train_dict = ret.json()['train']
+		ret = requests.get(url + '/project/task/params',json=params)  
+
+methods=='POST':#设置任务参数,将前端用户设置训练参数dict保存在后端的pkl文件中
+	Args:
+		tid(str):任务id
+		train(dict):训练参数
+	Return:
+		status
+	Example:
+		#设置训练参数
+		params = {'tid': 'T0001', 'train': train_dict}
+		ret = requests.post(url + '/project/task/params',json=params)
+```
+
+### /project/task/train [POST,PUT]
+任务训练(包括剪裁任务训练),主要是启动和停止任务,需要先设置好训练参数
+-POST请求:启动一个训练任务,异步操作,启动前需要设置好训练的参数
+-PUT请求:暂停一个训练任务或者重启一个暂停的训练任务,重启训练任务可以设置重启的epoch数  
+
+```
+methods=='POST':#异步,启动训练或者裁剪任务
+	Args:
+		tid(str):任务id
+		eval_metric_loss(int,optional):可选,裁剪任务时可用,裁剪任务所需的评估loss
+	Return:
+		status
+	Example:
+		#启动任务id为T0001的任务的训练
+		params = {'tid':'T0001'}
+		ret = requests.post(url + '/project/task/train',json=params)
+
+methods=='PUT':#改变任务训练的状态,即终止训练或者恢复训练
+	Args:
+		tid(str):任务id
+		act(str):[stop,resume]暂停或者恢复
+		epoch(int):(resume下可以设置)恢复训练的起始轮数
+    Return:
+		status
+	Example:
+		#停止任务id为T0001的任务的训练
+		params = {'tid':'T0001', 'act': 'stop'}
+		ret = requests.put(url + '/project/task/train',json=params)
+```
+
+### /project/task/prune [GET,POST,PUT]
+创建、获取、停止剪裁任务分析;在启动剪裁任务训练之前需要通过此接口完成剪裁任务分析
+- GET请求:获取剪裁任务状态信息
+- POST请求:创建剪裁分析任务,异步操作
+- PUT请求:停止正在进行的剪裁分析任务  
+PruneStatus定义了裁剪分析任务状态,具体请参考[裁剪分析状态变量](./data_struct.md)  
+
+```
+methods=='GET':#获取剪裁任务的状态
+	Args:
+		tid(str):任务id
+	Return:
+		prune_status(int): 剪裁任务状态(PruneStatus)枚举变量的值
+		status
+	Example:
+		#启动任务id为T0001的任务的训练
+		params = {'tid':'T0001'}
+		ret = requests.get(url + '/project/task/prune',json=params)
+
+methods=='POST':#异步,创建一个剪裁分析,对于启动剪裁任务前需要先启动剪裁分析
+	Args:
+		tid(str):任务id
+	Return:
+		status
+	Example:
+		#对任务id为T0001的任务启动剪裁分析任务
+		params = {'tid':'T0001'}
+		ret = requests.post(url + '/project/task/prune',json=params)
+
+methods=='PUT':#改变裁剪分析任务的状态
+	Args:
+		tid(str):任务id
+		act(str):[stop],目前仅支持停止一个裁剪分析任务
+	Return
+		status
+	Example:
+		#停止T0001的任务的裁剪分析
+		params = {'tid':'T0001', 'act': 'stop'}
+		ret = requests.put(url + '/project/task/prune',json=params)
+```
+
+### /project/task/evaluate [GET,POST]
+创建、获取一个评估任务
+- POST请求:创建一个评估任务,需要模型训练好后调用,异步操作
+- GET请求: 获取评估任务的状态  
+
+```
+methods=='GET':#获取模型评估的结果
+	Args:
+		tid(str):任务id
+	Return:
+		evaluate_status(int): 任务状态(TaskStatus)枚举变量的值
+		message(str):描述评估任务的信息
+		result(dict):如果评估成功,返回评估结果的dict,否则为None
+		status
+	Example:
+		#获取任务id为T0001的任务的评估数据
+		params = {'tid':'T0001'}
+		ret = requests.get(url + '/project/task/evaluate',json=params)
+		result = ret.json()['result']
+
+methods=='POST':#异步,创建一个评估任务
+	Args:
+		tid(str):任务id
+		epoch(int,optional):需要评估的epoch,如果为None则会评估训练时指标最好的epoch
+		topk(int,optional):分类任务topk指标,如果为None默认输入为5
+		score_thresh(float):检测任务类别的score threshhold值,如果为None默认输入为0.5
+		overlap_thresh(float):实例分割任务IOU threshhold值,如果为None默认输入为0.3
+	Return:
+		status
+	Example:
+		#对任务id为T0001的分类任务进行评估,topk=5
+		params = {'tid':'T0001', 'epoch': None, 'topk': 5, 'score_thresh': None, 'overlap_thresh': None}
+		ret = requests.post(url + '/project/task/evaluate',json=params)
+```
+
+### /project/task/evaluate/file [GET]
+评估结果生成excel表格  
+- GET请求:评估完成的情况下,在服务器端生成评估结果的excel表格
+
+```
+methods=='GET':#评估结果生成excel表格
+	Args:
+		tid(str):任务id
+	Return:
+		path(str):评估结果excel表格在服务器端的路径
+		message(str):提示信息
+		status
+	Example:
+		#任务id为T0001的任务在服务器端生成评估excel表格
+		params = {'tid': 'T0001'}
+		ret = requests.get(url + '/project/task/evaluate/file',json=params)
+		#显示保存路径
+		print(ret.json()['path'])
+```
+
+### /project/task/metrics [GET]
+获取训练、评估、剪裁的日志和敏感度与模型裁剪率关系图
+- GET请求:通过type来确定需要获取的内容  
+
+```
+methods=='GET':#获取日志数据
+	Args:
+		tid(str):任务id
+		type(str):可以获取日志的类型,[train,eval,sensitivities,prune],包括训练,评估,敏感度与模型裁剪率关系图,裁剪的日志
+	Return:
+		status
+		if type == 'train':
+			train_log(dict): 训练日志
+		elif type == 'eval':
+			eval_metrics(dict): 评估结果
+		elif type == 'sensitivities':
+			sensitivities_loss_img(dict): 敏感度与模型裁剪率关系图
+		elif type == 'prune':
+			prune_log(dict):裁剪日志
+	Example:
+		#获取训练日志
+		paramas = {'tid': 'T0002', 'type': 'train'}
+		ret = requests.get(url + '/project/task/metrics',json=params)
+	Ruturn中的自定数据结构:
+		train_log(dict){
+			eta: 剩余时间,
+			train_metrics: 训练指标,
+			eval_metircs: 评估指标,
+			download_status: 下载模型状态,
+			eval_done: 是否已保存模型,
+			train_error: 训练错误原因
+		}
+```
+
+### /project/task/predict [GET, POST]
+创建、查询、停止一个预测任务
+- POST请求:创建一个预测任务、图片输入需要先进行base64编码、异步操作
+- GET请求:获取预测任务的状态
+- PUT请求:停止一个预测任务
+PredictStatus定义了预测任务状态变量,具体请参考[预测任务状态变量](./data_struct.md)  
+
+```
+methods=='GET':#获取预测状态
+	Args:
+		tid(str):任务id
+	Return:
+		predict_status(int): 预测任务状态(PredictStatus)枚举变量的值
+		message(str): 预测信息
+		status
+	Example:
+		#获取预测状态
+		paramas = {'tid': 'T0002'}
+		ret = requests.get(url + '/project/task/predict',json=params)
+		predict_status = PredictStatus(ret.json()['predict_status'])
+
+methods=='POST':#创建预测任务,目前仅支持单张图片的预测
+	Args:
+		tid(str):任务id
+		image_data(str):base64编码的image数据
+		score_thresh(float,optional):可选,检测任务时有效,检测类别的score threashold值默认是0.5
+		epoch(int,float,optional):可选,选择需要做预测的ephoch,默认为评估指标最好的那一个epoch
+	Return:
+		path(str):服务器上保存预测结果图片的路径
+		status
+	Example:
+		#对一张图片进行预测并取回预测结果
+		import base64
+		import cv2
+		#对图片进行base64编码
+		img_path = 'path to img need to be predict'
+		f = open(img_path, 'rb')
+		base64_data = base64.b64encode(f.read())
+		base64_str = str(base64_data,'utf-8')
+		params[tid: 'T0001', 'image_data', base64_str]
+		#进行预测
+		ret = requests.post(url + '/project/task/predict',json=params)
+		result_path = ret.json()['path']
+		#判断预测是否完成
+		paramas = {'tid': 'T0001'}
+		ret = requests.get(url + '/project/task/predict',json=params)
+		predict_status = PredictStatus(ret.json()['predict_status'])
+		if (predict_status == PredictStatus.XPREDONE):
+		#取回预测结果图片
+			params = {'path' : result_path}
+			ret = requests.get(url + '/file',json=params)
+			img_data = ret.json()['img_data']
+
+methods=='PUT':#停止一个预测任务
+	Args:
+		tid(str):任务id
+	Return:
+	    status
+		predict_status:评估的状态
+```
+
+### /project/task/export [GET,POST,PUT]
+创建、获取、停止模型装换或者导出、支持导出inference和lite的模型
+- POST请求:创建模型导出,可以通过type确定导出inference模型还是lite模型
+- GET请求:获取导出的结果日志、或者时导出状态
+- PUT请求:停止模型的导出  
+
+```
+methods=='GET':#获取导出模型的状态
+	Args:
+		tid(str):任务id
+		quant(str,optional)可选,[log,result],导出量模型导出状态,若值为log则返回量化的日志;若值为result则返回量化的结果
+	Return:
+		status
+		if quant == 'log':
+			quant_log(dict):量化日志
+		if quant == 'result'
+			quant_result(dict):量化结果
+		if quant not in Args:
+			export_status(int):模型导出状态(PredictStatus)枚举变量的值
+			message(str):模型导出提示信息
+	Example:
+		#获取模型导出状态信息
+		params = {'tid':'T0002'}
+		ret = requests.get(url + '/project/task/export',json=params)
+
+methods=='POST':#导出inference模型或者导出lite模型
+	Args:
+		tid(str):任务id
+		type(str):保存模型的类别[infer,lite],支持inference模型导出和lite的模型导出
+		save_dir(str):保存模型的路径
+		epoch(str,optional)可选,指定导出的epoch数默认为评估效果最好的epoch
+		quant(bool,optional)可选,type为infer有效,是否导出量化后的模型,默认为False
+		model_path(str,optional)可选,type为lite时有效,inference模型的地址
+	Return:
+		status
+		if type == 'infer':
+			save_dir:模型保存路径
+		if type == 'lite':
+			message:模型保存信息
+	Example:
+		#导出inference模型
+		params = {tid:'T0001', type:'infer', save_dir:'path to save', 'quant': False}
+		ret = requests.post(url + '/project/task/export',json=params)
+methods=='PUT':#停止导出模型
+	Args:
+		tid(str):任务id
+	Return:
+		export_status(int):模型导出状态(PredictStatus)枚举变量的值
+		message(str):停止模型导出提示信息
+		status
+	Example:
+		#停止导出模型
+		params = {tid:'T0001'}
+		ret = requests.put(url + '/project/task/export',json=params)
+```
+
+### /project/task/vdl [GET]
+打开任务的可视化分析工具(VisualDL)  
+- GET请求:打开任务的vdl  
+
+```
+methods=='GET':#打开某个任务的可视化分析工具(VisualDL)
+	Args:
+		tid(str):任务id
+	Return:
+		url(str):vdl地址
+		status
+	Example:
+		#打开任务T0002的vdl
+		params = {tid:'T0002'}
+		ret = requests.get(url + '/project/task/vdl',json=params)
+		#获取打开vdl的url
+		url = ret.json()['url']
+```
+
+### /system [GET]
+获取系统信息包括CPU、GPU信息
+- GET请求:获取系统信息、在paddlex启动restful时会自行调用此api、若需要使用GPU请确定已经安装好了pycuda包
+```
+methods=='GET':#获取系统GPU、CPU信息
+	Args:
+		type(str):[machine_info,gpu_memory_size]选择需要获取的系统信息
+	Return:
+		status
+		if type=='machine_info'
+			info(dict):服务端信息
+		if type=='gpu_memory_size'
+			gpu_mem_infos(list):GPU内存信息
+	Example1:
+		#获取服务器gpu与cpu信息
+		params = {'type': 'machine_info'}
+		ret = requests.get(url + 'system', json=params)
+		info  = ret.json()['info']
+	Example2:
+		#获取服务器gpu显存信息
+		params = {'type': 'gpu_memory_size'}
+		ret = requests.get(url + 'system', json=params)
+		gpu_mem_infos = ret.json()['gpu_mem_infos']
+#info(dict):服务端信息
+info={
+	message(str):获取提示信息
+	cpu_num(int):cpu个数
+	gpu_num(int):gpu个数
+	sysstr(str):服务器系统信息
+}
+#gpu_mem_infos(list):GPU内存信息,对于list里面第i个元素表示第i个GPU的显存信息,包含:
+	free:可用显存
+	used:已经使用的显存
+	total:总共的显存
+```
+
+### /demo [GET,POST,PUT]
+创建、获取、删除demo项目,
+- GET请求: 获取demo下载的进度
+- POST请求: 下载和载入demo项目
+- PUT请求: 停止下载demo项目  
+
+```
+methods=='GET':#获取demo下载进度
+	Args:
+		prj_type(str):项目类型可以是['classification', 'detection', 'segmentation','instance_segmentation']
+	Return:
+		status
+		attr(dict):demo下载信息
+	Example:
+		#分类项目示例demo下载
+		params = {'prj_type' = 'classification'}
+		ret = requests.get(url + 'demo', json=params)
+#attr(dict):demo下载信息,包含
+attr={
+	status(int):demo下载状态枚举变量DownloadStatus的int值
+	progress(float):demo下载进度
+}
+
+methods=='POST':#下载或创建demo工程
+	Args:
+		type(str):{download,load}下载或者创建样例
+		prj_type(int):项目类型ProjectType枚举变量的int值
+	Return:
+		status
+		if type=='load':
+			did:数据集id
+			pid:项目id
+	Example1:
+		#下载分类demo样例
+		params = {'type': 'download', 'prj_type': 0}
+		ret = requests.post(url + 'demo', json=params)
+	Example2:
+		#创建分类demo样例工程
+		params = {'type': 'load', 'prj_type': 0}
+		ret = requests.post(url + 'demo', json=params)
+
+methods=='PUT':#停止下载或创建demo工程
+	Args:
+		prj_type(int):项目类型ProjectType枚举变量的int值
+	Return:
+		status
+	Example:
+		#停止分类demo下载或者创建
+		params = {'prj_type': 0}
+		ret = requests.put(url + 'demo', json=params)
+```
+
+### /model [GET,POST,DELETE]
+- GET请求: 获取所有或者单个模型的信息,可以是预训练模型或者inference模型
+- POST请求: 在workspace中创建模型,对于inference模型需要先通过/project/task/export接口现在导出inference模型
+- DELETE请求: 删除一个模型
+
+```
+methods=='GET':#获取一个或者所有模型的信息
+	Args:
+		mid(str,optional)可选,若存在则返回某个模型的信息
+		type(str,optional)可选,[pretrained,exported].若存在则返回对应类型下所有的模型信息
+	Return:
+		status
+		if mid in Args:
+			dataset_attr(dict):数据集属性
+			task_params(dict):模型训练参数
+			eval_result(dict):模型评估结果
+		if type in Args and type == 'pretrained':
+			pretrained_models(list):所有预训练模型信息
+		if type in Args and type == 'exported':
+			exported_models(list):所有inference模型的信息
+	Example:
+		#获取所有保存的预训练模型信息
+		params = {'type': 'exported'}
+		ret = requests.get(url + 'model', json=params)
+
+methods=='POST':#创建一个模型
+	Args:
+		pid(str):项目id
+		tid(str):任务id
+		name(str):模型名字
+		type(str):创建模型的类型,[pretrained,exported],pretrained代表创建预训练模型、exported代表创建inference或者lite模型
+		source_path(str):仅type为pretrained时有效,训练好的模型的路径
+		path(str):仅type为exported时有效,inference或者lite模型的路径
+		exported_type(int):0为inference模型,1为lite模型
+		eval_results(dict,optional):可选,仅type为pretrained时有效,模型评估的指标
+	Return:
+		status
+		if type == 'pretrained':
+			pmid(str):预训练模型id
+		if type == 'exported':
+			emid(str):inference模型id
+	Exampe:
+		#创建一个预训练模型
+		params={
+			pid : 'P0001',
+			tid : 'T0001',
+			name : 'Pretrain_model',
+			type : 'pretrained',
+			source_path : '/path/to/pretrian_model',
+		}
+		ret = requests.post(url + 'model', json=params)
+
+methods=='DELETE':删除一个模型
+	Args:
+		type(str):删除模型的类型,[pretrained,exported],pretrained代表创建预训练模型、exported代表创建inference或者lite模型
+		if type='pretrained':
+			pmid:预训练模型id
+		if type='exported':
+			emid:inference或者lite模型id
+	Return:
+		status
+	Example:
+		#删除模型id为EM0001的inference模型
+		params = {'type': 'exported', 'emid': 'EM0001'}
+		ret = requests.delete(url + 'model', json=params)
+```

+ 57 - 0
docs/gui/restful/tree.md

@@ -0,0 +1,57 @@
+# RESTful目录结构  
+
+介绍了PaddleX RESTful的整体目录结构
+
+```
+restful
+|____system.py	// 处理/system 请求
+|____workspace_pb2.py
+|____dir.py
+|____dataset	// 数据集相关
+| |____datasetbase.py	// 数据集基类
+| |______init__.py
+| |____seg_dataset.py	// 分割数据集
+| |____cls_dataset.py	// 分类数据集
+| |____dataset.py	// 处理/dataset 请求
+| |____operate.py	// 数据集基础操作函数
+| |____utils.py		// 数据集基础工具函数
+| |____ins_seg_dataset.py	// 示例分割数据集
+| |____det_dataset.py	// 检测数据集
+|______init__.py
+|____model.py	// 处理/model 请求
+|____project	// 项目相关
+| |____task.py	// 处理/project/task 请求
+| |______init__.py
+| |____visualize.py	// 数据可视化
+| |____operate.py	// 任务基础操作函数
+| |____evaluate		// 模型评估
+| | |____detection.py	// 检测模型评估
+| | |____classification.py	// 分类模型评估
+| | |______init__.py
+| | |____draw_pred_result.py	// 评估与预测结果可视化
+| | |____segmentation.py	// 分割模型评估
+| |____train	//模型训练
+| | |____detection.py	// 检测模型训练
+| | |____params.py	// 模型参数
+| | |____classification.py	// 分类模型训练
+| | |______init__.py
+| | |____params_v2.py	// 模型参数V2版本
+| | |____segmentation.py	// 分割模型训练
+| |____prune	// 模型剪裁
+| | |____detection.py	// 检测模型剪裁
+| | |____classification.py	// 分类模型剪裁
+| | |______init__.py
+| | |____segmentation.py	// 分割模型剪裁
+| |____project.py	// 处理/project请求
+|____utils.py	// 基础工具函数
+|____app.py	// 创建flask app
+|____front_demo	// 前端demo
+|____workspace.py	// 处理/workspace请求
+|____demo.py	// 处理/demo 请求
+|____workspace.proto	// workspace 结构化信息
+|____frontend_demo // 前端demo
+| |____paddlex_restful_demo.html    //前端demo文件
+|____templates  // flask html文件存放目录
+| |____paddlex_restful_demo.html    //前端demo文件
+
+```

+ 4 - 4
docs/install.md

@@ -33,7 +33,7 @@ pip install cython
 pip install pycocotools
 ```
 
-**我们推荐大家先安装Anacaonda,而后在新建的conoda环境中使用上述pip安装方式**。Anaconda是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。使用Anaconda可以通过创建多个独立的Python环境,避免用户的Python环境安装太多不同版本依赖导致冲突。参考[Anaconda安装PaddleX文档](../../docs/appendix/anaconda_install.md)
+**我们推荐大家先安装Anacaonda,而后在新建的conoda环境中使用上述pip安装方式**。Anaconda是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。使用Anaconda可以通过创建多个独立的Python环境,避免用户的Python环境安装太多不同版本依赖导致冲突。参考[Anaconda安装PaddleX文档](./appendix/anaconda_install.md)
 
 #### * Windows 操作系统
 
@@ -72,12 +72,12 @@ python setup.py install
 
 - 前往[PaddleX官网](https://www.paddlepaddle.org.cn/paddle/paddlex),申请下载PaddleX GUI一键绿色安装包。
 
-- 前往[PaddleX GUI使用教程](../../docs/gui/how_to_use.md)了解PaddleX GUI使用详情。
+- 前往[PaddleX GUI使用教程](./gui/how_to_use.md)了解PaddleX GUI使用详情。
 
-- [PaddleX GUI安装环境说明](../../docs/gui/download.md)
+- [PaddleX GUI安装环境说明](./gui/download.md)
 
 
 ## <h2 id="3">3. PaddleX Restful开发模式安装</h2>
 
 使用基于RESTful API开发的GUI与Web Demo实现远程的深度学习全流程开发;同时开发者也可以基于RESTful API开发个性化的可视化界面
-- 前往[PaddleX RESTful API使用教程](../../docs/Resful_API/docs/readme.md)  
+- 前往[PaddleX RESTful API使用教程](./Resful_API/docs/readme.md)  

+ 3 - 2
examples/meter_reader/README.md

@@ -425,7 +425,7 @@ git clone https://github.com/PaddlePaddle/PaddleX.git
   点击:`项目`->`CMake设置`
   ![](./images/step5_3.png)
 
-4. 点击`浏览`,分别设置编译选项指定`CUDA`、`OpenCV`、`PaddleXManufacture`、`TensorRT`的路径(也可以点击右上角的“编辑 JSON”,直接修改json文件,然后保存点 项目->生成缓存)
+4. 点击`浏览`,分别设置编译选项指定`CUDA`、`OPENCV_DIR`、`PADDLEX_DIR`、`PaddleXManufacture_DIR`、`TensorRT`的路径(也可以点击右上角的“编辑 JSON”,直接修改json文件,然后保存点 项目->生成缓存)
    ![](./images/step5_4.png)
    依赖库路径的含义说明如下(带*表示仅在使用**GPU版本**预测库时指定, 其中CUDA库版本与PaddleXManufacture的对齐,例如PaddleXManufacture是**使用9.0、10.0版本**编译的,则编译PaddleX预测代码时**不使用9.2、10.1等版本**CUDA库):
 
@@ -433,7 +433,8 @@ git clone https://github.com/PaddlePaddle/PaddleX.git
 | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
 | CUDA_LIB  | CUDA的库路径, 注:请将CUDNN的cudnn.lib文件拷贝到CUDA_LIB路径下。<br />例如 `C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v10.2\\lib\\x64` |
 | OPENCV_DIR | OpenCV的安装路径,例如`D:\\projects\\opencv`                                                                                                        |
-| PaddleXManufacture_DIR | PaddleXManufacture的路径,例如 `D:\\projects\\PaddleXManufacture`                                                                           |
+| PADDLEX_DIR | PaddleXManufacture的路径,例如 `D:\\projects\\PaddleXManufacture` |
+| PaddleXManufacture_DIR | PaddleXManufacture的config.cmake所在路径,例如 `D:\\projects\\PaddleXManufacture\\share\\PaddleXManufacture`                                                                           |
 | TENSORRT_DIR | PaddleXManufacture的路径,例如 `D:\\projects\\TensorRT-7.0.0.11`                                                                           |
 
 - 如果使用`CPU`版预测库,请把`WITH_GPU`的`值`去掉勾

BIN
examples/meter_reader/images/step5_4.png


+ 1 - 1
paddlex/cv/models/detector.py

@@ -1329,7 +1329,7 @@ class PPYOLOv2(YOLOv3):
         if backbone not in ['ResNet50_vd_dcn', 'ResNet101_vd_dcn']:
             raise ValueError(
                 "backbone: {} is not supported. Please choose one of "
-                "('ResNet50_vd_dcn', 'ResNet18_vd')".format(backbone))
+                "('ResNet50_vd_dcn', 'ResNet101_vd_dcn')".format(backbone))
         self.backbone_name = backbone
 
         if paddlex.env_info['place'] == 'gpu' and paddlex.env_info[

+ 9 - 7
static/paddlex/deploy.py

@@ -123,13 +123,15 @@ class Predictor:
         else:
             config.disable_gpu()
         if use_mkl and not use_gpu:
-            if self.model_name not in ["HRNet", "DeepLabv3p", "PPYOLO"]:
-                config.enable_mkldnn()
-                config.set_cpu_math_library_num_threads(mkl_thread_num)
-            else:
-                logging.warning(
-                    "HRNet/DeepLabv3p/PPYOLO are not supported for the use of mkldnn\n"
-                )
+            import paddle
+            if not hasattr(paddle, 'enable_static'):
+                if self.model_name not in ["HRNet", "DeepLabv3p", "PPYOLO"]:
+                    config.enable_mkldnn()
+                    config.set_cpu_math_library_num_threads(mkl_thread_num)
+                else:
+                    logging.warning(
+                        "HRNet/DeepLabv3p/PPYOLO are not supported for the use of mkldnn\n"
+                    )
         if use_glog:
             config.enable_glog_info()
         else: