diff --git a/CMakeLists.txt b/CMakeLists.txt index f05e52ee447e06ba812ce5ac52e238dcebc9bbbc..6228877f582b82e89bd1c73707460a7ce8224b97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,12 @@ option(APP "Compile Paddle Serving App package" OFF) option(WITH_ELASTIC_CTR "Compile ELASITC-CTR solution" OFF) option(PACK "Compile for whl" OFF) option(WITH_TRT "Compile Paddle Serving with TRT" OFF) +option(PADDLE_ON_INFERENCE "Compile for encryption" ON) +if (PADDLE_ON_INFERENCE) + add_definitions(-DPADDLE_ON_INFERENCE) + message(STATUS "Use PADDLE_ON_INFERENCE") +endif() set(WITH_MKLML ${WITH_MKL}) if (NOT DEFINED WITH_MKLDNN) if (WITH_MKL AND AVX2_FOUND) diff --git a/cmake/paddlepaddle.cmake b/cmake/paddlepaddle.cmake index 0e202d3b06537646e489510c781cf125e87e3e07..f1fdfb6c2db878bcced73afbc78ab62b496df57a 100644 --- a/cmake/paddlepaddle.cmake +++ b/cmake/paddlepaddle.cmake @@ -31,7 +31,7 @@ message( "WITH_GPU = ${WITH_GPU}") # Paddle Version should be one of: # latest: latest develop build # version number like 1.5.2 -SET(PADDLE_VERSION "2.0.0-rc1") +SET(PADDLE_VERSION "2.0.0") if (WITH_GPU) if (WITH_TRT) @@ -124,8 +124,8 @@ LINK_DIRECTORIES(${PADDLE_INSTALL_DIR}/third_party/install/mkldnn/lib) ADD_LIBRARY(openblas STATIC IMPORTED GLOBAL) SET_PROPERTY(TARGET openblas PROPERTY IMPORTED_LOCATION ${PADDLE_INSTALL_DIR}/third_party/install/openblas/lib/libopenblas.a) -ADD_LIBRARY(paddle_fluid SHARED IMPORTED GLOBAL) -SET_PROPERTY(TARGET paddle_fluid PROPERTY IMPORTED_LOCATION ${PADDLE_INSTALL_DIR}/lib/libpaddle_fluid.so) +ADD_LIBRARY(paddle_fluid STATIC IMPORTED GLOBAL) +SET_PROPERTY(TARGET paddle_fluid PROPERTY IMPORTED_LOCATION ${PADDLE_INSTALL_DIR}/lib/libpaddle_fluid.a) if (WITH_TRT) ADD_LIBRARY(nvinfer SHARED IMPORTED GLOBAL) @@ -136,8 +136,8 @@ if (WITH_TRT) endif() if (WITH_LITE) - ADD_LIBRARY(paddle_api_full_bundled STATIC IMPORTED GLOBAL) - SET_PROPERTY(TARGET paddle_api_full_bundled PROPERTY IMPORTED_LOCATION ${PADDLE_INSTALL_DIR}/third_party/install/lite/cxx/lib/libpaddle_api_full_bundled.a) + ADD_LIBRARY(paddle_full_api_shared STATIC IMPORTED GLOBAL) + SET_PROPERTY(TARGET paddle_full_api_shared PROPERTY IMPORTED_LOCATION ${PADDLE_INSTALL_DIR}/third_party/install/lite/cxx/lib/libpaddle_full_api_shared.so) if (WITH_XPU) ADD_LIBRARY(xpuapi SHARED IMPORTED GLOBAL) @@ -151,13 +151,16 @@ endif() ADD_LIBRARY(xxhash STATIC IMPORTED GLOBAL) SET_PROPERTY(TARGET xxhash PROPERTY IMPORTED_LOCATION ${PADDLE_INSTALL_DIR}/third_party/install/xxhash/lib/libxxhash.a) +ADD_LIBRARY(cryptopp STATIC IMPORTED GLOBAL) +SET_PROPERTY(TARGET cryptopp PROPERTY IMPORTED_LOCATION ${PADDLE_INSTALL_DIR}/third_party/install/cryptopp/lib/libcryptopp.a) + LIST(APPEND external_project_dependencies paddle) LIST(APPEND paddle_depend_libs - xxhash) + xxhash cryptopp) if(WITH_LITE) - LIST(APPEND paddle_depend_libs paddle_api_full_bundled) + LIST(APPEND paddle_depend_libs paddle_full_api_shared) if(WITH_XPU) LIST(APPEND paddle_depend_libs xpuapi xpurt) endif() diff --git a/core/general-server/CMakeLists.txt b/core/general-server/CMakeLists.txt index be6c3477551cb71c3499f6a6c713dd44600b7d58..27ceddc044de31914bbe60a7f125c226cc7a728c 100644 --- a/core/general-server/CMakeLists.txt +++ b/core/general-server/CMakeLists.txt @@ -29,7 +29,8 @@ target_link_libraries(serving -Wl,--whole-archive fluid_cpu_engine -Wl,--no-whole-archive) target_link_libraries(serving paddle_fluid ${paddle_depend_libs}) - +target_link_libraries(serving brpc) +target_link_libraries(serving protobuf) target_link_libraries(serving pdserving) target_link_libraries(serving cube-api) target_link_libraries(serving utils) diff --git a/core/general-server/op/general_reader_op.cpp b/core/general-server/op/general_reader_op.cpp index 24259e24d7f00b52eb35170bc9b887ecf301f157..b46071a3292dfb7429b240f374163df3adc324da 100644 --- a/core/general-server/op/general_reader_op.cpp +++ b/core/general-server/op/general_reader_op.cpp @@ -91,7 +91,7 @@ int GeneralReaderOp::inference() { capacity.resize(var_num); for (int i = 0; i < var_num; ++i) { std::string tensor_name = model_config->_feed_name[i]; - VLOG(2) << "(logid=" << log_id << ") get tensor name: " << tensor_name; + VLOG(2) << "(logid=" << log_id << ") get tensor name: " << tensor_name; auto lod_tensor = InferManager::instance().GetInputHandle( engine_name.c_str(), tensor_name.c_str()); std::vector> lod; diff --git a/doc/COMPILE.md b/doc/COMPILE.md index 84254f4f46949de8b4b91896eef4e5158155ed48..03d135e006c36e57e52b1d353c79217b53baa5e1 100644 --- a/doc/COMPILE.md +++ b/doc/COMPILE.md @@ -104,7 +104,7 @@ you can execute `make install` to put targets under directory `./output`, you ne ### CUDNN_LIBRARY && CUDA_CUDART_LIBRARY is the lib path, it should be /usr/local/cuda/lib64/ ``` shell -export CUDA_PATH='/usr/local' +export CUDA_PATH='/usr/local/cuda' export CUDNN_LIBRARY='/usr/local/cuda/lib64/' export CUDA_CUDART_LIBRARY="/usr/local/cuda/lib64/" @@ -123,7 +123,7 @@ make -j10 ### Integrated TRT version paddle inference library ``` -export CUDA_PATH='/usr/local' +export CUDA_PATH='/usr/local/cuda' export CUDNN_LIBRARY='/usr/local/cuda/lib64/' export CUDA_CUDART_LIBRARY="/usr/local/cuda/lib64/" diff --git a/doc/COMPILE_CN.md b/doc/COMPILE_CN.md index 9691808eda61a77808a971cc99648a7212b5747c..e5024b1a11aa871ca404287333ac3ff4ee70e21c 100644 --- a/doc/COMPILE_CN.md +++ b/doc/COMPILE_CN.md @@ -100,7 +100,7 @@ make -j10 ### CUDA_PATH是cuda的安装路径,可以使用命令行whereis cuda命令确认你的cuda安装路径,通常应该是/usr/local/cuda ### CUDNN_LIBRARY CUDA_CUDART_LIBRARY 是cuda库文件的路径,通常应该是/usr/local/cuda/lib64/ ``` shell -export CUDA_PATH='/usr/local' +export CUDA_PATH='/usr/local/cuda' export CUDNN_LIBRARY='/usr/local/cuda/lib64/' export CUDA_CUDART_LIBRARY="/usr/local/cuda/lib64/" @@ -119,7 +119,7 @@ make -j10 ### 集成TensorRT版本Paddle Inference Library ``` -export CUDA_PATH='/usr/local' +export CUDA_PATH='/usr/local/cuda' export CUDNN_LIBRARY='/usr/local/cuda/lib64/' export CUDA_CUDART_LIBRARY="/usr/local/cuda/lib64/" export TENSORRT_LIBRARY_PATH="/usr/local/TensorRT-6.0.1.5/targets/x86_64-linux-gnu/" diff --git a/doc/DOCKER_IMAGES.md b/doc/DOCKER_IMAGES.md index 582945be6d5eb39a54e329b3294c849843e1baa5..2de493fa6fcb20deb0601a2a338436785e605662 100644 --- a/doc/DOCKER_IMAGES.md +++ b/doc/DOCKER_IMAGES.md @@ -38,10 +38,22 @@ If you want to customize your Serving based on source code, use the version with | GPU (cuda9.0-cudnn7) development | CentOS7 | latest-cuda9.0-cudnn7-devel | [Dockerfile.cuda9.0-cudnn7.devel](../tools/Dockerfile.cuda9.0-cudnn7.devel) | | GPU (cuda10.0-cudnn7) runtime | CentOS7 | latest-cuda10.0-cudnn7 | [Dockerfile.cuda10.0-cudnn7](../tools/Dockerfile.cuda10.0-cudnn7) | | GPU (cuda10.0-cudnn7) development | CentOS7 | latest-cuda10.0-cudnn7-devel | [Dockerfile.cuda10.0-cudnn7.devel](../tools/Dockerfile.cuda10.0-cudnn7.devel) | -| CPU development (Used to compile packages on Ubuntu) | CentOS6 | | [Dockerfile.centos6.devel](../tools/Dockerfile.centos6.devel) | -| GPU (cuda9.0-cudnn7) development (Used to compile packages on Ubuntu) | CentOS6 | | [Dockerfile.centos6.cuda9.0-cudnn7.devel](../tools/Dockerfile.centos6.cuda9.0-cudnn7.devel) | - - +| GPU (cuda10.1-cudnn7-tensorRT6) runtime | Ubuntu16 | latest-cuda10.1-cudnn7 | [Dockerfile.cuda10.1-cudnn7](../tools/Dockerfile.cuda10.1-cudnn7) | +| GPU (cuda10.1-cudnn7-tensorRT6) development | Ubuntu16 | latest-cuda10.1-cudnn7-devel | [Dockerfile.cuda10.1-cudnn7.devel](../tools/Dockerfile.cuda10.1-cudnn7.devel) | +| GPU (cuda10.2-cudnn8-tensorRT7) runtime | Ubuntu16| latest-cuda10.2-cudnn8 | [Dockerfile.cuda10.2-cudnn8](../tools/Dockerfile.cuda10.2-cudnn8) | +| GPU (cuda10.2-cudnn8-tensorRT7) development | Ubuntu16 | latest-cuda10.2-cudnn8-devel | [Dockerfile.cuda10.2-cudnn8.devel](../tools/Dockerfile.cuda10.2-cudnn8.devel) | +| GPU (cuda11-cudnn8-tensorRT7) runtime | Ubuntu18| latest-cuda11-cudnn8 | [Dockerfile.cuda11-cudnn8](../tools/Dockerfile.cuda11-cudnn8) | +| GPU (cuda11-cudnn8-tensorRT7) development | Ubuntu18 | latest-cuda11-cudnn8-devel | [Dockerfile.cuda11-cudnn8.devel](../tools/Dockerfile.cuda11-cudnn8.devel) | + +**Java Client:** +``` +hub.baidubce.com/paddlepaddle/serving:latest-java +``` + +**XPU:** +``` +hub.baidubce.com/paddlepaddle/serving:xpu-beta +``` ## Requirements for running CUDA containers diff --git a/doc/DOCKER_IMAGES_CN.md b/doc/DOCKER_IMAGES_CN.md index 30aca584162b67e6f3c503ef2c1f95a86d0e6879..7180b3bea4e20380766ff0c49845d1d04685c43d 100644 --- a/doc/DOCKER_IMAGES_CN.md +++ b/doc/DOCKER_IMAGES_CN.md @@ -30,18 +30,30 @@ 运行时镜像不能用于开发编译。 若需要基于源代码二次开发编译,请使用后缀为-devel的版本。 -| 镜像说明 | 操作系统 | TAG | Dockerfile | -| -------------------------------------------------- | -------- | ---------------------------- | ------------------------------------------------------------ | -| CPU 运行镜像 | CentOS7 | latest | [Dockerfile](../tools/Dockerfile) | -| CPU 开发镜像 | CentOS7 | latest-devel | [Dockerfile.devel](../tools/Dockerfile.devel) | -| GPU (cuda9.0-cudnn7) 运行镜像 | CentOS7 | latest-cuda9.0-cudnn7 | [Dockerfile.cuda9.0-cudnn7](../tools/Dockerfile.cuda9.0-cudnn7) | -| GPU (cuda9.0-cudnn7) 开发镜像 | CentOS7 | latest-cuda9.0-cudnn7-devel | [Dockerfile.cuda9.0-cudnn7.devel](../tools/Dockerfile.cuda9.0-cudnn7.devel) | -| GPU (cuda10.0-cudnn7) 运行镜像 | CentOS7 | latest-cuda10.0-cudnn7 | [Dockerfile.cuda10.0-cudnn7](../tools/Dockerfile.cuda10.0-cudnn7) | -| GPU (cuda10.0-cudnn7) 开发镜像 | CentOS7 | latest-cuda10.0-cudnn7-devel | [Dockerfile.cuda10.0-cudnn7.devel](../tools/Dockerfile.cuda10.0-cudnn7.devel) | -| CPU 开发镜像 (用于编译 Ubuntu 包) | CentOS6 | <无> | [Dockerfile.centos6.devel](../tools/Dockerfile.centos6.devel) | -| GPU (cuda9.0-cudnn7) 开发镜像 (用于编译 Ubuntu 包) | CentOS6 | <无> | [Dockerfile.centos6.cuda9.0-cudnn7.devel](../tools/Dockerfile.centos6.cuda9.0-cudnn7.devel) | - - +| 镜像选择 | 操作系统 | TAG | Dockerfile | +| :----------------------------------------------------------: | :-----: | :--------------------------: | :----------------------------------------------------------: | +| CPU 运行镜像 | CentOS7 | latest | [Dockerfile](../tools/Dockerfile) | +| CPU 开发镜像 | CentOS7 | latest-devel | [Dockerfile.devel](../tools/Dockerfile.devel) | +| GPU (cuda9.0-cudnn7) 运行镜像 | CentOS7 | latest-cuda9.0-cudnn7 | [Dockerfile.cuda9.0-cudnn7](../tools/Dockerfile.cuda9.0-cudnn7) | +| GPU (cuda9.0-cudnn7) 开发镜像 | CentOS7 | latest-cuda9.0-cudnn7-devel | [Dockerfile.cuda9.0-cudnn7.devel](../tools/Dockerfile.cuda9.0-cudnn7.devel) | +| GPU (cuda10.0-cudnn7) 运行镜像 | CentOS7 | latest-cuda10.0-cudnn7 | [Dockerfile.cuda10.0-cudnn7](../tools/Dockerfile.cuda10.0-cudnn7) | +| GPU (cuda10.0-cudnn7) 开发镜像 | CentOS7 | latest-cuda10.0-cudnn7-devel | [Dockerfile.cuda10.0-cudnn7.devel](../tools/Dockerfile.cuda10.0-cudnn7.devel) | +| GPU (cuda10.1-cudnn7-tensorRT6) 运行镜像 | Ubuntu16 | latest-cuda10.1-cudnn7 | [Dockerfile.cuda10.1-cudnn7](../tools/Dockerfile.cuda10.1-cudnn7) | +| GPU (cuda10.1-cudnn7-tensorRT6) 开发镜像 | Ubuntu16 | latest-cuda10.1-cudnn7-devel | [Dockerfile.cuda10.1-cudnn7.devel](../tools/Dockerfile.cuda10.1-cudnn7.devel) | +| GPU (cuda10.2-cudnn8-tensorRT7) 运行镜像 | Ubuntu16| latest-cuda10.2-cudnn8 | [Dockerfile.cuda10.2-cudnn8](../tools/Dockerfile.cuda10.2-cudnn8) | +| GPU (cuda10.2-cudnn8-tensorRT7) 开发镜像 | Ubuntu16 | latest-cuda10.2-cudnn8-devel | [Dockerfile.cuda10.2-cudnn8.devel](../tools/Dockerfile.cuda10.2-cudnn8.devel) | +| GPU (cuda11-cudnn8-tensorRT7) 运行镜像 | Ubuntu18| latest-cuda11-cudnn8 | [Dockerfile.cuda11-cudnn8](../tools/Dockerfile.cuda11-cudnn8) | +| GPU (cuda11-cudnn8-tensorRT7) 开发镜像 | Ubuntu18 | latest-cuda11-cudnn8-devel | [Dockerfile.cuda11-cudnn8.devel](../tools/Dockerfile.cuda11-cudnn8.devel) | + +**Java镜像:** +``` +hub.baidubce.com/paddlepaddle/serving:latest-java +``` + +**XPU镜像:** +``` +hub.baidubce.com/paddlepaddle/serving:xpu-beta +``` ## 运行CUDA容器的要求 diff --git a/doc/FAQ.md b/doc/FAQ.md index 0dc4ed35a55e5904adbd1b924441aa21bc5436ab..e102857750e1d50731654a8f384bb9f7c1b21d88 100644 --- a/doc/FAQ.md +++ b/doc/FAQ.md @@ -34,6 +34,57 @@ **A:** http rpc +## 安装问题 + +#### Q: pip install安装whl包过程,报错信息如下: +``` +Collecting opencv-python + Using cached opencv-python-4.3.0.38.tar.gz (88.0 MB) + Installing build dependencies ... done + Getting requirements to build wheel ... error + ERROR: Command errored out with exit status 1: + command: /home/work/Python-2.7.17/build/bin/python /home/work/Python-2.7.17/build/lib/python2.7/site-packages/pip/_vendor/pep517/_in_process.py get_requires_for_build_wheel /tmp/tmpLiweA9 + cwd: /tmp/pip-install-_w6AUI/opencv-python + Complete output (22 lines): + Traceback (most recent call last): + File "/home/work/Python-2.7.17/build/lib/python2.7/site-packages/pip/_vendor/pep517/_in_process.py", line 280, in + main() + File "/home/work/Python-2.7.17/build/lib/python2.7/site-packages/pip/_vendor/pep517/_in_process.py", line 263, in main + json_out['return_val'] = hook(**hook_input['kwargs']) + File "/home/work/Python-2.7.17/build/lib/python2.7/site-packages/pip/_vendor/pep517/_in_process.py", line 114, in get_requires_for_build_wheel + return hook(config_settings) + File "/tmp/pip-build-env-AUCbP4/overlay/lib/python2.7/site-packages/setuptools/build_meta.py", line 146, in get_requires_for_build_wheel + return self._get_build_requires(config_settings, requirements=['wheel']) + File "/tmp/pip-build-env-AUCbP4/overlay/lib/python2.7/site-packages/setuptools/build_meta.py", line 127, in _get_build_requires + self.run_setup() + File "/tmp/pip-build-env-AUCbP4/overlay/lib/python2.7/site-packages/setuptools/build_meta.py", line 243, in run_setup + self).run_setup(setup_script=setup_script) + File "/tmp/pip-build-env-AUCbP4/overlay/lib/python2.7/site-packages/setuptools/build_meta.py", line 142, in run_setup + exec(compile(code, __file__, 'exec'), locals()) + File "setup.py", line 448, in + main() + File "setup.py", line 99, in main + % {"ext": re.escape(sysconfig.get_config_var("EXT_SUFFIX"))} + File "/home/work/Python-2.7.17/build/lib/python2.7/re.py", line 210, in escape + s = list(pattern) + TypeError: 'NoneType' object is not iterable +``` +**A:** 指定opencv-python版本安装,pip install opencv-python==4.2.0.32,再安装whl包 + +#### Q: pip3 install whl包过程报错信息如下: +``` + Complete output from command python setup.py egg_info: + Found cython-generated files... + error in grpcio setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers; Expected ',' or end-of-list in futures>=2.2.0; python_version<'3.2' at ; python_version<'3.2' + + ---------------------------------------- +Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-taoxz02y/grpcio/ +``` +**A:** 需要升级pip3,再重新执行安装命令。 +``` +pip3 install --upgrade pip +pip3 install --upgrade setuptools +``` ## 编译问题 diff --git a/doc/INFERENCE_TO_SERVING.md b/doc/INFERENCE_TO_SERVING.md index 719aa63c0a9b408d6bff628e7be4f35dfb49c5c8..15647dbbf8d461bcda237b0ef09b6818ee92fb00 100644 --- a/doc/INFERENCE_TO_SERVING.md +++ b/doc/INFERENCE_TO_SERVING.md @@ -2,35 +2,15 @@ ([简体中文](./INFERENCE_TO_SERVING_CN.md)|English) -We should know something before converting to serving model - -**inference_model_dir**:the directory of Paddle inference model - -**serving_client_dir**: the directory of server side configuration - -**serving_client_dir**: the directory of client side configuration - -**model_filename**: this is model description file whose default value is `__model__`, if it's not default name, set `model_filename` explicitly - -**params_filename**: during `save_inference_model` every Variable will be save as a single file. If we have the inference model whose params are compressed into one file, please set `params_filename` explicitly - - - -## Example - -``` python -from paddle_serving_client.io import inference_model_to_serving -inference_model_dir = "your_inference_model" -serving_client_dir = "serving_client_dir" -serving_server_dir = "serving_server_dir" -feed_var_names, fetch_var_names = inference_model_to_serving( - inference_model_dir, serving_server_dir, serving_client_dir) -``` - -if your model file and params file are both standalone, please use the following api. - -``` -feed_var_names, fetch_var_names = inference_model_to_serving( - inference_model_dir, serving_server_dir, serving_client_dir, - model_filename="model", params_filename="params") +you can use a build-in python module called `paddle_serving_client.convert` to convert it. +```python +python -m paddle_serving_client.convert --dirname ./your_inference_model_dir ``` +Arguments are the same as `inference_model_to_serving` API. +| Argument | Type | Default | Description | +|--------------|------|-----------|--------------------------------| +| `dirname` | str | - | Path of saved model files. Program file and parameter files are saved in this directory. | +| `serving_server` | str | `"serving_server"` | The path of model files and configuration files for server. | +| `serving_client` | str | `"serving_client"` | The path of configuration files for client. | +| `model_filename` | str | None | The name of file to load the inference program. If it is None, the default filename `__model__` will be used. | +| `params_filename` | str | None | The name of file to load all parameters. It is only used for the case that all parameters were saved in a single binary file. If parameters were saved in separate files, set it as None. | diff --git a/doc/INFERENCE_TO_SERVING_CN.md b/doc/INFERENCE_TO_SERVING_CN.md index 5d783f25a3f367baa94d471e50f227d9e6f733d1..64caf659f66f000cfab8a43abc66e3c3cd2e377c 100644 --- a/doc/INFERENCE_TO_SERVING_CN.md +++ b/doc/INFERENCE_TO_SERVING_CN.md @@ -2,32 +2,15 @@ ([English](./INFERENCE_TO_SERVING.md)|简体中文) -## 示例 - -在下列代码中,我们需要知道以下信息。 - -**模型文件夹**:这个文件夹就是Paddle的inference_model所在的文件夹 - -**serving_client_dir**: 这个文件夹是inference_model转换成Serving模型后,服务端配置的保存路径 - -**serving_client_dir**: 这个文件夹是inference_model转换成Serving模型后,客户端配置的保存路径 - -**模型描述文件**: 模型描述文件也就是`model_filename`默认值为`__model__`,是一个pb2文本文件,如果是别的文件名需要显式指定 - -**模型参数文件**: 在`save_inference_model`阶段,默认方式是每一个Variable保存一个二进制文件,如果是这种情况就不需要做指定。如果所有参数用压缩成一个文件的形式保存,则需要显式指定`params_filename` - - -``` python -from paddle_serving_client.io import inference_model_to_serving -inference_model_dir = "your_inference_model" -serving_client_dir = "serving_client_dir" -serving_server_dir = "serving_server_dir" -feed_var_names, fetch_var_names = inference_model_to_serving( - inference_model_dir, serving_server_dir, serving_client_dir) -``` -如果模型中有模型描述文件`model_filename` 和 模型参数文件`params_filename`,那么请用 -``` -feed_var_names, fetch_var_names = inference_model_to_serving( - inference_model_dir, serving_server_dir, serving_client_dir, - model_filename="model", params_filename="params") +你可以使用Paddle Serving提供的名为`paddle_serving_client.convert`的内置模块进行转换。 +```python +python -m paddle_serving_client.convert --dirname ./your_inference_model_dir ``` +模块参数与`inference_model_to_serving`接口参数相同。 +| 参数 | 类型 | 默认值 | 描述 | +|--------------|------|-----------|--------------------------------| +| `dirname` | str | - | 需要转换的模型文件存储路径,Program结构文件和参数文件均保存在此目录。| +| `serving_server` | str | `"serving_server"` | 转换后的模型文件和配置文件的存储路径。默认值为serving_server | +| `serving_client` | str | `"serving_client"` | 转换后的客户端配置文件存储路径。默认值为serving_client | +| `model_filename` | str | None | 存储需要转换的模型Inference Program结构的文件名称。如果设置为None,则使用 `__model__` 作为默认的文件名 | +| `params_filename` | str | None | 存储需要转换的模型所有参数的文件名称。当且仅当所有模型参数被保存在一个单独的>二进制文件中,它才需要被指定。如果模型参数是存储在各自分离的文件中,设置它的值为None | diff --git a/doc/LATEST_PACKAGES.md b/doc/LATEST_PACKAGES.md index 1c15371fda01e0f1aee00312a2f7bc9628b741af..63f9f4e6394796382eac5893196d73a40eae847d 100644 --- a/doc/LATEST_PACKAGES.md +++ b/doc/LATEST_PACKAGES.md @@ -29,7 +29,7 @@ https://paddle-serving.bj.bcebos.com/whl/paddle_serving_server_gpu-0.0.0.post102 https://paddle-serving.bj.bcebos.com/whl/paddle_serving_server_gpu-0.0.0.post9-py2-none-any.whl #cuda 10.0 https://paddle-serving.bj.bcebos.com/whl/paddle_serving_server_gpu-0.0.0.post10-py2-none-any.whl -##cuda10.1 with TensorRT 6 +#cuda10.1 with TensorRT 6 https://paddle-serving.bj.bcebos.com/whl/paddle_serving_server_gpu-0.0.0.post101-py2-none-any.whl #cuda10.2 with TensorRT 7 https://paddle-serving.bj.bcebos.com/whl/paddle_serving_server_gpu-0.0.0.post102-py2-none-any.whl @@ -63,3 +63,17 @@ https://paddle-serving.bj.bcebos.com/whl/paddle_serving_app-0.0.0-py3-none-any.w ``` https://paddle-serving.bj.bcebos.com/whl/paddle_serving_app-0.0.0-py2-none-any.whl ``` + +## ARM user +for ARM user who uses [PaddleLite](https://github.com/PaddlePaddle/PaddleLite) can download the wheel packages as follows. And ARM user should use the xpu-beta docker [DOCKER IMAGES](./DOCKER_IMAGES.md) +**We only support Python 3.6 for Arm Users.** + +### Wheel Package Links +``` +# Server +https://paddle-serving.bj.bcebos.com/whl/xpu/paddle_serving_server_gpu-0.0.0.postarm_xpu-py3-none-any.whl +# Client +https://paddle-serving.bj.bcebos.com/whl/xpu/paddle_serving_client-0.0.0-cp36-none-any.whl +# App +https://paddle-serving.bj.bcebos.com/whl/xpu/paddle_serving_app-0.0.0-py3-none-any.whl +``` diff --git a/java/README.md b/java/README.md index 2346d13e20b4f81c454bd4bf731fe406015ab26f..225c8b0345817719ddb7a872a9fc07f9aa33a535 100644 --- a/java/README.md +++ b/java/README.md @@ -110,10 +110,8 @@ The first is that GPU Serving and Java Client are in the same image. After start The second is to deploy GPU Serving and Java Client separately. If they are on the same host, you can learn the IP address of the corresponding container through ifconfig, and then when you connect to client.connect in `examples/src/main/java/PaddleServingClientExample.java` Make changes to the endpoint, and then compile it again. Or select `--net=host` to bind the network device of docker and host when docker starts, so that it can run directly without customizing java code. -**It should be noted that in the example, all models need to use `--use_multilang` to start GRPC multi-programming language support, and the port number is 9393. If you need another port, you need to modify it in the java file** - -**Currently Serving has launched the Pipeline mode (see [Pipeline Serving](../doc/PIPELINE_SERVING.md) for details). Pipeline Serving Client for Java is released, the next version multi-thread java client example will be released** - -**It should be noted that in the example, Java Pipeline Client code is in path /Java/Examples and /Java/src/main, and the Pipeline server code is in path /python/examples/pipeline/** +**It should be noted that in the example, all models(not pipeline) need to use `--use_multilang` to start GRPC multi-programming language support, and the port number is 9393. If you need another port, you need to modify it in the java file** +**Currently Serving has launched the Pipeline mode (see [Pipeline Serving](../doc/PIPELINE_SERVING.md) for details). Pipeline Serving Client for Java is released.** +**It should be noted that in the example, Java Pipeline Client code is in path /Java/Examples and /Java/src/main, and the Pipeline server code is in path /python/examples/pipeline/ The Client IP and Port(which is configured in java/examples/src/main/java/PipelineClientExample.java) should be corresponding to the Pipeline Server IP and Port(which is configured in config.yaml) ** diff --git a/java/README_CN.md b/java/README_CN.md index 4c1df65fbeb78340187c9e603ff185751ebecf56..8fb6edd1af562bde12044f36ec2d9e71558c5a6b 100644 --- a/java/README_CN.md +++ b/java/README_CN.md @@ -111,11 +111,9 @@ java -cp paddle-serving-sdk-java-examples-0.0.1-jar-with-dependencies.jar Pipeli 第二种是GPU Serving和Java Client分开部署,如果在同一台宿主机,可以通过ifconfig了解对应容器的IP地址,然后在`examples/src/main/java/PaddleServingClientExample.java`当中对client.connect时的endpoint做修改,然后再编译一次。 或者在docker启动时选择 `--net=host`来绑定docker和宿主机的网络设备,这样不需要定制java代码可以直接运行。 -**需要注意的是,在示例中,所有模型都需要使用`--use_multilang`来启动GRPC多编程语言支持,以及端口号都是9393,如果需要别的端口,需要在java文件里修改** +**需要注意的是,在示例中,所有非Pipeline模型都需要使用`--use_multilang`来启动GRPC多编程语言支持,以及端口号都是9393,如果需要别的端口,需要在java文件里修改** -**目前Serving已推出Pipeline模式(详见[Pipeline Serving](../doc/PIPELINE_SERVING_CN.md)),面向Java的Pipeline Serving Client已发布,下个更新会发布Java版本的多线程用例敬请期待。** +**目前Serving已推出Pipeline模式(详见[Pipeline Serving](../doc/PIPELINE_SERVING_CN.md)),面向Java的Pipeline Serving Client已发布。** -**需要注意的是,Java Pipeline Client相关示例在/Java/Examples和/Java/src/main中,对应的Pipeline server在/python/examples/pipeline/中** - - -**目前Serving已推出Pipeline模式(详见[Pipeline Serving](../doc/PIPELINE_SERVING_CN.md)),下个版本(0.4.1)面向Java的Pipeline Serving Client将会发布,敬请期待。** +**需要注意的是,Java Pipeline Client相关示例在/Java/Examples和/Java/src/main中,对应的Pipeline server在/python/examples/pipeline/中 +注意java/examples/src/main/java/PipelineClientExample.java中的ip和port,需要与/python/examples/pipeline/中对应Pipeline server的config.yaml文件中配置的ip和port相对应。** diff --git a/java/examples/src/main/java/PipelineClientExample.java b/java/examples/src/main/java/PipelineClientExample.java index 1f459d82a99ad707c5803ab00d662eeceea56219..d279e00e30de5aeec37e14dfedc1aeb998222825 100644 --- a/java/examples/src/main/java/PipelineClientExample.java +++ b/java/examples/src/main/java/PipelineClientExample.java @@ -32,7 +32,7 @@ public class PipelineClientExample { System.out.println(fetch); if (StaticPipelineClient.succ != true) { - if(!StaticPipelineClient.initClient("172.17.0.2","18070")){ + if(!StaticPipelineClient.initClient("127.0.0.1","18070")){ System.out.println("connect failed."); return false; } @@ -57,12 +57,12 @@ public class PipelineClientExample { List fetch = Arrays.asList("prediction"); System.out.println(fetch); if (StaticPipelineClient.succ != true) { - if(!StaticPipelineClient.initClient("172.17.0.2","18070")){ + if(!StaticPipelineClient.initClient("127.0.0.1","18070")){ System.out.println("connect failed."); return false; } } - PipelineFuture future = StaticPipelineClient.client.asyn_pr::qedict(feed_data, fetch,false,0); + PipelineFuture future = StaticPipelineClient.client.asyn_predict(feed_data, fetch,false,0); HashMap result = future.get(); if (result == null) { return false; @@ -86,7 +86,7 @@ public class PipelineClientExample { }}; List fetch = Arrays.asList("prediction"); if (StaticPipelineClient.succ != true) { - if(!StaticPipelineClient.initClient("172.17.0.2","9998")){ + if(!StaticPipelineClient.initClient("127.0.0.1","9998")){ System.out.println("connect failed."); return false; } diff --git a/java/examples/src/main/java/StaticPipelineClient.java b/java/examples/src/main/java/StaticPipelineClient.java index 7399b05969c712602bc097d36ec5db2380c89328..6a54ce2e5cc5e302c5debe07d119b21c0873f7a6 100644 --- a/java/examples/src/main/java/StaticPipelineClient.java +++ b/java/examples/src/main/java/StaticPipelineClient.java @@ -37,7 +37,7 @@ public class StaticPipelineClient { System.out.println("already connect."); return true; } - succ = clieint.connect(target); + succ = client.connect(target); if (succ != true) { System.out.println("connect failed."); return false; diff --git a/paddle_inference/inferencer-fluid-arm/include/fluid_arm_engine.h b/paddle_inference/inferencer-fluid-arm/include/fluid_arm_engine.h index 92408cdacc581f7f9323840b87518df8ab8136ed..b3db6e1ad03d1822155918f9eb8714b6285972d1 100644 --- a/paddle_inference/inferencer-fluid-arm/include/fluid_arm_engine.h +++ b/paddle_inference/inferencer-fluid-arm/include/fluid_arm_engine.h @@ -128,20 +128,22 @@ class FluidArmAnalysisCore : public FluidFamilyCore { config.DisableGpu(); config.SetCpuMathLibraryNumThreads(1); - if (params.enable_memory_optimization()) { - config.EnableMemoryOptim(); + if (params.use_lite()) { + config.EnableLiteEngine(PrecisionType::kFloat32, true); } - if (params.enable_memory_optimization()) { - config.EnableMemoryOptim(); + if (params.use_xpu()) { + config.EnableXpu(2 * 1024 * 1024); } - if (params.use_lite()) { - config.EnableLiteEngine(PrecisionType::kFloat32, true); + if (params.enable_memory_optimization()) { + config.EnableMemoryOptim(); } - if (params.use_xpu()) { - config.EnableXpu(100); + if (params.enable_ir_optimization()) { + config.SwitchIrOptim(true); + } else { + config.SwitchIrOptim(false); } config.SwitchSpecifyInputNames(true); @@ -173,6 +175,14 @@ class FluidArmAnalysisDirCore : public FluidFamilyCore { config.SwitchSpecifyInputNames(true); config.SetCpuMathLibraryNumThreads(1); + if (params.use_lite()) { + config.EnableLiteEngine(PrecisionType::kFloat32, true); + } + + if (params.use_xpu()) { + config.EnableXpu(2 * 1024 * 1024); + } + if (params.enable_memory_optimization()) { config.EnableMemoryOptim(); } @@ -183,14 +193,6 @@ class FluidArmAnalysisDirCore : public FluidFamilyCore { config.SwitchIrOptim(false); } - if (params.use_lite()) { - config.EnableLiteEngine(PrecisionType::kFloat32, true); - } - - if (params.use_xpu()) { - config.EnableXpu(100); - } - AutoLock lock(GlobalPaddleCreateMutex::instance()); _core = CreatePredictor(config); if (NULL == _core.get()) { diff --git a/paddle_inference/inferencer-fluid-cpu/include/fluid_cpu_engine.h b/paddle_inference/inferencer-fluid-cpu/include/fluid_cpu_engine.h index b20a4f4cf34e2f250788ae84c1b5b681d36cea4f..681f2fe2fd1c030f03aca28376ca5bc14795c44b 100644 --- a/paddle_inference/inferencer-fluid-cpu/include/fluid_cpu_engine.h +++ b/paddle_inference/inferencer-fluid-cpu/include/fluid_cpu_engine.h @@ -263,6 +263,61 @@ class Parameter { float* _params; }; +class FluidCpuAnalysisEncryptCore : public FluidFamilyCore { + public: + void ReadBinaryFile(const std::string& filename, std::string* contents) { + std::ifstream fin(filename, std::ios::in | std::ios::binary); + fin.seekg(0, std::ios::end); + contents->clear(); + contents->resize(fin.tellg()); + fin.seekg(0, std::ios::beg); + fin.read(&(contents->at(0)), contents->size()); + fin.close(); + } + + int create(const predictor::InferEngineCreationParams& params) { + std::string data_path = params.get_path(); + if (access(data_path.c_str(), F_OK) == -1) { + LOG(ERROR) << "create paddle predictor failed, path note exits: " + << data_path; + return -1; + } + + std::string model_buffer, params_buffer, key_buffer; + ReadBinaryFile(data_path + "encrypt_model", &model_buffer); + ReadBinaryFile(data_path + "encrypt_params", ¶ms_buffer); + ReadBinaryFile(data_path + "key", &key_buffer); + + VLOG(2) << "prepare for encryption model"; + + auto cipher = paddle::MakeCipher(""); + std::string real_model_buffer = cipher->Decrypt(model_buffer, key_buffer); + std::string real_params_buffer = cipher->Decrypt(params_buffer, key_buffer); + + Config analysis_config; + // paddle::AnalysisConfig analysis_config; + analysis_config.SetModelBuffer(&real_model_buffer[0], + real_model_buffer.size(), + &real_params_buffer[0], + real_params_buffer.size()); + analysis_config.DisableGpu(); + analysis_config.SetCpuMathLibraryNumThreads(1); + if (params.enable_memory_optimization()) { + analysis_config.EnableMemoryOptim(); + } + analysis_config.SwitchSpecifyInputNames(true); + AutoLock lock(GlobalPaddleCreateMutex::instance()); + VLOG(2) << "decrypt model file sucess"; + _core = CreatePredictor(analysis_config); + if (NULL == _core.get()) { + LOG(ERROR) << "create paddle predictor failed, path: " << data_path; + return -1; + } + VLOG(2) << "create paddle predictor sucess, path: " << data_path; + return 0; + } +}; + } // namespace fluid_cpu } // namespace paddle_serving } // namespace baidu diff --git a/paddle_inference/inferencer-fluid-cpu/src/fluid_cpu_engine.cpp b/paddle_inference/inferencer-fluid-cpu/src/fluid_cpu_engine.cpp index 91cb0bd20c97e53952f95bb05a25582242793f57..f8cf24ef2218705bef71a05194860565961451a1 100644 --- a/paddle_inference/inferencer-fluid-cpu/src/fluid_cpu_engine.cpp +++ b/paddle_inference/inferencer-fluid-cpu/src/fluid_cpu_engine.cpp @@ -30,6 +30,13 @@ REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( ::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_ANALYSIS_DIR"); +#if 1 +REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( + ::baidu::paddle_serving::predictor::FluidInferEngine< + FluidCpuAnalysisEncryptCore>, + ::baidu::paddle_serving::predictor::InferEngine, + "FLUID_CPU_ANALYSIS_ENCRYPT"); +#endif } // namespace fluid_cpu } // namespace paddle_serving } // namespace baidu diff --git a/paddle_inference/inferencer-fluid-gpu/include/fluid_gpu_engine.h b/paddle_inference/inferencer-fluid-gpu/include/fluid_gpu_engine.h index 3d59a5009471ff5c76e037a941a0da87377684ab..d3f63f724ffd473b274deccad751ee65d6a7cf93 100644 --- a/paddle_inference/inferencer-fluid-gpu/include/fluid_gpu_engine.h +++ b/paddle_inference/inferencer-fluid-gpu/include/fluid_gpu_engine.h @@ -283,6 +283,60 @@ class Parameter { float* _params; }; +class FluidGpuAnalysisEncryptCore : public FluidFamilyCore { + public: + void ReadBinaryFile(const std::string& filename, std::string* contents) { + std::ifstream fin(filename, std::ios::in | std::ios::binary); + fin.seekg(0, std::ios::end); + contents->clear(); + contents->resize(fin.tellg()); + fin.seekg(0, std::ios::beg); + fin.read(&(contents->at(0)), contents->size()); + fin.close(); + } + + int create(const predictor::InferEngineCreationParams& params) { + std::string data_path = params.get_path(); + if (access(data_path.c_str(), F_OK) == -1) { + LOG(ERROR) << "create paddle predictor failed, path note exits: " + << data_path; + return -1; + } + + std::string model_buffer, params_buffer, key_buffer; + ReadBinaryFile(data_path + "encrypt_model", &model_buffer); + ReadBinaryFile(data_path + "encrypt_params", ¶ms_buffer); + ReadBinaryFile(data_path + "key", &key_buffer); + + VLOG(2) << "prepare for encryption model"; + + auto cipher = paddle::MakeCipher(""); + std::string real_model_buffer = cipher->Decrypt(model_buffer, key_buffer); + std::string real_params_buffer = cipher->Decrypt(params_buffer, key_buffer); + + Config analysis_config; + analysis_config.SetModelBuffer(&real_model_buffer[0], + real_model_buffer.size(), + &real_params_buffer[0], + real_params_buffer.size()); + analysis_config.EnableUseGpu(100, FLAGS_gpuid); + analysis_config.SetCpuMathLibraryNumThreads(1); + if (params.enable_memory_optimization()) { + analysis_config.EnableMemoryOptim(); + } + analysis_config.SwitchSpecifyInputNames(true); + AutoLock lock(GlobalPaddleCreateMutex::instance()); + VLOG(2) << "decrypt model file sucess"; + _core = CreatePredictor(analysis_config); + if (NULL == _core.get()) { + LOG(ERROR) << "create paddle predictor failed, path: " << data_path; + return -1; + } + VLOG(2) << "create paddle predictor sucess, path: " << data_path; + return 0; + } +}; + } // namespace fluid_gpu } // namespace paddle_serving } // namespace baidu diff --git a/paddle_inference/inferencer-fluid-gpu/src/fluid_gpu_engine.cpp b/paddle_inference/inferencer-fluid-gpu/src/fluid_gpu_engine.cpp index c00ea8719414f5ac324ac62e3e36128ad6035f91..613b83432ba5f8fb6c3217f1ba24162bc33b493d 100644 --- a/paddle_inference/inferencer-fluid-gpu/src/fluid_gpu_engine.cpp +++ b/paddle_inference/inferencer-fluid-gpu/src/fluid_gpu_engine.cpp @@ -31,6 +31,11 @@ REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( FluidGpuAnalysisDirCore>, ::baidu::paddle_serving::predictor::InferEngine, "FLUID_GPU_ANALYSIS_DIR"); +REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( + ::baidu::paddle_serving::predictor::FluidInferEngine< + FluidGpuAnalysisEncryptCore>, + ::baidu::paddle_serving::predictor::InferEngine, + "FLUID_GPU_ANALYSIS_ENCRPT") } // namespace fluid_gpu } // namespace paddle_serving diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 2f3865d67d22403c38d9db21fbfb39e98de2659f..d17844991ea342e142476acececb14ac2e6ae106 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -99,15 +99,27 @@ if (SERVER) DEPENDS ${SERVING_SERVER_CORE} server_config_py_proto ${PY_FILES}) add_custom_target(paddle_python ALL DEPENDS ${PADDLE_SERVING_BINARY_DIR}/.timestamp) elseif(WITH_LITE) - add_custom_command( - OUTPUT ${PADDLE_SERVING_BINARY_DIR}/.timestamp - COMMAND cp -r - ${CMAKE_CURRENT_SOURCE_DIR}/paddle_serving_server_gpu/ ${PADDLE_SERVING_BINARY_DIR}/python/ - COMMAND env ${py_env} ${PYTHON_EXECUTABLE} gen_version.py - "server_gpu" arm - COMMAND env ${py_env} ${PYTHON_EXECUTABLE} setup.py bdist_wheel - DEPENDS ${SERVING_SERVER_CORE} server_config_py_proto ${PY_FILES}) - add_custom_target(paddle_python ALL DEPENDS ${PADDLE_SERVING_BINARY_DIR}/.timestamp) + if(WITH_XPU) + add_custom_command( + OUTPUT ${PADDLE_SERVING_BINARY_DIR}/.timestamp + COMMAND cp -r + ${CMAKE_CURRENT_SOURCE_DIR}/paddle_serving_server_gpu/ ${PADDLE_SERVING_BINARY_DIR}/python/ + COMMAND env ${py_env} ${PYTHON_EXECUTABLE} gen_version.py + "server_gpu" arm-xpu + COMMAND env ${py_env} ${PYTHON_EXECUTABLE} setup.py bdist_wheel + DEPENDS ${SERVING_SERVER_CORE} server_config_py_proto ${PY_FILES}) + add_custom_target(paddle_python ALL DEPENDS ${PADDLE_SERVING_BINARY_DIR}/.timestamp) + else() + add_custom_command( + OUTPUT ${PADDLE_SERVING_BINARY_DIR}/.timestamp + COMMAND cp -r + ${CMAKE_CURRENT_SOURCE_DIR}/paddle_serving_server_gpu/ ${PADDLE_SERVING_BINARY_DIR}/python/ + COMMAND env ${py_env} ${PYTHON_EXECUTABLE} gen_version.py + "server_gpu" arm + COMMAND env ${py_env} ${PYTHON_EXECUTABLE} setup.py bdist_wheel + DEPENDS ${SERVING_SERVER_CORE} server_config_py_proto ${PY_FILES}) + add_custom_target(paddle_python ALL DEPENDS ${PADDLE_SERVING_BINARY_DIR}/.timestamp) + endif() else() add_custom_command( OUTPUT ${PADDLE_SERVING_BINARY_DIR}/.timestamp diff --git a/python/examples/bert/README.md b/python/examples/bert/README.md index 4cfa5590ffb4501c78e9e6ff886f5f82c94dd2db..a8fa35ddaec86ea2f05b025a3bde4b999d57f1dc 100644 --- a/python/examples/bert/README.md +++ b/python/examples/bert/README.md @@ -3,9 +3,10 @@ ([简体中文](./README_CN.md)|English) In the example, a BERT model is used for semantic understanding prediction, and the text is represented as a vector, which can be used for further analysis and prediction. +If your python version is 3.X, replace the 'pip' field in the following command with 'pip3',replace 'python' with 'python3'. ### Getting Model - +method 1: This example use model [BERT Chinese Model](https://www.paddlepaddle.org.cn/hubdetail?name=bert_chinese_L-12_H-768_A-12&en_category=SemanticModel) from [Paddlehub](https://github.com/PaddlePaddle/PaddleHub). Install paddlehub first @@ -22,11 +23,13 @@ the 128 in the command above means max_seq_len in BERT model, which is the lengt the config file and model file for server side are saved in the folder bert_seq128_model. the config file generated for client side is saved in the folder bert_seq128_client. +method 2: You can also download the above model from BOS(max_seq_len=128). After decompression, the config file and model file for server side are stored in the bert_chinese_L-12_H-768_A-12_model folder, and the config file generated for client side is stored in the bert_chinese_L-12_H-768_A-12_client folder: ```shell wget https://paddle-serving.bj.bcebos.com/paddle_hub_models/text/SemanticModel/bert_chinese_L-12_H-768_A-12.tar.gz tar -xzf bert_chinese_L-12_H-768_A-12.tar.gz ``` +if your model is bert_chinese_L-12_H-768_A-12_model, replace the 'bert_seq128_model' field in the following command with 'bert_chinese_L-12_H-768_A-12_model',replace 'bert_seq128_client' with 'bert_chinese_L-12_H-768_A-12_client'. ### Getting Dict and Sample Dataset @@ -36,11 +39,11 @@ sh get_data.sh this script will download Chinese Dictionary File vocab.txt and Chinese Sample Data data-c.txt ### RPC Inference Service -Run +start cpu inference service,Run ``` python -m paddle_serving_server.serve --model bert_seq128_model/ --port 9292 #cpu inference service ``` -Or +Or,start gpu inference service,Run ``` python -m paddle_serving_server_gpu.serve --model bert_seq128_model/ --port 9292 --gpu_ids 0 #launch gpu inference service at GPU 0 ``` @@ -59,12 +62,18 @@ head data-c.txt | python bert_client.py --model bert_seq128_client/serving_clien the client reads data from data-c.txt and send prediction request, the prediction is given by word vector. (Due to massive data in the word vector, we do not print it). ### HTTP Inference Service +start cpu HTTP inference service,Run +``` + python bert_web_service.py bert_seq128_model/ 9292 #launch gpu inference service +``` + +Or,start gpu HTTP inference service,Run ``` export CUDA_VISIBLE_DEVICES=0,1 ``` set environmental variable to specify which gpus are used, the command above means gpu 0 and gpu 1 is used. ``` - python bert_web_service.py bert_seq128_model/ 9292 #launch gpu inference service + python bert_web_service_gpu.py bert_seq128_model/ 9292 #launch gpu inference service ``` ### HTTP Inference diff --git a/python/examples/bert/README_CN.md b/python/examples/bert/README_CN.md index 93ec8f2adbd9ae31489011900472a0077cb33783..e06e17c8f345b65884feabee08d40e5f345fa322 100644 --- a/python/examples/bert/README_CN.md +++ b/python/examples/bert/README_CN.md @@ -4,8 +4,9 @@ 示例中采用BERT模型进行语义理解预测,将文本表示为向量的形式,可以用来做进一步的分析和预测。 +若使用python的版本为3.X, 将以下命令中的pip 替换为pip3, python替换为python3. ### 获取模型 - +方法1: 示例中采用[Paddlehub](https://github.com/PaddlePaddle/PaddleHub)中的[BERT中文模型](https://www.paddlepaddle.org.cn/hubdetail?name=bert_chinese_L-12_H-768_A-12&en_category=SemanticModel)。 请先安装paddlehub ``` @@ -19,11 +20,15 @@ python prepare_model.py 128 生成server端配置文件与模型文件,存放在bert_seq128_model文件夹。 生成client端配置文件,存放在bert_seq128_client文件夹。 +方法2: 您也可以从bos上直接下载上述模型(max_seq_len=128),解压后server端配置文件与模型文件存放在bert_chinese_L-12_H-768_A-12_model文件夹,client端配置文件存放在bert_chinese_L-12_H-768_A-12_client文件夹: ```shell wget https://paddle-serving.bj.bcebos.com/paddle_hub_models/text/SemanticModel/bert_chinese_L-12_H-768_A-12.tar.gz tar -xzf bert_chinese_L-12_H-768_A-12.tar.gz ``` +若使用bert_chinese_L-12_H-768_A-12_model模型,将下面命令中的bert_seq128_model字段替换为bert_chinese_L-12_H-768_A-12_model,bert_seq128_client字段替换为bert_chinese_L-12_H-768_A-12_client. + + ### 获取词典和样例数据 @@ -33,13 +38,15 @@ sh get_data.sh 脚本将下载中文词典vocab.txt和中文样例数据data-c.txt ### 启动RPC预测服务 -执行 +启动cpu预测服务,执行 ``` python -m paddle_serving_server.serve --model bert_seq128_model/ --port 9292 #启动cpu预测服务 + ``` -或者 +或者,启动gpu预测服务,执行 ``` python -m paddle_serving_server_gpu.serve --model bert_seq128_model/ --port 9292 --gpu_ids 0 #在gpu 0上启动gpu预测服务 + ``` ### 执行预测 @@ -51,17 +58,28 @@ pip install paddle_serving_app 执行 ``` head data-c.txt | python bert_client.py --model bert_seq128_client/serving_client_conf.prototxt + ``` 启动client读取data-c.txt中的数据进行预测,预测结果为文本的向量表示(由于数据较多,脚本中没有将输出进行打印),server端的地址在脚本中修改。 + + ### 启动HTTP预测服务 +启动cpu HTTP预测服务,执行 +``` +python bert_web_service.py bert_seq128_model/ 9292 #启动gpu预测服务 + +``` + +或者,启动gpu HTTP预测服务,执行 ``` export CUDA_VISIBLE_DEVICES=0,1 ``` 通过环境变量指定gpu预测服务使用的gpu,示例中指定索引为0和1的两块gpu ``` - python bert_web_service.py bert_seq128_model/ 9292 #启动gpu预测服务 +python bert_web_service_gpu.py bert_seq128_model/ 9292 #启动gpu预测服务 ``` + ### 执行预测 ``` diff --git a/python/examples/bert/bert_web_service_gpu.py b/python/examples/bert/bert_web_service_gpu.py new file mode 100644 index 0000000000000000000000000000000000000000..cbdd321c0932bf68c1e37f02f0c08e08a6c0e43e --- /dev/null +++ b/python/examples/bert/bert_web_service_gpu.py @@ -0,0 +1,48 @@ +# coding=utf-8 +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# pylint: disable=doc-string-missing +from paddle_serving_server_gpu.web_service import WebService +from paddle_serving_app.reader import ChineseBertReader +import sys +import os +import numpy as np + + +class BertService(WebService): + def load(self): + self.reader = ChineseBertReader({ + "vocab_file": "vocab.txt", + "max_seq_len": 128 + }) + + def preprocess(self, feed=[], fetch=[]): + feed_res = [] + is_batch = False + for ins in feed: + feed_dict = self.reader.process(ins["words"].encode("utf-8")) + for key in feed_dict.keys(): + feed_dict[key] = np.array(feed_dict[key]).reshape( + (len(feed_dict[key]), 1)) + feed_res.append(feed_dict) + return feed_res, fetch, is_batch + + +bert_service = BertService(name="bert") +bert_service.load() +bert_service.load_model_config(sys.argv[1]) +bert_service.prepare_server( + workdir="workdir", port=int(sys.argv[2]), device="gpu") +bert_service.run_rpc_service() +bert_service.run_web_service() diff --git a/python/examples/encryption/get_data.sh b/python/examples/encryption/get_data.sh index d1e97727fe5602552e48fbd7899128a274186948..c3cd5c236f5643d53c3a30bf0ffd367853ffaf13 100644 --- a/python/examples/encryption/get_data.sh +++ b/python/examples/encryption/get_data.sh @@ -1,4 +1,4 @@ wget --no-check-certificate https://paddle-serving.bj.bcebos.com/uci_housing_example/encrypt.tar.gz tar -xzf encrypt.tar.gz -cp -rvf ../fit_a_line/uci_housing_model . -cp -rvf ../fit_a_line/uci_housing_client . +wget --no-check-certificate https://paddle-serving.bj.bcebos.com/uci_housing.tar.gz +tar -xzf uci_housing.tar.gz diff --git a/python/examples/fit_a_line/README.md b/python/examples/fit_a_line/README.md index 480457f8ce856cf22a89ff29260be7d1a9f0ccf8..af45b2a854381cb5c5739e9c89518d2e80753f1b 100644 --- a/python/examples/fit_a_line/README.md +++ b/python/examples/fit_a_line/README.md @@ -34,7 +34,7 @@ python test_client.py uci_housing_client/serving_client_conf.prototxt Start a web service with default web service hosting modules: ``` shell -python test_server.py +python -m paddle_serving_server.serve --model uci_housing_model --thread 10 --port 9393 --name uci ``` ### Client prediction diff --git a/python/examples/fit_a_line/README_CN.md b/python/examples/fit_a_line/README_CN.md index 451f273322afe6c5ae76c4cd3ef102b01b8856e6..9ef55749b123f00b1e0da4627bdad6de5cea0d98 100644 --- a/python/examples/fit_a_line/README_CN.md +++ b/python/examples/fit_a_line/README_CN.md @@ -14,12 +14,6 @@ sh get_data.sh ### 开启服务端 -``` shell -python test_server.py uci_housing_model/ -``` - -也可以通过下面的一行代码开启默认RPC服务: - ```shell python -m paddle_serving_server.serve --model uci_housing_model --thread 10 --port 9393 ``` @@ -41,7 +35,7 @@ python test_client.py uci_housing_client/serving_client_conf.prototxt 通过下面的一行代码开启默认web服务: ``` shell -python test_server.py +python -m paddle_serving_server.serve --model uci_housing_model --thread 10 --port 9393 --name uci ``` ### 客户端预测 diff --git a/python/examples/fit_a_line/test_server.py b/python/examples/fit_a_line/test_server.py index c3f2406640537190ebfc0cae35ecc0297f3aa661..d055b309d7530ccbe928d50e2bcaba23fb1ddaff 100644 --- a/python/examples/fit_a_line/test_server.py +++ b/python/examples/fit_a_line/test_server.py @@ -31,6 +31,6 @@ class UciService(WebService): uci_service = UciService(name="uci") uci_service.load_model_config("uci_housing_model") -uci_service.prepare_server(workdir="workdir", port=9292) +uci_service.prepare_server(workdir="workdir", port=9393) uci_service.run_rpc_service() uci_service.run_web_service() diff --git a/python/examples/grpc_impl_example/fit_a_line/README_CN.md b/python/examples/grpc_impl_example/fit_a_line/README_CN.md index 4b2bd59e7ba3a52952496b929689c6bd026bf0ce..728932b21498b119b46756bc5a67ed38c8db358d 100644 --- a/python/examples/grpc_impl_example/fit_a_line/README_CN.md +++ b/python/examples/grpc_impl_example/fit_a_line/README_CN.md @@ -43,4 +43,3 @@ python test_batch_client.py ``` shell python test_timeout_client.py ``` - diff --git a/python/examples/grpc_impl_example/fit_a_line/test_asyn_client.py b/python/examples/grpc_impl_example/fit_a_line/test_asyn_client.py index eb0e1c2dcaad998a51b370f63655299ce8d93889..e9562359031fb32372d76dbbac25229d15ac0265 100644 --- a/python/examples/grpc_impl_example/fit_a_line/test_asyn_client.py +++ b/python/examples/grpc_impl_example/fit_a_line/test_asyn_client.py @@ -43,8 +43,9 @@ x = [ ] task_count = 0 for i in range(3): - new_data = np.array(x).astype("float32").reshape((1,13)) - future = client.predict(feed={"x": new_data}, fetch=["price"], batch=False, asyn=True) + new_data = np.array(x).astype("float32").reshape((1, 13)) + future = client.predict( + feed={"x": new_data}, fetch=["price"], batch=False, asyn=True) task_count += 1 future.add_done_callback(functools.partial(call_back)) diff --git a/python/examples/grpc_impl_example/fit_a_line/test_batch_client.py b/python/examples/grpc_impl_example/fit_a_line/test_batch_client.py index 30da59342571dfc2353a5177476ac5d229b91181..41494e71c3c26d3f9af36b83ef50509e8bd071f0 100644 --- a/python/examples/grpc_impl_example/fit_a_line/test_batch_client.py +++ b/python/examples/grpc_impl_example/fit_a_line/test_batch_client.py @@ -27,7 +27,8 @@ for i in range(3): new_data = np.array(x).astype("float32").reshape((1, 1, 13)) batch_data = np.concatenate([new_data, new_data, new_data], axis=0) print(batch_data.shape) - fetch_map = client.predict(feed={"x":batch_data}, fetch=["price"], batch=True) + fetch_map = client.predict( + feed={"x": batch_data}, fetch=["price"], batch=True) if fetch_map["serving_status_code"] == 0: print(fetch_map) diff --git a/python/examples/grpc_impl_example/fit_a_line/test_sync_client.py b/python/examples/grpc_impl_example/fit_a_line/test_sync_client.py index dbc9a7bbdd31e37726edef4eb71de08c90ec39d2..879bc1ce6790de67041dcb077d2be49a437f2b14 100644 --- a/python/examples/grpc_impl_example/fit_a_line/test_sync_client.py +++ b/python/examples/grpc_impl_example/fit_a_line/test_sync_client.py @@ -17,7 +17,6 @@ from paddle_serving_client import MultiLangClient as Client import numpy as np client = Client() client.connect(["127.0.0.1:9393"]) - """ for data in test_reader(): new_data = np.zeros((1, 1, 13)).astype("float32") @@ -33,8 +32,9 @@ x = [ 0.4919, 0.1856, 0.0795, -0.0332 ] for i in range(3): - new_data = np.array(x).astype("float32").reshape((1,13)) - fetch_map = client.predict(feed={"x": new_data}, fetch=["price"], batch=False) + new_data = np.array(x).astype("float32").reshape((1, 13)) + fetch_map = client.predict( + feed={"x": new_data}, fetch=["price"], batch=False) if fetch_map["serving_status_code"] == 0: print(fetch_map) else: diff --git a/python/examples/grpc_impl_example/fit_a_line/test_timeout_client.py b/python/examples/grpc_impl_example/fit_a_line/test_timeout_client.py index 082fc9080ec49a0fc2bcaef68842a1c1695faf7c..3e9dcc907fff5c51ff76864cfa406bdbf3f3e082 100644 --- a/python/examples/grpc_impl_example/fit_a_line/test_timeout_client.py +++ b/python/examples/grpc_impl_example/fit_a_line/test_timeout_client.py @@ -25,8 +25,9 @@ x = [ 0.4919, 0.1856, 0.0795, -0.0332 ] for i in range(3): - new_data = np.array(x).astype("float32").reshape((1,13)) - fetch_map = client.predict(feed={"x": new_data}, fetch=["price"], batch=False) + new_data = np.array(x).astype("float32").reshape((1, 13)) + fetch_map = client.predict( + feed={"x": new_data}, fetch=["price"], batch=False) if fetch_map["serving_status_code"] == 0: print(fetch_map) elif fetch_map["serving_status_code"] == grpc.StatusCode.DEADLINE_EXCEEDED: diff --git a/python/examples/grpc_impl_example/yolov4/test_client.py b/python/examples/grpc_impl_example/yolov4/test_client.py index 49573bb79ef5be09fc39f882c980d3c048d5ceba..520d8bec5a830450f644a2e3fbf143c744419441 100644 --- a/python/examples/grpc_impl_example/yolov4/test_client.py +++ b/python/examples/grpc_impl_example/yolov4/test_client.py @@ -35,7 +35,8 @@ fetch_map = client.predict( "image": im, "im_size": np.array(list(im.shape[1:])), }, - fetch=["save_infer_model/scale_0.tmp_0"], batch=False) + fetch=["save_infer_model/scale_0.tmp_0"], + batch=False) print(fetch_map) fetch_map.pop("serving_status_code") fetch_map["image"] = sys.argv[1] diff --git a/python/examples/pipeline/simple_web_service/web_service_java.py b/python/examples/pipeline/simple_web_service/web_service_java.py index ef6a144866a4764338c438f1b9b2b1f8a44a7ca5..d06bc58492c812f36a5bb9446f0078dec3d30210 100644 --- a/python/examples/pipeline/simple_web_service/web_service_java.py +++ b/python/examples/pipeline/simple_web_service/web_service_java.py @@ -23,6 +23,8 @@ import base64 _LOGGER = logging.getLogger() np.set_printoptions(threshold=sys.maxsize) + + class UciOp(Op): def init_op(self): self.separator = "," @@ -38,8 +40,8 @@ class UciOp(Op): log_id, input_dict)) proc_dict = {} x_value = input_dict["x"] - input_dict["x"] = x_value.reshape(1,13) - + input_dict["x"] = x_value.reshape(1, 13) + return input_dict, False, None, "" def postprocess(self, input_dicts, fetch_dict, log_id): diff --git a/python/paddle_serving_app/local_predict.py b/python/paddle_serving_app/local_predict.py index 5a641fe6358a62b67c435e9881d481c2c5616b1f..1c49f01f22cbc23cfecb70fb36d3a72ff0991e5f 100644 --- a/python/paddle_serving_app/local_predict.py +++ b/python/paddle_serving_app/local_predict.py @@ -132,6 +132,7 @@ class LocalPredictor(object): ops_filter=[]) if use_xpu: + # 2MB l3 cache config.enable_xpu(8 * 1024 * 1024) self.predictor = create_paddle_predictor(config) diff --git a/python/paddle_serving_client/__init__.py b/python/paddle_serving_client/__init__.py index b2094b3b29b9fedfacd01af179841a135c36f9f9..4c9a9dead2bc55d56526a2fd18229509bf52f9c7 100644 --- a/python/paddle_serving_client/__init__.py +++ b/python/paddle_serving_client/__init__.py @@ -19,6 +19,9 @@ from .proto import sdk_configure_pb2 as sdk from .proto import general_model_config_pb2 as m_config import google.protobuf.text_format import numpy as np +import requests +import json +import base64 import time import sys @@ -161,6 +164,7 @@ class Client(object): self.fetch_names_to_idx_ = {} self.lod_tensor_set = set() self.feed_tensor_len = {} + self.key = None for i, var in enumerate(model_conf.feed_var): self.feed_names_to_idx_[var.alias_name] = i @@ -193,7 +197,28 @@ class Client(object): else: self.rpc_timeout_ms = rpc_timeout - def connect(self, endpoints=None): + def use_key(self, key_filename): + with open(key_filename, "r") as f: + self.key = f.read() + + def get_serving_port(self, endpoints): + if self.key is not None: + req = json.dumps({"key": base64.b64encode(self.key)}) + else: + req = json.dumps({}) + r = requests.post("http://" + endpoints[0], req) + result = r.json() + print(result) + if "endpoint_list" not in result: + raise ValueError("server not ready") + else: + endpoints = [ + endpoints[0].split(":")[0] + ":" + + str(result["endpoint_list"][0]) + ] + return endpoints + + def connect(self, endpoints=None, encryption=False): # check whether current endpoint is available # init from client config # create predictor here @@ -203,6 +228,8 @@ class Client(object): "You must set the endpoints parameter or use add_variant function to create a variant." ) else: + if encryption: + endpoints = self.get_serving_port(endpoints) if self.predictor_sdk_ is None: self.add_variant('default_tag_{}'.format(id(self)), endpoints, 100) diff --git a/python/paddle_serving_client/io/__init__.py b/python/paddle_serving_client/io/__init__.py index e6aa9947ca3326d8ff8e2bce012c37bffdb69b8d..b7b0898a3b3b811c8f089c8409b6c5f94185660a 100644 --- a/python/paddle_serving_client/io/__init__.py +++ b/python/paddle_serving_client/io/__init__.py @@ -21,26 +21,34 @@ from paddle.fluid.framework import Program from paddle.fluid import CPUPlace from paddle.fluid.io import save_inference_model import paddle.fluid as fluid +from paddle.fluid.core import CipherUtils +from paddle.fluid.core import CipherFactory +from paddle.fluid.core import Cipher from ..proto import general_model_config_pb2 as model_conf import os import paddle import paddle.nn.functional as F +import errno from paddle.jit import to_static + def save_dygraph_model(serving_model_folder, client_config_folder, model): paddle.jit.save(model, "serving_tmp") - loaded_layer = paddle.jit.load(path=".", model_filename="serving_tmp.pdmodel", params_filename="serving_tmp.pdiparams") + loaded_layer = paddle.jit.load( + path=".", + model_filename="serving_tmp.pdmodel", + params_filename="serving_tmp.pdiparams") feed_target_names = [x.name for x in loaded_layer._input_spec()] fetch_target_names = [x.name for x in loaded_layer._output_spec()] inference_program = loaded_layer.program() feed_var_dict = { - x: inference_program.global_block().var(x) - for x in feed_target_names + x: inference_program.global_block().var(x) + for x in feed_target_names } fetch_var_dict = { - x: inference_program.global_block().var(x) - for x in fetch_target_names + x: inference_program.global_block().var(x) + for x in fetch_target_names } config = model_conf.GeneralModelConfig() @@ -89,9 +97,11 @@ def save_dygraph_model(serving_model_folder, client_config_folder, model): os.system(cmd) cmd = "mkdir -p {}".format(serving_model_folder) os.system(cmd) - cmd = "mv {} {}/__model__".format("serving_tmp.pdmodel", serving_model_folder) + cmd = "mv {} {}/__model__".format("serving_tmp.pdmodel", + serving_model_folder) os.system(cmd) - cmd = "mv {} {}/__params__".format("serving_tmp.pdiparams", serving_model_folder) + cmd = "mv {} {}/__params__".format("serving_tmp.pdiparams", + serving_model_folder) os.system(cmd) cmd = "rm -rf serving_tmp.pd*" os.system(cmd) @@ -108,11 +118,15 @@ def save_dygraph_model(serving_model_folder, client_config_folder, model): serving_model_folder), "wb") as fout: fout.write(config.SerializeToString()) + def save_model(server_model_folder, client_config_folder, feed_var_dict, fetch_var_dict, - main_program=None): + main_program=None, + encryption=False, + key_len=128, + encrypt_conf=None): executor = Executor(place=CPUPlace()) feed_var_names = [feed_var_dict[x].name for x in feed_var_dict] @@ -122,14 +136,31 @@ def save_model(server_model_folder, target_vars.append(fetch_var_dict[key]) target_var_names.append(key) - save_inference_model( - server_model_folder, - feed_var_names, - target_vars, - executor, - model_filename="__model__", - params_filename="__params__", - main_program=main_program) + if not encryption: + save_inference_model( + server_model_folder, + feed_var_names, + target_vars, + executor, + model_filename="__model__", + params_filename="__params__", + main_program=main_program) + else: + if encrypt_conf == None: + aes_cipher = CipherFactory.create_cipher() + else: + #todo: more encryption algorithms + pass + key = CipherUtils.gen_key_to_file(128, "key") + params = fluid.io.save_persistables( + executor=executor, dirname=None, main_program=main_program) + model = main_program.desc.serialize_to_string() + if not os.path.exists(server_model_folder): + os.makedirs(server_model_folder) + os.chdir(server_model_folder) + aes_cipher.encrypt_to_file(params, key, "encrypt_params") + aes_cipher.encrypt_to_file(model, key, "encrypt_model") + os.chdir("..") config = model_conf.GeneralModelConfig() @@ -201,7 +232,11 @@ def inference_model_to_serving(dirname, serving_server="serving_server", serving_client="serving_client", model_filename=None, - params_filename=None): + params_filename=None, + encryption=False, + key_len=128, + encrypt_conf=None): + paddle.enable_static() place = fluid.CPUPlace() exe = fluid.Executor(place) inference_program, feed_target_names, fetch_targets = \ @@ -212,7 +247,7 @@ def inference_model_to_serving(dirname, } fetch_dict = {x.name: x for x in fetch_targets} save_model(serving_server, serving_client, feed_dict, fetch_dict, - inference_program) + inference_program, encryption, key_len, encrypt_conf) feed_names = feed_dict.keys() fetch_names = fetch_dict.keys() return feed_names, fetch_names diff --git a/python/paddle_serving_server/__init__.py b/python/paddle_serving_server/__init__.py index a46d0f246cc471b7c98f678b3e87d95e601db774..5ef3cf751925072594f8cb749fb926e233f4c0e9 100644 --- a/python/paddle_serving_server/__init__.py +++ b/python/paddle_serving_server/__init__.py @@ -157,6 +157,7 @@ class Server(object): self.cur_path = os.getcwd() self.use_local_bin = False self.mkl_flag = False + self.encryption_model = False self.product_name = None self.container_id = None self.model_config_paths = None # for multi-model in a workflow @@ -197,6 +198,9 @@ class Server(object): def set_ir_optimize(self, flag=False): self.ir_optimization = flag + def use_encryption_model(self, flag=False): + self.encryption_model = flag + def set_product_name(self, product_name=None): if product_name == None: raise ValueError("product_name can't be None.") @@ -233,12 +237,18 @@ class Server(object): if os.path.exists('{}/__params__'.format(model_config_path)): suffix = "" else: - suffix = "_DIR" + suffix = "_DIR" if device == "cpu": - engine.type = "FLUID_CPU_ANALYSIS" + suffix + if self.encryption_model: + engine.type = "FLUID_CPU_ANALYSIS_ENCRYPT" + else: + engine.type = "FLUID_CPU_ANALYSIS" + suffix elif device == "gpu": - engine.type = "FLUID_GPU_ANALYSIS" + suffix + if self.encryption_model: + engine.type = "FLUID_GPU_ANALYSIS_ENCRYPT" + else: + engine.type = "FLUID_GPU_ANALYSIS" + suffix self.model_toolkit_conf.engines.extend([engine]) diff --git a/python/paddle_serving_server/serve.py b/python/paddle_serving_server/serve.py index d282ac076e377806e9a3b320b880ffed6300b971..a8f1ad29151fd28050c0d15d92972c5e38908c4d 100644 --- a/python/paddle_serving_server/serve.py +++ b/python/paddle_serving_server/serve.py @@ -18,8 +18,14 @@ Usage: python -m paddle_serving_server.serve --model ./serving_server_model --port 9292 """ import argparse -from .web_service import WebService +import sys +import json +import base64 +import time +from multiprocessing import Process +from web_service import WebService, port_is_available from flask import Flask, request +from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer def parse_args(): # pylint: disable=doc-string-missing @@ -53,6 +59,11 @@ def parse_args(): # pylint: disable=doc-string-missing type=int, default=512 * 1024 * 1024, help="Limit sizes of messages") + parser.add_argument( + "--use_encryption_model", + default=False, + action="store_true", + help="Use encryption model") parser.add_argument( "--use_multilang", default=False, @@ -71,17 +82,18 @@ def parse_args(): # pylint: disable=doc-string-missing return parser.parse_args() -def start_standard_model(): # pylint: disable=doc-string-missing +def start_standard_model(serving_port): # pylint: disable=doc-string-missing args = parse_args() thread_num = args.thread model = args.model - port = args.port + port = serving_port workdir = args.workdir device = args.device mem_optim = args.mem_optim_off is False ir_optim = args.ir_optim max_body_size = args.max_body_size use_mkl = args.use_mkl + use_encryption_model = args.use_encryption_model use_multilang = args.use_multilang if model == "": @@ -111,6 +123,7 @@ def start_standard_model(): # pylint: disable=doc-string-missing server.use_mkl(use_mkl) server.set_max_body_size(max_body_size) server.set_port(port) + server.use_encryption_model(use_encryption_model) if args.product_name != None: server.set_product_name(args.product_name) if args.container_id != None: @@ -121,11 +134,89 @@ def start_standard_model(): # pylint: disable=doc-string-missing server.run_server() +class MainService(BaseHTTPRequestHandler): + def get_available_port(self): + default_port = 12000 + for i in range(1000): + if port_is_available(default_port + i): + return default_port + i + + def start_serving(self): + start_standard_model(serving_port) + + def get_key(self, post_data): + if "key" not in post_data: + return False + else: + key = base64.b64decode(post_data["key"]) + with open(args.model + "/key", "w") as f: + f.write(key) + return True + + def check_key(self, post_data): + if "key" not in post_data: + return False + else: + key = base64.b64decode(post_data["key"]) + with open(args.model + "/key", "r") as f: + cur_key = f.read() + return (key == cur_key) + + def start(self, post_data): + post_data = json.loads(post_data) + global p_flag + if not p_flag: + if args.use_encryption_model: + print("waiting key for model") + if not self.get_key(post_data): + print("not found key in request") + return False + global serving_port + global p + serving_port = self.get_available_port() + p = Process(target=self.start_serving) + p.start() + time.sleep(3) + if p.is_alive(): + p_flag = True + else: + return False + else: + if p.is_alive(): + if not self.check_key(post_data): + return False + else: + return False + return True + + def do_POST(self): + content_length = int(self.headers['Content-Length']) + post_data = self.rfile.read(content_length) + if self.start(post_data): + response = {"endpoint_list": [serving_port]} + else: + response = {"message": "start serving failed"} + self.send_response(200) + self.send_header('Content-type', 'application/json') + self.end_headers() + self.wfile.write(json.dumps(response)) + + if __name__ == "__main__": args = parse_args() if args.name == "None": - start_standard_model() + if args.use_encryption_model: + p_flag = False + p = None + serving_port = 0 + server = HTTPServer(('localhost', int(args.port)), MainService) + print( + 'Starting encryption server, waiting for key from client, use to stop' + ) + server.serve_forever() + else: + start_standard_model(args.port) else: service = WebService(name=args.name) service.load_model_config(args.model) diff --git a/python/paddle_serving_server/web_service.py b/python/paddle_serving_server/web_service.py index 1f035db9262ffbd8e031c9b0018877eb2ba6fad2..3be818f0ed778bc8e7a1297cae6638fac88ac20c 100644 --- a/python/paddle_serving_server/web_service.py +++ b/python/paddle_serving_server/web_service.py @@ -20,11 +20,21 @@ from paddle_serving_server import OpMaker, OpSeqMaker, Server from paddle_serving_client import Client from contextlib import closing import socket - +import numpy as np from paddle_serving_server import pipeline from paddle_serving_server.pipeline import Op +def port_is_available(port): + with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock: + sock.settimeout(2) + result = sock.connect_ex(('0.0.0.0', port)) + if result != 0: + return True + else: + return False + + class WebService(object): def __init__(self, name="default_service"): self.name = name @@ -64,8 +74,8 @@ class WebService(object): f = open(client_config, 'r') model_conf = google.protobuf.text_format.Merge( str(f.read()), model_conf) - self.feed_names = [var.alias_name for var in model_conf.feed_var] - self.fetch_names = [var.alias_name for var in model_conf.fetch_var] + self.feed_vars = {var.name: var for var in model_conf.feed_var} + self.fetch_vars = {var.name: var for var in model_conf.fetch_var} def _launch_rpc_service(self): op_maker = OpMaker() @@ -110,7 +120,7 @@ class WebService(object): self.mem_optim = mem_optim self.ir_optim = ir_optim for i in range(1000): - if self.port_is_available(default_port + i): + if port_is_available(default_port + i): self.port_list.append(default_port + i) break @@ -201,6 +211,17 @@ class WebService(object): def preprocess(self, feed=[], fetch=[]): print("This API will be deprecated later. Please do not use it") is_batch = True + feed_dict = {} + for var_name in self.feed_vars.keys(): + feed_dict[var_name] = [] + for feed_ins in feed: + for key in feed_ins: + feed_dict[key].append( + np.array(feed_ins[key]).reshape( + list(self.feed_vars[key].shape))[np.newaxis, :]) + feed = {} + for key in feed_dict: + feed[key] = np.concatenate(feed_dict[key], axis=0) return feed, fetch, is_batch def postprocess(self, feed=[], fetch=[], fetch_map=None): diff --git a/python/paddle_serving_server_gpu/__init__.py b/python/paddle_serving_server_gpu/__init__.py index b8fe91bb594b1f91141658afcb876f2291d4d35e..04566bfa995cf65bf250334e44d340a810f60312 100644 --- a/python/paddle_serving_server_gpu/__init__.py +++ b/python/paddle_serving_server_gpu/__init__.py @@ -70,6 +70,11 @@ def serve_args(): type=int, default=512 * 1024 * 1024, help="Limit sizes of messages") + parser.add_argument( + "--use_encryption_model", + default=False, + action="store_true", + help="Use encryption model") parser.add_argument( "--use_multilang", default=False, @@ -212,6 +217,7 @@ class Server(object): self.module_path = os.path.dirname(paddle_serving_server.__file__) self.cur_path = os.getcwd() self.use_local_bin = False + self.device = "cpu" self.gpuid = 0 self.use_trt = False self.use_lite = False @@ -279,6 +285,9 @@ class Server(object): "GPU not found, please check your environment or use cpu version by \"pip install paddle_serving_server\"" ) + def set_device(self, device="cpu"): + self.device = device + def set_gpuid(self, gpuid=0): self.gpuid = gpuid @@ -291,7 +300,7 @@ class Server(object): def set_xpu(self): self.use_xpu = True - def _prepare_engine(self, model_config_paths, device): + def _prepare_engine(self, model_config_paths, device, use_encryption_model): if self.model_toolkit_conf == None: self.model_toolkit_conf = server_sdk.ModelToolkitConf() @@ -311,18 +320,25 @@ class Server(object): engine.static_optimization = False engine.force_update_static_cache = False engine.use_trt = self.use_trt - engine.use_lite = self.use_lite - engine.use_xpu = self.use_xpu - - - + if os.path.exists('{}/__params__'.format(model_config_path)): + suffix = "" + else: + suffix = "_DIR" + if device == "arm": + engine.use_lite = self.use_lite + engine.use_xpu = self.use_xpu if device == "cpu": - engine.type = "FLUID_CPU_ANALYSIS_DIR" + if use_encryption_model: + engine.type = "FLUID_CPU_ANALYSIS_ENCRPT" + else: + engine.type = "FLUID_CPU_ANALYSIS" + suffix elif device == "gpu": - engine.type = "FLUID_GPU_ANALYSIS_DIR" + if use_encryption_model: + engine.type = "FLUID_GPU_ANALYSIS_ENCRPT" + else: + engine.type = "FLUID_GPU_ANALYSIS" + suffix elif device == "arm": - engine.type = "FLUID_ARM_ANALYSIS_DIR" - + engine.type = "FLUID_ARM_ANALYSIS" + suffix self.model_toolkit_conf.engines.extend([engine]) def _prepare_infer_service(self, port): @@ -425,7 +441,7 @@ class Server(object): cuda_version = line.split("\"")[1] if cuda_version == "101" or cuda_version == "102" or cuda_version == "110": device_version = "serving-gpu-" + cuda_version + "-" - elif cuda_version == "arm": + elif cuda_version == "arm" or cuda_version == "arm-xpu": device_version = "serving-" + cuda_version + "-" else: device_version = "serving-gpu-cuda" + cuda_version + "-" @@ -480,6 +496,7 @@ class Server(object): workdir=None, port=9292, device="cpu", + use_encryption_model=False, cube_conf=None): if workdir == None: workdir = "./tmp" @@ -493,7 +510,8 @@ class Server(object): self.set_port(port) self._prepare_resource(workdir, cube_conf) - self._prepare_engine(self.model_config_paths, device) + self._prepare_engine(self.model_config_paths, device, + use_encryption_model) self._prepare_infer_service(port) self.workdir = workdir @@ -528,7 +546,8 @@ class Server(object): else: print("Use local bin : {}".format(self.bin_path)) #self.check_cuda() - if self.use_lite: + # Todo: merge CPU and GPU code, remove device to model_toolkit + if self.device == "cpu" or self.device == "arm": command = "{} " \ "-enable_model_toolkit " \ "-inferservice_path {} " \ diff --git a/python/paddle_serving_server_gpu/serve.py b/python/paddle_serving_server_gpu/serve.py index ffa4c2336fd4307f67fd2f3578a1aa3102850ce9..2bba8a451090f345b34a48ff58fda7d07b7794a7 100644 --- a/python/paddle_serving_server_gpu/serve.py +++ b/python/paddle_serving_server_gpu/serve.py @@ -19,19 +19,22 @@ Usage: """ import argparse import os +import json +import base64 +import time from multiprocessing import Pool, Process from paddle_serving_server_gpu import serve_args from flask import Flask, request +from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer -def start_gpu_card_model(index, gpuid, args): # pylint: disable=doc-string-missing +def start_gpu_card_model(index, gpuid, port, args): # pylint: disable=doc-string-missing gpuid = int(gpuid) device = "gpu" - port = args.port if gpuid == -1: device = "cpu" elif gpuid >= 0: - port = args.port + index + port = port + index thread_num = args.thread model = args.model mem_optim = args.mem_optim_off is False @@ -73,6 +76,7 @@ def start_gpu_card_model(index, gpuid, args): # pylint: disable=doc-string-miss server.set_lite() device = "arm" + server.set_device(device) if args.use_xpu: server.set_xpu() @@ -82,14 +86,20 @@ def start_gpu_card_model(index, gpuid, args): # pylint: disable=doc-string-miss server.set_container_id(args.container_id) server.load_model_config(model) - server.prepare_server(workdir=workdir, port=port, device=device) + server.prepare_server( + workdir=workdir, + port=port, + device=device, + use_encryption_model=args.use_encryption_model) if gpuid >= 0: server.set_gpuid(gpuid) server.run_server() -def start_multi_card(args): # pylint: disable=doc-string-missing +def start_multi_card(args, serving_port=None): # pylint: disable=doc-string-missing gpus = "" + if serving_port == None: + serving_port = args.port if args.gpu_ids == "": gpus = [] else: @@ -109,14 +119,16 @@ def start_multi_card(args): # pylint: disable=doc-string-missing start_gpu_card_model(-1, -1, args) elif len(gpus) <= 0: print("gpu_ids not set, going to run cpu service.") - start_gpu_card_model(-1, -1, args) + start_gpu_card_model(-1, -1, serving_port, args) else: gpu_processes = [] for i, gpu_id in enumerate(gpus): p = Process( - target=start_gpu_card_model, args=( + target=start_gpu_card_model, + args=( i, gpu_id, + serving_port, args, )) gpu_processes.append(p) for p in gpu_processes: @@ -125,10 +137,89 @@ def start_multi_card(args): # pylint: disable=doc-string-missing p.join() +class MainService(BaseHTTPRequestHandler): + def get_available_port(self): + default_port = 12000 + for i in range(1000): + if port_is_available(default_port + i): + return default_port + i + + def start_serving(self): + start_multi_card(args, serving_port) + + def get_key(self, post_data): + if "key" not in post_data: + return False + else: + key = base64.b64decode(post_data["key"]) + with open(args.model + "/key", "w") as f: + f.write(key) + return True + + def check_key(self, post_data): + if "key" not in post_data: + return False + else: + key = base64.b64decode(post_data["key"]) + with open(args.model + "/key", "r") as f: + cur_key = f.read() + return (key == cur_key) + + def start(self, post_data): + post_data = json.loads(post_data) + global p_flag + if not p_flag: + if args.use_encryption_model: + print("waiting key for model") + if not self.get_key(post_data): + print("not found key in request") + return False + global serving_port + global p + serving_port = self.get_available_port() + p = Process(target=self.start_serving) + p.start() + time.sleep(3) + if p.is_alive(): + p_flag = True + else: + return False + else: + if p.is_alive(): + if not self.check_key(post_data): + return False + else: + return False + return True + + def do_POST(self): + content_length = int(self.headers['Content-Length']) + post_data = self.rfile.read(content_length) + if self.start(post_data): + response = {"endpoint_list": [serving_port]} + else: + response = {"message": "start serving failed"} + self.send_response(200) + self.send_header('Content-type', 'application/json') + self.end_headers() + self.wfile.write(json.dumps(response)) + + if __name__ == "__main__": args = serve_args() if args.name == "None": - start_multi_card(args) + from .web_service import port_is_available + if args.use_encryption_model: + p_flag = False + p = None + serving_port = 0 + server = HTTPServer(('localhost', int(args.port)), MainService) + print( + 'Starting encryption server, waiting for key from client, use to stop' + ) + server.serve_forever() + else: + start_multi_card(args) else: from .web_service import WebService web_service = WebService(name=args.name) @@ -140,8 +231,12 @@ if __name__ == "__main__": if len(gpu_ids) > 0: web_service.set_gpus(gpu_ids) web_service.prepare_server( - workdir=args.workdir, port=args.port, device=args.device, - use_lite=args.use_lite, use_xpu=args.use_xpu, ir_optim=args.ir_optim) + workdir=args.workdir, + port=args.port, + device=args.device, + use_lite=args.use_lite, + use_xpu=args.use_xpu, + ir_optim=args.ir_optim) web_service.run_rpc_service() app_instance = Flask(__name__) diff --git a/python/paddle_serving_server_gpu/web_service.py b/python/paddle_serving_server_gpu/web_service.py index 4b89d90ee6893c3fafd596dc8f6c5cabc3a248bf..67b78926688076fe911f871638d774bf6275b728 100644 --- a/python/paddle_serving_server_gpu/web_service.py +++ b/python/paddle_serving_server_gpu/web_service.py @@ -11,6 +11,7 @@ # 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. +#!flask/bin/python # pylint: disable=doc-string-missing from flask import Flask, request, abort @@ -28,6 +29,16 @@ from paddle_serving_server_gpu import pipeline from paddle_serving_server_gpu.pipeline import Op +def port_is_available(port): + with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock: + sock.settimeout(2) + result = sock.connect_ex(('0.0.0.0', port)) + if result != 0: + return True + else: + return False + + class WebService(object): def __init__(self, name="default_service"): self.name = name @@ -70,8 +81,8 @@ class WebService(object): f = open(client_config, 'r') model_conf = google.protobuf.text_format.Merge( str(f.read()), model_conf) - self.feed_names = [var.alias_name for var in model_conf.feed_var] - self.fetch_names = [var.alias_name for var in model_conf.fetch_var] + self.feed_vars = {var.name: var for var in model_conf.feed_var} + self.fetch_vars = {var.name: var for var in model_conf.fetch_var} def set_gpus(self, gpus): print("This API will be deprecated later. Please do not use it") @@ -107,6 +118,7 @@ class WebService(object): server.set_num_threads(thread_num) server.set_memory_optimize(mem_optim) server.set_ir_optimize(ir_optim) + server.set_device(device) if use_lite: server.set_lite() @@ -148,7 +160,7 @@ class WebService(object): self.port_list = [] default_port = 12000 for i in range(1000): - if self.port_is_available(default_port + i): + if port_is_available(default_port + i): self.port_list.append(default_port + i) if len(self.port_list) > len(self.gpus): break @@ -278,6 +290,17 @@ class WebService(object): def preprocess(self, feed=[], fetch=[]): print("This API will be deprecated later. Please do not use it") is_batch = True + feed_dict = {} + for var_name in self.feed_vars.keys(): + feed_dict[var_name] = [] + for feed_ins in feed: + for key in feed_ins: + feed_dict[key].append( + np.array(feed_ins[key]).reshape( + list(self.feed_vars[key].shape))[np.newaxis, :]) + feed = {} + for key in feed_dict: + feed[key] = np.concatenate(feed_dict[key], axis=0) return feed, fetch, is_batch def postprocess(self, feed=[], fetch=[], fetch_map=None): diff --git a/python/pipeline/local_service_handler.py b/python/pipeline/local_service_handler.py index eaa04ee01411260f82992d4327c9d8ac033b91f0..65261dfa38f20a2174dc90fea70b5296187f0044 100644 --- a/python/pipeline/local_service_handler.py +++ b/python/pipeline/local_service_handler.py @@ -249,6 +249,8 @@ class LocalServiceHandler(object): server = Server() if gpuid >= 0: server.set_gpuid(gpuid) + # TODO: support arm or arm + xpu later + server.set_device(self._device_name) server.set_op_sequence(op_seq_maker.get_op_sequence()) server.set_num_threads(thread_num) diff --git a/tools/Dockerfile.centos6.cuda9.0-cudnn7.devel b/tools/Dockerfile.centos6.cuda9.0-cudnn7.devel index d871e4e97f6e0201cb8d533ba9ca8e89664c7a18..eddd7e8b912b4cd2bb19f558413ffec1aea58071 100644 --- a/tools/Dockerfile.centos6.cuda9.0-cudnn7.devel +++ b/tools/Dockerfile.centos6.cuda9.0-cudnn7.devel @@ -39,6 +39,8 @@ RUN yum -y install wget && \ make clean && \ echo 'export PATH=/usr/local/python3.6/bin:$PATH' >> /root/.bashrc && \ echo 'export LD_LIBRARY_PATH=/usr/local/python3.6/lib:$LD_LIBRARY_PATH' >> /root/.bashrc && \ + pip install requests && \ + pip3 install requests && \ source /root/.bashrc && \ cd .. && rm -rf Python-3.6.8* && \ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.11.2/protobuf-all-3.11.2.tar.gz && \ diff --git a/tools/Dockerfile.centos6.devel b/tools/Dockerfile.centos6.devel index add3d9245ce3763d5f4ab9e8619a80bf058386c3..d0a4559ca29a22a8eb6627d19eb5e2f641ac37ec 100644 --- a/tools/Dockerfile.centos6.devel +++ b/tools/Dockerfile.centos6.devel @@ -49,6 +49,8 @@ RUN yum -y install wget && \ cd .. && rm -rf protobuf-* && \ yum -y install epel-release && yum -y install patchelf libXext libSM libXrender && \ yum clean all && \ + pip install requests && \ + pip3 install requests && \ localedef -c -i en_US -f UTF-8 en_US.UTF-8 && \ echo "export LANG=en_US.utf8" >> /root/.bashrc && \ echo "export LANGUAGE=en_US.utf8" >> /root/.bashrc diff --git a/tools/Dockerfile.ci b/tools/Dockerfile.ci index 390d67eb955e1fe8d51faa27c06351f38b2d7462..b3da3aafd041f34436b86323306dc9d4bc82adcf 100644 --- a/tools/Dockerfile.ci +++ b/tools/Dockerfile.ci @@ -23,7 +23,8 @@ RUN wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz >/dev/null \ RUN yum -y install python-devel sqlite-devel >/dev/null \ && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py >/dev/null \ && python get-pip.py >/dev/null \ - && rm get-pip.py + && rm get-pip.py \ + && pip install requests RUN wget http://nixos.org/releases/patchelf/patchelf-0.10/patchelf-0.10.tar.bz2 \ && yum -y install bzip2 >/dev/null \ @@ -34,6 +35,9 @@ RUN wget http://nixos.org/releases/patchelf/patchelf-0.10/patchelf-0.10.tar.bz2 && cd .. \ && rm -rf patchelf-0.10* +RUN yum install -y python3 python3-devel \ + && pip3 install requests + RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v3.11.2/protobuf-all-3.11.2.tar.gz && \ tar zxf protobuf-all-3.11.2.tar.gz && \ cd protobuf-3.11.2 && \ @@ -41,8 +45,6 @@ RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v3.11.2/p make clean && \ cd .. && rm -rf protobuf-* -RUN yum install -y python3 python3-devel - RUN yum -y update >/dev/null \ && yum -y install dnf >/dev/null \ && yum -y install dnf-plugins-core >/dev/null \ diff --git a/tools/Dockerfile.cuda10.0-cudnn7.devel b/tools/Dockerfile.cuda10.0-cudnn7.devel index c633c593ca5ad13a14b7ebee5edca3caf9882d9f..3215ee7dee0e64a0d5583a7d2024b413d526b000 100644 --- a/tools/Dockerfile.cuda10.0-cudnn7.devel +++ b/tools/Dockerfile.cuda10.0-cudnn7.devel @@ -30,11 +30,13 @@ RUN wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz >/dev/null \ RUN yum -y install python-devel sqlite-devel \ && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py >/dev/null \ && python get-pip.py >/dev/null \ - && rm get-pip.py + && rm get-pip.py \ + && pip install requests RUN yum install -y python3 python3-devel \ && yum -y install epel-release && yum -y install patchelf libXext libSM libXrender\ - && yum clean all + && yum clean all \ + && pip3 install requests RUN localedef -c -i en_US -f UTF-8 en_US.UTF-8 \ && echo "export LANG=en_US.utf8" >> /root/.bashrc \ diff --git a/tools/Dockerfile.cuda10.1-cudnn7-trt6.devel b/tools/Dockerfile.cuda10.1-cudnn7-trt6.devel deleted file mode 100644 index c6e1c1e050505e631493efe21732a98abd1bd52e..0000000000000000000000000000000000000000 --- a/tools/Dockerfile.cuda10.1-cudnn7-trt6.devel +++ /dev/null @@ -1,60 +0,0 @@ -FROM nvidia/cuda:10.1-cudnn7-devel-centos7 - -RUN export http_proxy="http://172.19.56.199:3128" \ - && export https_proxy="http://172.19.56.199:3128" \ - && yum -y install wget >/dev/null \ - && yum -y install gcc gcc-c++ make glibc-static which \ - && yum -y install git openssl-devel curl-devel bzip2-devel python-devel \ - && yum -y install libSM-1.2.2-2.el7.x86_64 --setopt=protected_multilib=false \ - && yum -y install libXrender-0.9.10-1.el7.x86_64 --setopt=protected_multilib=false \ - && yum -y install libXext-1.3.3-3.el7.x86_64 --setopt=protected_multilib=false - -RUN export http_proxy="http://172.19.56.199:3128" \ - && export https_proxy="http://172.19.56.199:3128" && \ - wget https://github.com/protocolbuffers/protobuf/releases/download/v3.11.2/protobuf-all-3.11.2.tar.gz && \ - tar zxf protobuf-all-3.11.2.tar.gz && \ - cd protobuf-3.11.2 && \ - ./configure && make -j4 && make install && \ - make clean && \ - cd .. && rm -rf protobuf-* - -RUN export http_proxy="http://172.19.56.199:3128" \ - && export https_proxy="http://172.19.56.199:3128" && \ - wget https://cmake.org/files/v3.2/cmake-3.2.0-Linux-x86_64.tar.gz >/dev/null \ - && tar xzf cmake-3.2.0-Linux-x86_64.tar.gz \ - && mv cmake-3.2.0-Linux-x86_64 /usr/local/cmake3.2.0 \ - && echo 'export PATH=/usr/local/cmake3.2.0/bin:$PATH' >> /root/.bashrc \ - && rm cmake-3.2.0-Linux-x86_64.tar.gz - - -RUN export http_proxy="http://172.19.56.199:3128" \ - && export https_proxy="http://172.19.56.199:3128" && \ - wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz >/dev/null \ - && tar xzf go1.14.linux-amd64.tar.gz \ - && mv go /usr/local/go \ - && echo 'export GOROOT=/usr/local/go' >> /root/.bashrc \ - && echo 'export PATH=/usr/local/go/bin:$PATH' >> /root/.bashrc \ - && rm go1.14.linux-amd64.tar.gz - -RUN export http_proxy="http://172.19.56.199:3128" \ - && export https_proxy="http://172.19.56.199:3128" && \ - yum -y install python-devel sqlite-devel \ - && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py >/dev/null \ - && python get-pip.py >/dev/null \ - && rm get-pip.py - -RUN export http_proxy="http://172.19.56.199:3128" \ - && export https_proxy="http://172.19.56.199:3128" && \ - yum install -y python3 python3-devel \ - && yum -y install epel-release && yum -y install patchelf libXext libSM libXrender\ - && yum clean all - -RUN localedef -c -i en_US -f UTF-8 en_US.UTF-8 \ - && echo "export LANG=en_US.utf8" >> /root/.bashrc \ - && echo "export LANGUAGE=en_US.utf8" >> /root/.bashrc - -RUN wget https://paddle-serving.bj.bcebos.com/tools/TensorRT-6.0.1.5.CentOS-7.6.x86_64-gnu.cuda-10.1.cudnn7.6.tar.gz \ - && tar -xzf TensorRT-6.0.1.5.CentOS-7.6.x86_64-gnu.cuda-10.1.cudnn7.6.tar.gz \ - && mv TensorRT-6.0.1.5 /usr/local/ \ - && rm TensorRT-6.0.1.5.CentOS-7.6.x86_64-gnu.cuda-10.1.cudnn7.6.tar.gz \ - && echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/TensorRT-6.0.1.5/lib/' >> /root/.bashrc diff --git a/tools/Dockerfile.cuda10.1-cudnn7.devel b/tools/Dockerfile.cuda10.1-cudnn7.devel new file mode 100644 index 0000000000000000000000000000000000000000..daab4340e35702b1728a62f3b7cf5d131a20097d --- /dev/null +++ b/tools/Dockerfile.cuda10.1-cudnn7.devel @@ -0,0 +1,219 @@ +# A image for building paddle binaries +# Use cuda devel base image for both cpu and gpu environment +# When you modify it, please be aware of cudnn-runtime version +FROM nvidia/cuda:8.0-cudnn7-devel-ubuntu16.04 +MAINTAINER PaddlePaddle Authors + +ARG UBUNTU_MIRROR +RUN /bin/bash -c 'if [[ -n ${UBUNTU_MIRROR} ]]; then sed -i 's#http://archive.ubuntu.com/ubuntu#${UBUNTU_MIRROR}#g' /etc/apt/sources.list; fi' + +# ENV variables +ARG WITH_GPU +ARG WITH_AVX + +ENV WITH_GPU=${WITH_GPU:-ON} +ENV WITH_AVX=${WITH_AVX:-ON} + +ENV HOME /root +# Add bash enhancements +COPY ./paddle/scripts/docker/root/ /root/ + +# Prepare packages for Python +RUN apt-get update && \ + apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \ + libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ + xz-utils tk-dev libffi-dev liblzma-dev + +# Downgrade gcc&&g++ +RUN apt-get update +WORKDIR /usr/bin +RUN apt install -y gcc-4.8 g++-4.8 +RUN cp gcc gcc.bak +RUN cp g++ g++.bak +RUN rm gcc +RUN rm g++ +RUN ln -s gcc-4.8 gcc +RUN ln -s g++-4.8 g++ + +# Install cmake3.16.0 +RUN mkdir -p /root/cmake_build && wget -q https://cmake.org/files/v3.16/cmake-3.16.0.tar.gz && \ + tar -zxvf cmake-3.16.0.tar.gz && rm cmake-3.16.0.tar.gz && \ + cd cmake-3.16.0 && ./bootstrap > /dev/null && \ + make -j8 > /dev/null && make install > /dev/null && \ + ln -s /usr/local/bin/cmake /usr/bin/cmake + +ENV PATH=/usr/local/bin:$PATH + +RUN rm -r /root/cmake_build + +# Install Python3.6 +RUN mkdir -p /root/python_build/ && wget -q https://www.sqlite.org/2018/sqlite-autoconf-3250300.tar.gz && \ + tar -zxf sqlite-autoconf-3250300.tar.gz && cd sqlite-autoconf-3250300 && \ + ./configure -prefix=/usr/local && make -j8 && make install && cd ../ && rm sqlite-autoconf-3250300.tar.gz && \ + wget -q https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tgz && \ + tar -xzf Python-3.6.0.tgz && cd Python-3.6.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null + +# Install Python3.7 +RUN wget -q https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz && \ + tar -xzf Python-3.7.0.tgz && cd Python-3.7.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null + +RUN rm -r /root/python_build + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + python3 python3-dev python3-pip \ + git python-pip python-dev python-opencv openssh-server bison \ + libnccl2=2.1.2-1+cuda8.0 libnccl-dev=2.1.2-1+cuda8.0 \ + wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \ + curl sed grep graphviz libjpeg-dev zlib1g-dev \ + python-matplotlib gcc-4.8 g++-4.8 \ + automake locales clang-format swig \ + liblapack-dev liblapacke-dev \ + clang-3.8 llvm-3.8 libclang-3.8-dev \ + net-tools libtool ccache && \ + apt-get clean -y + +# Install Python2.7.15 to replace original python +WORKDIR /home +ENV version=2.7.15 +RUN wget https://www.python.org/ftp/python/$version/Python-$version.tgz +RUN tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 +RUN make && make install + +RUN echo "export PATH=/usr/local/bin:${PATH}" >> ~/.bashrc +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc +RUN echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc +RUN echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc +RUN echo "export CPLUS_INCLUDE_PATH=/usr/local/python2.7.15/include/python2.7:$CPLUS_INCLUDE_PATH" >> ~/.bashrc +ENV PATH=/usr/local/python2.7.15/include:${PATH} +ENV PATH=/usr/local/python2.7.15/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python2.7.15/include/python2.7:$CPLUS_INCLUDE_PATH +RUN mv /usr/bin/python /usr/bin/python.bak +RUN ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python +RUN ln -s /usr/local/python2.7.15/bin/python2.7 /usr/bin/python +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip +RUN apt-get -y install unzip +RUN unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build +RUN python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz +RUN tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install + +WORKDIR /home +RUN rm Python-$version.tgz setuptools-40.6.2.zip pip-18.0.tar.gz && \ + rm -r Python-$version setuptools-40.6.2 pip-18.0 + +# Install Go and glide +RUN wget -qO- https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/gopath && \ + mkdir /root/gopath/bin && \ + mkdir /root/gopath/src +ENV GOROOT=/usr/local/go GOPATH=/root/gopath +# should not be in the same line with GOROOT definition, otherwise docker build could not find GOROOT. +ENV PATH=${PATH}:${GOROOT}/bin:${GOPATH}/bin +# install glide +RUN curl -s -q https://glide.sh/get | sh + +# Install TensorRT +# following TensorRT.tar.gz is not the default official one, we do two miny changes: +# 1. Remove the unnecessary files to make the library small. TensorRT.tar.gz only contains include and lib now, +# and its size is only one-third of the official one. +# 2. Manually add ~IPluginFactory() in IPluginFactory class of NvInfer.h, otherwise, it couldn't work in paddle. +# See https://github.com/PaddlePaddle/Paddle/issues/10129 for details. + +RUN wget -q https://paddlepaddledeps.bj.bcebos.com/TensorRT-4.0.1.6-ubuntu14.04.x86_64-gnu.cuda.8.0.cudnn7.0.tar.gz --no-check-certificate && \ + tar -zxf TensorRT-4.0.1.6-ubuntu14.04.x86_64-gnu.cuda.8.0.cudnn7.0.tar.gz -C /usr/local && \ + cp -rf /usr/local/TensorRT/include/* /usr/include/ && \ + cp -rf /usr/local/TensorRT/lib/* /usr/lib/ + +# git credential to skip password typing +RUN git config --global credential.helper store + +# Fix locales to en_US.UTF-8 +RUN localedef -i en_US -f UTF-8 en_US.UTF-8 + +# FIXME: due to temporary ipykernel dependency issue, specify ipykernel jupyter +# version util jupyter fixes this issue. + + +RUN pip3 --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + pip3.6 --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + pip3.7 --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + pip --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + +RUN pip3 --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip3 --no-cache-dir install 'ipykernel==4.6.0' 'jupyter==1.0.0' && \ + pip3.6 --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip3.6 --no-cache-dir install 'ipykernel==4.6.0' 'jupyter==1.0.0' && \ + pip3.7 --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip3.7 --no-cache-dir install 'ipykernel==4.6.0' 'jupyter==1.0.0' && \ + pip --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip --no-cache-dir install 'ipykernel==4.6.0' + +#For docstring checker +RUN pip3 --no-cache-dir install pylint pytest astroid isort +RUN pip3.6 --no-cache-dir install pylint pytest astroid isort +RUN pip3.7 --no-cache-dir install pylint pytest astroid isort +RUN pip --no-cache-dir install pylint pytest astroid isort LinkChecker + +RUN pip3 --no-cache-dir install coverage +RUN pip3.6 --no-cache-dir install coverage +RUN pip3.7 --no-cache-dir install coverage +RUN pip --no-cache-dir install coverage + +COPY ./python/requirements.txt /root/ +RUN pip3 --no-cache-dir install -r /root/requirements.txt +RUN pip3.6 --no-cache-dir install -r /root/requirements.txt +RUN pip3.7 --no-cache-dir install -r /root/requirements.txt +RUN pip --no-cache-dir install -r /root/requirements.txt + +# To fix https://github.com/PaddlePaddle/Paddle/issues/1954, we use +# the solution in https://urllib3.readthedocs.io/en/latest/user-guide.html#ssl-py2 +RUN apt-get install -y libssl-dev libffi-dev && apt-get clean -y +RUN pip3 --no-cache-dir install certifi urllib3[secure] +RUN pip3.6 --no-cache-dir install certifi urllib3[secure] +RUN pip3.7 --no-cache-dir install certifi urllib3[secure] +RUN pip --no-cache-dir install certifi urllib3[secure] + + + +# ar mishandles 4GB files +# https://sourceware.org/bugzilla/show_bug.cgi?id=14625 +# remove them when apt-get support 2.27 and higher version +RUN wget -q https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/binutils/2.27-9ubuntu1/binutils_2.27.orig.tar.gz && \ + tar -xzf binutils_2.27.orig.tar.gz && \ + cd binutils-2.27 && \ + ./configure && make -j && make install && cd .. && rm -rf binutils-2.27 binutils_2.27.orig.tar.gz + +RUN wget --no-check-certificate https://pslib.bj.bcebos.com/openmpi-1.4.5.tar.gz && tar -xzf openmpi-1.4.5.tar.gz && \ + cd openmpi-1.4.5 && ./configure --prefix=/usr/local && make all -j8 && make install -j8 && \ + export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH && export PATH=/usr/local/bin:$PATH && cd .. && \ + rm -rf openmpi-1.4.5.tar.gz && pip --no-cache-dir install mpi4py && ln -fs /bin/bash /bin/sh && \ + apt-get install libprotobuf-dev -y + +# Older versions of patchelf limited the size of the files being processed and were fixed in this pr. +# https://github.com/NixOS/patchelf/commit/ba2695a8110abbc8cc6baf0eea819922ee5007fa +# So install a newer version here. +RUN wget -q http://mirrors.kernel.org/ubuntu/pool/universe/p/patchelf/patchelf_0.10-2_amd64.deb && \ + dpkg -i patchelf_0.10-2_amd64.deb + +# Configure OpenSSH server. c.f. https://docs.docker.com/engine/examples/running_ssh_service +RUN mkdir /var/run/sshd +RUN echo 'root:root' | chpasswd +RUN sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config +RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +CMD source ~/.bashrc +EXPOSE 22 diff --git a/tools/Dockerfile.cuda10.2-cudnn8.devel b/tools/Dockerfile.cuda10.2-cudnn8.devel new file mode 100644 index 0000000000000000000000000000000000000000..daab4340e35702b1728a62f3b7cf5d131a20097d --- /dev/null +++ b/tools/Dockerfile.cuda10.2-cudnn8.devel @@ -0,0 +1,219 @@ +# A image for building paddle binaries +# Use cuda devel base image for both cpu and gpu environment +# When you modify it, please be aware of cudnn-runtime version +FROM nvidia/cuda:8.0-cudnn7-devel-ubuntu16.04 +MAINTAINER PaddlePaddle Authors + +ARG UBUNTU_MIRROR +RUN /bin/bash -c 'if [[ -n ${UBUNTU_MIRROR} ]]; then sed -i 's#http://archive.ubuntu.com/ubuntu#${UBUNTU_MIRROR}#g' /etc/apt/sources.list; fi' + +# ENV variables +ARG WITH_GPU +ARG WITH_AVX + +ENV WITH_GPU=${WITH_GPU:-ON} +ENV WITH_AVX=${WITH_AVX:-ON} + +ENV HOME /root +# Add bash enhancements +COPY ./paddle/scripts/docker/root/ /root/ + +# Prepare packages for Python +RUN apt-get update && \ + apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \ + libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ + xz-utils tk-dev libffi-dev liblzma-dev + +# Downgrade gcc&&g++ +RUN apt-get update +WORKDIR /usr/bin +RUN apt install -y gcc-4.8 g++-4.8 +RUN cp gcc gcc.bak +RUN cp g++ g++.bak +RUN rm gcc +RUN rm g++ +RUN ln -s gcc-4.8 gcc +RUN ln -s g++-4.8 g++ + +# Install cmake3.16.0 +RUN mkdir -p /root/cmake_build && wget -q https://cmake.org/files/v3.16/cmake-3.16.0.tar.gz && \ + tar -zxvf cmake-3.16.0.tar.gz && rm cmake-3.16.0.tar.gz && \ + cd cmake-3.16.0 && ./bootstrap > /dev/null && \ + make -j8 > /dev/null && make install > /dev/null && \ + ln -s /usr/local/bin/cmake /usr/bin/cmake + +ENV PATH=/usr/local/bin:$PATH + +RUN rm -r /root/cmake_build + +# Install Python3.6 +RUN mkdir -p /root/python_build/ && wget -q https://www.sqlite.org/2018/sqlite-autoconf-3250300.tar.gz && \ + tar -zxf sqlite-autoconf-3250300.tar.gz && cd sqlite-autoconf-3250300 && \ + ./configure -prefix=/usr/local && make -j8 && make install && cd ../ && rm sqlite-autoconf-3250300.tar.gz && \ + wget -q https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tgz && \ + tar -xzf Python-3.6.0.tgz && cd Python-3.6.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null + +# Install Python3.7 +RUN wget -q https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz && \ + tar -xzf Python-3.7.0.tgz && cd Python-3.7.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null + +RUN rm -r /root/python_build + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + python3 python3-dev python3-pip \ + git python-pip python-dev python-opencv openssh-server bison \ + libnccl2=2.1.2-1+cuda8.0 libnccl-dev=2.1.2-1+cuda8.0 \ + wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \ + curl sed grep graphviz libjpeg-dev zlib1g-dev \ + python-matplotlib gcc-4.8 g++-4.8 \ + automake locales clang-format swig \ + liblapack-dev liblapacke-dev \ + clang-3.8 llvm-3.8 libclang-3.8-dev \ + net-tools libtool ccache && \ + apt-get clean -y + +# Install Python2.7.15 to replace original python +WORKDIR /home +ENV version=2.7.15 +RUN wget https://www.python.org/ftp/python/$version/Python-$version.tgz +RUN tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 +RUN make && make install + +RUN echo "export PATH=/usr/local/bin:${PATH}" >> ~/.bashrc +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc +RUN echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc +RUN echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc +RUN echo "export CPLUS_INCLUDE_PATH=/usr/local/python2.7.15/include/python2.7:$CPLUS_INCLUDE_PATH" >> ~/.bashrc +ENV PATH=/usr/local/python2.7.15/include:${PATH} +ENV PATH=/usr/local/python2.7.15/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python2.7.15/include/python2.7:$CPLUS_INCLUDE_PATH +RUN mv /usr/bin/python /usr/bin/python.bak +RUN ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python +RUN ln -s /usr/local/python2.7.15/bin/python2.7 /usr/bin/python +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip +RUN apt-get -y install unzip +RUN unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build +RUN python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz +RUN tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install + +WORKDIR /home +RUN rm Python-$version.tgz setuptools-40.6.2.zip pip-18.0.tar.gz && \ + rm -r Python-$version setuptools-40.6.2 pip-18.0 + +# Install Go and glide +RUN wget -qO- https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/gopath && \ + mkdir /root/gopath/bin && \ + mkdir /root/gopath/src +ENV GOROOT=/usr/local/go GOPATH=/root/gopath +# should not be in the same line with GOROOT definition, otherwise docker build could not find GOROOT. +ENV PATH=${PATH}:${GOROOT}/bin:${GOPATH}/bin +# install glide +RUN curl -s -q https://glide.sh/get | sh + +# Install TensorRT +# following TensorRT.tar.gz is not the default official one, we do two miny changes: +# 1. Remove the unnecessary files to make the library small. TensorRT.tar.gz only contains include and lib now, +# and its size is only one-third of the official one. +# 2. Manually add ~IPluginFactory() in IPluginFactory class of NvInfer.h, otherwise, it couldn't work in paddle. +# See https://github.com/PaddlePaddle/Paddle/issues/10129 for details. + +RUN wget -q https://paddlepaddledeps.bj.bcebos.com/TensorRT-4.0.1.6-ubuntu14.04.x86_64-gnu.cuda.8.0.cudnn7.0.tar.gz --no-check-certificate && \ + tar -zxf TensorRT-4.0.1.6-ubuntu14.04.x86_64-gnu.cuda.8.0.cudnn7.0.tar.gz -C /usr/local && \ + cp -rf /usr/local/TensorRT/include/* /usr/include/ && \ + cp -rf /usr/local/TensorRT/lib/* /usr/lib/ + +# git credential to skip password typing +RUN git config --global credential.helper store + +# Fix locales to en_US.UTF-8 +RUN localedef -i en_US -f UTF-8 en_US.UTF-8 + +# FIXME: due to temporary ipykernel dependency issue, specify ipykernel jupyter +# version util jupyter fixes this issue. + + +RUN pip3 --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + pip3.6 --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + pip3.7 --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + pip --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + +RUN pip3 --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip3 --no-cache-dir install 'ipykernel==4.6.0' 'jupyter==1.0.0' && \ + pip3.6 --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip3.6 --no-cache-dir install 'ipykernel==4.6.0' 'jupyter==1.0.0' && \ + pip3.7 --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip3.7 --no-cache-dir install 'ipykernel==4.6.0' 'jupyter==1.0.0' && \ + pip --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip --no-cache-dir install 'ipykernel==4.6.0' + +#For docstring checker +RUN pip3 --no-cache-dir install pylint pytest astroid isort +RUN pip3.6 --no-cache-dir install pylint pytest astroid isort +RUN pip3.7 --no-cache-dir install pylint pytest astroid isort +RUN pip --no-cache-dir install pylint pytest astroid isort LinkChecker + +RUN pip3 --no-cache-dir install coverage +RUN pip3.6 --no-cache-dir install coverage +RUN pip3.7 --no-cache-dir install coverage +RUN pip --no-cache-dir install coverage + +COPY ./python/requirements.txt /root/ +RUN pip3 --no-cache-dir install -r /root/requirements.txt +RUN pip3.6 --no-cache-dir install -r /root/requirements.txt +RUN pip3.7 --no-cache-dir install -r /root/requirements.txt +RUN pip --no-cache-dir install -r /root/requirements.txt + +# To fix https://github.com/PaddlePaddle/Paddle/issues/1954, we use +# the solution in https://urllib3.readthedocs.io/en/latest/user-guide.html#ssl-py2 +RUN apt-get install -y libssl-dev libffi-dev && apt-get clean -y +RUN pip3 --no-cache-dir install certifi urllib3[secure] +RUN pip3.6 --no-cache-dir install certifi urllib3[secure] +RUN pip3.7 --no-cache-dir install certifi urllib3[secure] +RUN pip --no-cache-dir install certifi urllib3[secure] + + + +# ar mishandles 4GB files +# https://sourceware.org/bugzilla/show_bug.cgi?id=14625 +# remove them when apt-get support 2.27 and higher version +RUN wget -q https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/binutils/2.27-9ubuntu1/binutils_2.27.orig.tar.gz && \ + tar -xzf binutils_2.27.orig.tar.gz && \ + cd binutils-2.27 && \ + ./configure && make -j && make install && cd .. && rm -rf binutils-2.27 binutils_2.27.orig.tar.gz + +RUN wget --no-check-certificate https://pslib.bj.bcebos.com/openmpi-1.4.5.tar.gz && tar -xzf openmpi-1.4.5.tar.gz && \ + cd openmpi-1.4.5 && ./configure --prefix=/usr/local && make all -j8 && make install -j8 && \ + export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH && export PATH=/usr/local/bin:$PATH && cd .. && \ + rm -rf openmpi-1.4.5.tar.gz && pip --no-cache-dir install mpi4py && ln -fs /bin/bash /bin/sh && \ + apt-get install libprotobuf-dev -y + +# Older versions of patchelf limited the size of the files being processed and were fixed in this pr. +# https://github.com/NixOS/patchelf/commit/ba2695a8110abbc8cc6baf0eea819922ee5007fa +# So install a newer version here. +RUN wget -q http://mirrors.kernel.org/ubuntu/pool/universe/p/patchelf/patchelf_0.10-2_amd64.deb && \ + dpkg -i patchelf_0.10-2_amd64.deb + +# Configure OpenSSH server. c.f. https://docs.docker.com/engine/examples/running_ssh_service +RUN mkdir /var/run/sshd +RUN echo 'root:root' | chpasswd +RUN sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config +RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +CMD source ~/.bashrc +EXPOSE 22 diff --git a/tools/Dockerfile.cuda11-cudnn8.devel b/tools/Dockerfile.cuda11-cudnn8.devel new file mode 100644 index 0000000000000000000000000000000000000000..daab4340e35702b1728a62f3b7cf5d131a20097d --- /dev/null +++ b/tools/Dockerfile.cuda11-cudnn8.devel @@ -0,0 +1,219 @@ +# A image for building paddle binaries +# Use cuda devel base image for both cpu and gpu environment +# When you modify it, please be aware of cudnn-runtime version +FROM nvidia/cuda:8.0-cudnn7-devel-ubuntu16.04 +MAINTAINER PaddlePaddle Authors + +ARG UBUNTU_MIRROR +RUN /bin/bash -c 'if [[ -n ${UBUNTU_MIRROR} ]]; then sed -i 's#http://archive.ubuntu.com/ubuntu#${UBUNTU_MIRROR}#g' /etc/apt/sources.list; fi' + +# ENV variables +ARG WITH_GPU +ARG WITH_AVX + +ENV WITH_GPU=${WITH_GPU:-ON} +ENV WITH_AVX=${WITH_AVX:-ON} + +ENV HOME /root +# Add bash enhancements +COPY ./paddle/scripts/docker/root/ /root/ + +# Prepare packages for Python +RUN apt-get update && \ + apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \ + libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ + xz-utils tk-dev libffi-dev liblzma-dev + +# Downgrade gcc&&g++ +RUN apt-get update +WORKDIR /usr/bin +RUN apt install -y gcc-4.8 g++-4.8 +RUN cp gcc gcc.bak +RUN cp g++ g++.bak +RUN rm gcc +RUN rm g++ +RUN ln -s gcc-4.8 gcc +RUN ln -s g++-4.8 g++ + +# Install cmake3.16.0 +RUN mkdir -p /root/cmake_build && wget -q https://cmake.org/files/v3.16/cmake-3.16.0.tar.gz && \ + tar -zxvf cmake-3.16.0.tar.gz && rm cmake-3.16.0.tar.gz && \ + cd cmake-3.16.0 && ./bootstrap > /dev/null && \ + make -j8 > /dev/null && make install > /dev/null && \ + ln -s /usr/local/bin/cmake /usr/bin/cmake + +ENV PATH=/usr/local/bin:$PATH + +RUN rm -r /root/cmake_build + +# Install Python3.6 +RUN mkdir -p /root/python_build/ && wget -q https://www.sqlite.org/2018/sqlite-autoconf-3250300.tar.gz && \ + tar -zxf sqlite-autoconf-3250300.tar.gz && cd sqlite-autoconf-3250300 && \ + ./configure -prefix=/usr/local && make -j8 && make install && cd ../ && rm sqlite-autoconf-3250300.tar.gz && \ + wget -q https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tgz && \ + tar -xzf Python-3.6.0.tgz && cd Python-3.6.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null + +# Install Python3.7 +RUN wget -q https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz && \ + tar -xzf Python-3.7.0.tgz && cd Python-3.7.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null + +RUN rm -r /root/python_build + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + python3 python3-dev python3-pip \ + git python-pip python-dev python-opencv openssh-server bison \ + libnccl2=2.1.2-1+cuda8.0 libnccl-dev=2.1.2-1+cuda8.0 \ + wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \ + curl sed grep graphviz libjpeg-dev zlib1g-dev \ + python-matplotlib gcc-4.8 g++-4.8 \ + automake locales clang-format swig \ + liblapack-dev liblapacke-dev \ + clang-3.8 llvm-3.8 libclang-3.8-dev \ + net-tools libtool ccache && \ + apt-get clean -y + +# Install Python2.7.15 to replace original python +WORKDIR /home +ENV version=2.7.15 +RUN wget https://www.python.org/ftp/python/$version/Python-$version.tgz +RUN tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 +RUN make && make install + +RUN echo "export PATH=/usr/local/bin:${PATH}" >> ~/.bashrc +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc +RUN echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc +RUN echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc +RUN echo "export CPLUS_INCLUDE_PATH=/usr/local/python2.7.15/include/python2.7:$CPLUS_INCLUDE_PATH" >> ~/.bashrc +ENV PATH=/usr/local/python2.7.15/include:${PATH} +ENV PATH=/usr/local/python2.7.15/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python2.7.15/include/python2.7:$CPLUS_INCLUDE_PATH +RUN mv /usr/bin/python /usr/bin/python.bak +RUN ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python +RUN ln -s /usr/local/python2.7.15/bin/python2.7 /usr/bin/python +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip +RUN apt-get -y install unzip +RUN unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build +RUN python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz +RUN tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install + +WORKDIR /home +RUN rm Python-$version.tgz setuptools-40.6.2.zip pip-18.0.tar.gz && \ + rm -r Python-$version setuptools-40.6.2 pip-18.0 + +# Install Go and glide +RUN wget -qO- https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/gopath && \ + mkdir /root/gopath/bin && \ + mkdir /root/gopath/src +ENV GOROOT=/usr/local/go GOPATH=/root/gopath +# should not be in the same line with GOROOT definition, otherwise docker build could not find GOROOT. +ENV PATH=${PATH}:${GOROOT}/bin:${GOPATH}/bin +# install glide +RUN curl -s -q https://glide.sh/get | sh + +# Install TensorRT +# following TensorRT.tar.gz is not the default official one, we do two miny changes: +# 1. Remove the unnecessary files to make the library small. TensorRT.tar.gz only contains include and lib now, +# and its size is only one-third of the official one. +# 2. Manually add ~IPluginFactory() in IPluginFactory class of NvInfer.h, otherwise, it couldn't work in paddle. +# See https://github.com/PaddlePaddle/Paddle/issues/10129 for details. + +RUN wget -q https://paddlepaddledeps.bj.bcebos.com/TensorRT-4.0.1.6-ubuntu14.04.x86_64-gnu.cuda.8.0.cudnn7.0.tar.gz --no-check-certificate && \ + tar -zxf TensorRT-4.0.1.6-ubuntu14.04.x86_64-gnu.cuda.8.0.cudnn7.0.tar.gz -C /usr/local && \ + cp -rf /usr/local/TensorRT/include/* /usr/include/ && \ + cp -rf /usr/local/TensorRT/lib/* /usr/lib/ + +# git credential to skip password typing +RUN git config --global credential.helper store + +# Fix locales to en_US.UTF-8 +RUN localedef -i en_US -f UTF-8 en_US.UTF-8 + +# FIXME: due to temporary ipykernel dependency issue, specify ipykernel jupyter +# version util jupyter fixes this issue. + + +RUN pip3 --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + pip3.6 --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + pip3.7 --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + pip --no-cache-dir install -U wheel py-cpuinfo==5.0.0 && \ + +RUN pip3 --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip3 --no-cache-dir install 'ipykernel==4.6.0' 'jupyter==1.0.0' && \ + pip3.6 --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip3.6 --no-cache-dir install 'ipykernel==4.6.0' 'jupyter==1.0.0' && \ + pip3.7 --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip3.7 --no-cache-dir install 'ipykernel==4.6.0' 'jupyter==1.0.0' && \ + pip --no-cache-dir install 'pre-commit==1.10.4' 'ipython==5.3.0' && \ + pip --no-cache-dir install 'ipykernel==4.6.0' + +#For docstring checker +RUN pip3 --no-cache-dir install pylint pytest astroid isort +RUN pip3.6 --no-cache-dir install pylint pytest astroid isort +RUN pip3.7 --no-cache-dir install pylint pytest astroid isort +RUN pip --no-cache-dir install pylint pytest astroid isort LinkChecker + +RUN pip3 --no-cache-dir install coverage +RUN pip3.6 --no-cache-dir install coverage +RUN pip3.7 --no-cache-dir install coverage +RUN pip --no-cache-dir install coverage + +COPY ./python/requirements.txt /root/ +RUN pip3 --no-cache-dir install -r /root/requirements.txt +RUN pip3.6 --no-cache-dir install -r /root/requirements.txt +RUN pip3.7 --no-cache-dir install -r /root/requirements.txt +RUN pip --no-cache-dir install -r /root/requirements.txt + +# To fix https://github.com/PaddlePaddle/Paddle/issues/1954, we use +# the solution in https://urllib3.readthedocs.io/en/latest/user-guide.html#ssl-py2 +RUN apt-get install -y libssl-dev libffi-dev && apt-get clean -y +RUN pip3 --no-cache-dir install certifi urllib3[secure] +RUN pip3.6 --no-cache-dir install certifi urllib3[secure] +RUN pip3.7 --no-cache-dir install certifi urllib3[secure] +RUN pip --no-cache-dir install certifi urllib3[secure] + + + +# ar mishandles 4GB files +# https://sourceware.org/bugzilla/show_bug.cgi?id=14625 +# remove them when apt-get support 2.27 and higher version +RUN wget -q https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/binutils/2.27-9ubuntu1/binutils_2.27.orig.tar.gz && \ + tar -xzf binutils_2.27.orig.tar.gz && \ + cd binutils-2.27 && \ + ./configure && make -j && make install && cd .. && rm -rf binutils-2.27 binutils_2.27.orig.tar.gz + +RUN wget --no-check-certificate https://pslib.bj.bcebos.com/openmpi-1.4.5.tar.gz && tar -xzf openmpi-1.4.5.tar.gz && \ + cd openmpi-1.4.5 && ./configure --prefix=/usr/local && make all -j8 && make install -j8 && \ + export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH && export PATH=/usr/local/bin:$PATH && cd .. && \ + rm -rf openmpi-1.4.5.tar.gz && pip --no-cache-dir install mpi4py && ln -fs /bin/bash /bin/sh && \ + apt-get install libprotobuf-dev -y + +# Older versions of patchelf limited the size of the files being processed and were fixed in this pr. +# https://github.com/NixOS/patchelf/commit/ba2695a8110abbc8cc6baf0eea819922ee5007fa +# So install a newer version here. +RUN wget -q http://mirrors.kernel.org/ubuntu/pool/universe/p/patchelf/patchelf_0.10-2_amd64.deb && \ + dpkg -i patchelf_0.10-2_amd64.deb + +# Configure OpenSSH server. c.f. https://docs.docker.com/engine/examples/running_ssh_service +RUN mkdir /var/run/sshd +RUN echo 'root:root' | chpasswd +RUN sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config +RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +CMD source ~/.bashrc +EXPOSE 22 diff --git a/tools/Dockerfile.cuda9.0-cudnn7.devel b/tools/Dockerfile.cuda9.0-cudnn7.devel index 0fe6d69b1f39bb8bbea1008ea74a0c30607c6c73..42b2d7eb5c0766c8a97130ec93ea5945607cf32b 100644 --- a/tools/Dockerfile.cuda9.0-cudnn7.devel +++ b/tools/Dockerfile.cuda9.0-cudnn7.devel @@ -29,11 +29,13 @@ RUN wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz >/dev/null \ RUN yum -y install python-devel sqlite-devel \ && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py >/dev/null \ && python get-pip.py >/dev/null \ - && rm get-pip.py + && rm get-pip.py \ + && pip install requests RUN yum install -y python3 python3-devel \ && yum -y install epel-release && yum -y install patchelf libXext libSM libXrender\ - && yum clean all + && yum clean all \ + && pip3 install requests RUN localedef -c -i en_US -f UTF-8 en_US.UTF-8 \ && echo "export LANG=en_US.utf8" >> /root/.bashrc \ diff --git a/tools/Dockerfile.devel b/tools/Dockerfile.devel index 83e3b491c30fe99eaa615e836efeef6aad0c0cc4..a0f1d03983466b3ca70ce2d4673ad8874e323a08 100644 --- a/tools/Dockerfile.devel +++ b/tools/Dockerfile.devel @@ -19,11 +19,13 @@ RUN wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz >/dev/null \ RUN yum -y install python-devel sqlite-devel \ && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py >/dev/null \ && python get-pip.py >/dev/null \ - && rm get-pip.py + && rm get-pip.py \ + && pip install requests RUN yum install -y python3 python3-devel \ && yum -y install epel-release && yum -y install patchelf libXext libSM libXrender\ - && yum clean all + && yum clean all \ + && pip3 install requests RUN localedef -c -i en_US -f UTF-8 en_US.UTF-8 \ && echo "export LANG=en_US.utf8" >> /root/.bashrc \ diff --git a/tools/serving_build.sh b/tools/serving_build.sh index 6bc142c36efad60ec26f7dac6200c3127aef8252..5d5abaf64c575d6d3728d1c1fdea281f94e3c2d6 100644 --- a/tools/serving_build.sh +++ b/tools/serving_build.sh @@ -485,6 +485,42 @@ function python_test_lac() { cd .. } + +function python_test_encryption(){ + #pwd: /Serving/python/examples + cd encryption + sh get_data.sh + local TYPE=$1 + export SERVING_BIN=${SERIVNG_WORKDIR}/build-server-${TYPE}/core/general-server/serving + case $TYPE in + CPU) + #check_cmd "python encrypt.py" + #sleep 5 + check_cmd "python -m paddle_serving_server.serve --model encrypt_server/ --port 9300 --use_encryption_model > /dev/null &" + sleep 5 + check_cmd "python test_client.py encrypt_client/serving_client_conf.prototxt" + kill_server_process + ;; + GPU) + #check_cmd "python encrypt.py" + #sleep 5 + check_cmd "python -m paddle_serving_server_gpu.serve --model encrypt_server/ --port 9300 --use_encryption_model --gpu_ids 0" + sleep 5 + check_cmd "python test_client.py encrypt_client/serving_client_conf.prototxt" + kill_servere_process + ;; + *) + echo "error type" + exit 1 + ;; + esac + echo "encryption $TYPE test finished as expected" + setproxy + unset SERVING_BIN + cd .. +} + + function java_run_test() { # pwd: /Serving local TYPE=$1 @@ -921,6 +957,7 @@ function python_run_test() { python_test_lac $TYPE # pwd: /Serving/python/examples python_test_multi_process $TYPE # pwd: /Serving/python/examples python_test_multi_fetch $TYPE # pwd: /Serving/python/examples + python_test_encryption $TYPE # pwd: /Serving/python/examples python_test_yolov4 $TYPE # pwd: /Serving/python/examples python_test_grpc_impl $TYPE # pwd: /Serving/python/examples python_test_resnet50 $TYPE # pwd: /Serving/python/examples