2-3_Compile_CN.md 13.0 KB
Newer Older
S
ShiningZhang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 如何编译 PaddleServing

## 总体概述

编译 Paddle Serving 一共分以下几步

- 编译环境准备:根据模型和运行环境的需要,选择最合适的镜像
- 下载代码库:下载 Serving 代码库,按需要执行初始化操作
- 环境变量准备:根据运行环境的需要,确定 Python 各个环境变量,如GPU环境还需要确定 Cuda,Cudnn,TensorRT 等环境变量。
- 正式编译: 编译 `paddle-serving-server`, `paddle-serving-client`, `paddle-serving-app` 相关 whl 包
- 安装相关 whl 包:安装编译出的三个 whl 包,并设置 SERVING_BIN 环境变量

此外,针对某些 C++ 二次开发场景,我们也提供了 OPENCV 的联编方案。

S
ShiningZhang 已提交
15 16
<img src="images/2-3_Compile_CN_1.png">

S
ShiningZhang 已提交
17 18 19 20 21 22 23 24

## 编译环境准备

|             组件             |             版本要求              |
| :--------------------------: | :-------------------------------: |
|              OS              |     Ubuntu16 and 18/CentOS 7      |
|             gcc              |          5.4.0(Cuda 10.1) and 8.2.0         |
|           gcc-c++            |          5.4.0(Cuda 10.1) and 8.2.0         |
S
ShiningZhang 已提交
25
|            cmake             |          3.16.0 and later          |
S
ShiningZhang 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|            Python            |          3.6.0 and later          |
|              Go              |          1.17.2 and later          |
|             git              |         2.17.1 and later          |
|         glibc-static         |               2.17                |
|        openssl-devel         |              1.0.2k               |
|         bzip2-devel          |          1.0.6 and later          |
| python-devel / python3-devel |          3.6.0 and later          |
|         sqlite-devel         |         3.7.17 and later          |
|           patchelf           |                0.9                |
|           libXext            |               1.3.3               |
|            libSM             |               1.2.2               |
|          libXrender          |              0.9.10               |

推荐使用 Docker 编译,我们已经为您准备好了 Paddle Serving 编译环境并配置好了上述编译依赖,详见[镜像环境](Docker_Images_CN.md)

我们提供了五个环境的开发镜像,分别是 CPU, CUDA10.1+CUDNN7, CUDA10.2+CUDNN7,CUDA10.2+CUDNN8, CUDA11.2+CUDNN8。我们提供了 Serving 开发镜像涵盖以上环境。


|  环境                         |   Serving 开发镜像Tag               |    操作系统      
| :--------------------------: | :-------------------------------: | :-------------: |
|  CPU                         | 0.8.0-devel                       |  Ubuntu 16.04   |
|  CUDA10.1 + CUDNN7             | 0.8.0-cuda10.1-cudnn7-devel       |  Ubuntu 16.04   |
|  CUDA10.2 + CUDNN7             | 0.8.0-cuda10.2-cudnn7-devel       |  Ubuntu 16.04   |
|  CUDA10.2 + CUDNN8             | 0.8.0-cuda10.2-cudnn8-devel       |  Ubuntu 16.04   |
|  CUDA11.2 + CUDNN8             | 0.8.0-cuda11.2-cudnn8-devel       |  Ubuntu 16.04   |

我们首先要针对自己所需的环境拉取相关镜像。上表**环境**一列下,除了 CPU,其余(Cuda**+Cudnn**)都属于 GPU 环境。
您可以使用 Serving 开发镜像。
```
docker pull registry.baidubce.com/paddlepaddle/serving:${Serving开发镜像Tag}

# 如果是 GPU 镜像
nvidia-docker run --rm -it registry.baidubce.com/paddlepaddle/serving:${Serving开发镜像Tag} bash

# 如果是 CPU 镜像
docker run --rm -it registry.baidubce.com/paddlepaddle/serving:${Serving开发镜像Tag} bash
```


## 下载代码库
```
git clone https://github.com/PaddlePaddle/Serving
cd Serving && git submodule update --init --recursive

```

## 环境变量准备

**一. 设置 PYTHON 环境变量**

请按照如下,确定好需要编译的 Python 版本,设置对应的环境变量,一共需要设置三个环境变量,分别是 `PYTHON_INCLUDE_DIR`, `PYTHON_LIBRARIES`, `PYTHON_EXECUTABLE`。以下我们以 python 3.7为例,介绍如何设置这三个环境变量。

```
# 请自行修改至自身路径
export PYTHON_INCLUDE_DIR=/usr/local/include/python3.7m/
export PYTHON_LIBRARIES=/usr/local/lib/x86_64-linux-gnu/libpython3.7m.so
export PYTHON_EXECUTABLE=/usr/local/bin/python3.7

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

python3.7 -m pip install -r python/requirements.txt
 
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway@v1.15.2
go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger@v1.15.2
go install github.com/golang/protobuf/protoc-gen-go@v1.4.3
go install google.golang.org/grpc@v1.33.0
go env -w GO111MODULE=auto
```
S
ShiningZhang 已提交
97 98 99 100 101 102 103 104 105 106 107
环境变量的含义如下表所示。

| cmake 环境变量         | 含义                                | 注意事项               | Docker 环境是否需要 |
|-----------------------|-------------------------------------|-------------------------------|--------------------|
| PYTHON_INCLUDE_DIR | Python.h 所在的目录,通常为 **/include/python3.7/Python.h | 如果没有找到。说明 1)没有安装开发版本的 Python,需重新安装 2)权限不足无法查看相关系统目录。                | 是(/usr/local/include/python3.7)                 |
| PYTHON_LIBRARIES         | libpython3.7.so 或 libpython3.7m.so 所在目录,通常为 /usr/local/lib  | 如果没有找到。说明 1)没有安装开发版本的 Python,需重新安装 2)权限不足无法查看相关系统目录。                | 是(/usr/local/lib/x86_64-linux-gnu/libpython3.7m.so)                 |
| PYTHON_EXECUTABLE   | python3.7 所在目录,通常为 /usr/local/bin |                | 是(/usr/local/bin/python3.7)                 |


**二. 设置 CUDA 环境变量**

S
ShiningZhang 已提交
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129

如果您是 GPU 用户需要额外设置 `CUDA_PATH`, `CUDNN_LIBRARY`, `CUDA_CUDART_LIBRARY``TENSORRT_LIBRARY_PATH`
```
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/"
```
环境变量的含义如下表所示。

| cmake 环境变量         | 含义                                | GPU 环境注意事项               | Docker 环境是否需要 |
|-----------------------|-------------------------------------|-------------------------------|--------------------|
| CUDA_TOOLKIT_ROOT_DIR | cuda 安装路径,通常为 /usr/local/cuda | 全部 GPU 环境都需要                | 否(/usr/local/cuda)                 |
| CUDNN_LIBRARY         | libcudnn.so.* 所在目录,通常为 /usr/local/cuda/lib64/  | 全部 GPU 环境都需要                | 否(/usr/local/cuda/lib64/)                 |
| CUDA_CUDART_LIBRARY   | libcudart.so.* 所在目录,通常为 /usr/local/cuda/lib64/ | 全部 GPU 环境都需要                | 否(/usr/local/cuda/lib64/)                 |
| TENSORRT_ROOT         | libnvinfer.so.* 所在目录的上一级目录,取决于 TensorRT 安装目录 | 全部 GPU 环境都需要 | 否(/usr)                 |



## 正式编译

我们一共需要编译三个目标,分别是 `paddle-serving-server`, `paddle-serving-client`, `paddle-serving-app`,其中 `paddle-serving-server` 需要区分 CPU 或者 GPU 版本。
S
ShiningZhang 已提交
130
全部编译选项详见附录。
S
ShiningZhang 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154

**一. 编译 paddle-serving-server**

如果是 CPU 版本请运行,

```
mkdir build_server
cd build_server
cmake -DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR \
    -DPYTHON_LIBRARIES=$PYTHON_LIBRARIES \
    -DPYTHON_EXECUTABLE=$PYTHON_EXECUTABLE \
    -DSERVER=ON \
    -DWITH_GPU=OFF ..
make -j20
cd ..
```

如果是 GPU 版本,请运行,
```
mkdir build_server
cd build_server
cmake -DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR \
    -DPYTHON_LIBRARIES=$PYTHON_LIBRARIES \
    -DPYTHON_EXECUTABLE=$PYTHON_EXECUTABLE \
S
ShiningZhang 已提交
155 156 157 158
    -DCUDA_TOOLKIT_ROOT_DIR=$CUDA_PATH \
    -DCUDNN_LIBRARY=$CUDNN_LIBRARY \
    -DCUDA_CUDART_LIBRARY=$CUDA_CUDART_LIBRARY \
    -DTENSORRT_ROOT=$TENSORRT_LIBRARY_PATH \
S
ShiningZhang 已提交
159 160 161 162 163 164
    -DSERVER=ON \
    -DWITH_GPU=ON ..
make -j20
cd ..
``` 

S
ShiningZhang 已提交
165 166
编译出的 whl 包在 `build_server/python/dist/` 目录下,编译出的二进制文件在 `build_server/core/general-server/serving` 路径下。

S
ShiningZhang 已提交
167 168 169 170 171 172 173 174 175 176 177 178 179 180
**二. 编译 paddle-serving-client**

接下来,我们继续编译 client,这个包的编译命令在所有平台通用,不区分 CPU 和 GPU 的版本。
```
# 编译 paddle-serving-client
mkdir build_client
cd build_client
cmake -DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR \
    -DPYTHON_LIBRARIES=$PYTHON_LIBRARIES \
    -DPYTHON_EXECUTABLE=$PYTHON_EXECUTABLE \
    -DCLIENT=ON ..
make -j10
cd ..
```
S
ShiningZhang 已提交
181
编译出的 whl 包在 `build_client/python/dist/` 目录下。
S
ShiningZhang 已提交
182 183 184 185 186 187 188 189 190 191 192 193 194 195

**三. 编译 paddle-serving-app**

```
# 编译 paddle-serving-app
mkdir build_app
cd build_app
cmake -DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR \
    -DPYTHON_LIBRARIES=$PYTHON_LIBRARIES \
    -DPYTHON_EXECUTABLE=$PYTHON_EXECUTABLE \
    -DAPP=ON ..
make -j10
cd ..
```
S
ShiningZhang 已提交
196
编译出的 whl 包在 `build_app/python/dist/` 目录下。
S
ShiningZhang 已提交
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310

## 安装相关 whl 包
```
pip3.7 install -r build_server/python/dist/*.whl
pip3.7 install -r build_client/python/dist/*.whl
pip3.7 install -r build_app/python/dist/*.whl
export SERVING_BIN=${PWD}/build_server/core/general-server/serving
```

注意到最后一行 `export SERVING_BIN`,运行 python 端 Server 时,会检查 `SERVING_BIN` 环境变量,如果想使用自己编译的二进制文件,请将设置该环境变量为对应二进制文件的路径,通常是 `export SERVING_BIN=${BUILD_DIR}/core/general-server/serving`
其中 BUILD_DIR 为 `build_server` 的绝对路径。
可以 cd build_server 路径下,执行 `export SERVING_BIN=${PWD}/core/general-server/serving`


## 开启 WITH_OPENCV 选项编译 C++ Server

**注意:** 只有当您需要对 Paddle Serving C++ 部分进行二次开发,且新增的代码依赖于 OpenCV 库时,您才需要这样做。

编译 Serving C++ Server 部分,开启 WITH_OPENCV 选项时,需要已安装的 OpenCV 库,若尚未安装,可参考本文档后面的说明编译安装 OpenCV 库。

以开启 WITH_OPENCV 选项,编译 CPU 版本 Paddle Inference Library 为例,在上述编译命令基础上,加入 `DOPENCV_DIR=${OPENCV_DIR}``DWITH_OPENCV=ON` 选项。
```
OPENCV_DIR=your_opencv_dir #`your_opencv_dir` 为 opencv 库的安装路径。
mkdir build_server && cd build_server
cmake -DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR/ \
    -DPYTHON_LIBRARIES=$PYTHON_LIBRARIES \
    -DPYTHON_EXECUTABLE=$PYTHON_EXECUTABLE \
    -DOPENCV_DIR=${OPENCV_DIR} \
    -DWITH_OPENCV=ON \
    -DSERVER=ON ..
make -j10
```

**注意:** 编译成功后,需要设置 `SERVING_BIN` 路径。





## 附:CMake 选项说明

|     编译选项     |                    说明                    | 默认 |
| :--------------: | :----------------------------------------: | :--: |
|     WITH_AVX     | Compile Paddle Serving with AVX intrinsics | OFF  |
|     WITH_MKL     |  Compile Paddle Serving with MKL support   | OFF  |
|     WITH_GPU     |   Compile Paddle Serving with NVIDIA GPU   | OFF  |
|     WITH_TRT     |    Compile Paddle Serving with TensorRT    | OFF  |
|     WITH_OPENCV  |    Compile Paddle Serving with OPENCV      | OFF  |
|  CUDNN_LIBRARY   |    Define CuDNN library and header path    |      |
| CUDA_TOOLKIT_ROOT_DIR |       Define CUDA PATH                |      |
|   TENSORRT_ROOT  |           Define TensorRT PATH             |      |
|      CLIENT      |       Compile Paddle Serving Client        | OFF  |
|      SERVER      |       Compile Paddle Serving Server        | OFF  |
|       APP        |     Compile Paddle Serving App package     | OFF  |
|       PACK       |              Compile for whl               | OFF  |


## 附:编译安装 OpenCV 库
**注意:** 只有当您需要在 C++ 代码中引入 OpenCV 库时,您才需要这样做。

* 首先需要从 OpenCV 官网上下载在 Linux 环境下源码编译的包,以 OpenCV3.4.7 为例,下载命令如下。

```
wget https://github.com/opencv/opencv/archive/3.4.7.tar.gz
tar -xf 3.4.7.tar.gz
```

最终可以在当前目录下看到 `opencv-3.4.7/` 的文件夹。

* 编译 OpenCV,设置 OpenCV 源码路径(`root_path`)以及安装路径(`install_path`)。进入 OpenCV 源码路径下,按照下面的方式进行编译。

```shell
root_path=your_opencv_root_path
install_path=${root_path}/opencv3

rm -rf build
mkdir build
cd build

cmake .. \
    -DCMAKE_INSTALL_PREFIX=${install_path} \
    -DCMAKE_BUILD_TYPE=Release \
    -DBUILD_SHARED_LIBS=OFF \
    -DWITH_IPP=OFF \
    -DBUILD_IPP_IW=OFF \
    -DWITH_LAPACK=OFF \
    -DWITH_EIGEN=OFF \
    -DCMAKE_INSTALL_LIBDIR=lib64 \
    -DWITH_ZLIB=ON \
    -DBUILD_ZLIB=ON \
    -DWITH_JPEG=ON \
    -DBUILD_JPEG=ON \
    -DWITH_PNG=ON \
    -DBUILD_PNG=ON \
    -DWITH_TIFF=ON \
    -DBUILD_TIFF=ON

make -j
make install
```


其中 `root_path` 为下载的 OpenCV 源码路径,`install_path` 为 OpenCV 的安装路径,`make install` 完成之后,会在该文件夹下生成 OpenCV 头文件和库文件,用于引用 OpenCV 库的代码的编译。

最终在安装路径下的文件结构如下所示。

```
opencv3/
|-- bin
|-- include
|-- lib
|-- lib64
|-- share
```