diff --git a/README.md b/README.md index d15fe64bfd5a21ed379a3b63fc76b2e254a05ff4..d3c17ead4f1b8d6263bb6b144aeb4f0628daa8da 100644 --- a/README.md +++ b/README.md @@ -20,88 +20,135 @@

+- [Motivation](./README.md#motivation) +- [AIStudio Tutorial](./README.md#aistudio-tutorial) +- [Installation](./README.md#installation) +- [Quick Start Example](./README.md#quick-start-example) +- [Document](README.md#document) +- [Community](README.md#community) +

Motivation

We consider deploying deep learning inference service online to be a user-facing application in the future. **The goal of this project**: When you have trained a deep neural net with [Paddle](https://github.com/PaddlePaddle/Paddle), you are also capable to deploy the model online easily. A demo of Paddle Serving is as follows: + +

Some Key Features of Paddle Serving

+ +- Integrate with Paddle training pipeline seamlessly, most paddle models can be deployed **with one line command**. +- **Industrial serving features** supported, such as models management, online loading, online A/B testing etc. +- **Highly concurrent and efficient communication** between clients and servers supported. +- **Multiple programming languages** supported on client side, such as C++, python and Java. + +*** + +- Any model trained by [PaddlePaddle](https://github.com/paddlepaddle/paddle) can be directly used or [Model Conversion Interface](./doc/SAVE_CN.md) for online deployment of Paddle Serving. +- Support [Multi-model Pipeline Deployment](./doc/PIPELINE_SERVING.md), and provide the requirements of the REST interface and RPC interface itself, [Pipeline example](./python/examples/pipeline). +- Support the model zoos from the Paddle ecosystem, such as [PaddleDetection](./python/examples/detection), [PaddleOCR](./python/examples/ocr), [PaddleRec](https://github.com/PaddlePaddle/PaddleRec/tree/master/tools/recserving/movie_recommender). +- Provide a variety of pre-processing and post-processing to facilitate users in training, deployment and other stages of related code, bridging the gap between AI developers and application developers, please refer to +[Serving Examples](./python/examples/). +

+

AIStudio Tutorial

+ +Here we provide tutorial on AIStudio(Chinese Version) [AIStudio教程-Paddle Serving服务化部署框架](https://aistudio.baidu.com/aistudio/projectdetail/1550674) + +The tutorial provides + + +

Installation

-We **highly recommend** you to **run Paddle Serving in Docker**, please visit [Run in Docker](https://github.com/PaddlePaddle/Serving/blob/develop/doc/RUN_IN_DOCKER.md). See the [document](doc/DOCKER_IMAGES.md) for more docker images. +We **highly recommend** you to **run Paddle Serving in Docker**, please visit [Run in Docker](doc/RUN_IN_DOCKER.md). See the [document](doc/DOCKER_IMAGES.md) for more docker images. + +**Attention:**: Currently, the default GPU environment of paddlepaddle 2.0 is Cuda 10.2, so the sample code of GPU Docker is based on Cuda 10.2. We also provides docker images and whl packages for other GPU environments. If users use other environments, they need to carefully check and select the appropriate version. + ``` # Run CPU Docker -docker pull hub.baidubce.com/paddlepaddle/serving:latest -docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:latest +docker pull registry.baidubce.com/paddlepaddle/serving:0.5.0-devel +docker run -p 9292:9292 --name test -dit registry.baidubce.com/paddlepaddle/serving:0.5.0-devel docker exec -it test bash +git clone https://github.com/PaddlePaddle/Serving ``` ``` # Run GPU Docker -nvidia-docker pull hub.baidubce.com/paddlepaddle/serving:latest-cuda9.0-cudnn7 -nvidia-docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:latest-cuda9.0-cudnn7 +nvidia-docker pull registry.baidubce.com/paddlepaddle/serving:0.5.0-cuda10.2-cudnn8-devel +nvidia-docker run -p 9292:9292 --name test -dit registry.baidubce.com/paddlepaddle/serving:0.5.0-cuda10.2-cudnn8-devel nvidia-docker exec -it test bash +git clone https://github.com/PaddlePaddle/Serving ``` ```shell -pip install paddle-serving-client==0.4.0 -pip install paddle-serving-server==0.4.0 # CPU -pip install paddle-serving-app==0.2.0 -pip install paddle-serving-server-gpu==0.4.0.post9 # GPU with CUDA9.0 -pip install paddle-serving-server-gpu==0.4.0.post10 # GPU with CUDA10.0 -pip install paddle-serving-server-gpu==0.4.0.100 # GPU with CUDA10.1+TensorRT +pip install paddle-serving-client==0.5.0 +pip install paddle-serving-server==0.5.0 # CPU +pip install paddle-serving-app==0.3.0 +pip install paddle-serving-server-gpu==0.5.0.post102 #GPU with CUDA10.2 + TensorRT7 +# DO NOT RUN ALL COMMANDS! check your GPU env and select the right one +pip install paddle-serving-server-gpu==0.5.0.post9 # GPU with CUDA9.0 +pip install paddle-serving-server-gpu==0.5.0.post10 # GPU with CUDA10.0 +pip install paddle-serving-server-gpu==0.5.0.post101 # GPU with CUDA10.1 + TensorRT6 +pip install paddle-serving-server-gpu==0.5.0.post11 # GPU with CUDA10.1 + TensorRT7 ``` You may need to use a domestic mirror source (in China, you can use the Tsinghua mirror source, add `-i https://pypi.tuna.tsinghua.edu.cn/simple` to pip command) to speed up the download. -If you need install modules compiled with develop branch, please download packages from [latest packages list](./doc/LATEST_PACKAGES.md) and install with `pip install` command. +If you need install modules compiled with develop branch, please download packages from [latest packages list](./doc/LATEST_PACKAGES.md) and install with `pip install` command. If you want to compile by yourself, please refer to [How to compile Paddle Serving?](./doc/COMPILE.md) Packages of paddle-serving-server and paddle-serving-server-gpu support Centos 6/7, Ubuntu 16/18, Windows 10. -Packages of paddle-serving-client and paddle-serving-app support Linux and Windows, but paddle-serving-client only support python2.7/3.5/3.6/3.7. - -Recommended to install paddle >= 1.8.4. - -For **Windows Users**, please read the document [Paddle Serving for Windows Users](./doc/WINDOWS_TUTORIAL.md) +Packages of paddle-serving-client and paddle-serving-app support Linux and Windows, but paddle-serving-client only support python2.7/3.5/3.6/3.7/3.8. -

Pre-built services with Paddle Serving

+Recommended to install paddle >= 2.0.0 -

Chinese Word Segmentation

+``` +# CPU users, please run +pip install paddlepaddle==2.0.0 -``` shell -> python -m paddle_serving_app.package --get_model lac -> tar -xzf lac.tar.gz -> python lac_web_service.py lac_model/ lac_workdir 9393 & -> curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"words": "我爱北京天安门"}], "fetch":["word_seg"]}' http://127.0.0.1:9393/lac/prediction -{"result":[{"word_seg":"我|爱|北京|天安门"}]} +# GPU Cuda10.2 please run +pip install paddlepaddle-gpu==2.0.0 ``` -

Image Classification

+**Note**: If your Cuda version is not 10.2, please do not execute the above commands directly, you need to refer to [Paddle official documentation-multi-version whl package list +](https://www.paddlepaddle.org.cn/documentation/docs/en/install/Tables_en.html#multi-version-whl-package-list-release) -

-
- -
-

- -``` shell -> python -m paddle_serving_app.package --get_model resnet_v2_50_imagenet -> tar -xzf resnet_v2_50_imagenet.tar.gz -> python resnet50_imagenet_classify.py resnet50_serving_model & -> curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"image": "https://paddle-serving.bj.bcebos.com/imagenet-example/daisy.jpg"}], "fetch": ["score"]}' http://127.0.0.1:9292/image/prediction -{"result":{"label":["daisy"],"prob":[0.9341403245925903]}} +Select the url link of the corresponding GPU environment and install it. For example, for Python2.7 users of Cuda 9.0, please select `cp27-cp27mu` and +The url corresponding to `cuda9.0_cudnn7-mkl`, copy it and run +``` +pip install https://paddle-wheel.bj.bcebos.com/2.0.0-gpu-cuda9-cudnn7-mkl/paddlepaddle_gpu-2.0.0.post90-cp27-cp27mu-linux_x86_64.whl ``` +If it is other environment and Python version, please find the corresponding link in the table and install it with pip. +For **Windows Users**, please read the document [Paddle Serving for Windows Users](./doc/WINDOWS_TUTORIAL.md)

Quick Start Example

-This quick start example is only for users who already have a model to deploy and we prepare a ready-to-deploy model here. If you want to know how to use paddle serving from offline training to online serving, please reference to [Train_To_Service](https://github.com/PaddlePaddle/Serving/blob/develop/doc/TRAIN_TO_SERVICE.md) +This quick start example is mainly for those users who already have a model to deploy, and we also provide a model that can be used for deployment. in case if you want to know how to complete the process from offline training to online service, please refer to the AiStudio tutorial above. ### Boston House Price Prediction model + +get into the Serving git directory, and change dir to `fit_a_line` ``` shell -wget --no-check-certificate https://paddle-serving.bj.bcebos.com/uci_housing.tar.gz -tar -xzf uci_housing.tar.gz +cd Serving/python/examples/fit_a_line +sh get_data.sh ``` Paddle Serving provides HTTP and RPC based service for users to access @@ -123,6 +170,8 @@ python -m paddle_serving_server.serve --model uci_housing_model --thread 10 --po | `ir_optim` | - | - | Enable analysis and optimization of calculation graph | | `use_mkl` (Only for cpu version) | - | - | Run inference with MKL | | `use_trt` (Only for trt version) | - | - | Run inference with TensorRT | +| `use_lite` (Only for ARM) | - | - | Run PaddleLite inference | +| `use_xpu` (Only for ARM+XPU) | - | - | Run PaddleLite XPU inference | @@ -145,26 +194,8 @@ Here, `client.predict` function has two arguments. `feed` is a `python dict` wit Users can also put the data format processing logic on the server side, so that they can directly use curl to access the service, refer to the following case whose path is `python/examples/fit_a_line` -```python -from paddle_serving_server.web_service import WebService -import numpy as np - -class UciService(WebService): - def preprocess(self, feed=[], fetch=[]): - feed_batch = [] - is_batch = True - new_data = np.zeros((len(feed), 1, 13)).astype("float32") - for i, ins in enumerate(feed): - nums = np.array(ins["x"]).reshape(1, 1, 13) - new_data[i] = nums - feed = {"x": new_data} - return feed, fetch, is_batch - -uci_service = UciService(name="uci") -uci_service.load_model_config("uci_housing_model") -uci_service.prepare_server(workdir="workdir", port=9292) -uci_service.run_rpc_service() -uci_service.run_web_service() +``` +python -m paddle_serving_server.serve --model uci_housing_model --thread 10 --port 9292 --name uci ``` for client side, ``` @@ -175,32 +206,17 @@ the response is {"result":{"price":[[18.901151657104492]]}} ``` -

Some Key Features of Paddle Serving

- -- Integrate with Paddle training pipeline seamlessly, most paddle models can be deployed **with one line command**. -- **Industrial serving features** supported, such as models management, online loading, online A/B testing etc. -- **Distributed Key-Value indexing** supported which is especially useful for large scale sparse features as model inputs. -- **Highly concurrent and efficient communication** between clients and servers supported. -- **Multiple programming languages** supported on client side, such as Golang, C++ and python. -

Document

### New to Paddle Serving - [How to save a servable model?](doc/SAVE.md) -- [An End-to-end tutorial from training to inference service deployment](doc/TRAIN_TO_SERVICE.md) - [Write Bert-as-Service in 10 minutes](doc/BERT_10_MINS.md) - -### Tutorial at AIStudio -- [Introduction to PaddleServing](https://aistudio.baidu.com/aistudio/projectdetail/605819) -- [Image Segmentation on Paddle Serving](https://aistudio.baidu.com/aistudio/projectdetail/457715) -- [Sentimental Analysis](https://aistudio.baidu.com/aistudio/projectdetail/509014) +- [Paddle Serving Examples](python/examples) ### Developers -- [How to config Serving native operators on server side?](doc/SERVER_DAG.md) -- [How to develop a new Serving operator?](doc/NEW_OPERATOR.md) - [How to develop a new Web Service?](doc/NEW_WEB_SERVICE.md) -- [Golang client](doc/IMDB_GO_CLIENT.md) - [Compile from source code](doc/COMPILE.md) +- [Develop Pipeline Serving](doc/PIPELINE_SERVING.md) - [Deploy Web Service with uWSGI](doc/UWSGI_DEPLOY.md) - [Hot loading for model file](doc/HOT_LOADING_IN_SERVING.md) @@ -211,15 +227,13 @@ the response is - [CPU Benchmarks(Chinese)](doc/BENCHMARKING.md) - [GPU Benchmarks(Chinese)](doc/GPU_BENCHMARKING.md) -### FAQ -- [FAQ(Chinese)](doc/FAQ.md) - - ### Design - [Design Doc](doc/DESIGN_DOC.md) -

Community

+### FAQ +- [FAQ(Chinese)](doc/FAQ.md) +

Community

### Slack diff --git a/README_CN.md b/README_CN.md index 4e43ee56489d3b65e0174222f1de306bcb1ad4f4..b658d6194785bbf2dd14c7ebd21d11048261dbe1 100644 --- a/README_CN.md +++ b/README_CN.md @@ -20,91 +20,135 @@

+ + +- [动机](./README_CN.md#动机) +- [教程](./README_CN.md#教程) +- [安装](./README_CN.md#安装) +- [快速开始示例](./README_CN.md#快速开始示例) +- [文档](README_CN.md#文档) +- [社区](README_CN.md#社区) +

动机

Paddle Serving 旨在帮助深度学习开发者轻易部署在线预测服务。 **本项目目标**: 当用户使用 [Paddle](https://github.com/PaddlePaddle/Paddle) 训练了一个深度神经网络,就同时拥有了该模型的预测服务。 +

Paddle Serving的核心功能

+ +- 与Paddle训练紧密连接,绝大部分Paddle模型可以 **一键部署**. +- 支持 **工业级的服务能力** 例如模型管理,在线加载,在线A/B测试等. +- 支持客户端和服务端之间 **高并发和高效通信**. +- 支持 **多种编程语言** 开发客户端,例如C++, Python和Java. + +*** + +- 任何经过[PaddlePaddle](https://github.com/paddlepaddle/paddle)训练的模型,都可以经过直接保存或是[模型转换接口](./doc/SAVE_CN.md),用于Paddle Serving在线部署。 +- 支持[多模型串联服务部署](./doc/PIPELINE_SERVING_CN.md), 同时提供Rest接口和RPC接口以满足您的需求,[Pipeline示例](./python/examples/pipeline)。 +- 支持Paddle生态的各大模型库, 例如[PaddleDetection](./python/examples/detection),[PaddleOCR](./python/examples/ocr),[PaddleRec](https://github.com/PaddlePaddle/PaddleRec/tree/master/tools/recserving/movie_recommender)。 +- 提供丰富多彩的前后处理,方便用户在训练、部署等各阶段复用相关代码,弥合AI开发者和应用开发者之间的鸿沟,详情参考[模型示例](./python/examples/)。 +

+

教程

+ +Paddle Serving开发者为您提供了简单易用的[AIStudio教程-Paddle Serving服务化部署框架](https://aistudio.baidu.com/aistudio/projectdetail/1550674) + +教程提供了如下内容 + +

安装

**强烈建议**您在**Docker内构建**Paddle Serving,请查看[如何在Docker中运行PaddleServing](doc/RUN_IN_DOCKER_CN.md)。更多镜像请查看[Docker镜像列表](doc/DOCKER_IMAGES_CN.md)。 +**提示**:目前paddlepaddle 2.0版本的默认GPU环境是Cuda 10.2,因此GPU Docker的示例代码以Cuda 10.2为准。镜像和pip安装包也提供了其余GPU环境,用户如果使用其他环境,需要仔细甄别并选择合适的版本。 + ``` # 启动 CPU Docker -docker pull hub.baidubce.com/paddlepaddle/serving:latest -docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:latest +docker pull registry.baidubce.com/paddlepaddle/serving:0.5.0-devel +docker run -p 9292:9292 --name test -dit registry.baidubce.com/paddlepaddle/serving:0.5.0-devel docker exec -it test bash +git clone https://github.com/PaddlePaddle/Serving ``` ``` # 启动 GPU Docker -nvidia-docker pull hub.baidubce.com/paddlepaddle/serving:latest-cuda9.0-cudnn7 -nvidia-docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:latest-cuda9.0-cudnn7 +nvidia-docker pull registry.baidubce.com/paddlepaddle/serving:0.5.0-cuda10.2-cudnn8-devel +nvidia-docker run -p 9292:9292 --name test -dit registry.baidubce.com/paddlepaddle/serving:0.5.0-cuda10.2-cudnn8-devel nvidia-docker exec -it test bash +git clone https://github.com/PaddlePaddle/Serving ``` + ```shell -pip install paddle-serving-client==0.4.0 -pip install paddle-serving-server==0.4.0 # CPU -pip install paddle-serving-app==0.2.0 -pip install paddle-serving-server-gpu==0.4.0.post9 # GPU with CUDA9.0 -pip install paddle-serving-server-gpu==0.4.0.post10 # GPU with CUDA10.0 -pip install paddle-serving-server-gpu==0.4.0.100 # GPU with CUDA10.1+TensorRT +pip install paddle-serving-client==0.5.0 +pip install paddle-serving-server==0.5.0 # CPU +pip install paddle-serving-app==0.3.0 +pip install paddle-serving-server-gpu==0.5.0.post102 #GPU with CUDA10.2 + TensorRT7 +# 其他GPU环境需要确认环境再选择执行哪一条 +pip install paddle-serving-server-gpu==0.5.0.post9 # GPU with CUDA9.0 +pip install paddle-serving-server-gpu==0.5.0.post10 # GPU with CUDA10.0 +pip install paddle-serving-server-gpu==0.5.0.post101 # GPU with CUDA10.1 + TensorRT6 +pip install paddle-serving-server-gpu==0.5.0.post11 # GPU with CUDA10.1 + TensorRT7 ``` 您可能需要使用国内镜像源(例如清华源, 在pip命令中添加`-i https://pypi.tuna.tsinghua.edu.cn/simple`)来加速下载。 -如果需要使用develop分支编译的安装包,请从[最新安装包列表](./doc/LATEST_PACKAGES.md)中获取下载地址进行下载,使用`pip install`命令进行安装。 +如果需要使用develop分支编译的安装包,请从[最新安装包列表](./doc/LATEST_PACKAGES.md)中获取下载地址进行下载,使用`pip install`命令进行安装。如果您想自行编译,请参照[Paddle Serving编译文档](./doc/COMPILE_CN.md) paddle-serving-server和paddle-serving-server-gpu安装包支持Centos 6/7, Ubuntu 16/18和Windows 10。 -paddle-serving-client和paddle-serving-app安装包支持Linux和Windows,其中paddle-serving-client仅支持python2.7/3.5/3.6。 - -推荐安装1.8.4及以上版本的paddle +paddle-serving-client和paddle-serving-app安装包支持Linux和Windows,其中paddle-serving-client仅支持python2.7/3.5/3.6/3.7/3.8。 -对于**Windows 10 用户**,请参考文档[Windows平台使用Paddle Serving指导](./doc/WINDOWS_TUTORIAL_CN.md)。 - -

Paddle Serving预装的服务

- -

中文分词

+推荐安装2.0.0及以上版本的paddle -``` shell -> python -m paddle_serving_app.package --get_model lac -> tar -xzf lac.tar.gz -> python lac_web_service.py lac_model/ lac_workdir 9393 & -> curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"words": "我爱北京天安门"}], "fetch":["word_seg"]}' http://127.0.0.1:9393/lac/prediction -{"result":[{"word_seg":"我|爱|北京|天安门"}]} ``` +# CPU环境请执行 +pip install paddlepaddle==2.0.0 -

图像分类

+# GPU Cuda10.2环境请执行 +pip install paddlepaddle-gpu==2.0.0 +``` -

-
- -
-

+**注意**: 如果您的Cuda版本不是10.2,请勿直接执行上述命令,需要参考[Paddle官方文档-多版本whl包列表](https://www.paddlepaddle.org.cn/documentation/docs/zh/install/Tables.html#whl-release) -``` shell -> python -m paddle_serving_app.package --get_model resnet_v2_50_imagenet -> tar -xzf resnet_v2_50_imagenet.tar.gz -> python resnet50_imagenet_classify.py resnet50_serving_model & -> curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"image": "https://paddle-serving.bj.bcebos.com/imagenet-example/daisy.jpg"}], "fetch": ["score"]}' http://127.0.0.1:9292/image/prediction -{"result":{"label":["daisy"],"prob":[0.9341403245925903]}} +选择相应的GPU环境的url链接并进行安装,例如Cuda 9.0的Python2.7用户,请选择表格当中的`cp27-cp27mu`和`cuda9.0_cudnn7-mkl`对应的url,复制下来并执行 +``` +pip install https://paddle-wheel.bj.bcebos.com/2.0.0-gpu-cuda9-cudnn7-mkl/paddlepaddle_gpu-2.0.0.post90-cp27-cp27mu-linux_x86_64.whl ``` +如果是其他环境和Python版本,请在表格中找到对应的链接并用pip安装。 + +对于**Windows 10 用户**,请参考文档[Windows平台使用Paddle Serving指导](./doc/WINDOWS_TUTORIAL_CN.md)。

快速开始示例

-这个快速开始示例主要是为了给那些已经有一个要部署的模型的用户准备的,而且我们也提供了一个可以用来部署的模型。如果您想知道如何从离线训练到在线服务走完全流程,请参考[从训练到部署](https://github.com/PaddlePaddle/Serving/blob/develop/doc/TRAIN_TO_SERVICE_CN.md) +这个快速开始示例主要是为了给那些已经有一个要部署的模型的用户准备的,而且我们也提供了一个可以用来部署的模型。如果您想知道如何从离线训练到在线服务走完全流程,请参考前文的AiStudio教程。

波士顿房价预测

+进入到Serving的git目录下,进入到`fit_a_line`例子 ``` shell -wget --no-check-certificate https://paddle-serving.bj.bcebos.com/uci_housing.tar.gz -tar -xzf uci_housing.tar.gz +cd Serving/python/examples/fit_a_line +sh get_data.sh ``` Paddle Serving 为用户提供了基于 HTTP 和 RPC 的服务 @@ -127,10 +171,10 @@ python -m paddle_serving_server.serve --model uci_housing_model --thread 10 --po | `mem_optim_off` | - | - | Disable memory optimization | | `ir_optim` | - | - | Enable analysis and optimization of calculation graph | | `use_mkl` (Only for cpu version) | - | - | Run inference with MKL | -| `use_trt` (Only for trt version) | - | - | Run inference with TensorRT | +| `use_trt` (Only for Cuda>=10.1 version) | - | - | Run inference with TensorRT | +| `use_lite` (Only for ARM) | - | - | Run PaddleLite inference | +| `use_xpu` (Only for ARM+XPU) | - | - | Run PaddleLite XPU inference | -我们使用 `curl` 命令来发送HTTP POST请求给刚刚启动的服务。用户也可以调用python库来发送HTTP POST请求,请参考英文文 -档 [requests](https://requests.readthedocs.io/en/master/)。 ``` python @@ -151,26 +195,8 @@ print(fetch_map)

HTTP服务

用户也可以将数据格式处理逻辑放在服务器端进行,这样就可以直接用curl去访问服务,参考如下案例,在目录`python/examples/fit_a_line` -```python -from paddle_serving_server.web_service import WebService -import numpy as np - -class UciService(WebService): - def preprocess(self, feed=[], fetch=[]): - feed_batch = [] - is_batch = True - new_data = np.zeros((len(feed), 1, 13)).astype("float32") - for i, ins in enumerate(feed): - nums = np.array(ins["x"]).reshape(1, 1, 13) - new_data[i] = nums - feed = {"x": new_data} - return feed, fetch, is_batch - -uci_service = UciService(name="uci") -uci_service.load_model_config("uci_housing_model") -uci_service.prepare_server(workdir="workdir", port=9292) -uci_service.run_rpc_service() -uci_service.run_web_service() +``` +python -m paddle_serving_server.serve --model uci_housing_model --thread 10 --port 9292 --name uci ``` 客户端输入 ``` @@ -181,32 +207,17 @@ curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"x": [0.0137, -0.1 {"result":{"price":[[18.901151657104492]]}} ``` -

Paddle Serving的核心功能

- -- 与Paddle训练紧密连接,绝大部分Paddle模型可以 **一键部署**. -- 支持 **工业级的服务能力** 例如模型管理,在线加载,在线A/B测试等. -- 支持 **分布式键值对索引** 助力于大规模稀疏特征作为模型输入. -- 支持客户端和服务端之间 **高并发和高效通信**. -- 支持 **多种编程语言** 开发客户端,例如Golang,C++和Python. -

文档

### 新手教程 - [怎样保存用于Paddle Serving的模型?](doc/SAVE_CN.md) -- [端到端完成从训练到部署全流程](doc/TRAIN_TO_SERVICE_CN.md) - [十分钟构建Bert-As-Service](doc/BERT_10_MINS_CN.md) - -### AIStudio教程 -- [PaddleServing作业](https://aistudio.baidu.com/aistudio/projectdetail/605819) -- [PaddleServing图像分割](https://aistudio.baidu.com/aistudio/projectdetail/457715) -- [PaddleServing情感分析](https://aistudio.baidu.com/aistudio/projectdetail/509014) +- [Paddle Serving示例合辑](python/examples) ### 开发者教程 -- [如何配置Server端的计算图?](doc/SERVER_DAG_CN.md) -- [如何开发一个新的General Op?](doc/NEW_OPERATOR_CN.md) - [如何开发一个新的Web Service?](doc/NEW_WEB_SERVICE_CN.md) -- [如何在Paddle Serving使用Go Client?](doc/IMDB_GO_CLIENT_CN.md) - [如何编译PaddleServing?](doc/COMPILE_CN.md) +- [如何开发Pipeline?](doc/PIPELINE_SERVING_CN.md) - [如何使用uWSGI部署Web Service](doc/UWSGI_DEPLOY_CN.md) - [如何实现模型文件热加载](doc/HOT_LOADING_IN_SERVING_CN.md) @@ -217,12 +228,12 @@ curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"x": [0.0137, -0.1 - [CPU版Benchmarks](doc/BENCHMARKING.md) - [GPU版Benchmarks](doc/GPU_BENCHMARKING.md) -### FAQ -- [常见问答](doc/FAQ.md) - ### 设计文档 - [Paddle Serving设计文档](doc/DESIGN_DOC_CN.md) +### FAQ +- [常见问答](doc/FAQ.md) +

社区

### Slack diff --git a/doc/ABTEST_IN_PADDLE_SERVING.md b/doc/ABTEST_IN_PADDLE_SERVING.md index d901fe8d3141b25731321bc2e3a3df000f9fd6a1..09d13c12583ddfa0f1767cf46a309cac5ef86867 100644 --- a/doc/ABTEST_IN_PADDLE_SERVING.md +++ b/doc/ABTEST_IN_PADDLE_SERVING.md @@ -36,7 +36,7 @@ Here, we [use docker](RUN_IN_DOCKER.md) to start the server-side service. First, start the BOW server, which enables the `8000` port: ``` shell -docker run -dit -v $PWD/imdb_bow_model:/model -p 8000:8000 --name bow-server hub.baidubce.com/paddlepaddle/serving:latest /bin/bash +docker run -dit -v $PWD/imdb_bow_model:/model -p 8000:8000 --name bow-server registry.baidubce.com/paddlepaddle/serving:latest /bin/bash docker exec -it bow-server /bin/bash pip install paddle-serving-server -i https://pypi.tuna.tsinghua.edu.cn/simple pip install paddle-serving-client -i https://pypi.tuna.tsinghua.edu.cn/simple @@ -47,7 +47,7 @@ exit Similarly, start the LSTM server, which enables the `9000` port: ```bash -docker run -dit -v $PWD/imdb_lstm_model:/model -p 9000:9000 --name lstm-server hub.baidubce.com/paddlepaddle/serving:latest /bin/bash +docker run -dit -v $PWD/imdb_lstm_model:/model -p 9000:9000 --name lstm-server registry.baidubce.com/paddlepaddle/serving:latest /bin/bash docker exec -it lstm-server /bin/bash pip install paddle-serving-server -i https://pypi.tuna.tsinghua.edu.cn/simple pip install paddle-serving-client -i https://pypi.tuna.tsinghua.edu.cn/simple diff --git a/doc/ABTEST_IN_PADDLE_SERVING_CN.md b/doc/ABTEST_IN_PADDLE_SERVING_CN.md index 074960381858c64a2517a86553e295052b55e6a5..de2e57513f10a6a55a3e3baf48a4e0ba49c34ee7 100644 --- a/doc/ABTEST_IN_PADDLE_SERVING_CN.md +++ b/doc/ABTEST_IN_PADDLE_SERVING_CN.md @@ -35,7 +35,7 @@ pip install Shapely 首先启动BOW Server,该服务启用`8000`端口: ```bash -docker run -dit -v $PWD/imdb_bow_model:/model -p 8000:8000 --name bow-server hub.baidubce.com/paddlepaddle/serving:latest /bin/bash +docker run -dit -v $PWD/imdb_bow_model:/model -p 8000:8000 --name bow-server registry.baidubce.com/paddlepaddle/serving:latest /bin/bash docker exec -it bow-server /bin/bash pip install paddle-serving-server -i https://pypi.tuna.tsinghua.edu.cn/simple pip install paddle-serving-client -i https://pypi.tuna.tsinghua.edu.cn/simple @@ -46,7 +46,7 @@ exit 同理启动LSTM Server,该服务启用`9000`端口: ```bash -docker run -dit -v $PWD/imdb_lstm_model:/model -p 9000:9000 --name lstm-server hub.baidubce.com/paddlepaddle/serving:latest /bin/bash +docker run -dit -v $PWD/imdb_lstm_model:/model -p 9000:9000 --name lstm-server registry.baidubce.com/paddlepaddle/serving:latest /bin/bash docker exec -it lstm-server /bin/bash pip install paddle-serving-server -i https://pypi.tuna.tsinghua.edu.cn/simple pip install paddle-serving-client -i https://pypi.tuna.tsinghua.edu.cn/simple diff --git a/doc/BAIDU_KUNLUN_XPU_SERVING.md b/doc/BAIDU_KUNLUN_XPU_SERVING.md new file mode 100644 index 0000000000000000000000000000000000000000..8659e3a1dab5b16f6f5dfb56e9ed37ab86126385 --- /dev/null +++ b/doc/BAIDU_KUNLUN_XPU_SERVING.md @@ -0,0 +1,109 @@ +# Paddle Serving Using Baidu Kunlun Chips +(English|[简体中文](./BAIDU_KUNLUN_XPU_SERVING_CN.md)) + +Paddle serving supports deployment using Baidu Kunlun chips. At present, the pilot support is deployed on the ARM server with Baidu Kunlun chips + (such as Phytium FT-2000+/64). We will improve + the deployment capability on various heterogeneous hardware servers in the future. + +# Compilation and installation +Refer to [compile](COMPILE.md) document to setup the compilation environment。 +## Compilatiton +* Compile the Serving Server +``` +cd Serving +mkdir -p server-build-arm && cd server-build-arm + +cmake -DPYTHON_INCLUDE_DIR=/usr/include/python3.7m/ \ + -DPYTHON_LIBRARIES=/usr/lib64/libpython3.7m.so \ + -DPYTHON_EXECUTABLE=/usr/bin/python \ + -DWITH_PYTHON=ON \ + -DWITH_LITE=ON \ + -DWITH_XPU=ON \ + -DSERVER=ON .. +make -j10 +``` +You can run `make install` to produce the target in `./output` directory. Add `-DCMAKE_INSTALL_PREFIX=./output` to specify the output path to CMake command shown above。 +* Compile the Serving Client +``` +mkdir -p client-build-arm && cd client-build-arm + +cmake -DPYTHON_INCLUDE_DIR=/usr/include/python3.7m/ \ + -DPYTHON_LIBRARIES=/usr/lib64/libpython3.7m.so \ + -DPYTHON_EXECUTABLE=/usr/bin/python \ + -DWITH_PYTHON=ON \ + -DWITH_LITE=ON \ + -DWITH_XPU=ON \ + -DCLIENT=ON .. + +make -j10 +``` +* Compile the App +``` +cd Serving +mkdir -p app-build-arm && cd app-build-arm + +cmake -DPYTHON_INCLUDE_DIR=/usr/include/python3.7m/ \ + -DPYTHON_LIBRARIES=/usr/lib64/libpython3.7m.so \ + -DPYTHON_EXECUTABLE=/usr/bin/python \ + -DWITH_PYTHON=ON \ + -DWITH_LITE=ON \ + -DWITH_XPU=ON \ + -DAPP=ON .. + +make -j10 +``` +## Install the wheel package +After the compilations stages above, the whl package will be generated in ```python/dist/``` under the specific temporary directories. +For example, after the Server Compiation step,the whl package will be produced under the server-build-arm/python/dist directory, and you can run ```pip install -u python/dist/*.whl``` to install the package。 + +# Request parameters description +In order to deploy serving + service on the arm server with Baidu Kunlun xpu chips and use the acceleration capability of Paddle-Lite,please specify the following parameters during deployment。 +|param|param description|about| +|:--|:--|:--| +|use_lite|using Paddle-Lite Engine|use the inference capability of Paddle-Lite| +|use_xpu|using Baidu Kunlun for inference|need to be used with the use_lite option| +|ir_optim|open the graph optimization|refer to[Paddle-Lite](https://github.com/PaddlePaddle/Paddle-Lite)| +# Deplyment examples +## Download the model +``` +wget --no-check-certificate https://paddle-serving.bj.bcebos.com/uci_housing.tar.gz +tar -xzf uci_housing.tar.gz +``` +## Start RPC service +There are mainly three deployment methods: +* deploy on the ARM server with Baidu xpu using the acceleration capability of Paddle-Lite and xpu; +* deploy on the ARM server standalone with Paddle-Lite; +* deploy on the ARM server standalone without Paddle-Lite。 + +The first two deployment methods are recommended。 + +Start the rpc service, deploying on ARM server with Baidu Kunlun chips,and accelerate with Paddle-Lite and Baidu Kunlun xpu. +``` +python3 -m paddle_serving_server_gpu.serve --model uci_housing_model --thread 6 --port 9292 --use_lite --use_xpu --ir_optim +``` +Start the rpc service, deploying on ARM server,and accelerate with Paddle-Lite. +``` +python3 -m paddle_serving_server_gpu.serve --model uci_housing_model --thread 6 --port 9292 --use_lite --ir_optim +``` +Start the rpc service, deploying on ARM server. +``` +python3 -m paddle_serving_server_gpu.serve --model uci_housing_model --thread 6 --port 9292 +``` +## +``` +from paddle_serving_client import Client +import numpy as np +client = Client() +client.load_client_config("uci_housing_client/serving_client_conf.prototxt") +client.connect(["127.0.0.1:9292"]) +data = [0.0137, -0.1136, 0.2553, -0.0692, 0.0582, -0.0727, + -0.1583, -0.0584, 0.6283, 0.4919, 0.1856, 0.0795, -0.0332] +fetch_map = client.predict(feed={"x": np.array(data).reshape(1,13,1)}, fetch=["price"]) +print(fetch_map) +``` +Some examples are provided below, and other models can be modifed with reference to these examples。 +|sample name|sample links| +|:-----|:--| +|fit_a_line|[fit_a_line_xpu](../python/examples/xpu/fit_a_line_xpu)| +|resnet|[resnet_v2_50_xpu](../python/examples/xpu/resnet_v2_50_xpu)| diff --git a/doc/BAIDU_KUNLUN_XPU_SERVING_CN.md b/doc/BAIDU_KUNLUN_XPU_SERVING_CN.md new file mode 100644 index 0000000000000000000000000000000000000000..6640533cafee67360e3f8a12b87816f5aad97aa0 --- /dev/null +++ b/doc/BAIDU_KUNLUN_XPU_SERVING_CN.md @@ -0,0 +1,105 @@ +# Paddle Serving使用百度昆仑芯片部署 +(简体中文|[English](./BAIDU_KUNLUN_XPU_SERVING.md)) + +Paddle Serving支持使用百度昆仑芯片进行预测部署。目前试验性支持在百度昆仑芯片和arm服务器(如飞腾 FT-2000+/64)上进行部署,后续完善对其他异构硬件服务器部署能力。 + +# 编译、安装 +基本环境配置可参考[该文档](COMPILE_CN.md)进行配置。 +## 编译 +* 编译server部分 +``` +cd Serving +mkdir -p server-build-arm && cd server-build-arm + +cmake -DPYTHON_INCLUDE_DIR=/usr/include/python3.7m/ \ + -DPYTHON_LIBRARIES=/usr/lib64/libpython3.7m.so \ + -DPYTHON_EXECUTABLE=/usr/bin/python \ + -DWITH_PYTHON=ON \ + -DWITH_LITE=ON \ + -DWITH_XPU=ON \ + -DSERVER=ON .. +make -j10 +``` +可以执行`make install`把目标产出放在`./output`目录下,cmake阶段需添加`-DCMAKE_INSTALL_PREFIX=./output`选项来指定存放路径。 +* 编译client部分 +``` +mkdir -p client-build-arm && cd client-build-arm + +cmake -DPYTHON_INCLUDE_DIR=/usr/include/python3.7m/ \ + -DPYTHON_LIBRARIES=/usr/lib64/libpython3.7m.so \ + -DPYTHON_EXECUTABLE=/usr/bin/python \ + -DWITH_PYTHON=ON \ + -DWITH_LITE=ON \ + -DWITH_XPU=ON \ + -DCLIENT=ON .. + +make -j10 +``` +* 编译app部分 +``` +cd Serving +mkdir -p app-build-arm && cd app-build-arm + +cmake -DPYTHON_INCLUDE_DIR=/usr/include/python3.7m/ \ + -DPYTHON_LIBRARIES=/usr/lib64/libpython3.7m.so \ + -DPYTHON_EXECUTABLE=/usr/bin/python \ + -DWITH_PYTHON=ON \ + -DWITH_LITE=ON \ + -DWITH_XPU=ON \ + -DAPP=ON .. + +make -j10 +``` +## 安装wheel包 +以上编译步骤完成后,会在各自编译目录$build_dir/python/dist生成whl包,分别安装即可。例如server步骤,会在server-build-arm/python/dist目录下生成whl包, 使用命令```pip install -u xxx.whl```进行安装。 + +# 请求参数说明 +为了支持arm+xpu服务部署,使用Paddle-Lite加速能力,请求时需使用以下参数。 +|参数|参数说明|备注| +|:--|:--|:--| +|use_lite|使用Paddle-Lite Engine|使用Paddle-Lite cpu预测能力| +|use_xpu|使用Baidu Kunlun进行预测|该选项需要与use_lite配合使用| +|ir_optim|开启Paddle-Lite计算子图优化|详细见[Paddle-Lite](https://github.com/PaddlePaddle/Paddle-Lite)| +# 部署使用示例 +## 下载模型 +``` +wget --no-check-certificate https://paddle-serving.bj.bcebos.com/uci_housing.tar.gz +tar -xzf uci_housing.tar.gz +``` +## 启动rpc服务 +主要有三种启动配置: +* 使用arm cpu+xpu部署,使用Paddle-Lite xpu优化加速能力; +* 单独使用arm cpu部署,使用Paddle-Lite优化加速能力; +* 使用arm cpu部署,不使用Paddle-Lite加速。 + +推荐使用前两种部署方式。 + +启动rpc服务,使用arm cpu+xpu部署,使用Paddle-Lite xpu优化加速能力 +``` +python3 -m paddle_serving_server_gpu.serve --model uci_housing_model --thread 6 --port 9292 --use_lite --use_xpu --ir_optim +``` +启动rpc服务,使用arm cpu部署, 使用Paddle-Lite加速能力 +``` +python3 -m paddle_serving_server_gpu.serve --model uci_housing_model --thread 6 --port 9292 --use_lite --ir_optim +``` +启动rpc服务,使用arm cpu部署, 不使用Paddle-Lite加速能力 +``` +python3 -m paddle_serving_server_gpu.serve --model uci_housing_model --thread 6 --port 9292 +``` +## client调用 +``` +from paddle_serving_client import Client +import numpy as np +client = Client() +client.load_client_config("uci_housing_client/serving_client_conf.prototxt") +client.connect(["127.0.0.1:9292"]) +data = [0.0137, -0.1136, 0.2553, -0.0692, 0.0582, -0.0727, + -0.1583, -0.0584, 0.6283, 0.4919, 0.1856, 0.0795, -0.0332] +fetch_map = client.predict(feed={"x": np.array(data).reshape(1,13,1)}, fetch=["price"]) +print(fetch_map) +``` +以下提供部分样例,其他模型可参照进行修改。 +|示例名称|示例链接| +|:-----|:--| +|fit_a_line|[fit_a_line_xpu](../python/examples/xpu/fit_a_line_xpu)| +|resnet|[resnet_v2_50_xpu](../python/examples/xpu/resnet_v2_50_xpu)| diff --git a/doc/BERT_10_MINS.md b/doc/BERT_10_MINS.md index 7b981d7eda467197d1b1b741c35b00c97b74c532..7f2aef671cfca910c4fb07de288fb6ba28bcd451 100644 --- a/doc/BERT_10_MINS.md +++ b/doc/BERT_10_MINS.md @@ -2,35 +2,57 @@ ([简体中文](./BERT_10_MINS_CN.md)|English) -The goal of Bert-As-Service is to give a sentence, and the service can represent the sentence as a semantic vector and return it to the user. [Bert model](https://arxiv.org/abs/1810.04805) is a popular model in the current NLP field. It has achieved good results on a variety of public NLP tasks. The semantic vector calculated by the Bert model is used as input to other NLP models, which will also greatly improve the performance of the model. Bert-As-Service allows users to easily obtain the semantic vector representation of text and apply it to their own tasks. In order to achieve this goal, we have shown in four steps that using Paddle Serving can build such a service in ten minutes. All the code and files in the example can be found in [Example](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/bert) of Paddle Serving. +The goal of Bert-As-Service is to give a sentence, and the service can represent the sentence as a semantic vector and return it to the user. [Bert model](https://arxiv.org/abs/1810.04805) is a popular model in the current NLP field. It has achieved good results on a variety of public NLP tasks. The semantic vector calculated by the Bert model is used as input to other NLP models, which will also greatly improve the performance of the model. Bert-As-Service allows users to easily obtain the semantic vector representation of text and apply it to their own tasks. In order to achieve this goal, we have shown in five steps that using Paddle Serving can build such a service in ten minutes. All the code and files in the example can be found in [Example](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/bert) of Paddle Serving. -#### Step1: Save the serviceable model +If your python version is 3.X, replace the 'pip' field in the following command with 'pip3',replace 'python' with 'python3'. -Paddle Serving supports various models trained based on Paddle, and saves the serviceable model by specifying the input and output variables of the model. For convenience, we can load a trained bert Chinese model from paddlehub and save a deployable service with two lines of code. The server and client configurations are placed in the `bert_seq20_model` and` bert_seq20_client` folders, respectively. +### Step1: Getting Model -[//file]:#bert_10.py -``` python -import paddlehub as hub -model_name = "bert_chinese_L-12_H-768_A-12" -module = hub.Module(model_name) -inputs, outputs, program = module.context( - trainable=True, max_seq_len=20) -feed_keys = ["input_ids", "position_ids", "segment_ids", - "input_mask"] -fetch_keys = ["pooled_output", "sequence_output"] -feed_dict = dict(zip(feed_keys, [inputs[x] for x in feed_keys])) -fetch_dict = dict(zip(fetch_keys, [outputs[x] for x in fetch_keys])) +#### 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). -import paddle_serving_client.io as serving_io -serving_io.save_model("bert_seq20_model", "bert_seq20_client", - feed_dict, fetch_dict, program) +Install paddlehub first +``` +pip install paddlehub +``` + +run +``` +python prepare_model.py 128 +``` + +**PaddleHub only support Python 3.5+** + +the 128 in the command above means max_seq_len in BERT model, which is the length of sample after preprocessing. +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 +mv bert_chinese_L-12_H-768_A-12_model bert_seq128_model +mv bert_chinese_L-12_H-768_A-12_client bert_seq128_client ``` -#### Step2: Launch Service +### Step2: Getting Dict and Sample Dataset -[//file]:#server.sh -``` shell -python -m paddle_serving_server_gpu.serve --model bert_seq20_model --thread 10 --port 9292 --gpu_ids 0 +``` +sh get_data.sh +``` +this script will download Chinese Dictionary File vocab.txt and Chinese Sample Data data-c.txt + + +### Step3: Launch Service + +start cpu inference service,Run +``` +python -m paddle_serving_server.serve --model bert_seq128_model/ --port 9292 #cpu inference service +``` +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 ``` | Parameters | Meaning | | ---------- | ---------------------------------------- | @@ -39,52 +61,55 @@ python -m paddle_serving_server_gpu.serve --model bert_seq20_model --thread 10 - | port | server port number | | gpu_ids | GPU index number | -#### Step3: data preprocessing logic on Client Side +### Step4: data preprocessing logic on Client Side Paddle Serving has many built-in corresponding data preprocessing logics. For the calculation of Chinese Bert semantic representation, we use the ChineseBertReader class under paddle_serving_app for data preprocessing. Model input fields of multiple models corresponding to a raw Chinese sentence can be easily fetched by developers Install paddle_serving_app -[//file]:#pip_app.sh ```shell pip install paddle_serving_app ``` -#### Step4: Client Visit Serving +### Step5: Client Visit Serving -the script of client side bert_client.py is as follow: -[//file]:#bert_client.py -``` python -import sys -from paddle_serving_client import Client -from paddle_serving_client.utils import benchmark_args -from paddle_serving_app.reader import ChineseBertReader -import numpy as np -args = benchmark_args() +#### method 1: RPC Inference + +Run +``` +head data-c.txt | python bert_client.py --model bert_seq128_client/serving_client_conf.prototxt +``` + +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). -reader = ChineseBertReader({"max_seq_len": 128}) -fetch = ["pooled_output"] -endpoint_list = ['127.0.0.1:9292'] -client = Client() -client.load_client_config(args.model) -client.connect(endpoint_list) -for line in sys.stdin: - feed_dict = reader.process(line) - for key in feed_dict.keys(): - feed_dict[key] = np.array(feed_dict[key]).reshape((128, 1)) - result = client.predict(feed=feed_dict, fetch=fetch, batch=False) +#### method 2: HTTP Inference + +This method is divided into two steps: + +1. Start an HTTP prediction server. + +start cpu HTTP inference service,Run +``` + python bert_web_service.py bert_seq128_model/ 9292 #launch cpu inference service ``` -run +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_gpu.py bert_seq128_model/ 9292 #launch gpu inference service +``` -[//file]:#bert_10_cli.sh -```shell -cat data.txt | python bert_client.py +2. Prediction via HTTP request ``` +curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"words": "hello"}], "fetch":["pooled_output"]}' http://127.0.0.1:9292/bert/prediction +``` + -read samples from data.txt, print results at the standard output. ### Benchmark diff --git a/doc/BERT_10_MINS_CN.md b/doc/BERT_10_MINS_CN.md index b0578e8e84de7e36694e879e5a64737d275c505c..df4e8eb32614df0c8b0c2edeeb47fd1516a70710 100644 --- a/doc/BERT_10_MINS_CN.md +++ b/doc/BERT_10_MINS_CN.md @@ -2,30 +2,56 @@ (简体中文|[English](./BERT_10_MINS.md)) -Bert-As-Service的目标是给定一个句子,服务可以将句子表示成一个语义向量返回给用户。[Bert模型](https://arxiv.org/abs/1810.04805)是目前NLP领域的热门模型,在多种公开的NLP任务上都取得了很好的效果,使用Bert模型计算出的语义向量来做其他NLP模型的输入对提升模型的表现也有很大的帮助。Bert-As-Service可以让用户很方便地获取文本的语义向量表示并应用到自己的任务中。为了实现这个目标,我们通过四个步骤说明使用Paddle Serving在十分钟内就可以搭建一个这样的服务。示例中所有的代码和文件均可以在Paddle Serving的[示例](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/bert)中找到。 +Bert-As-Service的目标是给定一个句子,服务可以将句子表示成一个语义向量返回给用户。[Bert模型](https://arxiv.org/abs/1810.04805)是目前NLP领域的热门模型,在多种公开的NLP任务上都取得了很好的效果,使用Bert模型计算出的语义向量来做其他NLP模型的输入对提升模型的表现也有很大的帮助。Bert-As-Service可以让用户很方便地获取文本的语义向量表示并应用到自己的任务中。为了实现这个目标,我们通过以下几个步骤说明使用Paddle Serving在十分钟内就可以搭建一个这样的服务。示例中所有的代码和文件均可以在Paddle Serving的[示例](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/bert)中找到。 -#### Step1:保存可服务模型 -Paddle Serving支持基于Paddle进行训练的各种模型,并通过指定模型的输入和输出变量来保存可服务模型。为了方便,我们可以从paddlehub加载一个已经训练好的bert中文模型,并利用两行代码保存一个可部署的服务,服务端和客户端的配置分别放在`bert_seq20_model`和`bert_seq20_client`文件夹。 +若使用python的版本为3.X, 将以下命令中的pip 替换为pip3, python替换为python3. -``` python -import paddlehub as hub -model_name = "bert_chinese_L-12_H-768_A-12" -module = hub.Module(model_name) -inputs, outputs, program = module.context(trainable=True, max_seq_len=20) -feed_keys = ["input_ids", "position_ids", "segment_ids", "input_mask"] -fetch_keys = ["pooled_output", "sequence_output"] -feed_dict = dict(zip(feed_keys, [inputs[x] for x in feed_keys])) -fetch_dict = dict(zip(fetch_keys, [outputs[x] for x in fetch_keys])) -import paddle_serving_client.io as serving_io -serving_io.save_model("bert_seq20_model", "bert_seq20_client", feed_dict, fetch_dict, program) +### Step1:获取模型 +#### 方法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 ``` +pip install paddlehub +``` +执行 +``` +python prepare_model.py 128 +``` +参数128表示BERT模型中的max_seq_len,即预处理后的样本长度。 +生成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 +mv bert_chinese_L-12_H-768_A-12_model bert_seq128_model +mv bert_chinese_L-12_H-768_A-12_client bert_seq128_client +``` + -#### Step2:启动服务 +### Step2:获取词典和样例数据 + +``` +sh get_data.sh +``` +脚本将下载中文词典vocab.txt和中文样例数据data-c.txt + + +### Step3:启动服务 + +启动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预测服务 -``` shell -python -m paddle_serving_server_gpu.serve --model bert_seq20_model --port 9292 --gpu_ids 0 ``` | 参数 | 含义 | @@ -35,7 +61,8 @@ python -m paddle_serving_server_gpu.serve --model bert_seq20_model --port 9292 - | port | server端端口号 | | gpu_ids | GPU索引号 | -#### Step3:客户端数据预处理逻辑 + +### Step4:客户端数据预处理逻辑 Paddle Serving内建了很多经典典型对应的数据预处理逻辑,对于中文Bert语义表示的计算,我们采用paddle_serving_app下的ChineseBertReader类进行数据预处理,开发者可以很容易获得一个原始的中文句子对应的多个模型输入字段。 @@ -45,39 +72,40 @@ Paddle Serving内建了很多经典典型对应的数据预处理逻辑,对于 pip install paddle_serving_app ``` -#### Step4:客户端访问 +### Step5:客户端访问 + +#### 方法1:通过RPC方式执行预测 +执行 +``` +head data-c.txt | python bert_client.py --model bert_seq128_client/serving_client_conf.prototxt -客户端脚本 bert_client.py内容如下 +``` +启动client读取data-c.txt中的数据进行预测,预测结果为文本的向量表示(由于数据较多,脚本中没有将输出进行打印),server端的地址在脚本中修改。 -``` python -import sys -from paddle_serving_client import Client -from paddle_serving_client.utils import benchmark_args -from paddle_serving_app.reader import ChineseBertReader -import numpy as np -args = benchmark_args() -reader = ChineseBertReader({"max_seq_len": 128}) -fetch = ["pooled_output"] -endpoint_list = ['127.0.0.1:9292'] -client = Client() -client.load_client_config(args.model) -client.connect(endpoint_list) +#### 方法2:通过HTTP方式执行预测 +该方式分为两步 +1、启动一个HTTP预测服务端。 -for line in sys.stdin: - feed_dict = reader.process(line) - for key in feed_dict.keys(): - feed_dict[key] = np.array(feed_dict[key]).reshape((128, 1)) - result = client.predict(feed=feed_dict, fetch=fetch, batch=False) +启动cpu HTTP预测服务,执行 ``` +python bert_web_service.py bert_seq128_model/ 9292 #启动CPU预测服务 -执行 +``` -```shell -cat data.txt | python bert_client.py +或者,启动gpu HTTP预测服务,执行 +``` + export CUDA_VISIBLE_DEVICES=0,1 +``` +通过环境变量指定gpu预测服务使用的gpu,示例中指定索引为0和1的两块gpu +``` +python bert_web_service_gpu.py bert_seq128_model/ 9292 #启动gpu预测服务 ``` -从data.txt文件中读取样例,并将结果打印到标准输出。 +2、通过HTTP请求执行预测。 +``` +curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"words": "hello"}], "fetch":["pooled_output"]}' http://127.0.0.1:9292/bert/prediction +``` ### 性能测试 diff --git a/doc/COMPILE.md b/doc/COMPILE.md index 03d135e006c36e57e52b1d353c79217b53baa5e1..ec1900a89b9b2f0112f0d44adc539b138438bba7 100644 --- a/doc/COMPILE.md +++ b/doc/COMPILE.md @@ -6,12 +6,11 @@ | module | version | | :--------------------------: | :-------------------------------: | -| OS | CentOS 7 | -| gcc | 4.8.5 and later | -| gcc-c++ | 4.8.5 and later | -| git | 3.82 and later | +| OS | Ubuntu16 and 18/CentOS 7 | +| gcc | 4.8.5(Cuda 9.0 and 10.0) and 8.2(Others) | +| gcc-c++ | 4.8.5(Cuda 9.0 and 10.0) and 8.2(Others) | | cmake | 3.2.0 and later | -| Python | 2.7.2 and later / 3.6 and later | +| Python | 2.7.2 and later / 3.5.1 and later | | Go | 1.9.2 and later | | git | 2.17.1 and later | | glibc-static | 2.17 | @@ -19,19 +18,13 @@ | bzip2-devel | 1.0.6 and later | | python-devel / python3-devel | 2.7.5 and later / 3.6.8 and later | | sqlite-devel | 3.7.17 and later | -| patchelf | 0.9 and later | +| patchelf | 0.9 | | libXext | 1.3.3 | | libSM | 1.2.2 | | libXrender | 0.9.10 | It is recommended to use Docker for compilation. We have prepared the Paddle Serving compilation environment for you, see [this document](DOCKER_IMAGES.md). -This document will take Python2 as an example to show how to compile Paddle Serving. If you want to compile with Python3, just adjust the Python options of cmake: - -- Set `DPYTHON_INCLUDE_DIR` to `$PYTHONROOT/include/python3.6m/` -- Set `DPYTHON_LIBRARIES` to `$PYTHONROOT/lib64/libpython3.6.so` -- Set `DPYTHON_EXECUTABLE` to `$PYTHONROOT/bin/python3.6` - ## Get Code ``` python @@ -39,19 +32,47 @@ git clone https://github.com/PaddlePaddle/Serving cd Serving && git submodule update --init --recursive ``` - - - -## PYTHONROOT Setting +## PYTHONROOT settings ```shell -# for example, the path of python is /usr/bin/python, you can set /usr as PYTHONROOT -export PYTHONROOT=/usr/ +# For example, the path of python is /usr/bin/python, you can set PYTHONROOT +export PYTHONROOT=/usr ``` -In the default centos7 image we provide, the Python path is `/usr/bin/python`. If you want to use our centos6 image, you need to set it to `export PYTHONROOT=/usr/local/python2.7/`. +If you are using a Docker development image, please follow the following to determine the Python version to be compiled, and set the corresponding environment variables +``` +#Python 2.7 +export PYTHONROOT=/usr/local/python2.7.15/ +export PYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ +export PYTHON_LIBRARIES=$PYTHONROOT/lib/libpython2.7.so +export PYTHON_EXECUTABLE=$PYTHONROOT/bin/python2.7 + +#Python 3.5 +export PYTHONROOT=/usr/local/python3.5.1 +export PYTHON_INCLUDE_DIR=$PYTHONROOT/include/python3.5m +export PYTHON_LIBRARIES=$PYTHONROOT/lib/libpython3.5m.so +export PYTHON_EXECUTABLE=$PYTHONROOT/bin/python3.5 + +#Python3.6 +export PYTHONROOT=/usr/local/ +export PYTHON_INCLUDE_DIR=$PYTHONROOT/include/python3.6m +export PYTHON_LIBRARIES=$PYTHONROOT/lib/libpython3.6m.so +export PYTHON_EXECUTABLE=$PYTHONROOT/bin/python3.6 + +#Python3.7 +export PYTHONROOT=/usr/local/ +export PYTHON_INCLUDE_DIR=$PYTHONROOT/include/python3.7m +export PYTHON_LIBRARIES=$PYTHONROOT/lib/libpython3.7m.so +export PYTHON_EXECUTABLE=$PYTHONROOT/bin/python3.7 + +#Python3.8 +export PYTHONROOT=/usr/local/ +export PYTHON_INCLUDE_DIR=$PYTHONROOT/include/python3.8 +export PYTHON_LIBRARIES=$PYTHONROOT/lib/libpython3.8.so +export PYTHON_EXECUTABLE=$PYTHONROOT/bin/python3.8 +``` ## Install Python dependencies @@ -59,14 +80,11 @@ In the default centos7 image we provide, the Python path is `/usr/bin/python`. I pip install -r python/requirements.txt ``` -If Python3 is used, replace `pip` with `pip3`. +If you use other Python version, please use the right `pip` accordingly. ## GOPATH Setting +The default GOPATH is set to `$HOME/go`, you can also set it to other values. **If it is the Docker environment provided by Serving, you do not need to set up.** - -## Compile Arguments - -The default GOPATH is `$HOME/go`, which you can set to other values. ```shell export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin @@ -100,52 +118,42 @@ make -j10 you can execute `make install` to put targets under directory `./output`, you need to add`-DCMAKE_INSTALL_PREFIX=./output`to specify output path to cmake command shown above. ### Integrated GPU version paddle inference library -### CUDA_PATH is the cuda install path,use the command(whereis cuda) to check,it should be /usr/local/cuda. -### CUDNN_LIBRARY && CUDA_CUDART_LIBRARY is the lib path, it should be /usr/local/cuda/lib64/ - -``` shell -export CUDA_PATH='/usr/local/cuda' -export CUDNN_LIBRARY='/usr/local/cuda/lib64/' -export CUDA_CUDART_LIBRARY="/usr/local/cuda/lib64/" -mkdir server-build-gpu && cd server-build-gpu -cmake -DPYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ \ - -DPYTHON_LIBRARIES=$PYTHONROOT/lib/libpython2.7.so \ - -DPYTHON_EXECUTABLE=$PYTHONROOT/bin/python \ - -DCUDA_TOOLKIT_ROOT_DIR=${CUDA_PATH} \ - -DCUDNN_LIBRARY=${CUDNN_LIBRARY} \ - -DCUDA_CUDART_LIBRARY=${CUDA_CUDART_LIBRARY} \ - -DSERVER=ON \ - -DWITH_GPU=ON .. -make -j10 -``` +Compared with CPU environment, GPU environment needs to refer to the following table, +**It should be noted that the following table is used as a reference for non-Docker compilation environment. The Docker compilation environment has been configured with relevant parameters and does not need to be specified in cmake process. ** -### Integrated TRT version paddle inference library +| cmake environment variable | meaning | GPU environment considerations | whether Docker environment is needed | +|-----------------------|------------------------- ------------|-------------------------------|----- ---------------| +| CUDA_TOOLKIT_ROOT_DIR | cuda installation path, usually /usr/local/cuda | Required for all environments | No +(/usr/local/cuda) | +| CUDNN_LIBRARY | The directory where libcudnn.so.* is located, usually /usr/local/cuda/lib64/ | Required for all environments | No (/usr/local/cuda/lib64/) | +| CUDA_CUDART_LIBRARY | The directory where libcudart.so.* is located, usually /usr/local/cuda/lib64/ | Required for all environments | No (/usr/local/cuda/lib64/) | +| TENSORRT_ROOT | The upper level directory of the directory where libnvinfer.so.* is located, depends on the TensorRT installation directory | Cuda 9.0/10.0 does not need, other needs | No (/usr) | -``` +If not in Docker environment, users can refer to the following execution methods. The specific path is subject to the current environment, and the code is only for reference. + +``` shell 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/" -mkdir server-build-trt && cd server-build-trt -cmake -DPYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ \ - -DPYTHON_LIBRARIES=$PYTHONROOT/lib/libpython2.7.so \ - -DPYTHON_EXECUTABLE=$PYTHONROOT/bin/python \ - -DTENSORRT_ROOT=${TENSORRT_LIBRARY_PATH} \ +mkdir server-build-gpu && cd server-build-gpu +cmake -DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR \ + -DPYTHON_LIBRARIES=$PYTHON_LIBRARIES \ + -DPYTHON_EXECUTABLE=$PYTHON_EXECUTABLE \ -DCUDA_TOOLKIT_ROOT_DIR=${CUDA_PATH} \ -DCUDNN_LIBRARY=${CUDNN_LIBRARY} \ -DCUDA_CUDART_LIBRARY=${CUDA_CUDART_LIBRARY} \ + -DTENSORRT_ROOT=${TENSORRT_LIBRARY_PATH} -DSERVER=ON \ - -DWITH_GPU=ON \ - -DWITH_TRT=ON .. + -DWITH_GPU=ON .. make -j10 ``` -execute `make install` to put targets under directory `./output` - -**Attention:** After the compilation is successful, you need to set the path of `SERVING_BIN`. See [Note](https://github.com/PaddlePaddle/Serving/blob/develop/doc/COMPILE.md#Note) for details. - +Execute `make install` to put the target output in the `./output` directory. +**Note:** After the compilation is successful, you need to set the `SERVING_BIN` path, see the following [Notes](COMPILE.md#Notes) ). ## Compile Client @@ -208,7 +216,6 @@ Please use the example under `python/examples` to verify. | CLIENT | Compile Paddle Serving Client | OFF | | SERVER | Compile Paddle Serving Server | OFF | | APP | Compile Paddle Serving App package | OFF | -| WITH_ELASTIC_CTR | Compile ELASITC-CTR solution | OFF | | PACK | Compile for whl | OFF | ### WITH_GPU Option @@ -230,11 +237,13 @@ Note here: The following is the base library version matching relationship used by the PaddlePaddle release version for reference: -| | CUDA | CuDNN | TensorRT | -| :----: | :-----: | :----------------------: | :----: | -| post9 | 9.0 | CuDNN 7.3.1 for CUDA 9.0 | | -| post10 | 10.0 | CuDNN 7.5.1 for CUDA 10.0| | -| trt | 10.1 | CuDNN 7.5.1 for CUDA 10.1| 6.0.1.5 | +| | CUDA | CuDNN | TensorRT | +| :----: | :-----: | :----------: | :----: | +| post9 | 9.0 | CuDNN 7.6.4 | | +| post10 | 10.0 | CuDNN 7.6.5 | | +| post101 | 10.1 | CuDNN 7.6.5 | 6.0.1 | +| post102 | 10.2 | CuDNN 8.0.5 | 7.1.3 | +| post11 | 11.0 | CuDNN 8.0.4 | 7.1.3 | ### How to make the compiler detect the CuDNN library diff --git a/doc/COMPILE_CN.md b/doc/COMPILE_CN.md index e5024b1a11aa871ca404287333ac3ff4ee70e21c..740a33028c2c1fff7364e3d771360d4a579e3ae8 100644 --- a/doc/COMPILE_CN.md +++ b/doc/COMPILE_CN.md @@ -6,12 +6,11 @@ | 组件 | 版本要求 | | :--------------------------: | :-------------------------------: | -| OS | CentOS 7 | -| gcc | 4.8.5 and later | -| gcc-c++ | 4.8.5 and later | -| git | 3.82 and later | +| OS | Ubuntu16 and 18/CentOS 7 | +| gcc | 4.8.5(Cuda 9.0 and 10.0) and 8.2(Others) | +| gcc-c++ | 4.8.5(Cuda 9.0 and 10.0) and 8.2(Others) | | cmake | 3.2.0 and later | -| Python | 2.7.2 and later / 3.6 and later | +| Python | 2.7.2 and later / 3.5.1 and later | | Go | 1.9.2 and later | | git | 2.17.1 and later | | glibc-static | 2.17 | @@ -24,13 +23,7 @@ | libSM | 1.2.2 | | libXrender | 0.9.10 | -推荐使用Docker编译,我们已经为您准备好了Paddle Serving编译环境,详见[该文档](DOCKER_IMAGES_CN.md)。 - -本文档将以Python2为例介绍如何编译Paddle Serving。如果您想用Python3进行编译,只需要调整cmake的Python相关选项即可: - -- 将`DPYTHON_INCLUDE_DIR`设置为`$PYTHONROOT/include/python3.6m/` -- 将`DPYTHON_LIBRARIES`设置为`$PYTHONROOT/lib64/libpython3.6.so` -- 将`DPYTHON_EXECUTABLE`设置为`$PYTHONROOT/bin/python3.6` +推荐使用Docker编译,我们已经为您准备好了Paddle Serving编译环境并配置好了上述编译依赖,详见[该文档](DOCKER_IMAGES_CN.md)。 ## 获取代码 @@ -39,19 +32,46 @@ git clone https://github.com/PaddlePaddle/Serving cd Serving && git submodule update --init --recursive ``` - - - ## PYTHONROOT设置 ```shell # 例如python的路径为/usr/bin/python,可以设置PYTHONROOT -export PYTHONROOT=/usr/ +export PYTHONROOT=/usr ``` -我们提供默认Centos7的Python路径为`/usr/bin/python`,如果您要使用我们的Centos6镜像,需要将其设置为`export PYTHONROOT=/usr/local/python2.7/`。 - +如果您使用的是Docker开发镜像,请按照如下,确定好需要编译的Python版本,设置对应的环境变量 +``` +#Python 2.7 +export PYTHONROOT=/usr/local/python2.7.15/ +export PYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ +export PYTHON_LIBRARIES=$PYTHONROOT/lib/libpython2.7.so +export PYTHON_EXECUTABLE=$PYTHONROOT/bin/python2.7 + +#Python 3.5 +export PYTHONROOT=/usr/local/python3.5.1 +export PYTHON_INCLUDE_DIR=$PYTHONROOT/include/python3.5m +export PYTHON_LIBRARIES=$PYTHONROOT/lib/libpython3.5m.so +export PYTHON_EXECUTABLE=$PYTHONROOT/bin/python3.5 + +#Python3.6 +export PYTHONROOT=/usr/local/ +export PYTHON_INCLUDE_DIR=$PYTHONROOT/include/python3.6m +export PYTHON_LIBRARIES=$PYTHONROOT/lib/libpython3.6m.so +export PYTHON_EXECUTABLE=$PYTHONROOT/bin/python3.6 + +#Python3.7 +export PYTHONROOT=/usr/local/ +export PYTHON_INCLUDE_DIR=$PYTHONROOT/include/python3.7m +export PYTHON_LIBRARIES=$PYTHONROOT/lib/libpython3.7m.so +export PYTHON_EXECUTABLE=$PYTHONROOT/bin/python3.7 + +#Python3.8 +export PYTHONROOT=/usr/local/ +export PYTHON_INCLUDE_DIR=$PYTHONROOT/include/python3.8 +export PYTHON_LIBRARIES=$PYTHONROOT/lib/libpython3.8.so +export PYTHON_EXECUTABLE=$PYTHONROOT/bin/python3.8 +``` ## 安装Python依赖 @@ -59,11 +79,11 @@ export PYTHONROOT=/usr/ pip install -r python/requirements.txt ``` -如果使用 Python3,请以 `pip3` 替换 `pip`。 +如果使用其他Python版本,请使用对应版本的`pip`。 ## GOPATH 设置 -默认 GOPATH 设置为 `$HOME/go`,您也可以设置为其他值。 +默认 GOPATH 设置为 `$HOME/go`,您也可以设置为其他值。** 如果是Serving提供的Docker环境,可以不需要设置。** ```shell export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin @@ -87,9 +107,9 @@ go get -u google.golang.org/grpc@v1.33.0 ``` shell mkdir server-build-cpu && cd server-build-cpu -cmake -DPYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ \ - -DPYTHON_LIBRARIES=$PYTHONROOT/lib/libpython2.7.so \ - -DPYTHON_EXECUTABLE=$PYTHONROOT/bin/python \ +cmake -DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR/ \ + -DPYTHON_LIBRARIES=$PYTHON_LIBRARIES \ + -DPYTHON_EXECUTABLE=$PYTHON_EXECUTABLE \ -DSERVER=ON .. make -j10 ``` @@ -97,44 +117,35 @@ make -j10 可以执行`make install`把目标产出放在`./output`目录下,cmake阶段需添加`-DCMAKE_INSTALL_PREFIX=./output`选项来指定存放路径。 ### 集成GPU版本Paddle Inference Library -### 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/cuda' -export CUDNN_LIBRARY='/usr/local/cuda/lib64/' -export CUDA_CUDART_LIBRARY="/usr/local/cuda/lib64/" -mkdir server-build-gpu && cd server-build-gpu -cmake -DPYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ \ - -DPYTHON_LIBRARIES=$PYTHONROOT/lib/libpython2.7.so \ - -DPYTHON_EXECUTABLE=$PYTHONROOT/bin/python \ - -DCUDA_TOOLKIT_ROOT_DIR=${CUDA_PATH} \ - -DCUDNN_LIBRARY=${CUDNN_LIBRARY} \ - -DCUDA_CUDART_LIBRARY=${CUDA_CUDART_LIBRARY} \ - -DSERVER=ON \ - -DWITH_GPU=ON .. -make -j10 -``` +相比CPU环境,GPU环境需要参考以下表格, +**需要说明的是,以下表格对非Docker编译环境作为参考,Docker编译环境已经配置好相关参数,无需在cmake过程指定。** -### 集成TensorRT版本Paddle Inference Library +| cmake环境变量 | 含义 | GPU环境注意事项 | Docker环境是否需要 | +|-----------------------|-------------------------------------|-------------------------------|--------------------| +| CUDA_TOOLKIT_ROOT_DIR | cuda安装路径,通常为/usr/local/cuda | 全部环境都需要 | 否(/usr/local/cuda) | +| CUDNN_LIBRARY | libcudnn.so.*所在目录,通常为/usr/local/cuda/lib64/ | 全部环境都需要 | 否(/usr/local/cuda/lib64/) | +| CUDA_CUDART_LIBRARY | libcudart.so.*所在目录,通常为/usr/local/cuda/lib64/ | 全部环境都需要 | 否(/usr/local/cuda/lib64/) | +| TENSORRT_ROOT | libnvinfer.so.*所在目录的上一级目录,取决于TensorRT安装目录 | Cuda 9.0/10.0不需要,其他需要 | 否(/usr) | -``` +非Docker环境下,用户可以参考如下执行方式,具体的路径以当时环境为准,代码仅作为参考。 + +``` shell 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/" -mkdir server-build-trt && cd server-build-trt -cmake -DPYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ \ - -DPYTHON_LIBRARIES=$PYTHONROOT/lib/libpython2.7.so \ - -DPYTHON_EXECUTABLE=$PYTHONROOT/bin/python \ - -DTENSORRT_ROOT=${TENSORRT_LIBRARY_PATH} \ +mkdir server-build-gpu && cd server-build-gpu +cmake -DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR \ + -DPYTHON_LIBRARIES=$PYTHON_LIBRARIES \ + -DPYTHON_EXECUTABLE=$PYTHON_EXECUTABLE \ -DCUDA_TOOLKIT_ROOT_DIR=${CUDA_PATH} \ -DCUDNN_LIBRARY=${CUDNN_LIBRARY} \ -DCUDA_CUDART_LIBRARY=${CUDA_CUDART_LIBRARY} \ + -DTENSORRT_ROOT=${TENSORRT_LIBRARY_PATH} -DSERVER=ON \ - -DWITH_GPU=ON \ - -DWITH_TRT=ON .. + -DWITH_GPU=ON .. make -j10 ``` @@ -146,9 +157,9 @@ make -j10 ``` shell mkdir client-build && cd client-build -cmake -DPYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ \ - -DPYTHON_LIBRARIES=$PYTHONROOT/lib/libpython2.7.so \ - -DPYTHON_EXECUTABLE=$PYTHONROOT/bin/python \ +cmake -DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR \ + -DPYTHON_LIBRARIES=$PYTHON_LIBRARIES \ + -DPYTHON_EXECUTABLE=$PYTHON_EXECUTABLE \ -DCLIENT=ON .. make -j10 ``` @@ -161,10 +172,9 @@ make -j10 ```bash mkdir app-build && cd app-build -cmake -DPYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ \ - -DPYTHON_LIBRARIES=$PYTHONROOT/lib/libpython2.7.so \ - -DPYTHON_EXECUTABLE=$PYTHONROOT/bin/python \ - -DCMAKE_INSTALL_PREFIX=./output \ +cmake -DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR \ + -DPYTHON_LIBRARIES=$PYTHON_LIBRARIES \ + -DPYTHON_EXECUTABLE=$PYTHON_EXECUTABLE \ -DAPP=ON .. make ``` @@ -183,7 +193,7 @@ make 运行python端Server时,会检查`SERVING_BIN`环境变量,如果想使用自己编译的二进制文件,请将设置该环境变量为对应二进制文件的路径,通常是`export SERVING_BIN=${BUILD_DIR}/core/general-server/serving`。 其中BUILD_DIR为server-build-cpu或server-build-gpu的绝对路径。 -可以cd server-build-cpu路径下,执行export SERVING_BIN=${PWD}/core/general-server/serving +可以cd server-build-cpu路径下,执行`export SERVING_BIN=${PWD}/core/general-server/serving` @@ -207,7 +217,6 @@ make | CLIENT | Compile Paddle Serving Client | OFF | | SERVER | Compile Paddle Serving Server | OFF | | APP | Compile Paddle Serving App package | OFF | -| WITH_ELASTIC_CTR | Compile ELASITC-CTR solution | OFF | | PACK | Compile for whl | OFF | ### WITH_GPU选项 @@ -226,13 +235,15 @@ Paddle Serving通过PaddlePaddle预测库支持在GPU上做预测。WITH_GPU选 1. 编译Serving所在的系统上所安装的CUDA/CUDNN等基础库版本,需要兼容实际的GPU设备。例如,Tesla V100卡至少要CUDA 9.0。如果编译时所用CUDA等基础库版本过低,由于生成的GPU代码和实际硬件设备不兼容,会导致Serving进程无法启动,或出现coredump等严重问题。 2. 运行Paddle Serving的系统上安装与实际GPU设备兼容的CUDA driver,并安装与编译期所用的CUDA/CuDNN等版本兼容的基础库。如运行Paddle Serving的系统上安装的CUDA/CuDNN的版本低于编译时所用版本,可能会导致奇怪的cuda函数调用失败等问题。 -以下是PaddlePaddle发布版本所使用的基础库版本匹配关系,供参考: +以下是PaddleServing 镜像的Cuda与Cudnn,TensorRT的匹配关系,供参考: -| | CUDA | CuDNN | TensorRT | -| :----: | :-----: | :----------------------: | :----: | -| post9 | 9.0 | CuDNN 7.3.1 for CUDA 9.0 | | -| post10 | 10.0 | CuDNN 7.5.1 for CUDA 10.0| | -| trt | 10.1 | CuDNN 7.5.1 for CUDA 10.1| 6.0.1.5 | +| | CUDA | CuDNN | TensorRT | +| :----: | :-----: | :----------: | :----: | +| post9 | 9.0 | CuDNN 7.6.4 | | +| post10 | 10.0 | CuDNN 7.6.5 | | +| post101 | 10.1 | CuDNN 7.6.5 | 6.0.1 | +| post102 | 10.2 | CuDNN 8.0.5 | 7.1.3 | +| post11 | 11.0 | CuDNN 8.0.4 | 7.1.3 | ### 如何让Paddle Serving编译系统探测到CuDNN库 diff --git a/doc/DESIGN_DOC.md b/doc/DESIGN_DOC.md index b8169b43b63c9f2548a29d454eb24f8577b755ef..d0c66a97946f700690097e1cb82d589476735edc 100644 --- a/doc/DESIGN_DOC.md +++ b/doc/DESIGN_DOC.md @@ -4,158 +4,93 @@ ## 1. Design Objectives -- Long Term Vision: Online deployment of deep learning models will be a user-facing application in the future. Any AI developer will face the problem of deploying an online service for his or her trained model. -Paddle Serving is the official open source online deployment framework. The long term goal of Paddle Serving is to provide professional, reliable and easy-to-use online service to the last mile of AI application. +Paddle Serving is the official open source online deployment framework. The long term goal of Paddle Serving is to provide professional, reliable and easy-to-use online service to the last mile of AI application. Online deployment of deep learning models will be a user-facing application in the future. Any AI developer will face the problem of deploying an online service for his or her trained model. -- Easy-To-Use: For algorithmic developers to quickly deploy their models online, Paddle Serving designs APIs that can be used with Paddle's training process seamlessly, most Paddle models can be deployed as a service with one line command. +- Industrial Oriented: To meet industrial deployment requirements, Paddle Serving supports lots of large-scale deployment functions: 1) Model management, model hot loading, model encryption and decryption. 2)Support cross-platform, multiple hardware deployment. 3) Distributed Sparse Embedding Indexing. 4) online A/B test + +- High Performance: Thinking about improving the performance of model inference from the two dimensions of low latency and high throughput. 1) High-performance prediction engine Paddle Inference is integrated. 2) Nvidia Tensor RT is supported. 3) High-performance network framework brpc is Integrated. 4) Asynchronous Pipeline mode greatly improves throughput. -- Industrial Oriented: To meet industrial deployment requirements, Paddle Serving supports lots of large-scale deployment functions: 1) Distributed Sparse Embedding Indexing. 2) Highly concurrent underlying communications. 3) Model Management, online A/B test, model online loading. +- Easy-To-Use: For algorithmic developers to quickly deploy their models online, Paddle Serving designs APIs that can be used with Paddle's training process seamlessly, most Paddle models can be deployed as a service with one line command. More than 20 common model cases and documents. -- Extensibility: Paddle Serving supports C++, Python and Golang client, and will support more clients with different languages. It is very easy to extend Paddle Serving to support other machine learning inference library, although currently Paddle inference library is the only official supported inference backend. +- Extensibility: Paddle Serving supports C++, Python, Golang, Java four client SDK, and will support more clients with different languages. It is very easy to extend Paddle Serving to support other machine learning inference library, although currently Paddle inference library is the only official supported inference backend. +---- -## 2. Module design and implementation +## 2. Preliminary Design +Any excellent software product must start from user needs, have clear positioning and good preliminary designs. Same goes for Paddle Serving, which aims to provide professional, reliable and easy-to-use online service to the last mile of AI application. By investigating the usage scenarios of a large number of users, and abstracting these scenarios, for example, online services focus on high concurrency and low response time; offline services focus on high batch throughput and high resource utilization; Algorithm developers are good at using Python for model training and inference. -### 2.1 Python API interface design +### 2.1 Design selection -#### 2.1.1 save a servable model -The inference phase of Paddle model focuses on 1) input variables of the model. 2) output variables of the model. 3) model structure and model parameters. Paddle Serving Python API provides a `save_model` interface for trained model, and save necessary information for Paddle Serving to use during deployment phase. An example is as follows: +In order to meet the needs of users in different scenarios, Paddle Serving's product positioning adopts lower-dimensional features, such as response time, throughput, development efficiency, etc., to achieve target selection and technology selection. -``` python -import paddle_serving_client.io as serving_io -serving_io.save_model("serving_model", "client_conf", - {"words": data}, {"prediction": prediction}, - fluid.default_main_program()) -``` -In the example, `{"words": data}` and `{"prediction": prediction}` assign the inputs and outputs of a model. `"words"` and `"prediction"` are alias names of inputs and outputs. The design of alias name is to help developers to memorize model inputs and model outputs. `data` and `prediction` are Paddle `[Variable](https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/Variable_cn.html#variable)` in training phase that often represents ([Tensor](https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/Tensor_cn.html#tensor)) or ([LodTensor](https://www.paddlepaddle.org.cn/documentation/docs/zh/beginners_guide/basic_concept/lod_tensor.html#lodtensor)). When the `save_model` API is called, two directories called `"serving_model"` and `"client_conf"` will be generated. The content of the saved model is as follows: - -``` shell -. -├── client_conf -│   ├── serving_client_conf.prototxt -│   └── serving_client_conf.stream.prototxt -└── serving_model - ├── embedding_0.w_0 - ├── fc_0.b_0 - ├── fc_0.w_0 - ├── fc_1.b_0 - ├── fc_1.w_0 - ├── fc_2.b_0 - ├── fc_2.w_0 - ├── lstm_0.b_0 - ├── lstm_0.w_0 - ├── __model__ - ├── serving_server_conf.prototxt - └── serving_server_conf.stream.prototxt -``` -`"serving_client_conf.prototxt"` and `"serving_server_conf.prototxt"` are the client side and the server side configurations of Paddle Serving, and `"serving_client_conf.stream.prototxt"` and `"serving_server_conf.stream.prototxt"` are the corresponding parts. Other contents saved in the directory are the same as Paddle saved inference model. We are considering to support `save_model` interface in Paddle training framework so that a user is not aware of the servable configurations. +| Response time | throughput | development efficiency | Resource utilization | selection | Applications| +|-----|------|-----|-----|------|------| +| LOW | HIGH | LOW | HIGH |C++ Serving | High-performance,recall and ranking services of large-scale online recommendation systems| +| HIGH | HIGH | HIGH | HIGH |Python Pipeline Serving| High-throughput, high-efficiency, asynchronous mode, fitting for single operator multi-model combination scenarios| +| HIGH | LOW | HIGH| LOW |Python webserver| High-throughput,Low-traffic services or projects that require rapid iteration, model effect verification| -#### 2.1.2 Model loading on the server side +Performance index description: +1. Response time (ms): Average response time of a single request, calculate the response time of 50, 90, 95, 99 quantiles, the lower the better. +2. Throughput(QPS/TPS): The efficiency of service processing requests, the number of requests processed per unit time, the higher the better. +3. Development efficiency: Using different development languages ​​to complete the same work takes different time, including the efficiency of development, debugging, and maintenance, the higher the better. +4. Resource utilization: Deploy a service to resource utilization (CPU/GPU), low resource utilization is a waste of resources, the higher the better. -Prediction logics on the server side can be defined through Paddle Serving Server API with a few lines of code, an example is as follows: -``` python -import paddle_serving_server as serving -op_maker = serving.OpMaker() -read_op = op_maker.create('general_reader') -dist_kv_op = op_maker.create('general_dist_kv') -general_infer_op = op_maker.create('general_infer') -general_response_op = op_maker.create('general_response') - -op_seq_maker = serving.OpSeqMaker() -op_seq_maker.add_op(read_op) -op_seq_maker.add_op(dist_kv_op) -op_seq_maker.add_op(general_infer_op) -op_seq_maker.add_op(general_response_op) -``` -Current Paddle Serving supports operator list on the server side as follows: - -
- -| Op Name | Description | -|--------------|------| -| `general_reader` | General Data Reading Operator | -| `genreal_infer` | General Data Inference with Paddle Operator | -| `general_response` | General Data Response Operator | -| `general_dist_kv` | Distributed Sparse Embedding Indexing | +Paddle Serving provides RPC and HTTP protocol for users. For HTTP service, we recommend users with median or small traffic services to use, and the latency is not a strict requirement. For RPC protocol, we recommend high traffic services and low latency required services to use. For users who use distributed sparse parameter indexing built-in service, it is not necessary to care about the underlying details of communication. The following figure gives out several scenarios that user may want to use Paddle Serving. -
+

+
+ +
+

-Paddle Serving supports inference engine on multiple devices. Current supports are CPU and GPU engine. Docker Images of CPU and GPU are provided officially. User can use one line command to start an inference service either on CPU or on GPU. +For servable models saved from Paddle Serving IO API, users do not need to do extra coding work to startup a service, but may need some coding work on the client side. For development of Web Service plugin, a user needs to provide implementation of Web Service's preprocessing and postprocessing work if needed to get a HTTP service. -``` shell -python -m paddle_serving_server.serve --model your_servable_model --thread 10 --port 9292 -``` -``` shell -python -m paddle_serving_server_gpu.serve --model your_servable_model --thread 10 --port 9292 -``` +### 2.2 Industrial Features -Options of startup command are listed below: -

+Paddle Serving takes into account a series of issues such as different operating systems, different development languages, multiple hardware devices, cross-deep learning platform model conversion, distributed sparse parameter indexing, and cloud deployment by different teams in industrial-level scenarios. -| Arguments | Types | Defaults | Descriptions | -|--------------|------|-----------|--------------------------------| -| `thread` | int | `4` | Concurrency on server side, usually equal to the number of CPU core | -| `port` | int | `9292` | Port exposed to users | -| `name` | str | `""` | Service name that if a user specifies, the name of HTTP service is allocated | -| `model` | str | `""` | Servable models for Paddle Serving | -| `gpu_ids` | str | `""` | Supported only in paddle_serving_server_gpu, similar to the usage of CUDA_VISIBLE_DEVICES | +> Cross-platform operation -
+Cross-platform is not dependent on the operating system, nor on the hardware environment. Applications developed under one operating system can still run under another operating system. Therefore, the design should consider not only the development language and the cross-platform components, but also the interpretation differences of the compilers on different systems. -For example, `python -m paddle_serving_server.serve --model your_servable_model --thread 10 --port 9292` is the same as the following code as user can define: -``` python -from paddle_serving_server import OpMaker, OpSeqMaker, Server - -op_maker = OpMaker() -read_op = op_maker.create('general_reader') -general_infer_op = op_maker.create('general_infer') -general_response_op = op_maker.create('general_response') -op_seq_maker = OpSeqMaker() -op_seq_maker.add_op(read_op) -op_seq_maker.add_op(general_infer_op) -op_seq_maker.add_op(general_response_op) -server = Server() -server.set_op_sequence(op_seq_maker.get_op_sequence()) -server.set_num_threads(10) -server.load_model_config(”your_servable_model“) -server.prepare_server(port=9292, device="cpu") -server.run_server() -``` +Docker is an open source application container engine that allows developers to package their applications and dependencies into a portable container, and then publish it to any popular Linux machine or Windows machine. We have packaged a variety of Docker images for the Paddle Serving framework. Refer to the image list《[Docker Images](DOCKER_IMAGES.md)》, Select mirrors according to user's usage. We provide Docker usage documentation《[How to run PaddleServing in Docker](RUN_IN_DOCKER.md)》.Currently, the Python webserver mode can be deployed and run on the native Linux and Windows dual systems.《[Paddle Serving for Windows Users](WINDOWS_TUTORIAL.md)》 -#### 2.1.3 Paddle Serving Client API -Paddle Serving supports remote service access through RPC(remote procedure call) and HTTP. RPC access of remote service can be called through Client API of Paddle Serving. A user can define data preprocess function before calling Paddle Serving's client API. The example below explains how to define the input data of Paddle Serving Client. The servable model has two inputs with alias name of `sparse` and `dense`. `sparse` corresponds to sparse sequence ids such as `[1, 1001, 100001]` and `dense` corresponds to dense vector such as `[0.2, 0.5, 0.1, 0.4, 0.11, 0.22]`. For sparse sequence data, current design supports `lod_level=0` and `lod_level=1` of Paddle, that corresponds to `Tensor` and `LodTensor`. For dense vector, current design supports any `N-D Tensor`. Users do not need to assign the shape of inference model input. The Paddle Serving Client API will check the input data's shape with servable configurations. +> Support multiple development languages client ​​SDKs -``` python -feed_dict["sparse"] = [1, 1001, 100001] -feed_dict["dense"] = [0.2, 0.5, 0.1, 0.4, 0.11, 0.22] -fetch_map = client.predict(feed=feed_dict, fetch=["prob"]) -``` +Paddle Serving provides 4 development language client SDKs, including Python, C++, Java, and Golang. Golang SDK is under construction, We hope that interested open source developers can help submit PR. -The following code sample shows that Paddle Serving Client API connects to Server API with endpoint of the servers. To use the data parallelism ability during prediction, Paddle Serving Client allows users to define multiple server endpoints. -``` python -client = Client() -client.load_client_config('servable_client_configs') -client.connect(["127.0.0.1:9292"]) -``` ++ Python, Refer to the client example under python/examples or 4.2 web service example. ++ C++, Refer to《[从零开始写一个预测服务](deprecated/CREATING.md)》 ++ Java, Refer to《[Paddle Serving Client Java SDK](JAVA_SDK.md)》 ++ Golang, Refer to《[How to use Go Client of Paddle Serving](deprecated/IMDB_GO_CLIENT.md)》 -### 2.2 Underlying Communication Mechanism -Paddle Serving adopts [baidu-rpc](https://github.com/apache/incubator-brpc) as underlying communication layer. baidu-rpc is an open-source RPC communication library with high concurrency and low latency advantages compared with other open source RPC library. Millions of instances and thousands of services are using baidu-rpc within Baidu. +> Support multiple hardware devices -### 2.3 Core Execution Engine -The core execution engine of Paddle Serving is a Directed acyclic graph(DAG). In the DAG, each node represents a phase of inference service, such as paddle inference prediction, data preprocessing and data postprocessing. DAG can fully parallelize the computation efficiency and can fully utilize the computation resources. For example, when a user has input data that needs to be feed into two models, and combine the scores of the two models, the computation of model scoring is parallelized through DAG. +The inference framework of the well-known deep learning platform only supports CPU and GPU inference on the X86 platform. With the rapid increase in the complexity of AI algorithms, the computing power of chips has greatly increased, which has promoted the accelerated implementation of IoT applications and deployment on a variety of hardware.Paddle Serving integrates high-performance inference engine Paddle Inference and mobile terminal inference engine Paddle Lite, Provide inference services on multiple hardware devices. At present, in addition to X86 CPU and GPU, Paddle Serving has implemented the deployment of inference services on ARM CPU and Kunlun XPU. In the future, more hardware will be added to Paddle Serving. -

-
- -
-

+> Model conversion across deep learning platforms -### 2.4 Micro service plugin -The underlying communication of Paddle Serving is implemented with C++ as well as the core framework, it is hard for users who do not familiar with C++ to implement new Paddle Serving Server Operators. Another approach is to use the light-weighted Web Service in Paddle Serving Server that can be viewed as a plugin. A user can implement complex data preprocessing and postprocessing logics to build a complex AI service. If access of the AI service has a large volumn, it is worth to implement the service with high performance Paddle Serving Server operators. The relationship between Web Service and RPC Service can be referenced in `User Type`. +Models trained on other deep learning platforms can be passed《[PaddlePaddle/X2Paddle工具](https://github.com/PaddlePaddle/X2Paddle)》.We convert multiple mainstream CV models to Paddle models. TensorFlow, Caffe, ONNX, PyTorch model conversion is tested.《[An End-to-end Tutorial from Training to Inference Service Deployment](TRAIN_TO_SERVICE.md)》 -## 3. Industrial Features +Because it is impossible to directly view the feed and fetch parameter information in the model file, it is not convenient for users to assemble the parameters. Therefore, Paddle Serving developed a tool to convert the Paddle model into Serving format and generate a prototxt file containing feed and fetch parameter information. The following figure is the generated prototxt file of the uci_housing example. For more conversion methods, refer to the document《[How to save a servable model of Paddle Serving?](SAVE.md)》. +``` +feed_var { + name: "x" + alias_name: "x" + is_lod_tensor: false + feed_type: 1 + shape: 13 +} +fetch_var { + name: "fc_0.tmp_1" + alias_name: "price" + is_lod_tensor: false + fetch_type: 1 + shape: 1 +} +``` -### 3.1 Distributed Sparse Parameter Indexing +> Distributed Sparse Parameter Indexing Distributed Sparse Parameter Indexing is commonly seen in advertising and recommendation scenarios, and is often used coupled with distributed training. The figure below explains a commonly seen architecture for online recommendation. When the recommendation service receives a request from a user, the system will automatically collects training log for the offline distributed online training. Mean while, the request is sent to Paddle Serving Server. For sparse features, distributed sparse parameter index service is called so that sparse parameters can be looked up. The dense input features together with the looked up sparse model parameters are fed into the Paddle Inference Node of the DAG in Paddle Serving Server. Then the score can be responsed through RPC to product service for item ranking. @@ -164,41 +99,56 @@ Distributed Sparse Parameter Indexing is commonly seen in advertising and recomm

+ Why do we need to support distributed sparse parameter indexing in Paddle Serving? 1) In some recommendation scenarios, the number of features can be up to hundreds of billions that a single node can not hold the parameters within random access memory. 2) Paddle Serving supports distributed sparse parameter indexing that can couple with paddle inference. Users do not need to do extra work to have a low latency inference engine with hundreds of billions of parameters. -### 3.2 Online A/B test +---- -After sufficient offline evaluation of the model, online A/B test is usually needed to decide whether to enable the service on a large scale. The following figure shows the basic structure of A/B test with Paddle Serving. After the client is configured with the corresponding configuration, the traffic will be automatically distributed to different servers to achieve A/B test. Please refer to [ABTEST in Paddle Serving](ABTEST_IN_PADDLE_SERVING.md) for specific examples. +## 3. C++ Serving design + +C++ Serving aims to achieve high-performance reasoning services with high concurrency and low latency. Its network framework and core execution engine are written based on C/C++, and provide powerful industrial-grade application capabilities, including model management, model security, and A/B Testing + +### 3.1 Network Communication Mechanism +Paddle Serving adopts [brpc](https://github.com/apache/incubator-brpc) as underlying communication layer. brpc is an open-source RPC communication library with high concurrency and low latency advantages compared with other open source RPC library. Millions of instances and thousands of services are using brpc within Baidu. + +### 3.2 Core Execution Engine +The core execution engine of Paddle Serving is a Directed acyclic graph(DAG). In the DAG, each node represents a phase of inference service, such as paddle inference prediction, data preprocessing and data postprocessing. DAG can fully parallelize the computation efficiency and can fully utilize the computation resources. For example, when a user has input data that needs to be feed into two models, and combine the scores of the two models, the computation of model scoring is parallelized through DAG.


- +

+### 3.3 Model Management and Hot Reloading +C++ Serving supports model management functions, including management of multiple models and multiple model versions.In order to ensure the availability of services, the model needs to be hot loaded without service interruption. Paddle Serving supports this feature and provides a tool for monitoring output models to update local models. Please refer to [Hot loading in Paddle Serving](HOT_LOADING_IN_SERVING.md) for specific examples. -### 3.3 Model Online Reloading +### 3.4 MOEDL ENCRYPTION INFERENCE +Paddle Serving uses a symmetric encryption algorithm to encrypt the model, and decrypts it in memory during the service loading model. At present, providing basic model security capabilities does not guarantee absolute model security. Users can improve them according to our design to achieve a higher level of security. Documentation reference《[MOEDL ENCRYPTION INFERENCE](ENCRYPTION.md)》 -In order to ensure the availability of services, the model needs to be hot loaded without service interruption. Paddle Serving supports this feature and provides a tool for monitoring output models to update local models. Please refer to [Hot loading in Paddle Serving](HOT_LOADING_IN_SERVING.md) for specific examples. +### 3.5 A/B Test -### 3.4 Model Management - -Paddle Serving's C++ engine supports model management. Currently, python API is not released yet, please wait for the next release. - -## 4. User Types -Paddle Serving provides RPC and HTTP protocol for users. For HTTP service, we recommend users with median or small traffic services to use, and the latency is not a strict requirement. For RPC protocol, we recommend high traffic services and low latency required services to use. For users who use distributed sparse parameter indexing built-in service, it is not necessary to care about the underlying details of communication. The following figure gives out several scenarios that user may want to use Paddle Serving. +After sufficient offline evaluation of the model, online A/B test is usually needed to decide whether to enable the service on a large scale. The following figure shows the basic structure of A/B test with Paddle Serving. After the client is configured with the corresponding configuration, the traffic will be automatically distributed to different servers to achieve A/B test. Please refer to [ABTEST in Paddle Serving](ABTEST_IN_PADDLE_SERVING.md) for specific examples.


- +

-For servable models saved from Paddle Serving IO API, users do not need to do extra coding work to startup a service, but may need some coding work on the client side. For development of Web Service plugin, a user needs to provide implementation of Web Service's preprocessing and postprocessing work if needed to get a HTTP service. +### 3.6 Micro service plugin +The underlying communication of Paddle Serving is implemented with C++ as well as the core framework, it is hard for users who do not familiar with C++ to implement new Paddle Serving Server Operators. Another approach is to use the light-weighted Web Service in Paddle Serving Server that can be viewed as a plugin. A user can implement complex data preprocessing and postprocessing logics to build a complex AI service. If access of the AI service has a large volumn, it is worth to implement the service with high performance Paddle Serving Server operators. The relationship between Web Service and RPC Service can be referenced in `User Type`. -### 4.1 Web Service Development +---- -Web Service has lots of open sourced framework. Currently Paddle Serving uses Flask as built-in service framework, and users are not aware of this. More efficient web service will be integrated in the furture if needed. +## 4. Python Webserver Design + +### 4.1 Network Communication Mechanism +There are many open source frameworks for web services. Paddle Serving currently integrates the Flask framework, but this part is not visible to users. In the future, a better-performing web framework may be provided as the underlying HTTP service integration engine. + +### 4.2 Web Service Development + +`WebService` is a Base Class, providing inheritable interfaces such `preprocess` and `postprocess` for users to implement. In the inherited class of `WebService` class, users can define any functions they want and the startup function interface is the same as RPC service. ``` python from paddle_serving_server.web_service import WebService @@ -229,15 +179,36 @@ imdb_service.prepare_dict({"dict_file_path": sys.argv[4]}) imdb_service.run_server() ``` -`WebService` is a Base Class, providing inheritable interfaces such `preprocess` and `postprocess` for users to implement. In the inherited class of `WebService` class, users can define any functions they want and the startup function interface is the same as RPC service. +---- + +## 5. Python Pipeline Serving Design +The end-to-end deep learning model is currently unable to solve all problems. The use of multiple deep learning models together is still a conventional means to solve real-world problems. +the end-to-end deep learning model can not solve all the problems at present. Usually, it is necessary to use multiple deep learning models to solve practical problems. + +### 5.1 Network Communication Mechanism +The network framework of Pipeline Serving uses gRPC and gPRC gateway. The gRPC service receives the RPC request, and the gPRC gateway receives the RESTful API request and forwards the request to the gRPC Service through the reverse proxy server. Therefore, the network layer of Pipeline Serving receives both RPC and RESTful API. +

+ +
+ +### 5.2 Core Design And Use Cases + +The core design of Pipeline Serving is a graph execution engine, and the basic processing units are OP and Channel. A set of directed acyclic graphs can be realized through combination. Reference for design and use documents《[Pipeline Serving](PIPELINE_SERVING.md)》 + +
+ +
-## 5. Future Plan +---- -### 5.1 Open DAG definition API -Current version of Paddle Serving Server supports sequential type of execution flow. DAG definition API can be more helpful to users on complex tasks. -### 5.2 Auto Deployment on Cloud +## 6. Future Plan + +### 5.1 Auto Deployment on Cloud In order to make deployment more easily on public cloud, Paddle Serving considers to provides Operators on Kubernetes in submitting a service job. -### 5.3 Vector Indexing and Tree based Indexing +### 6.2 Vector Indexing and Tree based Indexing In recommendation and advertisement systems, it is commonly seen to use vector based index or tree based indexing service to do candidate retrievals. These retrieval tasks will be built-in services of Paddle Serving. + +### 6.3 Service Monitoring +Paddle Serving will integrate Prometheus monitoring, which is a set of open source monitoring & alarm & time series database combination, suitable for k8s and docker monitoring systems. diff --git a/doc/DESIGN_DOC_CN.md b/doc/DESIGN_DOC_CN.md index 94a829f8d38b9f0f89a83d587aac1a0e7ad9eff3..a9159e932da1d372d13c46738da9cd1630ca67eb 100644 --- a/doc/DESIGN_DOC_CN.md +++ b/doc/DESIGN_DOC_CN.md @@ -6,28 +6,30 @@ Paddle Serving是一个PaddlePaddle开源的在线服务框架,长期目标就是围绕着人工智能落地的最后一公里提供越来越专业、可靠、易用的服务。 -- 工业级:为了达到工业级深度学习模型在线部署的要求, -Paddle Serving提供很多大规模场景需要的部署功能:1)模型管理、模型热加载、模型加解密。2)支持跨平台、多种硬件部署和推理。3)分布式稀疏参数索引功能。4)在线A/B流量测试 +- 工业级:为了达到工业级深度学习模型在线部署的要求,Paddle Serving提供很多大规模场景需要的部署功能:1)模型管理、模型热加载、模型加解密;2)支持跨平台、多种硬件部署;3)分布式稀疏参数索引功能;4)在线A/B流量测试 -- 高性能:从低延时和高吞吐2个维度思考提升模型推理的性能。1)集成Paddle Inference高性能预测引擎;2)支持Nvidia Tensor RT高性能推理引擎;3)高性能网络框架;4)异步Pipeline模式大幅提升吞吐量 +- 高性能:从低延时和高吞吐2个维度思考提升模型推理的性能。1)集成Paddle Inference高性能预测引擎;2)支持Nvidia Tensor RT高性能推理引擎;3)集成高性能网络框架brpc;4)异步Pipeline模式大幅提升吞吐量 - 简单易用:为了让使用Paddle的用户能够以极低的成本部署模型,PaddleServing设计了一套与Paddle训练框架无缝打通的预测部署API,普通模型可以使用一行命令进行服务部署。20多种常见模型案例和文档。 -- 功能扩展:当前,Paddle Serving支持C++、Python、Golang、Java 4种语言客户端,能力上也会持续加强。在Paddle Serving的框架设计方面,尽管当前Paddle Serving以支持Paddle模型的部署为核心功能, +- 功能扩展:当前,Paddle Serving支持C++、Python、Golang、Java 4种语言客户端,未来会支持更多语。在Paddle Serving的框架设计方面,尽管当前Paddle Serving以支持Paddle模型的部署为核心功能, 用户可以很容易嵌入其他的机器学习库部署在线预测。 ----- + +## 2. 概要设计 + +任何优秀软件产品一定从用户需求出发,具有清晰的定位和良好的概要设计。Paddle Serving也不例外,Paddle Serving目标围绕着人工智能落地的最后一公里提供越来越专业、可靠、易用的服务。通过调研大量用户的使用场景,并将这些场景抽象归纳,例如在线服务侧重高并发,低平响;离线服务侧重批量高吞吐,高资源利用率;算法开发者擅长使用Python做模型训练和推理等。 + ## 2. 整体设计 任何优秀产品一定从用户需求出发,具有清晰的定位和良好的设计。Paddle Serving也不例外,Paddle Serving目标围绕着人工智能落地的最后一公里提供越来越专业、可靠、易用的服务。通过调研大量用户的使用场景,并将这些场景抽象归纳,例如在线服务侧重高并发,低平响;离线服务侧重批量高吞吐,高资源利用率;算法开发同学擅长使用Python做模型训练和推理等。 - ### 2.1 设计选型 为了满足不同场景的用户需求,Paddle Serving的产品定位采用更低维度特征,如响应时间、吞吐、开发效率等,实现目标的选型和技术选型。 -| 响应时间 | 吞吐 | 开发效率 | 资源利用率 | 选型 | 类似场景| +| 响应时间 | 吞吐 | 开发效率 | 资源利用率 | 选型 | 应用场景| |-----|------|-----|-----|------|------| -| 低 | 高 | 低 | 高 |C++ Serving | 高性能场景,大型在线推荐系统召回、排序服务。支持批量推理| +| 低 | 高 | 低 | 高 |C++ Serving | 高性能场景,大型在线推荐系统召回、排序服务| | 高 | 高 | 较高 |高|Python Pipeline Serving| 兼顾吞吐和效率,单算子多模型组合场景,异步模式| | 高 | 低 | 高| 低 |Python webserver| 高迭代效率场景,小型服务或需要快速迭代,模型效果验证| @@ -55,20 +57,20 @@ Paddle Serving从做顶层设计时考虑到不同团队在工业级场景中会 > 跨平台运行 跨平台是不依赖于操作系统,也不依赖硬件环境。一个操作系统下开发的应用,放到另一个操作系统下依然可以运行。因此,设计上既要考虑开发语言、组件是跨平台的,同时也要考虑不同系统上编译器的解释差异。 -Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows机器上。我们将Paddle Serving框架打包了多种Docker镜像,镜像列表参考《[Docker镜像](DOCKER_IMAGES_CN.md)》,根据用户的使用场景选择。为方便用户使用Docker镜像,我们提供了帮助文档《[如何在Docker中运行PaddleServing](RUN_IN_DOCKER_CN.md)》。目前,Python webserver模式可在原生系统Linux和Windows双系统上部署运行。《[Windows平台使用Paddle Serving指导](WINDOWS_TUTORIAL_CN.md)》 + +Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows机器上。我们将Paddle Serving框架打包了多种Docker镜像,镜像列表参考《[Docker镜像](DOCKER_IMAGES_CN.md)》,根据用户的使用场景选择镜像。为方便用户使用Docker,我们提供了帮助文档《[如何在Docker中运行PaddleServing](RUN_IN_DOCKER_CN.md)》。目前,Python webserver模式可在原生系统Linux和Windows双系统上部署运行。《[Windows平台使用Paddle Serving指导](WINDOWS_TUTORIAL_CN.md)》 > 支持多种开发语言SDK -为了方便不同场景使用Serving,Paddle Serving提供了4种开发语言SDK,包括Python、C++、Java、Golang。Golang SDK在持续建设中,有兴趣的开源开发者可以提交PR。 -+ Python 参考python/examples下client示例 或 4.2 web服务示例 -+ C++使用文档 《[从零开始写一个预测服务](deprecated/CREATING.md)》 -+ Java使用文档 《[Paddle Serving Client Java SDK](JAVA_SDK_CN.md)》 -+ Golang示例文档 《[如何在Paddle Serving使用Go Client](IMDB_GO_CLIENT_CN.md)》 +Paddle Serving提供了4种开发语言SDK,包括Python、C++、Java、Golang。Golang SDK在建设中,有兴趣的开源开发者可以提交PR。 ++ Python,参考python/examples下client示例 或 4.2 web服务示例 ++ C++,参考《[从零开始写一个预测服务](deprecated/CREATING.md)》 ++ Java,参考《[Paddle Serving Client Java SDK](JAVA_SDK_CN.md)》 ++ Golang,参考《[如何在Paddle Serving使用Go Client](deprecated/IMDB_GO_CLIENT_CN.md)》 > 支持多种硬件设备 -主流深度学习平台的推理框架仅支持X86平台的CPU和GPU推理,随着AI算法复杂度高速增长,推动芯片算力不断提升,推动物联网应用加速落地,在多种硬件环境的推理场景越来越多。Paddle Serving集成高性能Paddle Inference和Paddle Lite,提供在多种硬件设备上推理服务。目前,除了X86 CPU、GPU外,Paddle Serving已实现ARM CPU和昆仑 XPU上部署推理服务,未来会有更多的硬件加入Paddle Serving。 - +知名的深度学习平台的推理框架仅支持X86平台的CPU和GPU推理。随着AI算法复杂度高速增长,芯片算力大幅提升,推动物联网应用加速落地,在多种硬件上部署。Paddle Serving集成高性能推理引擎Paddle Inference和移动端推理引擎Paddle Lite,在多种硬件设备上提供推理服务。目前,除了X86 CPU、GPU外,Paddle Serving已实现ARM CPU和昆仑 XPU上部署推理服务,未来会有更多的硬件加入Paddle Serving。 > 跨深度学习平台模型转换 @@ -105,18 +107,15 @@ fetch_var { 分布式稀疏参数索引通常在广告推荐中出现,并与分布式训练配合形成完整的离线-在线一体化部署。下图解释了其中的流程,产品的在线服务接受用户请求后将请求发送给预估服务,同时系统会记录用户的请求以进行相应的训练日志处理和拼接。离线分布式训练系统会针对流式产出的训练日志进行模型增量训练,而增量产生的模型会配送至分布式稀疏参数索引服务,同时对应的稠密的模型参数也会配送至在线的预估服务。在线服务由两部分组成,一部分是针对用户的请求提取特征后,将需要进行模型的稀疏参数索引的特征发送请求给分布式稀疏参数索引服务,针对分布式稀疏参数索引服务返回的稀疏参数再进行后续深度学习模型的计算流程,从而完成预估。 -> 云上部署 - -云端部署能力正在建设中,待开放 - ---- ## 3. C++ Serving设计 -C++ Serving目标实现高并发、低延时的高性能推理服务。其网络框架和核心执行引擎均是基于C/C++编写,并且提供一定的工业级应用能力,包括模型管理、模型安全、A/B Testing +C++ Serving目标实现高并发、低延时的高性能推理服务。其网络框架和核心执行引擎均是基于C/C++编写,并且提供强大的工业级应用能力,包括模型管理、模型安全、A/B Testing -### 3.1 网络框架 +### 3.1 通信机制 C++ Serving采用[better-rpc](https://github.com/apache/incubator-brpc)进行底层的通信。better-rpc是百度开源的一款PRC通信库,具有高并发、低延时等特点,已经支持了包括百度在内上百万在线预估实例、上千个在线预估服务,稳定可靠。与gRPC网络框架相比,具有更低的延时,更高的并发性能;缺点是跨操作系统平台、跨语言能力不足。 + ### 3.2 核心执行引擎 C++ Serving的核心执行引擎是一个有向无环图,图中的每个节点代表预估服务的一个环节,例如计算模型预测打分就是其中一个环节。有向无环图有利于可并发节点充分利用部署实例内的计算资源,缩短延时。一个例子,当同一份输入需要送入两个不同的模型进行预估,并将两个模型预估的打分进行加权求和时,两个模型的打分过程即可以通过有向无环图的拓扑关系并发。 @@ -128,7 +127,7 @@ C++ Serving的核心执行引擎是一个有向无环图,图中的每个节点 ### 3.3 模型管理与热加载 -addle Serving的C++引擎支持模型管理功能,支持多种模型和模型不同版本的管理。为了保证在模型更换期间推理服务的可用性,需要在服务不中断的情况下对模型进行热加载。Paddle Serving对该特性进行了支持,并提供了一个监控产出模型更新本地模型的工具,具体例子请参考《[Paddle Serving中的模型热加载](HOT_LOADING_IN_SERVING_CN.md)》。 +Paddle Serving的C++引擎支持模型管理功能,支持多种模型和模型不同版本的管理。为了保证在模型更换期间推理服务的可用性,需要在服务不中断的情况下对模型进行热加载。Paddle Serving对该特性进行了支持,并提供了一个监控产出模型更新本地模型的工具,具体例子请参考《[Paddle Serving中的模型热加载](HOT_LOADING_IN_SERVING_CN.md)》。 ### 3.4 模型加解密 @@ -136,6 +135,7 @@ Paddle Serving采用对称加密算法对模型进行加密,在服务加载模 ### 3.5 A/B Test + 在对模型进行充分的离线评估后,通常需要进行在线A/B测试,来决定是否大规模上线服务。下图为使用Paddle Serving做A/B测试的基本结构,Client端做好相应的配置后,自动将流量分发给不同的Server,从而完成A/B测试。具体例子请参考《[如何使用Paddle Serving做ABTEST](ABTEST_IN_PADDLE_SERVING_CN.md)》。

@@ -210,3 +210,6 @@ Pipeline Serving核心设计是图执行引擎,基本处理单元是OP和Chann ### 6.2 向量检索、树结构检索 在推荐与广告场景的召回系统中,通常需要采用基于向量的快速检索或者基于树结构的快速检索,Paddle Serving会对这方面的检索引擎进行集成或扩展。 + +### 6.3 服务监控 +集成普罗米修斯监控,一套开源的监控&报警&时间序列数据库的组合,适合k8s和docker的监控系统。 diff --git a/doc/DOCKER_IMAGES.md b/doc/DOCKER_IMAGES.md index 2de493fa6fcb20deb0601a2a338436785e605662..cf5023c18365bd1994f1192d6faae0c77f3c49db 100644 --- a/doc/DOCKER_IMAGES.md +++ b/doc/DOCKER_IMAGES.md @@ -8,11 +8,10 @@ This document maintains a list of docker images provided by Paddle Serving. You can get images in two ways: -1. Pull image directly from `hub.baidubce.com ` or `docker.io` through TAG: +1. Pull image directly from `registry.baidubce.com ` through TAG: ```shell - docker pull hub.baidubce.com/paddlepaddle/serving: # hub.baidubce.com - docker pull paddlepaddle/serving: # hub.docker.com + docker pull registry.baidubce.com/paddlepaddle/serving: # registry.baidubce.com ``` 2. Building image based on dockerfile @@ -20,7 +19,7 @@ You can get images in two ways: Create a new folder and copy Dockerfile to this folder, and run the following command: ```shell - docker build -t : . + docker build -f ${DOCKERFILE} -t : . ``` @@ -47,18 +46,54 @@ If you want to customize your Serving based on source code, use the version with **Java Client:** ``` -hub.baidubce.com/paddlepaddle/serving:latest-java +registry.baidubce.com/paddlepaddle/serving:latest-java ``` **XPU:** ``` -hub.baidubce.com/paddlepaddle/serving:xpu-beta +registry.baidubce.com/paddlepaddle/serving:xpu-beta ``` ## Requirements for running CUDA containers Running a CUDA container requires a machine with at least one CUDA-capable GPU and a driver compatible with the CUDA toolkit version you are using. -The machine running the CUDA container **only requires the NVIDIA driver**, the CUDA toolkit doesn't have to be installed. +The machine running the CUDA container **only requires the NVIDIA driver**, the CUDA toolkit does not have to be installed. For the relationship between CUDA toolkit version, Driver version and GPU architecture, please refer to [nvidia-docker wiki](https://github.com/NVIDIA/nvidia-docker/wiki/CUDA). + +# (Attachment) The List of All the Docker images + +Develop Images: + +| Env | Version | Docker images tag | OS | Gcc Version | +|----------|---------|------------------------------|-----------|-------------| +| CPU | 0.5.0 | 0.5.0-devel | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | 0.4.0-devel | CentOS 7 | 4.8.5 | +| Cuda9.0 | 0.5.0 | 0.5.0-cuda9.0-cudnn7-devel | Ubuntu 16 | 4.8.5 | +| | <=0.4.0 | 0.4.0-cuda9.0-cudnn7-devel | CentOS 7 | 4.8.5 | +| Cuda10.0 | 0.5.0 | 0.5.0-cuda10.0-cudnn7-devel | Ubuntu 16 | 4.8.5 | +| | <=0.4.0 | 0.4.0-cuda10.0-cudnn7-devel | CentOS 7 | 4.8.5 | +| Cuda10.1 | 0.5.0 | 0.5.0-cuda10.1-cudnn7-devel | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | 0.4.0-cuda10.1-cudnn7-devel | CentOS 7 | 4.8.5 | +| Cuda10.2 | 0.5.0 | 0.5.0-cuda10.2-cudnn8-devel | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | Nan | Nan | Nan | +| Cuda11.0 | 0.5.0 | 0.5.0-cuda11.0-cudnn8-devel | Ubuntu 18 | 8.2.0 | +| | <=0.4.0 | Nan | Nan | Nan | + +Running Images: + +| Env | Version | Docker images tag | OS | Gcc Version | +|----------|---------|-----------------------|-----------|-------------| +| CPU | 0.5.0 | 0.5.0 | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | 0.4.0 | CentOS 7 | 4.8.5 | +| Cuda9.0 | 0.5.0 | 0.5.0-cuda9.0-cudnn7 | Ubuntu 16 | 4.8.5 | +| | <=0.4.0 | 0.4.0-cuda9.0-cudnn7 | CentOS 7 | 4.8.5 | +| Cuda10.0 | 0.5.0 | 0.5.0-cuda10.0-cudnn7 | Ubuntu 16 | 4.8.5 | +| | <=0.4.0 | 0.4.0-cuda10.0-cudnn7 | CentOS 7 | 4.8.5 | +| Cuda10.1 | 0.5.0 | 0.5.0-cuda10.1-cudnn7 | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | 0.4.0-cuda10.1-cudnn7 | CentOS 7 | 4.8.5 | +| Cuda10.2 | 0.5.0 | 0.5.0-cuda10.2-cudnn8 | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | Nan | Nan | Nan | +| Cuda11.0 | 0.5.0 | 0.5.0-cuda11.0-cudnn8 | Ubuntu 18 | 8.2.0 | +| | <=0.4.0 | Nan | Nan | Nan | diff --git a/doc/DOCKER_IMAGES_CN.md b/doc/DOCKER_IMAGES_CN.md index 7180b3bea4e20380766ff0c49845d1d04685c43d..d84b6f8d2834480c7ab8228309fbe1e75a375d63 100644 --- a/doc/DOCKER_IMAGES_CN.md +++ b/doc/DOCKER_IMAGES_CN.md @@ -8,11 +8,10 @@ 您可以通过两种方式获取镜像。 -1. 通过 TAG 直接从 `hub.baidubce.com ` 或 `docker.io` 拉取镜像: +1. 通过 TAG 直接从 `registry.baidubce.com ` 或 拉取镜像,具体TAG请参见下文的**镜像说明**章节的表格。 ```shell - docker pull hub.baidubce.com/paddlepaddle/serving: # hub.baidubce.com - docker pull paddlepaddle/serving: # hub.docker.com + docker pull registry.baidubce.com/paddlepaddle/serving: # registry.baidubce.com ``` 2. 基于 Dockerfile 构建镜像 @@ -20,7 +19,8 @@ 建立新目录,复制对应 Dockerfile 内容到该目录下 Dockerfile 文件。执行 ```shell - docker build -t : . + cd tools + docker build -f ${DOCKERFILE} -t : . ``` @@ -29,6 +29,8 @@ 运行时镜像不能用于开发编译。 若需要基于源代码二次开发编译,请使用后缀为-devel的版本。 +**在TAG列,latest也可以替换成对应的版本号,例如0.5.0/0.4.1等,但需要注意的是,部分开发环境随着某个版本迭代才增加,因此并非所有环境都有对应的版本号可以使用。** + | 镜像选择 | 操作系统 | TAG | Dockerfile | | :----------------------------------------------------------: | :-----: | :--------------------------: | :----------------------------------------------------------: | @@ -47,14 +49,15 @@ **Java镜像:** ``` -hub.baidubce.com/paddlepaddle/serving:latest-java +registry.baidubce.com/paddlepaddle/serving:latest-java ``` **XPU镜像:** ``` -hub.baidubce.com/paddlepaddle/serving:xpu-beta +registry.baidubce.com/paddlepaddle/serving:xpu-beta ``` + ## 运行CUDA容器的要求 运行CUDA容器需要至少具有一个支持CUDA的GPU以及与您所使用的CUDA工具包版本兼容的驱动程序。 @@ -62,3 +65,40 @@ hub.baidubce.com/paddlepaddle/serving:xpu-beta 运行CUDA容器的机器**只需要相应的NVIDIA驱动程序**,而CUDA工具包不是必要的。 相关CUDA工具包版本、驱动版本和GPU架构的关系请参阅 [nvidia-docker wiki](https://github.com/NVIDIA/nvidia-docker/wiki/CUDA)。 + +# (附录)所有镜像列表 + +编译镜像: + +| Env | Version | Docker images tag | OS | Gcc Version | +|----------|---------|------------------------------|-----------|-------------| +| CPU | 0.5.0 | 0.5.0-devel | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | 0.4.0-devel | CentOS 7 | 4.8.5 | +| Cuda9.0 | 0.5.0 | 0.5.0-cuda9.0-cudnn7-devel | Ubuntu 16 | 4.8.5 | +| | <=0.4.0 | 0.4.0-cuda9.0-cudnn7-devel | CentOS 7 | 4.8.5 | +| Cuda10.0 | 0.5.0 | 0.5.0-cuda10.0-cudnn7-devel | Ubuntu 16 | 4.8.5 | +| | <=0.4.0 | 0.4.0-cuda10.0-cudnn7-devel | CentOS 7 | 4.8.5 | +| Cuda10.1 | 0.5.0 | 0.5.0-cuda10.1-cudnn7-devel | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | 0.4.0-cuda10.1-cudnn7-devel | CentOS 7 | 4.8.5 | +| Cuda10.2 | 0.5.0 | 0.5.0-cuda10.2-cudnn8-devel | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | Nan | Nan | Nan | +| Cuda11.0 | 0.5.0 | 0.5.0-cuda11.0-cudnn8-devel | Ubuntu 18 | 8.2.0 | +| | <=0.4.0 | Nan | Nan | Nan | + +运行镜像: + +| Env | Version | Docker images tag | OS | Gcc Version | +|----------|---------|-----------------------|-----------|-------------| +| CPU | 0.5.0 | 0.5.0 | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | 0.4.0 | CentOS 7 | 4.8.5 | +| Cuda9.0 | 0.5.0 | 0.5.0-cuda9.0-cudnn7 | Ubuntu 16 | 4.8.5 | +| | <=0.4.0 | 0.4.0-cuda9.0-cudnn7 | CentOS 7 | 4.8.5 | +| Cuda10.0 | 0.5.0 | 0.5.0-cuda10.0-cudnn7 | Ubuntu 16 | 4.8.5 | +| | <=0.4.0 | 0.4.0-cuda10.0-cudnn7 | CentOS 7 | 4.8.5 | +| Cuda10.1 | 0.5.0 | 0.5.0-cuda10.1-cudnn7 | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | 0.4.0-cuda10.1-cudnn7 | CentOS 7 | 4.8.5 | +| Cuda10.2 | 0.5.0 | 0.5.0-cuda10.2-cudnn8 | Ubuntu 16 | 8.2.0 | +| | <=0.4.0 | Nan | Nan | Nan | +| Cuda11.0 | 0.5.0 | 0.5.0-cuda11.0-cudnn8 | Ubuntu 18 | 8.2.0 | +| | <=0.4.0 | Nan | Nan | Nan | + diff --git a/doc/ENCRYPTION.md b/doc/ENCRYPTION.md index 1e6a53aa386bf672d5f87647cb1682531ea3d62c..b3639bbc6572623f4f0b7af28f44effd665d9f4e 100644 --- a/doc/ENCRYPTION.md +++ b/doc/ENCRYPTION.md @@ -42,11 +42,3 @@ Once the server gets the key, it uses the key to parse the model and starts the ### Example of Model Encryption Inference Example of model encryption inference, See the [`/python/examples/encryption/`](../python/examples/encryption/)。 - -### Other Details -Interface of encryption method in paddlepaddle official website: - -[Python encryption method](https://github.com/HexToString/Serving/blob/develop/python/paddle_serving_app/local_predict.py) - -[C++ encryption method](https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/python_infer_cn.html#analysispre) - diff --git a/doc/ENCRYPTION_CN.md b/doc/ENCRYPTION_CN.md index 5ca304d00d198ba2c6df1c7cfbff7315ba46fe15..87452ea365f2cf3b05a0b356a3e709f882568b88 100644 --- a/doc/ENCRYPTION_CN.md +++ b/doc/ENCRYPTION_CN.md @@ -42,11 +42,3 @@ python -m paddle_serving_server_gpu.serve --model encrypt_server/ --port 9300 -- ### 模型加密推理示例 模型加密推理示例, 请参见[`/python/examples/encryption/`](../python/examples/encryption/)。 - -### 其他详细信息 -飞桨官方网站加密方法接口 - -[Python加密方法接口](https://github.com/HexToString/Serving/blob/develop/python/paddle_serving_app/local_predict.py) - -[C++加密方法接口](https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/python_infer_cn.html#analysispre) - diff --git a/doc/GRPC_IMPL_CN.md b/doc/GRPC_IMPL_CN.md index 7cfa9d86f7c92d0f33f2984c116993544159f7e8..bac9caf7340515212d975ba8721475ed6bfa4cad 100644 --- a/doc/GRPC_IMPL_CN.md +++ b/doc/GRPC_IMPL_CN.md @@ -115,24 +115,12 @@ python test_asyn_client.py python test_batch_client.py ``` -#### 通用 pb 预测 - -``` shell -python test_general_pb_client.py -``` - #### 预测超时 ``` shell python test_timeout_client.py ``` -#### List 输入 - -``` shell -python test_list_input_client.py -``` - ## 3.更多示例 详见[`python/examples/grpc_impl_example`](../python/examples/grpc_impl_example)下的示例文件。 diff --git a/doc/JAVA_SDK.md b/doc/JAVA_SDK.md index 01da7156a6d1a803bd06171664fe9e2c4e977d83..cb1d60bc6a16ebf1d8621b2b4fd650271ca6ab87 100644 --- a/doc/JAVA_SDK.md +++ b/doc/JAVA_SDK.md @@ -18,7 +18,7 @@ The following table shows compatibilities between Paddle Serving Server and Java | Paddle Serving Server version | Java SDK version | | :---------------------------: | :--------------: | -| 0.3.2 | 0.0.1 | +| 0.5.0 | 0.0.1 | 1. Directly use the provided Java SDK as the client for prediction ### Install Java SDK diff --git a/doc/JAVA_SDK_CN.md b/doc/JAVA_SDK_CN.md index 7033b96078e1143567ccb19f14b80fc2b126a45d..333a29a67f1664db608803781babeb1b91435de0 100644 --- a/doc/JAVA_SDK_CN.md +++ b/doc/JAVA_SDK_CN.md @@ -17,7 +17,7 @@ Paddle Serving 提供了 Java SDK,支持 Client 端用 Java 语言进行预测 | Paddle Serving Server version | Java SDK version | | :---------------------------: | :--------------: | -| 0.3.2 | 0.0.1 | +| 0.5.0 | 0.0.1 | 1. 直接使用提供的Java SDK作为Client进行预测 ### 安装 diff --git a/doc/LATEST_PACKAGES.md b/doc/LATEST_PACKAGES.md index 1ce1e2c569b3864b0bdc6f84629de7e6e99df584..d21a102f661865cd51675ac54277cd89d0397534 100644 --- a/doc/LATEST_PACKAGES.md +++ b/doc/LATEST_PACKAGES.md @@ -87,3 +87,34 @@ https://paddle-serving.bj.bcebos.com/whl/xpu/paddle_serving_client-0.0.0-cp36-no # App https://paddle-serving.bj.bcebos.com/whl/xpu/paddle_serving_app-0.0.0-py3-none-any.whl ``` + + +### Binary Package +for most users, we do not need to read this section. But if you deploy your Paddle Serving on a machine without network, you will encounter a problem that the binary executable tar file cannot be downloaded. Therefore, here we give you all the download links for various environment. + +#### Bin links +``` +# CPU AVX MKL +https://paddle-serving.bj.bcebos.com/bin/serving-cpu-avx-mkl-0.0.0.tar.gz +# CPU AVX OPENBLAS +https://paddle-serving.bj.bcebos.com/bin/serving-cpu-avx-openblas-0.0.0.tar.gz +# CPU NOAVX OPENBLAS +https://paddle-serving.bj.bcebos.com/bin/serving-cpu-noavx-openblas-0.0.0.tar.gz +# Cuda 9 +https://paddle-serving.bj.bcebos.com/bin/serving-gpu-cuda9-0.0.0.tar.gz +# Cuda 10 +https://paddle-serving.bj.bcebos.com/bin/serving-gpu-cuda10-0.0.0.tar.gz +# Cuda 10.1 +https://paddle-serving.bj.bcebos.com/bin/serving-gpu-101-0.0.0.tar.gz +# Cuda 10.2 +https://paddle-serving.bj.bcebos.com/bin/serving-gpu-102-0.0.0.tar.gz +# Cuda 11 +https://paddle-serving.bj.bcebos.com/bin/serving-gpu-cuda11-0.0.0.tar.gz +``` + +#### How to setup SERVING_BIN offline? + +- download the serving server whl package and bin package, and make sure they are for the same environment +- download the serving client whl and serving app whl, pay attention to the Python version. +- `pip install ` the serving and `tar xf ` the binary package, then `export SERVING_BIN=$PWD/serving-gpu-cuda10-0.0.0/serving` (take Cuda 10.0 as the example) + diff --git a/doc/MULTI_SERVICE_ON_ONE_GPU_CN.md b/doc/MULTI_SERVICE_ON_ONE_GPU_CN.md index 3abe12100123a139e9ce56c7ff20035cdb1cbeeb..7554e6658e1fdc4b7bd6eb7f110b0d67c118e254 100644 --- a/doc/MULTI_SERVICE_ON_ONE_GPU_CN.md +++ b/doc/MULTI_SERVICE_ON_ONE_GPU_CN.md @@ -5,7 +5,7 @@ 例如: ```shell -python -m paddle_serving_server_gpu.serve --model bert_seq20_model --port 9292 --gpu_ids 0 +python -m paddle_serving_server_gpu.serve --model bert_seq128_model --port 9292 --gpu_ids 0 python -m paddle_serving_server_gpu.serve --model ResNet50_vd_model --port 9393 --gpu_ids 0 ``` diff --git a/doc/RUN_IN_DOCKER.md b/doc/RUN_IN_DOCKER.md index caffcf3b8ea5fec820c02f1ed5e02b45c4417d93..debe08a96b9512759473022c094d9115b24805fa 100644 --- a/doc/RUN_IN_DOCKER.md +++ b/doc/RUN_IN_DOCKER.md @@ -17,14 +17,14 @@ This document takes Python2 as an example to show how to run Paddle Serving in d Refer to [this document](DOCKER_IMAGES.md) for a docker image: ```shell -docker pull hub.baidubce.com/paddlepaddle/serving:latest +docker pull registry.baidubce.com/paddlepaddle/serving:latest-devel ``` ### Create container ```bash -docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:latest +docker run -p 9292:9292 --name test -dit registry.baidubce.com/paddlepaddle/serving:latest-devel docker exec -it test bash ``` @@ -46,20 +46,20 @@ The GPU version is basically the same as the CPU version, with only some differe Refer to [this document](DOCKER_IMAGES.md) for a docker image, the following is an example of an `cuda9.0-cudnn7` image: ```shell -docker pull hub.baidubce.com/paddlepaddle/serving:latest-cuda9.0-cudnn7 +docker pull registry.baidubce.com/paddlepaddle/serving:latest-cuda10.2-cudnn8-devel ``` ### Create container ```bash -nvidia-docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:latest-cuda9.0-cudnn7 +nvidia-docker run -p 9292:9292 --name test -dit registry.baidubce.com/paddlepaddle/serving:latest-cuda10.2-cudnn8-devel nvidia-docker exec -it test bash ``` or ```bash -docker run --gpus all -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:latest-cuda9.0-cudnn7 +docker run --gpus all -p 9292:9292 --name test -dit registry.baidubce.com/paddlepaddle/serving:latest-cuda10.2-cudnn8-devel docker exec -it test bash ``` @@ -69,7 +69,7 @@ The `-p` option is to map the `9292` port of the container to the `9292` port of The mirror comes with `paddle_serving_server_gpu`, `paddle_serving_client`, and `paddle_serving_app` corresponding to the mirror tag version. If users don’t need to change the version, they can use it directly, which is suitable for environments without extranet services. -If you need to change the version, please refer to the instructions on the homepage to download the pip package of the corresponding version. +If you need to change the version, please refer to the instructions on the homepage to download the pip package of the corresponding version. [LATEST_PACKAGES](./LATEST_PACKAGES.md) ## Precautious diff --git a/doc/RUN_IN_DOCKER_CN.md b/doc/RUN_IN_DOCKER_CN.md index 6fe4147bfb4e68fcb014e32c2a5bf0c3c4a927e7..7dfc3eee62b3bf8f6d925b97e3d7da3fd51ad423 100644 --- a/doc/RUN_IN_DOCKER_CN.md +++ b/doc/RUN_IN_DOCKER_CN.md @@ -16,14 +16,16 @@ Docker(GPU版本需要在GPU机器上安装nvidia-docker) 参考[该文档](DOCKER_IMAGES_CN.md)获取镜像: +以CPU编译镜像为例 + ```shell -docker pull hub.baidubce.com/paddlepaddle/serving:latest +docker pull registry.baidubce.com/paddlepaddle/serving:latest-devel ``` ### 创建容器并进入 ```bash -docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:latest +docker run -p 9292:9292 --name test -dit registry.baidubce.com/paddlepaddle/serving:latest-devel docker exec -it test bash ``` @@ -37,15 +39,19 @@ docker exec -it test bash ## GPU 版本 +```shell +docker pull registry.baidubce.com/paddlepaddle/serving:latest-cuda10.2-cudnn8-devel +``` + ### 创建容器并进入 ```bash -nvidia-docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:latest-cuda9.0-cudnn7 +nvidia-docker run -p 9292:9292 --name test -dit registry.baidubce.com/paddlepaddle/serving:latest-cuda10.2-cudnn8-devel nvidia-docker exec -it test bash ``` 或者 ```bash -docker run --gpus all -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:latest-cuda9.0-cudnn7 +docker run --gpus all -p 9292:9292 --name test -dit registry.baidubce.com/paddlepaddle/serving:latest-cuda10.2-cudnn8-devel docker exec -it test bash ``` @@ -55,7 +61,7 @@ docker exec -it test bash 镜像里自带对应镜像tag版本的`paddle_serving_server_gpu`,`paddle_serving_client`,`paddle_serving_app`,如果用户不需要更改版本,可以直接使用,适用于没有外网服务的环境。 -如果需要更换版本,请参照首页的指导,下载对应版本的pip包。 +如果需要更换版本,请参照首页的指导,下载对应版本的pip包。[最新安装包合集](LATEST_PACKAGES.md) ## 注意事项 diff --git a/doc/SAVE.md b/doc/SAVE.md index 8a909dc98d60579cd2861f5cdf38619264bae2fa..32562fa55af253bdaa6328c9bd02f5d54328161b 100644 --- a/doc/SAVE.md +++ b/doc/SAVE.md @@ -2,7 +2,74 @@ ([简体中文](./SAVE_CN.md)|English) -## Save from training or prediction script +## Export from saved model files + +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 +``` + +If you have saved model files using Paddle's `save_inference_model` API, you can use Paddle Serving's` inference_model_to_serving` API to convert it into a model file that can be used for Paddle Serving. +```python +import paddle_serving_client.io as serving_io +serving_io.inference_model_to_serving(dirname, serving_server="serving_server", serving_client="serving_client", model_filename=None, params_filename=None ) +``` +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. | + +**Demo: Convert From Dynamic Graph** + +PaddlePaddle 2.0 provides a new dynamic graph mode, so here we use imagenet ResNet50 dynamic graph as an example to teach how to export from a saved model and use it for real online inference scenarios. + +``` +wget https://paddle-serving.bj.bcebos.com/others/dygraph_res50.tar #模型 +wget https://paddle-serving.bj.bcebos.com/imagenet-example/daisy.jpg #示例输入(向日葵) +tar xf dygraph_res50.tar +python -m paddle_serving_client.convert --dirname . --model_filename dygraph_model.pdmodel --params_filename dygraph_model.pdiparams --serving_server serving_server --serving_client serving_client``` + +We can see that the `serving_server` and `serving_client` folders hold the server and client configuration of the model respectively + +Start the server (GPU) + +``` +python -m paddle_serving_server_gpu.serve --model serving_server --port 9393 --gpu_id 0 +``` + +Client (`test_client.py`) +``` +from paddle_serving_client import Client +from paddle_serving_app.reader import Sequential, File2Image, Resize, CenterCrop +from paddle_serving_app.reader import RGB2BGR, Transpose, Div, Normalize + +client = Client() +client.load_client_config( + "serving_client/serving_client_conf.prototxt") +client.connect(["127.0.0.1:9393"]) + +seq = Sequential([ + File2Image(), Resize(256), CenterCrop(224), RGB2BGR(), Transpose((2, 0, 1)), + Div(255), Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225], True) +]) + +image_file = "daisy.jpg" +img = seq(image_file) +fetch_map = client.predict(feed={"inputs": img}, fetch=["save_infer_model/scale_0.tmp_0"]) +print(fetch_map["save_infer_model/scale_0.tmp_0"].reshape(-1)) +``` +Run +``` +python test_client.py +``` + +You can see that the prediction has been successfully executed. The above is the content predicted by the dynamic graph ResNet50 model on Serving. The use of other dynamic graph models is similar. + +## Save from training or prediction script (Static Graph Mode) Currently, paddle serving provides a save_model interface for users to access, the interface is similar with `save_inference_model` of Paddle. ``` python import paddle_serving_client.io as serving_io @@ -31,22 +98,3 @@ for line in sys.stdin: fetch_map = client.predict(feed=feed, fetch=fetch) print("{} {}".format(fetch_map["prediction"][1], label[0])) ``` - -## Export from saved model files -If you have saved model files using Paddle's `save_inference_model` API, you can use Paddle Serving's` inference_model_to_serving` API to convert it into a model file that can be used for Paddle Serving. -```python -import paddle_serving_client.io as serving_io -serving_io.inference_model_to_serving(dirname, serving_server="serving_server", serving_client="serving_client", model_filename=None, params_filename=None ) -``` -Or 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/SAVE_CN.md b/doc/SAVE_CN.md index 3ede0471ab640a670fd5beb4ada68e0385b4c85b..1bb3df108275c2587ffc0979beca89d4d0ada4ea 100644 --- a/doc/SAVE_CN.md +++ b/doc/SAVE_CN.md @@ -2,14 +2,79 @@ (简体中文|[English](./SAVE.md)) -## 从训练或预测脚本中保存 +## 从已保存的模型文件中导出 +如果已使用Paddle 的`save_inference_model`接口保存出预测要使用的模型,你可以使用Paddle Serving提供的名为`paddle_serving_client.convert`的内置模块进行转换。 +```python +python -m paddle_serving_client.convert --dirname ./your_inference_model_dir +``` + +也可以通过Paddle Serving的`inference_model_to_serving`接口转换成可用于Paddle Serving的模型文件。 +```python +import paddle_serving_client.io as serving_io +serving_io.inference_model_to_serving(dirname, serving_server="serving_server", serving_client="serving_client", model_filename=None, params_filename=None) +``` + +模块参数与`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 | + +**示例:从动态图模型中导出** + +PaddlePaddle 2.0提供了全新的动态图模式,因此我们这里以imagenet ResNet50动态图为示例教学如何从已保存模型导出,并用于真实的在线预测场景。 + +``` +wget https://paddle-serving.bj.bcebos.com/others/dygraph_res50.tar #模型 +wget https://paddle-serving.bj.bcebos.com/imagenet-example/daisy.jpg #示例输入(向日葵) +tar xf dygraph_res50.tar +python -m paddle_serving_client.convert --dirname . --model_filename dygraph_model.pdmodel --params_filename dygraph_model.pdiparams --serving_server serving_server --serving_client serving_client +``` +我们可以看到`serving_server`和`serving_client`文件夹分别保存着模型的服务端和客户端配置 + +启动服务端(GPU) +``` +python -m paddle_serving_server_gpu.serve --model serving_server --port 9393 --gpu_id 0 +``` + +客户端写法,保存为`test_client.py` +``` +from paddle_serving_client import Client +from paddle_serving_app.reader import Sequential, File2Image, Resize, CenterCrop +from paddle_serving_app.reader import RGB2BGR, Transpose, Div, Normalize + +client = Client() +client.load_client_config( + "serving_client/serving_client_conf.prototxt") +client.connect(["127.0.0.1:9393"]) + +seq = Sequential([ + File2Image(), Resize(256), CenterCrop(224), RGB2BGR(), Transpose((2, 0, 1)), + Div(255), Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225], True) +]) + +image_file = "daisy.jpg" +img = seq(image_file) +fetch_map = client.predict(feed={"inputs": img}, fetch=["save_infer_model/scale_0.tmp_0"]) +print(fetch_map["save_infer_model/scale_0.tmp_0"].reshape(-1)) +``` +执行 +``` +python test_client.py +``` +即可看到成功的执行了预测,以上就是动态图ResNet50模型在Serving上预测的内容,其他动态图模型使用方式与之类似。 + +## 从训练或预测脚本中保存(静态图) 目前,Paddle Serving提供了一个save_model接口供用户访问,该接口与Paddle的`save_inference_model`类似。 ``` python import paddle_serving_client.io as serving_io serving_io.save_model("imdb_model", "imdb_client_conf", {"words": data}, {"prediction": prediction}, - fluid.default_main_program()) + paddle.static.default_main_program()) ``` imdb_model是具有服务配置的服务器端模型。 imdb_client_conf是客户端rpc配置。 @@ -32,22 +97,3 @@ for line in sys.stdin: fetch_map = client.predict(feed=feed, fetch=fetch) print("{} {}".format(fetch_map["prediction"][1], label[0])) ``` - -## 从已保存的模型文件中导出 -如果已使用Paddle 的`save_inference_model`接口保存出预测要使用的模型,则可以通过Paddle Serving的`inference_model_to_serving`接口转换成可用于Paddle Serving的模型文件。 -```python -import paddle_serving_client.io as serving_io -serving_io.inference_model_to_serving(dirname, serving_server="serving_server", serving_client="serving_client", model_filename=None, params_filename=None) -``` -或者你可以使用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/TRAIN_TO_SERVICE.md b/doc/TRAIN_TO_SERVICE.md deleted file mode 100644 index 90046b03ebc4af1394fb85fb41fccf1d844f6917..0000000000000000000000000000000000000000 --- a/doc/TRAIN_TO_SERVICE.md +++ /dev/null @@ -1,361 +0,0 @@ -# An End-to-end Tutorial from Training to Inference Service Deployment - -([简体中文](./TRAIN_TO_SERVICE_CN.md)|English) - -Paddle Serving is Paddle's high-performance online inference service framework, which can flexibly support the deployment of most models. In this article, the IMDB review sentiment analysis task is used as an example to show the entire process from model training to deployment of inference service through 9 steps. - -## Step1:Prepare for Running Environment -Paddle Serving can be deployed on Linux environments.Currently the server supports deployment on Centos7. [Docker deployment is recommended](RUN_IN_DOCKER.md). The rpc client supports deploymen on Centos7 and Ubuntu 18.On other systems or in environments where you do not want to install the serving module, you can still access the server-side prediction service through the http service. - -You can choose to install the cpu or gpu version of the server module according to the requirements and machine environment, and install the client module on the client machine. When you want to access the server with http, there is not need to install client module. - -```shell -pip install paddle_serving_server #cpu version server side -pip install paddle_serving_server_gpu #gpu version server side -pip install paddle_serving_client #client version -``` - -After simple preparation, we will take the IMDB review sentiment analysis task as an example to show the process from model training to deployment of prediction services. All the code in the example can be found in the [IMDB example](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/imdb) of the Paddle Serving code base, the data and dictionary used in the example The file can be obtained by executing the get_data.sh script in the IMDB sample code. - -## Step2:Determine Tasks and Raw Data Format - -IMDB review sentiment analysis task is to classify the content of movie reviews to determine whether the review is a positive review or a negative review. - -First let's take a look at the raw data: -``` -saw a trailer for this on another video, and decided to rent when it came out. boy, was i disappointed! the story is extremely boring, the acting (aside from christopher walken) is bad, and i couldn't care less about the characters, aside from really wanting to see nora's husband get thrashed. christopher walken's role is such a throw-away, what a tease! | 0 -``` - -This is a sample of English comments. The sample uses | as the separator. The content of the comment is before the separator. The label is the sample after the separator. 0 is the negative while 1 is the positive. - -## Step3:Define Reader, divide training set and test set - -For the original text we need to convert it to a numeric id that the neural network can use. The imdb_reader.py script defines the method of text idization, and the words are mapped to integers through the dictionary file imdb.vocab. - -

- imdb_reader.py - -```python -import sys -import os -import paddle -import re -import paddle.fluid.incubate.data_generator as dg - - -class IMDBDataset(dg.MultiSlotDataGenerator): - def load_resource(self, dictfile): - self._vocab = {} - wid = 0 - with open(dictfile) as f: - for line in f: - self._vocab[line.strip()] = wid - wid += 1 - self._unk_id = len(self._vocab) - self._pattern = re.compile(r'(;|,|\.|\?|!|\s|\(|\))') - self.return_value = ("words", [1, 2, 3, 4, 5, 6]), ("label", [0]) - - def get_words_only(self, line): - sent = line.lower().replace("
", " ").strip() - words = [x for x in self._pattern.split(sent) if x and x != " "] - feas = [ - self._vocab[x] if x in self._vocab else self._unk_id for x in words - ] - return feas - - def get_words_and_label(self, line): - send = '|'.join(line.split('|')[:-1]).lower().replace("
", - " ").strip() - label = [int(line.split('|')[-1])] - - words = [x for x in self._pattern.split(send) if x and x != " "] - feas = [ - self._vocab[x] if x in self._vocab else self._unk_id for x in words - ] - return feas, label - - def infer_reader(self, infer_filelist, batch, buf_size): - def local_iter(): - for fname in infer_filelist: - with open(fname, "r") as fin: - for line in fin: - feas, label = self.get_words_and_label(line) - yield feas, label - - import paddle - batch_iter = paddle.batch( - paddle.reader.shuffle( - local_iter, buf_size=buf_size), - batch_size=batch) - return batch_iter - - def generate_sample(self, line): - def memory_iter(): - for i in range(1000): - yield self.return_value - - def data_iter(): - feas, label = self.get_words_and_label(line) - yield ("words", feas), ("label", label) - - return data_iter -``` -
- -The sample after mapping is similar to the following format: - -``` -257 142 52 898 7 0 12899 1083 824 122 89527 134 6 65 47 48 904 89527 13 0 87 170 8 248 9 15 4 25 1365 4360 89527 702 89527 1 89527 240 3 28 89527 19 7 0 216 219 614 89527 0 84 89527 225 3 0 15 67 2356 89527 0 498 117 2 314 282 7 38 1097 89527 1 0 174 181 38 11 71 198 44 1 3110 89527 454 89527 34 37 89527 0 15 5912 80 2 9856 7748 89527 8 421 80 9 15 14 55 2218 12 4 45 6 58 25 89527 154 119 224 41 0 151 89527 871 89527 505 89527 501 89527 29 2 773 211 89527 54 307 90 0 893 89527 9 407 4 25 2 614 15 46 89527 89527 71 8 1356 35 89527 12 0 89527 89527 89 527 577 374 3 39091 22950 1 3771 48900 95 371 156 313 89527 37 154 296 4 25 2 217 169 3 2759 7 0 15 89527 0 714 580 11 2094 559 34 0 84 539 89527 1 0 330 355 3 0 15 15607 935 80 0 5369 3 0 622 89527 2 15 36 9 2291 2 7599 6968 2449 89527 1 454 37 256 2 211 113 0 480 218 1152 700 4 1684 1253 352 10 2449 89527 39 4 1819 129 1 316 462 29 0 12957 3 6 28 89527 13 0 457 8952 7 225 89527 8 2389 0 1514 89527 1 -``` - -In this way, the neural network can train the transformed text information as feature values. - -## Step4:Define CNN network for training and saving - -Net we use [CNN Model](https://www.paddlepaddle.org.cn/documentation/docs/zh/user_guides/nlp_case/understand_sentiment/README.cn.html#cnn) for training, in nets.py we define the network structure. - -
- nets.py - -```python -import sys -import time -import numpy as np - -import paddle -import paddle.fluid as fluid - -def cnn_net(data, - label, - dict_dim, - emb_dim=128, - hid_dim=128, - hid_dim2=96, - class_dim=2, - win_size=3): - """ conv net. """ - emb = fluid.layers.embedding( - input=data, size=[dict_dim, emb_dim], is_sparse=True) - - conv_3 = fluid.nets.sequence_conv_pool( - input=emb, - num_filters=hid_dim, - filter_size=win_size, - act="tanh", - pool_type="max") - - fc_1 = fluid.layers.fc(input=[conv_3], size=hid_dim2) - - prediction = fluid.layers.fc(input=[fc_1], size=class_dim, act="softmax") - cost = fluid.layers.cross_entropy(input=prediction, label=label) - avg_cost = fluid.layers.mean(x=cost) - acc = fluid.layers.accuracy(input=prediction, label=label) - - return avg_cost, acc, prediction -``` - -
- -Use training dataset for training. The training script is local_train.py. After training, use the paddle_serving_client.io.save_model function to save the model files and configuration files used by the servingdeployment. - -
- local_train.py - -```python -import os -import sys -import paddle -import logging -import paddle.fluid as fluid - -logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s') -logger = logging.getLogger("fluid") -logger.setLevel(logging.INFO) - -# load dict file -def load_vocab(filename): - vocab = {} - with open(filename) as f: - wid = 0 - for line in f: - vocab[line.strip()] = wid - wid += 1 - vocab[""] = len(vocab) - return vocab - - -if __name__ == "__main__": - from nets import cnn_net - model_name = "imdb_cnn" - vocab = load_vocab('imdb.vocab') - dict_dim = len(vocab) - - #define model input - data = fluid.layers.data( - name="words", shape=[1], dtype="int64", lod_level=1) - label = fluid.layers.data(name="label", shape=[1], dtype="int64") - #define dataset,train_data is the dataset directory - dataset = fluid.DatasetFactory().create_dataset() - filelist = ["train_data/%s" % x for x in os.listdir("train_data")] - dataset.set_use_var([data, label]) - pipe_command = "python imdb_reader.py" - dataset.set_pipe_command(pipe_command) - dataset.set_batch_size(4) - dataset.set_filelist(filelist) - dataset.set_thread(10) - #define model - avg_cost, acc, prediction = cnn_net(data, label, dict_dim) - optimizer = fluid.optimizer.SGD(learning_rate=0.001) - optimizer.minimize(avg_cost) - #execute training - exe = fluid.Executor(fluid.CPUPlace()) - exe.run(fluid.default_startup_program()) - epochs = 100 - - import paddle_serving_client.io as serving_io - - for i in range(epochs): - exe.train_from_dataset( - program=fluid.default_main_program(), dataset=dataset, debug=False) - logger.info("TRAIN --> pass: {}".format(i)) - if i == 64: - #At the end of training, use the model save interface in PaddleServing to save the models and configuration files required by Serving - serving_io.save_model("{}_model".format(model_name), - "{}_client_conf".format(model_name), - {"words": data}, {"prediction": prediction}, - fluid.default_main_program()) -``` - -
- -![Training process](./imdb_loss.png) As can be seen from the above figure, the loss of the model starts to converge after the 65th round. We save the model and configuration file after the 65th round of training is completed. The saved files are divided into imdb_cnn_client_conf and imdb_cnn_model folders. The former contains client-side configuration files, and the latter contains server-side configuration files and saved model files. -The parameter list of the save_model function is as follows: - -| Parameter | Meaning | -| -------------------- | ------------------------------------------------------------ | -| server_model_folder | Directory for server-side configuration files and model files | -| client_config_folder | Directory for saving client configuration files | -| feed_var_dict | The input of the inference model. The dict type and key can be customized. The value is the input variable in the model. Each key corresponds to a variable. When using the prediction service, the input data uses the key as the input name. | -| fetch_var_dict | The output of the model used for prediction, dict type, key can be customized, value is the input variable in the model, and each key corresponds to a variable. When using the prediction service, use the key to get the returned data | -| main_program | Model's program | - -## Step5: Deploy RPC Prediction Service - -The Paddle Serving framework supports two types of prediction service methods. One is to communicate through RPC and the other is to communicate through HTTP. The deployment and use of RPC prediction service will be introduced first. The deployment and use of HTTP prediction service will be introduced at Step 8. . - -```shell -python -m paddle_serving_server.serve --model imdb_cnn_model / --port 9292 #cpu prediction service -python -m paddle_serving_server_gpu.serve --model imdb_cnn_model / --port 9292 --gpu_ids 0 #gpu prediction service -``` - -The parameter --model in the command specifies the server-side model and configuration file directory previously saved, --port specifies the port of the prediction service. When deploying the gpu prediction service using the gpu version, you can use --gpu_ids to specify the gpu used. - -After executing one of the above commands, the RPC prediction service deployment of the IMDB sentiment analysis task is completed. - -## Step6: Reuse Reader, define remote RPC client -Below we access the RPC prediction service through Python code, the script is test_client.py - -
- test_client.py - -```python -from paddle_serving_client import Client -from imdb_reader import IMDBDataset -import sys - -client = Client() -client.load_client_config(sys.argv[1]) -client.connect(["127.0.0.1:9292"]) - -#The code of the data preprocessing part is reused here to convert the original text into a numeric id -imdb_dataset = IMDBDataset() -imdb_dataset.load_resource(sys.argv[2]) - -for line in sys.stdin: - word_ids, label = imdb_dataset.get_words_and_label(line) - feed = {"words": word_ids} - fetch = ["acc", "cost", "prediction"] - fetch_map = client.predict(feed=feed, fetch=fetch) - print("{} {}".format(fetch_map["prediction"][1], label[0])) -``` - -
- -The script receives data from standard input and prints out the probability that the sample whose infer result is 1 and its real label. - -## Step7: Call the RPC service to test the model effect - -The client implemented in the previous step runs the prediction service as an example. The usage method is as follows: - -```shell -cat test_data/part-0 | python test_client.py imdb_lstm_client_conf/serving_client_conf.prototxt imdb.vocab -``` - -Using 2084 samples in the test_data/part-0 file for test testing, the model prediction accuracy is 88.19%. - -**Note**: The effect of each model training may be slightly different, and the accuracy of predictions using the trained model will be close to the examples but may not be exactly the same. - -## Step8: Deploy HTTP Prediction Service - -When using the HTTP prediction service, the client does not need to install any modules of Paddle Serving, it only needs to be able to send HTTP requests. Of course, the HTTP method consumes more time in the communication phase than the RPC method. - -For the IMDB sentiment analysis task, the original text needs to be preprocessed before prediction. In the RPC prediction service, we put the preprocessing in the client's script, and in the HTTP prediction service, we put the preprocessing on the server. Paddle Serving's HTTP prediction service framework prepares data pre-processing and post-processing interfaces for this situation. We just need to rewrite it according to the needs of the task. - -Serving provides sample code, which is obtained by executing the imdb_web_service_demo.sh script in [IMDB Example](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/imdb). - -Let's take a look at the script text_classify_service.py that starts the HTTP prediction service. -
- text_clssify_service.py - -```python -from paddle_serving_server.web_service import WebService -from imdb_reader import IMDBDataset -import sys - -#extend class WebService -class IMDBService(WebService): - def prepare_dict(self, args={}): - if len(args) == 0: - exit(-1) - self.dataset = IMDBDataset() - self.dataset.load_resource(args["dict_file_path"]) - - #rewrite preprocess() to implement data preprocessing, here we reuse reader script for training - def preprocess(self, feed={}, fetch=[]): - if "words" not in feed: - exit(-1) - res_feed = {} - res_feed["words"] = self.dataset.get_words_only(feed["words"])[0] - return res_feed, fetch - -#Here you need to use the name parameter to specify the name of the prediction service. -imdb_service = IMDBService(name="imdb") -imdb_service.load_model_config(sys.argv[1]) -imdb_service.prepare_server( - workdir=sys.argv[2], port=int(sys.argv[3]), device="cpu") -imdb_service.prepare_dict({"dict_file_path": sys.argv[4]}) -imdb_service.run_server() -``` -
- -run - -```shell -python text_classify_service.py imdb_cnn_model/ workdir/ 9292 imdb.vocab -``` - -In the above command, the first parameter is the saved server-side model and configuration file. The second parameter is the working directory, which will save some configuration files for the prediction service. The directory may not exist but needs to be specified. The prediction service will be created by itself. the third parameter is Port number, the fourth parameter is the dictionary file. - -## Step9: Call the prediction service with plaintext data -After starting the HTTP prediction service, you can make prediction with a single command: - -``` -curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"words": "i am very sad | 0"}], "fetch":["prediction"]}' http://127.0.0.1:9292/imdb/prediction -``` -When the inference process is normal, the prediction probability is returned, as shown below. - -``` -{"result":{"prediction":[[0.4389057457447052,0.561094343662262]]}} -``` - -**Note**: The effect of each model training may be slightly different, and the inferred probability value using the trained model may not be consistent with the example. diff --git a/doc/TRAIN_TO_SERVICE_CN.md b/doc/TRAIN_TO_SERVICE_CN.md deleted file mode 100644 index 1c8a2848bcc198c66e617be145c43d2651b7f885..0000000000000000000000000000000000000000 --- a/doc/TRAIN_TO_SERVICE_CN.md +++ /dev/null @@ -1,364 +0,0 @@ -# 端到端完成从训练到部署全流程 - -(简体中文|[English](./TRAIN_TO_SERVICE.md)) - -Paddle Serving是Paddle的高性能在线预测服务框架,可以灵活支持大多数模型的部署。本文中将以IMDB评论情感分析任务为例通过9步展示从模型的训练到部署预测服务的全流程。 - -## Step1:准备环境 - -Paddle Serving可以部署在Linux环境上,目前server端支持在Centos7上部署,推荐使用[Docker部署](RUN_IN_DOCKER_CN.md)。rpc client端可以在Centos7和Ubuntu18上部署,在其他系统上或者不希望安装serving模块的环境中仍然可以通过http服务来访问server端的预测服务。 - -可以根据需求和机器环境来选择安装cpu或gpu版本的server模块,在client端机器上安装client模块。使用http请求的方式来访问server时,client端机器不需要安装client模块。 - -```shell -pip install paddle_serving_server #cpu版本server端 -pip install paddle_serving_server_gpu #gpu版本server端 -pip install paddle_serving_client #client端 -``` - -简单准备后,我们将以IMDB评论情感分析任务为例,展示从模型训练到部署预测服务的流程。示例中的所有代码都可以在Paddle Serving代码库的[IMDB示例](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/imdb)中找到,示例中使用的数据和词典文件可以通过执行IMDB示例代码中的get_data.sh脚本得到。 - -## Step2:确定任务和原始数据格式 - -IMDB评论情感分析任务是对电影评论的内容进行二分类,判断该评论是属于正面评论还是负面评论。 - -首先我们来看一下原始的数据: - -``` -saw a trailer for this on another video, and decided to rent when it came out. boy, was i disappointed! the story is extremely boring, the acting (aside from christopher walken) is bad, and i couldn't care less about the characters, aside from really wanting to see nora's husband get thrashed. christopher walken's role is such a throw-away, what a tease! | 0 -``` - -这是一条英文评论样本,样本中使用|作为分隔符,分隔符之前为评论的内容,分隔符之后是样本的标签,0代表负样本,即负面评论,1代表正样本,即正面评论。 - -## Step3:定义Reader,划分训练集、测试集 - -对于原始文本我们需要将它转化为神经网络可以使用的数字id。imdb_reader.py脚本中定义了文本id化的方法,通过词典文件imdb.vocab将单词映射为整形数。 - -
- imdb_reader.py - -```python -import sys -import os -import paddle -import re -import paddle.fluid.incubate.data_generator as dg - - -class IMDBDataset(dg.MultiSlotDataGenerator): - def load_resource(self, dictfile): - self._vocab = {} - wid = 0 - with open(dictfile) as f: - for line in f: - self._vocab[line.strip()] = wid - wid += 1 - self._unk_id = len(self._vocab) - self._pattern = re.compile(r'(;|,|\.|\?|!|\s|\(|\))') - self.return_value = ("words", [1, 2, 3, 4, 5, 6]), ("label", [0]) - - def get_words_only(self, line): - sent = line.lower().replace("
", " ").strip() - words = [x for x in self._pattern.split(sent) if x and x != " "] - feas = [ - self._vocab[x] if x in self._vocab else self._unk_id for x in words - ] - return feas - - def get_words_and_label(self, line): - send = '|'.join(line.split('|')[:-1]).lower().replace("
", - " ").strip() - label = [int(line.split('|')[-1])] - - words = [x for x in self._pattern.split(send) if x and x != " "] - feas = [ - self._vocab[x] if x in self._vocab else self._unk_id for x in words - ] - return feas, label - - def infer_reader(self, infer_filelist, batch, buf_size): - def local_iter(): - for fname in infer_filelist: - with open(fname, "r") as fin: - for line in fin: - feas, label = self.get_words_and_label(line) - yield feas, label - - import paddle - batch_iter = paddle.batch( - paddle.reader.shuffle( - local_iter, buf_size=buf_size), - batch_size=batch) - return batch_iter - - def generate_sample(self, line): - def memory_iter(): - for i in range(1000): - yield self.return_value - - def data_iter(): - feas, label = self.get_words_and_label(line) - yield ("words", feas), ("label", label) - - return data_iter -``` -
- -映射之后的样本类似于以下的格式: - -``` -257 142 52 898 7 0 12899 1083 824 122 89527 134 6 65 47 48 904 89527 13 0 87 170 8 248 9 15 4 25 1365 4360 89527 702 89527 1 89527 240 3 28 89527 19 7 0 216 219 614 89527 0 84 89527 225 3 0 15 67 2356 89527 0 498 117 2 314 282 7 38 1097 89527 1 0 174 181 38 11 71 198 44 1 3110 89527 454 89527 34 37 89527 0 15 5912 80 2 9856 7748 89527 8 421 80 9 15 14 55 2218 12 4 45 6 58 25 89527 154 119 224 41 0 151 89527 871 89527 505 89527 501 89527 29 2 773 211 89527 54 307 90 0 893 89527 9 407 4 25 2 614 15 46 89527 89527 71 8 1356 35 89527 12 0 89527 89527 89 527 577 374 3 39091 22950 1 3771 48900 95 371 156 313 89527 37 154 296 4 25 2 217 169 3 2759 7 0 15 89527 0 714 580 11 2094 559 34 0 84 539 89527 1 0 330 355 3 0 15 15607 935 80 0 5369 3 0 622 89527 2 15 36 9 2291 2 7599 6968 2449 89527 1 454 37 256 2 211 113 0 480 218 1152 700 4 1684 1253 352 10 2449 89527 39 4 1819 129 1 316 462 29 0 12957 3 6 28 89527 13 0 457 8952 7 225 89527 8 2389 0 1514 89527 1 -``` - -这样神经网络就可以将转化后的文本信息作为特征值进行训练。 - -## Step4:定义CNN网络进行训练并保存 - -接下来我们使用[CNN模型](https://www.paddlepaddle.org.cn/documentation/docs/zh/user_guides/nlp_case/understand_sentiment/README.cn.html#cnn)来进行训练。在nets.py脚本中定义网络结构。 - -
- nets.py - -```python -import sys -import time -import numpy as np - -import paddle -import paddle.fluid as fluid - -def cnn_net(data, - label, - dict_dim, - emb_dim=128, - hid_dim=128, - hid_dim2=96, - class_dim=2, - win_size=3): - """ conv net. """ - emb = fluid.layers.embedding( - input=data, size=[dict_dim, emb_dim], is_sparse=True) - - conv_3 = fluid.nets.sequence_conv_pool( - input=emb, - num_filters=hid_dim, - filter_size=win_size, - act="tanh", - pool_type="max") - - fc_1 = fluid.layers.fc(input=[conv_3], size=hid_dim2) - - prediction = fluid.layers.fc(input=[fc_1], size=class_dim, act="softmax") - cost = fluid.layers.cross_entropy(input=prediction, label=label) - avg_cost = fluid.layers.mean(x=cost) - acc = fluid.layers.accuracy(input=prediction, label=label) - - return avg_cost, acc, prediction -``` - -
- -使用训练样本进行训练,训练脚本为local_train.py。在训练结束后使用paddle_serving_client.io.save_model函数来保存部署预测服务使用的模型文件和配置文件。 - -
- local_train.py - -```python -import os -import sys -import paddle -import logging -import paddle.fluid as fluid - -logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s') -logger = logging.getLogger("fluid") -logger.setLevel(logging.INFO) - -# 加载词典文件 -def load_vocab(filename): - vocab = {} - with open(filename) as f: - wid = 0 - for line in f: - vocab[line.strip()] = wid - wid += 1 - vocab[""] = len(vocab) - return vocab - - -if __name__ == "__main__": - from nets import cnn_net - model_name = "imdb_cnn" - vocab = load_vocab('imdb.vocab') - dict_dim = len(vocab) - - #定义模型输入 - data = fluid.layers.data( - name="words", shape=[1], dtype="int64", lod_level=1) - label = fluid.layers.data(name="label", shape=[1], dtype="int64") - #定义dataset,train_data为训练数据目录 - dataset = fluid.DatasetFactory().create_dataset() - filelist = ["train_data/%s" % x for x in os.listdir("train_data")] - dataset.set_use_var([data, label]) - pipe_command = "python imdb_reader.py" - dataset.set_pipe_command(pipe_command) - dataset.set_batch_size(4) - dataset.set_filelist(filelist) - dataset.set_thread(10) - #定义模型 - avg_cost, acc, prediction = cnn_net(data, label, dict_dim) - optimizer = fluid.optimizer.SGD(learning_rate=0.001) - optimizer.minimize(avg_cost) - #执行训练 - exe = fluid.Executor(fluid.CPUPlace()) - exe.run(fluid.default_startup_program()) - epochs = 100 - - import paddle_serving_client.io as serving_io - - for i in range(epochs): - exe.train_from_dataset( - program=fluid.default_main_program(), dataset=dataset, debug=False) - logger.info("TRAIN --> pass: {}".format(i)) - if i == 64: - #在训练结束时使用PaddleServing中的模型保存接口保存出Serving所需的模型和配置文件 - serving_io.save_model("{}_model".format(model_name), - "{}_client_conf".format(model_name), - {"words": data}, {"prediction": prediction}, - fluid.default_main_program()) -``` - -
- -![训练过程](./imdb_loss.png)由上图可以看出模型的损失在第65轮之后开始收敛,我们在第65轮训练完成后保存模型和配置文件。保存的文件分为imdb_cnn_client_conf和imdb_cnn_model文件夹,前者包含client端的配置文件,后者包含server端的配置文件和保存的模型文件。 -save_model函数的参数列表如下: - -| 参数 | 含义 | -| -------------------- | ------------------------------------------------------------ | -| server_model_folder | 保存server端配置文件和模型文件的目录 | -| client_config_folder | 保存client端配置文件的目录 | -| feed_var_dict | 用于预测的模型的输入,dict类型,key可以自定义,value为模型中的input variable,每个key对应一个variable,使用预测服务时,输入数据使用key作为输入的名称 | -| fetch_var_dict | 用于预测的模型的输出,dict类型,key可以自定义,value为模型中的input variable,每个key对应一个variable,使用预测服务时,通过key来获取返回数据 | -| main_program | 模型的program | - -## Step5:部署RPC预测服务 - -Paddle Serving框架支持两种预测服务方式,一种是通过RPC进行通信,一种是通过HTTP进行通信,下面将先介绍RPC预测服务的部署和使用方法,在Step8开始介绍HTTP预测服务的部署和使用。 - -```shell -python -m paddle_serving_server.serve --model imdb_cnn_model/ --port 9292 #cpu预测服务 -python -m paddle_serving_server_gpu.serve --model imdb_cnn_model/ --port 9292 --gpu_ids 0 #gpu预测服务 -``` - -命令中参数--model 指定在之前保存的server端的模型和配置文件目录,--port指定预测服务的端口,当使用gpu版本部署gpu预测服务时可以使用--gpu_ids指定使用的gpu 。 - -执行完以上命令之一,就完成了IMDB 情感分析任务的RPC预测服务部署。 - -## Step6:复用Reader,定义远程RPC客户端 -下面我们通过Python代码来访问RPC预测服务,脚本为test_client.py - -
- test_client.py - -```python -from paddle_serving_client import Client -from imdb_reader import IMDBDataset -import sys - -client = Client() -client.load_client_config(sys.argv[1]) -client.connect(["127.0.0.1:9292"]) - -#在这里复用了数据预处理部分的代码将原始文本转换成数字id -imdb_dataset = IMDBDataset() -imdb_dataset.load_resource(sys.argv[2]) - -for line in sys.stdin: - word_ids, label = imdb_dataset.get_words_and_label(line) - feed = {"words": word_ids} - fetch = ["acc", "cost", "prediction"] - fetch_map = client.predict(feed=feed, fetch=fetch) - print("{} {}".format(fetch_map["prediction"][1], label[0])) -``` - -
- -脚本从标准输入接收数据,并打印出样本预测为1的概率与真实的label。 - -## Step7:调用RPC服务,测试模型效果 - -以上一步实现的客户端为例运行预测服务,使用方式如下: - -```shell -cat test_data/part-0 | python test_client.py imdb_lstm_client_conf/serving_client_conf.prototxt imdb.vocab -``` - -使用test_data/part-0文件中的2084个样本进行测试测试,模型预测的准确率为88.19%。 - -**注意**:每次模型训练的效果可能略有不同,使用训练出的模型预测的准确率会与示例中接近但有可能不完全一致。 - -## Step8:部署HTTP预测服务 - -使用HTTP预测服务时,client端不需要安装Paddle Serving的任何模块,仅需要能发送HTTP请求即可。当然HTTP的通信方式会相较于RPC的通信方式在通信阶段消耗更多的时间。 - -对于IMDB情感分析任务原始文本在预测之前需要进行预处理,在RPC预测服务中我们将预处理放在client的脚本中,而在HTTP预测服务中我们将预处理放在server端。Paddle Serving的HTTP预测服务框架为这种情况准备了数据预处理和后处理的接口,我们只要根据任务需要重写即可。 - -Serving提供了示例代码,通过执行[IMDB示例](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/imdb)中的imdb_web_service_demo.sh脚本来获取。 - -下面我们来看一下启动HTTP预测服务的脚本text_classify_service.py。 - -
- text_clssify_service.py - -```python -from paddle_serving_server.web_service import WebService -from imdb_reader import IMDBDataset -import sys - -#继承框架中的WebService类 -class IMDBService(WebService): - def prepare_dict(self, args={}): - if len(args) == 0: - exit(-1) - self.dataset = IMDBDataset() - self.dataset.load_resource(args["dict_file_path"]) - - #重写preprocess方法来实现数据预处理,这里也复用了训练时使用的reader脚本 - def preprocess(self, feed={}, fetch=[]): - if "words" not in feed: - exit(-1) - res_feed = {} - res_feed["words"] = self.dataset.get_words_only(feed["words"])[0] - return res_feed, fetch - -#这里需要使用name参数指定预测服务的名称, -imdb_service = IMDBService(name="imdb") -imdb_service.load_model_config(sys.argv[1]) -imdb_service.prepare_server( - workdir=sys.argv[2], port=int(sys.argv[3]), device="cpu") -imdb_service.prepare_dict({"dict_file_path": sys.argv[4]}) -imdb_service.run_server() -``` -
- -启动命令 - -```shell -python text_classify_service.py imdb_cnn_model/ workdir/ 9292 imdb.vocab -``` - -以上命令中参数1为保存的server端模型和配置文件,参数2为工作目录会保存一些预测服务工作时的配置文件,该目录可以不存在但需要指定名称,预测服务会自行创建,参数3为端口号,参数4为词典文件。 - -## Step9:明文数据调用预测服务 -启动完HTTP预测服务,即可通过一行命令进行预测: - -``` -curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"words": "i am very sad | 0"}], "fetch":["prediction"]}' http://127.0.0.1:9292/imdb/prediction -``` -预测流程正常时,会返回预测概率,示例如下。 - -``` -{"result":{"prediction":[[0.4389057457447052,0.561094343662262]]}} -``` - -**注意**:每次模型训练的效果可能略有不同,使用训练出的模型预测概率数值可能与示例不一致。 diff --git a/doc/WINDOWS_TUTORIAL.md b/doc/WINDOWS_TUTORIAL.md index 8450472f4b93a44475f459342e35c658f5f187c9..73cf52bb4fab14c213a13f358ed84f1e643b0734 100644 --- a/doc/WINDOWS_TUTORIAL.md +++ b/doc/WINDOWS_TUTORIAL.md @@ -117,9 +117,9 @@ Please refer to [Docker Desktop](https://www.docker.com/products/docker-desktop) After installation, start the docker linux engine and download the relevant image. In the Serving directory ``` -docker pull hub.baidubce.com/paddlepaddle/serving:latest-devel +docker pull registry.baidubce.com/paddlepaddle/serving:latest-devel # There is no expose port here, users can set -p to perform port mapping as needed -docker run --rm -dit --name serving_devel -v $PWD:/Serving hub.baidubce.com/paddlepaddle/serving:latest-devel +docker run --rm -dit --name serving_devel -v $PWD:/Serving registry.baidubce.com/paddlepaddle/serving:latest-devel docker exec -it serving_devel bash cd /Serving ``` diff --git a/doc/WINDOWS_TUTORIAL_CN.md b/doc/WINDOWS_TUTORIAL_CN.md index d40e238d3b58e8959460f437dea7bfcb1e039c45..4184840f4e5646fcd998dfa33b80b8b9210b05d7 100644 --- a/doc/WINDOWS_TUTORIAL_CN.md +++ b/doc/WINDOWS_TUTORIAL_CN.md @@ -117,9 +117,9 @@ python your_client.py 安装之后启动docker的linux engine,下载相关镜像。在Serving目录下 ``` -docker pull hub.baidubce.com/paddlepaddle/serving:latest-devel +docker pull registry.baidubce.com/paddlepaddle/serving:latest-devel # 此处没有expose端口,用户可根据需要设置-p来进行端口映射 -docker run --rm -dit --name serving_devel -v $PWD:/Serving hub.baidubce.com/paddlepaddle/serving:latest-devel +docker run --rm -dit --name serving_devel -v $PWD:/Serving registry.baidubce.com/paddlepaddle/serving:latest-devel docker exec -it serving_devel bash cd /Serving ``` diff --git a/doc/DESIGN.md b/doc/deprecated/DESIGN.md similarity index 100% rename from doc/DESIGN.md rename to doc/deprecated/DESIGN.md diff --git a/doc/DESIGN_CN.md b/doc/deprecated/DESIGN_CN.md similarity index 100% rename from doc/DESIGN_CN.md rename to doc/deprecated/DESIGN_CN.md diff --git a/java/README.md b/java/README.md index 28663274d486d70d9a2f20cf2fdbaddb8877ec3a..51f08d6ae1433385b0dff9c987e6cd52d88f8174 100644 --- a/java/README.md +++ b/java/README.md @@ -7,8 +7,8 @@ In order to facilitate users to use java for development, we provide the compiled Serving project to be placed in the java mirror. The way to get the mirror and enter the development environment is ``` -docker pull hub.baidubce.com/paddlepaddle/serving:0.4.1-java -docker run --rm -dit --name java_serving hub.baidubce.com/paddlepaddle/serving:0.4.1-java +docker pull registry.baidubce.com/paddlepaddle/serving:0.5.0-java +docker run --rm -dit --name java_serving registry.baidubce.com/paddlepaddle/serving:0.5.0-java docker exec -it java_serving bash cd Serving/java ``` diff --git a/java/README_CN.md b/java/README_CN.md index e8cca0cc7b9b53529628f06f82219113e44e8aae..59e1ca56c9176ccc81ed3eeb3aab1ff7e6e9c122 100644 --- a/java/README_CN.md +++ b/java/README_CN.md @@ -7,8 +7,8 @@ 为了方便用户使用java进行开发,我们提供了编译好的Serving工程放置在java镜像当中,获取镜像并进入开发环境的方式是 ``` -docker pull hub.baidubce.com/paddlepaddle/serving:0.4.1-java -docker run --rm -dit --name java_serving hub.baidubce.com/paddlepaddle/serving:0.4.1-java +docker pull registry.baidubce.com/paddlepaddle/serving:0.5.0-java +docker run --rm -dit --name java_serving registry.baidubce.com/paddlepaddle/serving:0.5.0-java docker exec -it java_serving bash cd Serving/java ``` diff --git a/python/examples/README.md b/python/examples/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6e0ee808373f9f9b1c37ae5dab249a864337c642 --- /dev/null +++ b/python/examples/README.md @@ -0,0 +1,11 @@ +## Examples + +### Support `--use_trt` + +the following models support `--use_trt`, which means you can use TensorRT to accelerate inference at Cuda 10.1 or higher. + +- imagenet ResNet50/ResNet101 +- detection faster_rcnn/yolov3/pp-yolo/ttf-net + + + diff --git a/python/examples/README_CN.md b/python/examples/README_CN.md new file mode 100644 index 0000000000000000000000000000000000000000..60b7cd77aadbca0002be1618a53af8caba215afa --- /dev/null +++ b/python/examples/README_CN.md @@ -0,0 +1,9 @@ +## Serving模型示例 + +### 支持TensorRT的模型列表 `--use_trt` + +以下模型支持TensorRT,可以开启 `--use_trt`来加速在线预测,其他模型不能开启。 + +- imagenet ResNet50/ResNet101 +- detection faster_rcnn/yolov3/pp-yolo/ttf-net + diff --git a/python/examples/bert/README.md b/python/examples/bert/README.md index a8fa35ddaec86ea2f05b025a3bde4b999d57f1dc..90e96d53a13626d7f540e79e6b313634dd1b1cf3 100644 --- a/python/examples/bert/README.md +++ b/python/examples/bert/README.md @@ -11,14 +11,16 @@ This example use model [BERT Chinese Model](https://www.paddlepaddle.org.cn/hubd Install paddlehub first ``` -pip install paddlehub +pip3 install paddlehub ``` run ``` -python prepare_model.py 128 +python3 prepare_model.py 128 ``` +**PaddleHub only support Python 3.5+** + the 128 in the command above means max_seq_len in BERT model, which is the length of sample after preprocessing. 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. @@ -28,8 +30,9 @@ You can also download the above model from BOS(max_seq_len=128). After decompres ```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 +mv bert_chinese_L-12_H-768_A-12_model bert_seq128_model +mv bert_chinese_L-12_H-768_A-12_client bert_seq128_client ``` -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 @@ -64,7 +67,7 @@ the client reads data from data-c.txt and send prediction request, the predictio ### HTTP Inference Service start cpu HTTP inference service,Run ``` - python bert_web_service.py bert_seq128_model/ 9292 #launch gpu inference service + python bert_web_service.py bert_seq128_model/ 9292 #launch cpu inference service ``` Or,start gpu HTTP inference service,Run diff --git a/python/examples/bert/README_CN.md b/python/examples/bert/README_CN.md index e06e17c8f345b65884feabee08d40e5f345fa322..ef780b1cc08c053d4369a758d1b2e465291872c5 100644 --- a/python/examples/bert/README_CN.md +++ b/python/examples/bert/README_CN.md @@ -10,11 +10,11 @@ 示例中采用[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 ``` -pip install paddlehub +pip3 install paddlehub ``` 执行 ``` -python prepare_model.py 128 +python3 prepare_model.py 128 ``` 参数128表示BERT模型中的max_seq_len,即预处理后的样本长度。 生成server端配置文件与模型文件,存放在bert_seq128_model文件夹。 @@ -25,9 +25,9 @@ python prepare_model.py 128 ```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 +mv bert_chinese_L-12_H-768_A-12_model bert_seq128_model +mv bert_chinese_L-12_H-768_A-12_client bert_seq128_client ``` -若使用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. - ### 获取词典和样例数据 @@ -67,7 +67,7 @@ head data-c.txt | python bert_client.py --model bert_seq128_client/serving_clien ### 启动HTTP预测服务 启动cpu HTTP预测服务,执行 ``` -python bert_web_service.py bert_seq128_model/ 9292 #启动gpu预测服务 +python bert_web_service.py bert_seq128_model/ 9292 #启动CPU预测服务 ``` diff --git a/python/examples/criteo_ctr/README.md b/python/examples/criteo_ctr/README.md index 4780fb667dfe2a0bc4bc4497dc24a495b59aa3ac..2e9c5c53781a70be262e9f7f9d604933b35d868d 100644 --- a/python/examples/criteo_ctr/README.md +++ b/python/examples/criteo_ctr/README.md @@ -14,7 +14,7 @@ tar xf criteo_ctr_demo_model.tar.gz mv models/ctr_client_conf . mv models/ctr_serving_model . ``` -the directories like serving_server_model and serving_client_config will appear. +the directories like `ctr_serving_model` and `ctr_client_conf` will appear. ### Start RPC Inference Service @@ -26,6 +26,6 @@ python -m paddle_serving_server_gpu.serve --model ctr_serving_model/ --port 9292 ### RPC Infer ``` -python test_client.py ctr_client_conf/serving_client_conf.prototxt raw_data/ +python test_client.py ctr_client_conf/serving_client_conf.prototxt raw_data/part-0 ``` the latency will display in the end. diff --git a/python/examples/criteo_ctr/README_CN.md b/python/examples/criteo_ctr/README_CN.md index bee946aac8eca4293811057baff061bceb9508af..0fd8fd5ec9a3842702268aa2cc5393c79dbf6ca0 100644 --- a/python/examples/criteo_ctr/README_CN.md +++ b/python/examples/criteo_ctr/README_CN.md @@ -14,7 +14,7 @@ tar xf criteo_ctr_demo_model.tar.gz mv models/ctr_client_conf . mv models/ctr_serving_model . ``` -会在当前目录出现serving_server_model和serving_client_config文件夹。 +会在当前目录出现`ctr_serving_model` 和 `ctr_client_conf`文件夹。 ### 启动RPC预测服务 @@ -26,6 +26,6 @@ python -m paddle_serving_server_gpu.serve --model ctr_serving_model/ --port 9292 ### 执行预测 ``` -python test_client.py ctr_client_conf/serving_client_conf.prototxt raw_data/ +python test_client.py ctr_client_conf/serving_client_conf.prototxt raw_data/part-0 ``` 预测完毕会输出预测过程的耗时。 diff --git a/python/examples/criteo_ctr/criteo_reader.py b/python/examples/criteo_ctr/criteo_reader.py deleted file mode 100644 index 2a80af78a9c2033bf246f703ca70a817ab786af3..0000000000000000000000000000000000000000 --- a/python/examples/criteo_ctr/criteo_reader.py +++ /dev/null @@ -1,83 +0,0 @@ -# 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 - -import sys -import paddle.fluid.incubate.data_generator as dg - - -class CriteoDataset(dg.MultiSlotDataGenerator): - def setup(self, sparse_feature_dim): - self.cont_min_ = [0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - self.cont_max_ = [ - 20, 600, 100, 50, 64000, 500, 100, 50, 500, 10, 10, 10, 50 - ] - self.cont_diff_ = [ - 20, 603, 100, 50, 64000, 500, 100, 50, 500, 10, 10, 10, 50 - ] - self.hash_dim_ = sparse_feature_dim - # here, training data are lines with line_index < train_idx_ - self.train_idx_ = 41256555 - self.continuous_range_ = range(1, 14) - self.categorical_range_ = range(14, 40) - - def _process_line(self, line): - features = line.rstrip('\n').split('\t') - dense_feature = [] - sparse_feature = [] - for idx in self.continuous_range_: - if features[idx] == '': - dense_feature.append(0.0) - else: - dense_feature.append((float(features[idx]) - self.cont_min_[idx - 1]) / \ - self.cont_diff_[idx - 1]) - for idx in self.categorical_range_: - sparse_feature.append( - [hash(str(idx) + features[idx]) % self.hash_dim_]) - - return dense_feature, sparse_feature, [int(features[0])] - - def infer_reader(self, filelist, batch, buf_size): - def local_iter(): - for fname in filelist: - with open(fname.strip(), "r") as fin: - for line in fin: - dense_feature, sparse_feature, label = self._process_line( - line) - #yield dense_feature, sparse_feature, label - yield [dense_feature] + sparse_feature + [label] - - import paddle - batch_iter = paddle.batch( - paddle.reader.shuffle( - local_iter, buf_size=buf_size), - batch_size=batch) - return batch_iter - - def generate_sample(self, line): - def data_iter(): - dense_feature, sparse_feature, label = self._process_line(line) - feature_name = ["dense_input"] - for idx in self.categorical_range_: - feature_name.append("C" + str(idx - 13)) - feature_name.append("label") - yield zip(feature_name, [dense_feature] + sparse_feature + [label]) - - return data_iter - - -if __name__ == "__main__": - criteo_dataset = CriteoDataset() - criteo_dataset.setup(int(sys.argv[1])) - criteo_dataset.run_from_stdin() diff --git a/python/examples/criteo_ctr/test_client.py b/python/examples/criteo_ctr/test_client.py index ecb2fc376c0d3a8c7174c9f2ab093b25c8ac4791..fd6c6e03178915bbfc2dd0608e27a7f597945dca 100644 --- a/python/examples/criteo_ctr/test_client.py +++ b/python/examples/criteo_ctr/test_client.py @@ -14,43 +14,63 @@ # pylint: disable=doc-string-missing from paddle_serving_client import Client -import paddle import sys import os import time -import criteo_reader as criteo from paddle_serving_client.metric import auc import numpy as np import sys +class CriteoReader(object): + def __init__(self, sparse_feature_dim): + self.cont_min_ = [0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + self.cont_max_ = [ + 20, 600, 100, 50, 64000, 500, 100, 50, 500, 10, 10, 10, 50 + ] + self.cont_diff_ = [ + 20, 603, 100, 50, 64000, 500, 100, 50, 500, 10, 10, 10, 50 + ] + self.hash_dim_ = sparse_feature_dim + # here, training data are lines with line_index < train_idx_ + self.train_idx_ = 41256555 + self.continuous_range_ = range(1, 14) + self.categorical_range_ = range(14, 40) + + def process_line(self, line): + features = line.rstrip('\n').split('\t') + dense_feature = [] + sparse_feature = [] + for idx in self.continuous_range_: + if features[idx] == '': + dense_feature.append(0.0) + else: + dense_feature.append((float(features[idx]) - self.cont_min_[idx - 1]) / \ + self.cont_diff_[idx - 1]) + for idx in self.categorical_range_: + sparse_feature.append( + [hash(str(idx) + features[idx]) % self.hash_dim_]) + + return sparse_feature + py_version = sys.version_info[0] client = Client() client.load_client_config(sys.argv[1]) client.connect(["127.0.0.1:9292"]) - +reader = CriteoReader(1000001) batch = 1 buf_size = 100 -dataset = criteo.CriteoDataset() -dataset.setup(1000001) -test_filelists = [ - "{}/part-%d".format(sys.argv[2]) % x - for x in range(len(os.listdir(sys.argv[2]))) -] -reader = dataset.infer_reader(test_filelists[len(test_filelists) - 40:], batch, - buf_size) label_list = [] prob_list = [] start = time.time() -for ei in range(1000): - if py_version == 2: - data = reader().next() - else: - data = reader().__next__() +f = open(sys.argv[2], 'r') +for ei in range(10): + data = reader.process_line(f.readline()) feed_dict = {} for i in range(1, 27): - feed_dict["sparse_{}".format(i - 1)] = np.array(data[0][i]).reshape(-1) - feed_dict["sparse_{}.lod".format(i - 1)] = [0, len(data[0][i])] + feed_dict["sparse_{}".format(i - 1)] = np.array(data[i-1]).reshape(-1) + feed_dict["sparse_{}.lod".format(i - 1)] = [0, len(data[i-1])] fetch_map = client.predict(feed=feed_dict, fetch=["prob"]) + print(fetch_map) end = time.time() -print(end - start) +f.close() diff --git a/python/examples/detection/README.md b/python/examples/detection/README.md index 6d136e0bf02140b5642faac97a8cd9db96598445..99ea3dd1fff9bdf88e90192e864e72b40b70421b 100644 --- a/python/examples/detection/README.md +++ b/python/examples/detection/README.md @@ -12,6 +12,7 @@ Paddle Detection provides a large number of [Model Zoo](https://github.com/Paddl ### Serving example Several examples of PaddleDetection models used in Serving are given in this folder +All examples support TensorRT. -[Faster RCNN](./faster_rcnn_r50_fpn_1x_coco) -[PPYOLO](./ppyolo_r50vd_dcn_1x_coco) diff --git a/python/examples/detection/faster_rcnn_r50_fpn_1x_coco/README.md b/python/examples/detection/faster_rcnn_r50_fpn_1x_coco/README.md index 7dd05f2ed6cf7e222a44dada8f1c9fc6b769198d..96ab08bf884694a6e285bfef21cbb6661bc510e6 100644 --- a/python/examples/detection/faster_rcnn_r50_fpn_1x_coco/README.md +++ b/python/examples/detection/faster_rcnn_r50_fpn_1x_coco/README.md @@ -13,6 +13,9 @@ tar xf faster_rcnn_r50_fpn_1x_coco.tar python -m paddle_serving_server_gpu.serve --model serving_server --port 9494 --gpu_ids 0 ``` +This model support TensorRT, if you want a faster inference, please use `--use_trt`. + + ### Perform prediction ``` python test_client.py 000000570688.jpg diff --git a/python/examples/detection/faster_rcnn_r50_fpn_1x_coco/README_CN.md b/python/examples/detection/faster_rcnn_r50_fpn_1x_coco/README_CN.md index 8e3d387d4a2918104c24f8e71048e59d1b51e6c2..1fcced94133e5c66f91f7e7972549cb7f86bfef3 100644 --- a/python/examples/detection/faster_rcnn_r50_fpn_1x_coco/README_CN.md +++ b/python/examples/detection/faster_rcnn_r50_fpn_1x_coco/README_CN.md @@ -11,8 +11,9 @@ wget --no-check-certificate https://paddle-serving.bj.bcebos.com/pddet_demo/2.0/ ### 启动服务 ``` tar xf faster_rcnn_r50_fpn_1x_coco.tar -python -m paddle_serving_server_gpu.serve --model pddet_serving_model --port 9494 --gpu_ids 0 +python -m paddle_serving_server_gpu.serve --model serving_server --port 9494 --gpu_ids 0 ``` +该模型支持TensorRT,如果想要更快的预测速度,可以开启`--use_trt`选项。 ### 执行预测 ``` diff --git a/python/examples/detection/ppyolo_r50vd_dcn_1x_coco/README.md b/python/examples/detection/ppyolo_r50vd_dcn_1x_coco/README.md index 7bad9c1e7a2decedcf736f73e5692ade7c1ae7d6..7c31f204628bb4e1bd214064baa503b3ade803f3 100644 --- a/python/examples/detection/ppyolo_r50vd_dcn_1x_coco/README.md +++ b/python/examples/detection/ppyolo_r50vd_dcn_1x_coco/README.md @@ -13,6 +13,8 @@ tar xf ppyolo_r50vd_dcn_1x_coco.tar python -m paddle_serving_server_gpu.serve --model serving_server --port 9494 --gpu_ids 0 ``` +This model support TensorRT, if you want a faster inference, please use `--use_trt`. + ### Perform prediction ``` python test_client.py 000000570688.jpg diff --git a/python/examples/detection/ppyolo_r50vd_dcn_1x_coco/README_CN.md b/python/examples/detection/ppyolo_r50vd_dcn_1x_coco/README_CN.md index 2b8c1c63844c703679c480953494c917a78b829c..f403246b6024eb3514991aba88881344cccb8dd8 100644 --- a/python/examples/detection/ppyolo_r50vd_dcn_1x_coco/README_CN.md +++ b/python/examples/detection/ppyolo_r50vd_dcn_1x_coco/README_CN.md @@ -11,9 +11,11 @@ wget --no-check-certificate https://paddle-serving.bj.bcebos.com/pddet_demo/2.0/ ### 启动服务 ``` tar xf ppyolo_r50vd_dcn_1x_coco.tar -python -m paddle_serving_server_gpu.serve --model pddet_serving_model --port 9494 --gpu_ids 0 +python -m paddle_serving_server_gpu.serve --model serving_server --port 9494 --gpu_ids 0 ``` +该模型支持TensorRT,如果想要更快的预测速度,可以开启`--use_trt`选项。 + ### 执行预测 ``` python test_client.py 000000570688.jpg diff --git a/python/examples/detection/ttfnet_darknet53_1x_coco/README.md b/python/examples/detection/ttfnet_darknet53_1x_coco/README.md index 530c6e445b4deffdd28c791c4f0bac6f3479a9ef..6b86e7d79622576f1fbe6056974ca2beba18c690 100644 --- a/python/examples/detection/ttfnet_darknet53_1x_coco/README.md +++ b/python/examples/detection/ttfnet_darknet53_1x_coco/README.md @@ -12,6 +12,7 @@ wget --no-check-certificate https://paddle-serving.bj.bcebos.com/pddet_demo/2.0/ tar xf ttfnet_darknet53_1x_coco.tar python -m paddle_serving_server_gpu.serve --model serving_server --port 9494 --gpu_ids 0 ``` +This model support TensorRT, if you want a faster inference, please use `--use_trt`. ### Perform prediction ``` diff --git a/python/examples/detection/ttfnet_darknet53_1x_coco/README_CN.md b/python/examples/detection/ttfnet_darknet53_1x_coco/README_CN.md index 28cf7cf6ab04882a67480404216ce29e3983a185..976c94a4d783802a72e5d2b72bccb6e2bcfe1cba 100644 --- a/python/examples/detection/ttfnet_darknet53_1x_coco/README_CN.md +++ b/python/examples/detection/ttfnet_darknet53_1x_coco/README_CN.md @@ -11,9 +11,11 @@ wget --no-check-certificate https://paddle-serving.bj.bcebos.com/pddet_demo/2.0/ ### 启动服务 ``` tar xf ttfnet_darknet53_1x_coco.tar -python -m paddle_serving_server_gpu.serve --model pddet_serving_model --port 9494 --gpu_ids 0 +python -m paddle_serving_server_gpu.serve --model serving_server --port 9494 --gpu_ids 0 ``` +该模型支持TensorRT,如果想要更快的预测速度,可以开启`--use_trt`选项。 + ### 执行预测 ``` python test_client.py 000000570688.jpg diff --git a/python/examples/detection/yolov3_darknet53_270e_coco/README.md b/python/examples/detection/yolov3_darknet53_270e_coco/README.md index c3d7638d12b7c1fd4c0da246acea70b4a816e366..7023794525c914b6451c7b15b84f36c1cf4d9004 100644 --- a/python/examples/detection/yolov3_darknet53_270e_coco/README.md +++ b/python/examples/detection/yolov3_darknet53_270e_coco/README.md @@ -13,6 +13,8 @@ tar xf yolov3_darknet53_270e_coco.tar python -m paddle_serving_server_gpu.serve --model serving_server --port 9494 --gpu_ids 0 ``` +This model support TensorRT, if you want a faster inference, please use `--use_trt`. + ### Perform prediction ``` python test_client.py 000000570688.jpg diff --git a/python/examples/detection/yolov3_darknet53_270e_coco/README_CN.md b/python/examples/detection/yolov3_darknet53_270e_coco/README_CN.md index 1f80df8f77f301c74e08088be3bdaa5fd8c4c75a..0dd69e25cfe04f743adb7c6f3b5c50215fa4598a 100644 --- a/python/examples/detection/yolov3_darknet53_270e_coco/README_CN.md +++ b/python/examples/detection/yolov3_darknet53_270e_coco/README_CN.md @@ -11,9 +11,11 @@ wget --no-check-certificate https://paddle-serving.bj.bcebos.com/pddet_demo/2.0/ ### 启动服务 ``` tar xf yolov3_darknet53_270e_coco.tar -python -m paddle_serving_server_gpu.serve --model pddet_serving_model --port 9494 --gpu_ids 0 +python -m paddle_serving_server_gpu.serve --model serving_server --port 9494 --gpu_ids 0 ``` +该模型支持TensorRT,如果想要更快的预测速度,可以开启`--use_trt`选项。 + ### 执行预测 ``` python test_client.py 000000570688.jpg diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/args.py b/python/examples/grpc_impl_example/criteo_ctr_with_cube/args.py deleted file mode 100755 index 30124d4ebd9cd27cdb4580e654a8a47c55b178bf..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/args.py +++ /dev/null @@ -1,105 +0,0 @@ -# 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 -import argparse - - -def parse_args(): - parser = argparse.ArgumentParser(description="PaddlePaddle CTR example") - parser.add_argument( - '--train_data_path', - type=str, - default='./data/raw/train.txt', - help="The path of training dataset") - parser.add_argument( - '--sparse_only', - type=bool, - default=False, - help="Whether we use sparse features only") - parser.add_argument( - '--test_data_path', - type=str, - default='./data/raw/valid.txt', - help="The path of testing dataset") - parser.add_argument( - '--batch_size', - type=int, - default=1000, - help="The size of mini-batch (default:1000)") - parser.add_argument( - '--embedding_size', - type=int, - default=10, - help="The size for embedding layer (default:10)") - parser.add_argument( - '--num_passes', - type=int, - default=10, - help="The number of passes to train (default: 10)") - parser.add_argument( - '--model_output_dir', - type=str, - default='models', - help='The path for model to store (default: models)') - parser.add_argument( - '--sparse_feature_dim', - type=int, - default=1000001, - help='sparse feature hashing space for index processing') - parser.add_argument( - '--is_local', - type=int, - default=1, - help='Local train or distributed train (default: 1)') - parser.add_argument( - '--cloud_train', - type=int, - default=0, - help='Local train or distributed train on paddlecloud (default: 0)') - parser.add_argument( - '--async_mode', - action='store_true', - default=False, - help='Whether start pserver in async mode to support ASGD') - parser.add_argument( - '--no_split_var', - action='store_true', - default=False, - help='Whether split variables into blocks when update_method is pserver') - parser.add_argument( - '--role', - type=str, - default='pserver', # trainer or pserver - help='The path for model to store (default: models)') - parser.add_argument( - '--endpoints', - type=str, - default='127.0.0.1:6000', - help='The pserver endpoints, like: 127.0.0.1:6000,127.0.0.1:6001') - parser.add_argument( - '--current_endpoint', - type=str, - default='127.0.0.1:6000', - help='The path for model to store (default: 127.0.0.1:6000)') - parser.add_argument( - '--trainer_id', - type=int, - default=0, - help='The path for model to store (default: models)') - parser.add_argument( - '--trainers', - type=int, - default=1, - help='The num of trianers, (default: 1)') - return parser.parse_args() diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/clean.sh b/python/examples/grpc_impl_example/criteo_ctr_with_cube/clean.sh deleted file mode 100755 index 99a4819802178f1910c5fced7d4c5a39c3037e4a..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/clean.sh +++ /dev/null @@ -1,4 +0,0 @@ -ps -ef | grep cube | awk {'print $2'} | xargs kill -9 -rm -rf cube/cube_data cube/data cube/log* cube/nohup* cube/output/ cube/donefile cube/input cube/monitor cube/cube-builder.INFO -ps -ef | grep test | awk {'print $2'} | xargs kill -9 -ps -ef | grep serving | awk {'print $2'} | xargs kill -9 diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/criteo.py b/python/examples/grpc_impl_example/criteo_ctr_with_cube/criteo.py deleted file mode 100755 index f37eb1d2c1d8df6975ec0c28923c6e17c0272290..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/criteo.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys - - -class CriteoDataset(object): - def setup(self, sparse_feature_dim): - self.cont_min_ = [0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - self.cont_max_ = [ - 20, 600, 100, 50, 64000, 500, 100, 50, 500, 10, 10, 10, 50 - ] - self.cont_diff_ = [ - 20, 603, 100, 50, 64000, 500, 100, 50, 500, 10, 10, 10, 50 - ] - self.hash_dim_ = sparse_feature_dim - # here, training data are lines with line_index < train_idx_ - self.train_idx_ = 41256555 - self.continuous_range_ = range(1, 14) - self.categorical_range_ = range(14, 40) - - def _process_line(self, line): - features = line.rstrip('\n').split('\t') - dense_feature = [] - sparse_feature = [] - for idx in self.continuous_range_: - if features[idx] == '': - dense_feature.append(0.0) - else: - dense_feature.append((float(features[idx]) - self.cont_min_[idx - 1]) / \ - self.cont_diff_[idx - 1]) - for idx in self.categorical_range_: - sparse_feature.append( - [hash(str(idx) + features[idx]) % self.hash_dim_]) - - return dense_feature, sparse_feature, [int(features[0])] - - def infer_reader(self, filelist, batch, buf_size): - def local_iter(): - for fname in filelist: - with open(fname.strip(), "r") as fin: - for line in fin: - dense_feature, sparse_feature, label = self._process_line( - line) - #yield dense_feature, sparse_feature, label - yield [dense_feature] + sparse_feature + [label] - - import paddle - batch_iter = paddle.batch( - paddle.reader.shuffle( - local_iter, buf_size=buf_size), - batch_size=batch) - return batch_iter - - def generate_sample(self, line): - def data_iter(): - dense_feature, sparse_feature, label = self._process_line(line) - feature_name = ["dense_input"] - for idx in self.categorical_range_: - feature_name.append("C" + str(idx - 13)) - feature_name.append("label") - yield zip(feature_name, [dense_feature] + sparse_feature + [label]) - - return data_iter - - -if __name__ == "__main__": - criteo_dataset = CriteoDataset() - criteo_dataset.setup(int(sys.argv[1])) - criteo_dataset.run_from_stdin() diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/criteo_reader.py b/python/examples/grpc_impl_example/criteo_ctr_with_cube/criteo_reader.py deleted file mode 100755 index 2a80af78a9c2033bf246f703ca70a817ab786af3..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/criteo_reader.py +++ /dev/null @@ -1,83 +0,0 @@ -# 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 - -import sys -import paddle.fluid.incubate.data_generator as dg - - -class CriteoDataset(dg.MultiSlotDataGenerator): - def setup(self, sparse_feature_dim): - self.cont_min_ = [0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - self.cont_max_ = [ - 20, 600, 100, 50, 64000, 500, 100, 50, 500, 10, 10, 10, 50 - ] - self.cont_diff_ = [ - 20, 603, 100, 50, 64000, 500, 100, 50, 500, 10, 10, 10, 50 - ] - self.hash_dim_ = sparse_feature_dim - # here, training data are lines with line_index < train_idx_ - self.train_idx_ = 41256555 - self.continuous_range_ = range(1, 14) - self.categorical_range_ = range(14, 40) - - def _process_line(self, line): - features = line.rstrip('\n').split('\t') - dense_feature = [] - sparse_feature = [] - for idx in self.continuous_range_: - if features[idx] == '': - dense_feature.append(0.0) - else: - dense_feature.append((float(features[idx]) - self.cont_min_[idx - 1]) / \ - self.cont_diff_[idx - 1]) - for idx in self.categorical_range_: - sparse_feature.append( - [hash(str(idx) + features[idx]) % self.hash_dim_]) - - return dense_feature, sparse_feature, [int(features[0])] - - def infer_reader(self, filelist, batch, buf_size): - def local_iter(): - for fname in filelist: - with open(fname.strip(), "r") as fin: - for line in fin: - dense_feature, sparse_feature, label = self._process_line( - line) - #yield dense_feature, sparse_feature, label - yield [dense_feature] + sparse_feature + [label] - - import paddle - batch_iter = paddle.batch( - paddle.reader.shuffle( - local_iter, buf_size=buf_size), - batch_size=batch) - return batch_iter - - def generate_sample(self, line): - def data_iter(): - dense_feature, sparse_feature, label = self._process_line(line) - feature_name = ["dense_input"] - for idx in self.categorical_range_: - feature_name.append("C" + str(idx - 13)) - feature_name.append("label") - yield zip(feature_name, [dense_feature] + sparse_feature + [label]) - - return data_iter - - -if __name__ == "__main__": - criteo_dataset = CriteoDataset() - criteo_dataset.setup(int(sys.argv[1])) - criteo_dataset.run_from_stdin() diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube/conf/cube.conf b/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube/conf/cube.conf deleted file mode 100755 index b70f6e34247e410f9b80054010338d3c8f452ec6..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube/conf/cube.conf +++ /dev/null @@ -1,13 +0,0 @@ -[{ - "dict_name": "test_dict", - "shard": 1, - "dup": 1, - "timeout": 200, - "retry": 3, - "backup_request": 100, - "type": "ipport_list", - "load_balancer": "rr", - "nodes": [{ - "ipport_list": "list://127.0.0.1:8027" - }] -}] diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube/conf/gflags.conf b/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube/conf/gflags.conf deleted file mode 100755 index 21c7bddebd8f22b91d0ba26a6121007f96a4380b..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube/conf/gflags.conf +++ /dev/null @@ -1,4 +0,0 @@ ---port=8027 ---dict_split=1 ---in_mem=true ---log_dir=./log/ diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube/keys b/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube/keys deleted file mode 100755 index f00c965d8307308469e537302baa73048488f162..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube/keys +++ /dev/null @@ -1,10 +0,0 @@ -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube_quant_prepare.sh b/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube_quant_prepare.sh deleted file mode 100755 index 0db6575ab307fb81cdd0336a20bb9a8ec30d446d..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube_quant_prepare.sh +++ /dev/null @@ -1,22 +0,0 @@ -# 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 -#! /bin/bash - -mkdir -p cube_model -mkdir -p cube/data -./seq_generator ctr_serving_model/SparseFeatFactors ./cube_model/feature 8 -./cube/cube-builder -dict_name=test_dict -job_mode=base -last_version=0 -cur_version=0 -depend_version=0 -input_path=./cube_model -output_path=${PWD}/cube/data -shard_num=1 -only_build=false -mv ./cube/data/0_0/test_dict_part0/* ./cube/data/ -cd cube && ./cube diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/local_train.py b/python/examples/grpc_impl_example/criteo_ctr_with_cube/local_train.py deleted file mode 100755 index d4a1bc930924e348048f7ac3e5c46381d9b6441b..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/local_train.py +++ /dev/null @@ -1,100 +0,0 @@ -# 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 __future__ import print_function - -from args import parse_args -import os -import paddle.fluid as fluid -import sys -from network_conf import dnn_model - -dense_feature_dim = 13 - - -def train(): - args = parse_args() - sparse_only = args.sparse_only - if not os.path.isdir(args.model_output_dir): - os.mkdir(args.model_output_dir) - dense_input = fluid.layers.data( - name="dense_input", shape=[dense_feature_dim], dtype='float32') - sparse_input_ids = [ - fluid.layers.data( - name="C" + str(i), shape=[1], lod_level=1, dtype="int64") - for i in range(1, 27) - ] - label = fluid.layers.data(name='label', shape=[1], dtype='int64') - - #nn_input = None if sparse_only else dense_input - nn_input = dense_input - predict_y, loss, auc_var, batch_auc_var, infer_vars = dnn_model( - nn_input, sparse_input_ids, label, args.embedding_size, - args.sparse_feature_dim) - - optimizer = fluid.optimizer.SGD(learning_rate=1e-4) - optimizer.minimize(loss) - - exe = fluid.Executor(fluid.CPUPlace()) - exe.run(fluid.default_startup_program()) - dataset = fluid.DatasetFactory().create_dataset("InMemoryDataset") - dataset.set_use_var([dense_input] + sparse_input_ids + [label]) - - python_executable = "python" - pipe_command = "{} criteo_reader.py {}".format(python_executable, - args.sparse_feature_dim) - - dataset.set_pipe_command(pipe_command) - dataset.set_batch_size(128) - thread_num = 10 - dataset.set_thread(thread_num) - - whole_filelist = [ - "raw_data/part-%d" % x for x in range(len(os.listdir("raw_data"))) - ] - - print(whole_filelist) - dataset.set_filelist(whole_filelist[:100]) - dataset.load_into_memory() - fluid.layers.Print(auc_var) - epochs = 1 - for i in range(epochs): - exe.train_from_dataset( - program=fluid.default_main_program(), dataset=dataset, debug=True) - print("epoch {} finished".format(i)) - - import paddle_serving_client.io as server_io - feed_var_dict = {} - feed_var_dict['dense_input'] = dense_input - for i, sparse in enumerate(sparse_input_ids): - feed_var_dict["embedding_{}.tmp_0".format(i)] = sparse - fetch_var_dict = {"prob": predict_y} - - feed_kv_dict = {} - feed_kv_dict['dense_input'] = dense_input - for i, emb in enumerate(infer_vars): - feed_kv_dict["embedding_{}.tmp_0".format(i)] = emb - fetch_var_dict = {"prob": predict_y} - - server_io.save_model("ctr_serving_model", "ctr_client_conf", feed_var_dict, - fetch_var_dict, fluid.default_main_program()) - - server_io.save_model("ctr_serving_model_kv", "ctr_client_conf_kv", - feed_kv_dict, fetch_var_dict, - fluid.default_main_program()) - - -if __name__ == '__main__': - train() diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/network_conf.py b/python/examples/grpc_impl_example/criteo_ctr_with_cube/network_conf.py deleted file mode 100755 index 2975533a72ad21d6dd5896446fd06c1f9bdfe8b4..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/network_conf.py +++ /dev/null @@ -1,77 +0,0 @@ -# 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 - -import paddle.fluid as fluid -import math - - -def dnn_model(dense_input, sparse_inputs, label, embedding_size, - sparse_feature_dim): - def embedding_layer(input): - emb = fluid.layers.embedding( - input=input, - is_sparse=True, - is_distributed=False, - size=[sparse_feature_dim, embedding_size], - param_attr=fluid.ParamAttr( - name="SparseFeatFactors", - initializer=fluid.initializer.Uniform())) - x = fluid.layers.sequence_pool(input=emb, pool_type='sum') - return emb, x - - def mlp_input_tensor(emb_sums, dense_tensor): - #if isinstance(dense_tensor, fluid.Variable): - # return fluid.layers.concat(emb_sums, axis=1) - #else: - return fluid.layers.concat(emb_sums + [dense_tensor], axis=1) - - def mlp(mlp_input): - fc1 = fluid.layers.fc(input=mlp_input, - size=400, - act='relu', - param_attr=fluid.ParamAttr( - initializer=fluid.initializer.Normal( - scale=1 / math.sqrt(mlp_input.shape[1])))) - fc2 = fluid.layers.fc(input=fc1, - size=400, - act='relu', - param_attr=fluid.ParamAttr( - initializer=fluid.initializer.Normal( - scale=1 / math.sqrt(fc1.shape[1])))) - fc3 = fluid.layers.fc(input=fc2, - size=400, - act='relu', - param_attr=fluid.ParamAttr( - initializer=fluid.initializer.Normal( - scale=1 / math.sqrt(fc2.shape[1])))) - pre = fluid.layers.fc(input=fc3, - size=2, - act='softmax', - param_attr=fluid.ParamAttr( - initializer=fluid.initializer.Normal( - scale=1 / math.sqrt(fc3.shape[1])))) - return pre - - emb_pair_sums = list(map(embedding_layer, sparse_inputs)) - emb_sums = [x[1] for x in emb_pair_sums] - infer_vars = [x[0] for x in emb_pair_sums] - mlp_in = mlp_input_tensor(emb_sums, dense_input) - predict = mlp(mlp_in) - cost = fluid.layers.cross_entropy(input=predict, label=label) - avg_cost = fluid.layers.reduce_sum(cost) - accuracy = fluid.layers.accuracy(input=predict, label=label) - auc_var, batch_auc_var, auc_states = \ - fluid.layers.auc(input=predict, label=label, num_thresholds=2 ** 12, slide_steps=20) - return predict, avg_cost, auc_var, batch_auc_var, infer_vars diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_client.py b/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_client.py deleted file mode 100755 index f82c1a21c153594e0be192506af5318c24a4e99a..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_client.py +++ /dev/null @@ -1,49 +0,0 @@ -# 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_client import MultiLangClient as Client -import sys -import os -import criteo as criteo -import time -from paddle_serving_client.metric import auc -import grpc - -client = Client() -client.connect(["127.0.0.1:9292"]) - -batch = 1 -buf_size = 100 -dataset = criteo.CriteoDataset() -dataset.setup(1000001) -test_filelists = ["{}/part-0".format(sys.argv[1])] -reader = dataset.infer_reader(test_filelists, batch, buf_size) -label_list = [] -prob_list = [] -start = time.time() -for ei in range(10000): - data = reader().next() - feed_dict = {} - feed_dict['dense_input'] = data[0][0] - for i in range(1, 27): - feed_dict["embedding_{}.tmp_0".format(i - 1)] = data[0][i] - fetch_map = client.predict(feed=feed_dict, fetch=["prob"]) - if fetch_map["serving_status_code"] == 0: - prob_list.append(fetch_map['prob'][0][1]) - label_list.append(data[0][-1][0]) - -print(auc(label_list, prob_list)) -end = time.time() -print(end - start) diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_server.py b/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_server.py deleted file mode 100755 index 8a3bee4e628ddd0896c1d2facbccbf2ef493df2b..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_server.py +++ /dev/null @@ -1,41 +0,0 @@ -# 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 - -import os -import sys -from paddle_serving_server import OpMaker -from paddle_serving_server import OpSeqMaker -from paddle_serving_server import MultiLangServer as Server - -op_maker = OpMaker() -read_op = op_maker.create('general_reader') -general_dist_kv_infer_op = op_maker.create('general_dist_kv_infer') -response_op = op_maker.create('general_response') - -op_seq_maker = OpSeqMaker() -op_seq_maker.add_op(read_op) -op_seq_maker.add_op(general_dist_kv_infer_op) -op_seq_maker.add_op(response_op) - -server = Server() -server.set_op_sequence(op_seq_maker.get_op_sequence()) -server.set_num_threads(4) -server.load_model_config(sys.argv[1], sys.argv[2]) -server.prepare_server( - workdir="work_dir1", - port=9292, - device="cpu", - cube_conf="./cube/conf/cube.conf") -server.run_server() diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_server_gpu.py b/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_server_gpu.py deleted file mode 100755 index 343ded248e2ead554cd0235f890ebefc0b09c071..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_server_gpu.py +++ /dev/null @@ -1,41 +0,0 @@ -# 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 - -import os -import sys -from paddle_serving_server_gpu import OpMaker -from paddle_serving_server_gpu import OpSeqMaker -from paddle_serving_server_gpu import MultiLangServer as Server - -op_maker = OpMaker() -read_op = op_maker.create('general_reader') -general_dist_kv_infer_op = op_maker.create('general_dist_kv_infer') -response_op = op_maker.create('general_response') - -op_seq_maker = OpSeqMaker() -op_seq_maker.add_op(read_op) -op_seq_maker.add_op(general_dist_kv_infer_op) -op_seq_maker.add_op(response_op) - -server = Server() -server.set_op_sequence(op_seq_maker.get_op_sequence()) -server.set_num_threads(4) -server.load_model_config(sys.argv[1], sys.argv[2]) -server.prepare_server( - workdir="work_dir1", - port=9292, - device="cpu", - cube_conf="./cube/conf/cube.conf") -server.run_server() diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_server_quant.py b/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_server_quant.py deleted file mode 100755 index 2fd9308454b4caa862e7d83ddadb48279bba7167..0000000000000000000000000000000000000000 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/test_server_quant.py +++ /dev/null @@ -1,41 +0,0 @@ -# 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 - -import os -import sys -from paddle_serving_server import OpMaker -from paddle_serving_server import OpSeqMaker -from paddle_serving_server import MultiLangServer as Server - -op_maker = OpMaker() -read_op = op_maker.create('general_reader') -general_dist_kv_infer_op = op_maker.create('general_dist_kv_quant_infer') -response_op = op_maker.create('general_response') - -op_seq_maker = OpSeqMaker() -op_seq_maker.add_op(read_op) -op_seq_maker.add_op(general_dist_kv_infer_op) -op_seq_maker.add_op(response_op) - -server = Server() -server.set_op_sequence(op_seq_maker.get_op_sequence()) -server.set_num_threads(4) -server.load_model_config(sys.argv[1], sys.argv[2]) -server.prepare_server( - workdir="work_dir1", - port=9292, - device="cpu", - cube_conf="./cube/conf/cube.conf") -server.run_server() diff --git a/python/examples/imdb/local_train.py b/python/examples/imdb/local_train.py index 3cb08af1d5d19aa0e3f9e67d03c2d7a5b8360b0f..98333e4e3440ff464b796619736dee46002ae2a4 100644 --- a/python/examples/imdb/local_train.py +++ b/python/examples/imdb/local_train.py @@ -21,7 +21,7 @@ import paddle.fluid as fluid logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger("fluid") logger.setLevel(logging.INFO) - +paddle.enable_static() def load_vocab(filename): vocab = {} diff --git a/python/examples/ocr/rec_debugger_server.py b/python/examples/ocr/rec_debugger_server.py index 9dc7b19b7bf17096cf3a0c18d0a337f990ecd1a4..f2b3d0705e387d81781cd8d632a91037105e0e38 100644 --- a/python/examples/ocr/rec_debugger_server.py +++ b/python/examples/ocr/rec_debugger_server.py @@ -22,7 +22,10 @@ from paddle_serving_client import Client from paddle_serving_app.reader import Sequential, URL2Image, ResizeByFactor from paddle_serving_app.reader import Div, Normalize, Transpose from paddle_serving_app.reader import DBPostProcess, FilterBoxes, GetRotateCropImage, SortedBoxes -from paddle_serving_server_gpu.web_service import WebService +if sys.argv[1] == 'gpu': + from paddle_serving_server_gpu.web_service import WebService +elif sys.argv[1] == 'cpu': + from paddle_serving_server.web_service import WebService import time import re import base64 @@ -65,8 +68,12 @@ class OCRService(WebService): ocr_service = OCRService(name="ocr") ocr_service.load_model_config("ocr_rec_model") -ocr_service.set_gpus("0") -ocr_service.init_rec() -ocr_service.prepare_server(workdir="workdir", port=9292, device="gpu", gpuid=0) +if sys.argv[1] == 'gpu': + ocr_service.set_gpus("0") + ocr_service.init_rec() + ocr_service.prepare_server(workdir="workdir", port=9292, device="gpu", gpuid=0) +elif sys.argv[1] == 'cpu': + ocr_service.init_rec() + ocr_service.prepare_server(workdir="workdir", port=9292, device="cpu") ocr_service.run_debugger_service() ocr_service.run_web_service() diff --git a/python/examples/pipeline/imagenet/README_CN.md b/python/examples/pipeline/imagenet/README_CN.md index ab7f63b392a391af8ca858aa8dc8f87abe3b4afa..335c96b2144b17e20d6007f376dec4416fb10aa5 100644 --- a/python/examples/pipeline/imagenet/README_CN.md +++ b/python/examples/pipeline/imagenet/README_CN.md @@ -1,6 +1,6 @@ # Imagenet Pipeline WebService -这里以 Uci 服务为例来介绍 Pipeline WebService 的使用。 +这里以 Imagenet 服务为例来介绍 Pipeline WebService 的使用。 ## 获取模型 ``` @@ -10,10 +10,11 @@ sh get_model.sh ## 启动服务 ``` -python web_service.py &>log.txt & +python resnet50_web_service.py &>log.txt & ``` ## 测试 ``` -curl -X POST -k http://localhost:18082/uci/prediction -d '{"key": ["x"], "value": ["0.0137, -0.1136, 0.2553, -0.0692, 0.0582, -0.0727, -0.1583, -0.0584, 0.6283, 0.4919, 0.1856, 0.0795, -0.0332"]}' +python pipeline_rpc_client.py ``` + diff --git a/python/examples/pipeline/imagenet/pipeline_rpc_client.py b/python/examples/pipeline/imagenet/pipeline_rpc_client.py index 3220e6c20b27c92a59cd0c28050719a8790d648d..77157359efbdb0b416009af7cfb95f41ce65a1fb 100644 --- a/python/examples/pipeline/imagenet/pipeline_rpc_client.py +++ b/python/examples/pipeline/imagenet/pipeline_rpc_client.py @@ -11,7 +11,10 @@ # 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. -from paddle_serving_server_gpu.pipeline import PipelineClient +try: + from paddle_serving_server_gpu.pipeline import PipelineClient +except ImportError: + from paddle_serving_server.pipeline import PipelineClient import numpy as np import requests import json diff --git a/python/examples/pipeline/ocr/pipeline_http_client.py b/python/examples/pipeline/ocr/pipeline_http_client.py index 48780599b97438b81a37aadd1edc420b39aef519..9952271430b2e260be292b63f39eaf1105b06521 100644 --- a/python/examples/pipeline/ocr/pipeline_http_client.py +++ b/python/examples/pipeline/ocr/pipeline_http_client.py @@ -11,7 +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. -from paddle_serving_server.pipeline import PipelineClient +# from paddle_serving_server.pipeline import PipelineClient import numpy as np import requests import json diff --git a/python/examples/pipeline/ocr/pipeline_rpc_client.py b/python/examples/pipeline/ocr/pipeline_rpc_client.py index e7cd9e5ce4bc911c8e0ff944058236aced0727b7..ec721ec359063233c616bc4d49cf6d15ec775115 100644 --- a/python/examples/pipeline/ocr/pipeline_rpc_client.py +++ b/python/examples/pipeline/ocr/pipeline_rpc_client.py @@ -11,7 +11,10 @@ # 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. -from paddle_serving_server_gpu.pipeline import PipelineClient +try: + from paddle_serving_server_gpu.pipeline import PipelineClient +except ImportError: + from paddle_serving_server.pipeline import PipelineClient import numpy as np import requests import json diff --git a/python/examples/xpu/fit_a_line_xpu/README.md b/python/examples/xpu/fit_a_line_xpu/README.md new file mode 100644 index 0000000000000000000000000000000000000000..15c5eecbc6c0c5d63f81178d1f9465e938bf5578 --- /dev/null +++ b/python/examples/xpu/fit_a_line_xpu/README.md @@ -0,0 +1,44 @@ +# Fit a line prediction example + +([简体中文](./README_CN.md)|English) + +## Get data + +```shell +sh get_data.sh +``` + + + +## RPC service + +### Start server + +```shell +python -m paddle_serving_server_gpu.serve --model uci_housing_model --thread 10 --port 9393 --use_lite --use_xpu --ir_optim +``` + +### Client prediction + +The `paddlepaddle` package is used in `test_client.py`, and you may need to download the corresponding package(`pip install paddlepaddle`). + +``` shell +python test_client.py uci_housing_client/serving_client_conf.prototxt +``` + + + +## HTTP service + +### Start server + +Start a web service with default web service hosting modules: +``` shell +python test_server.py +``` + +### Client prediction + +``` shell +curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"x": [0.0137, -0.1136, 0.2553, -0.0692, 0.0582, -0.0727, -0.1583, -0.0584, 0.6283, 0.4919, 0.1856, 0.0795, -0.0332]}], "fetch":["price"]}' http://127.0.0.1:9292/uci/prediction +``` diff --git a/python/examples/xpu/fit_a_line_xpu/README_CN.md b/python/examples/xpu/fit_a_line_xpu/README_CN.md new file mode 100644 index 0000000000000000000000000000000000000000..5434f70e267c971497233f942f76aaf784e50c70 --- /dev/null +++ b/python/examples/xpu/fit_a_line_xpu/README_CN.md @@ -0,0 +1,51 @@ +# 线性回归预测服务示例 + +(简体中文|[English](./README.md)) + +## 获取数据 + +```shell +sh get_data.sh +``` + + + +## RPC服务 + +### 开启服务端 + +``` shell +python test_server.py uci_housing_model/ +``` + +也可以通过下面的一行代码开启默认RPC服务: + +```shell +python -m paddle_serving_server.serve --model uci_housing_model --thread 10 --port 9393 --use_lite --use_xpu --ir_optim +``` + +### 客户端预测 + +`test_client.py`中使用了`paddlepaddle`包,需要进行下载(`pip install paddlepaddle`)。 + +``` shell +python test_client.py uci_housing_client/serving_client_conf.prototxt +``` + + + +## HTTP服务 + +### 开启服务端 + +通过下面的一行代码开启默认web服务: + +``` shell +python test_server.py +``` + +### 客户端预测 + +``` shell +curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"x": [0.0137, -0.1136, 0.2553, -0.0692, 0.0582, -0.0727, -0.1583, -0.0584, 0.6283, 0.4919, 0.1856, 0.0795, -0.0332]}], "fetch":["price"]}' http://127.0.0.1:9292/uci/prediction +``` diff --git a/python/examples/xpu/fit_a_line_xpu/benchmark.py b/python/examples/xpu/fit_a_line_xpu/benchmark.py new file mode 100644 index 0000000000000000000000000000000000000000..0ddda2a095eb8542887ea592a79b16665f2daa15 --- /dev/null +++ b/python/examples/xpu/fit_a_line_xpu/benchmark.py @@ -0,0 +1,57 @@ +# 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_client import Client +from paddle_serving_client.utils import MultiThreadRunner +from paddle_serving_client.utils import benchmark_args +import time +import paddle +import sys +import requests + +args = benchmark_args() + + +def single_func(idx, resource): + if args.request == "rpc": + client = Client() + client.load_client_config(args.model) + client.connect([args.endpoint]) + train_reader = paddle.batch( + paddle.reader.shuffle( + paddle.dataset.uci_housing.train(), buf_size=500), + batch_size=1) + start = time.time() + for data in train_reader(): + fetch_map = client.predict(feed={"x": data[0][0]}, fetch=["price"]) + end = time.time() + return [[end - start]] + elif args.request == "http": + train_reader = paddle.batch( + paddle.reader.shuffle( + paddle.dataset.uci_housing.train(), buf_size=500), + batch_size=1) + start = time.time() + for data in train_reader(): + r = requests.post( + 'http://{}/uci/prediction'.format(args.endpoint), + data={"x": data[0]}) + end = time.time() + return [[end - start]] + + +multi_thread_runner = MultiThreadRunner() +result = multi_thread_runner.run(single_func, args.thread, {}) +print(result) diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/get_data.sh b/python/examples/xpu/fit_a_line_xpu/get_data.sh old mode 100755 new mode 100644 similarity index 50% rename from python/examples/grpc_impl_example/criteo_ctr_with_cube/get_data.sh rename to python/examples/xpu/fit_a_line_xpu/get_data.sh index 1f244b3a4aa81488bb493825576ba30c4b3bba22..84a3966a0ef323cef4b146d8e9489c70a7a8ae35 --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/get_data.sh +++ b/python/examples/xpu/fit_a_line_xpu/get_data.sh @@ -1,2 +1,2 @@ -wget --no-check-certificate https://paddle-serving.bj.bcebos.com/data/ctr_prediction/ctr_data.tar.gz -tar -zxvf ctr_data.tar.gz +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/xpu/fit_a_line_xpu/local_train.py b/python/examples/xpu/fit_a_line_xpu/local_train.py new file mode 100644 index 0000000000000000000000000000000000000000..3e0f8880a4d006b346712f2592d6c44986882193 --- /dev/null +++ b/python/examples/xpu/fit_a_line_xpu/local_train.py @@ -0,0 +1,53 @@ +# 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 + +import sys +import paddle +import paddle.fluid as fluid +paddle.enable_static() +train_reader = paddle.batch( + paddle.reader.shuffle( + paddle.dataset.uci_housing.train(), buf_size=500), + batch_size=16) + +test_reader = paddle.batch( + paddle.reader.shuffle( + paddle.dataset.uci_housing.test(), buf_size=500), + batch_size=16) + +x = fluid.data(name='x', shape=[None, 13], dtype='float32') +y = fluid.data(name='y', shape=[None, 1], dtype='float32') + +y_predict = fluid.layers.fc(input=x, size=1, act=None) +cost = fluid.layers.square_error_cost(input=y_predict, label=y) +avg_loss = fluid.layers.mean(cost) +sgd_optimizer = fluid.optimizer.SGD(learning_rate=0.01) +sgd_optimizer.minimize(avg_loss) + +place = fluid.CPUPlace() +feeder = fluid.DataFeeder(place=place, feed_list=[x, y]) +exe = fluid.Executor(place) +exe.run(fluid.default_startup_program()) + +import paddle_serving_client.io as serving_io + +for pass_id in range(30): + for data_train in train_reader(): + avg_loss_value, = exe.run(fluid.default_main_program(), + feed=feeder.feed(data_train), + fetch_list=[avg_loss]) + +serving_io.save_model("uci_housing_model", "uci_housing_client", {"x": x}, + {"price": y_predict}, fluid.default_main_program()) diff --git a/python/examples/fit_a_line/test_numpy_input_client.py b/python/examples/xpu/fit_a_line_xpu/test_client.py similarity index 86% rename from python/examples/fit_a_line/test_numpy_input_client.py rename to python/examples/xpu/fit_a_line_xpu/test_client.py index 8557ed09fe0118d35e1cb169cec4e93442cf927a..c480e81c0a4b84db7a36c2a8102f16121009f19c 100644 --- a/python/examples/fit_a_line/test_numpy_input_client.py +++ b/python/examples/xpu/fit_a_line_xpu/test_client.py @@ -14,8 +14,8 @@ # pylint: disable=doc-string-missing from paddle_serving_client import Client -import numpy as np import sys +import numpy as np client = Client() client.load_client_config(sys.argv[1]) @@ -28,6 +28,8 @@ test_reader = paddle.batch( batch_size=1) for data in test_reader(): + new_data = np.zeros((1, 1, 13)).astype("float32") + new_data[0] = data[0][0] fetch_map = client.predict( - feed={"x": np.array(data[0][0])}, fetch=["price"]) - print("{} {}".format(fetch_map["price"][0][0], data[0][1][0])) + feed={"x": new_data}, fetch=["price"], batch=True) + print(fetch_map) diff --git a/python/examples/xpu/fit_a_line_xpu/test_multi_process_client.py b/python/examples/xpu/fit_a_line_xpu/test_multi_process_client.py new file mode 100644 index 0000000000000000000000000000000000000000..e6120266097f8fdd446998741582a9e396cd2efd --- /dev/null +++ b/python/examples/xpu/fit_a_line_xpu/test_multi_process_client.py @@ -0,0 +1,42 @@ +# 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. + +from paddle_serving_client import Client +from paddle_serving_client.utils import MultiThreadRunner +import paddle +import numpy as np + + +def single_func(idx, resource): + client = Client() + client.load_client_config( + "./uci_housing_client/serving_client_conf.prototxt") + client.connect(["127.0.0.1:9293", "127.0.0.1:9292"]) + x = [ + 0.0137, -0.1136, 0.2553, -0.0692, 0.0582, -0.0727, -0.1583, -0.0584, + 0.6283, 0.4919, 0.1856, 0.0795, -0.0332 + ] + x = np.array(x) + for i in range(1000): + fetch_map = client.predict(feed={"x": x}, fetch=["price"]) + if fetch_map is None: + return [[None]] + return [[0]] + + +multi_thread_runner = MultiThreadRunner() +thread_num = 4 +result = multi_thread_runner.run(single_func, thread_num, {}) +if None in result[0]: + exit(1) diff --git a/python/examples/xpu/fit_a_line_xpu/test_server.py b/python/examples/xpu/fit_a_line_xpu/test_server.py new file mode 100644 index 0000000000000000000000000000000000000000..43a690f2fc60a4153ab9f38dc185e2f289a7cf25 --- /dev/null +++ b/python/examples/xpu/fit_a_line_xpu/test_server.py @@ -0,0 +1,36 @@ +# 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 +import numpy as np + + +class UciService(WebService): + def preprocess(self, feed=[], fetch=[]): + feed_batch = [] + is_batch = True + new_data = np.zeros((len(feed), 1, 13)).astype("float32") + for i, ins in enumerate(feed): + nums = np.array(ins["x"]).reshape(1, 1, 13) + new_data[i] = nums + feed = {"x": new_data} + return feed, fetch, is_batch + + +uci_service = UciService(name="uci") +uci_service.load_model_config("uci_housing_model") +uci_service.prepare_server(workdir="workdir", port=9393, use_lite=True, use_xpu=True, ir_optim=True) +uci_service.run_rpc_service() +uci_service.run_web_service() diff --git a/python/examples/xpu/resnet_v2_50_xpu/README.md b/python/examples/xpu/resnet_v2_50_xpu/README.md new file mode 100644 index 0000000000000000000000000000000000000000..28a2d6017d4a2f7faa42f2aca419806c6e6e8400 --- /dev/null +++ b/python/examples/xpu/resnet_v2_50_xpu/README.md @@ -0,0 +1,22 @@ +# Image Classification + +## Get Model + +``` +python -m paddle_serving_app.package --get_model resnet_v2_50_imagenet +tar -xzvf resnet_v2_50_imagenet.tar.gz +``` + +## RPC Service + +### Start Service + +``` +python -m paddle_serving_server_gpu.serve --model resnet_v2_50_imagenet_model --port 9393 --use_lite --use_xpu --ir_optim +``` + +### Client Prediction + +``` +python resnet50_v2_client.py +``` diff --git a/python/examples/xpu/resnet_v2_50_xpu/README_CN.md b/python/examples/xpu/resnet_v2_50_xpu/README_CN.md new file mode 100644 index 0000000000000000000000000000000000000000..d08eb0e465941f64843249ef294b52c5eec147be --- /dev/null +++ b/python/examples/xpu/resnet_v2_50_xpu/README_CN.md @@ -0,0 +1,22 @@ +# 图像分类 + +## 获取模型 + +``` +python -m paddle_serving_app.package --get_model resnet_v2_50_imagenet +tar -xzvf resnet_v2_50_imagenet.tar.gz +``` + +## RPC 服务 + +### 启动服务端 + +``` +python -m paddle_serving_server_gpu.serve --model resnet_v2_50_imagenet_model --port 9393 --use_lite --use_xpu --ir_optim +``` + +### 客户端预测 + +``` +python resnet50_v2_client.py +``` diff --git a/python/examples/xpu/resnet_v2_50_xpu/daisy.jpg b/python/examples/xpu/resnet_v2_50_xpu/daisy.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7edeca63e5f32e68550ef720d81f59df58a8eabc Binary files /dev/null and b/python/examples/xpu/resnet_v2_50_xpu/daisy.jpg differ diff --git a/python/examples/xpu/resnet_v2_50_xpu/localpredict.py b/python/examples/xpu/resnet_v2_50_xpu/localpredict.py new file mode 100644 index 0000000000000000000000000000000000000000..2e76098e9771c85788bd350257d885f3867eac87 --- /dev/null +++ b/python/examples/xpu/resnet_v2_50_xpu/localpredict.py @@ -0,0 +1,31 @@ +# 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. + +from paddle_serving_app.reader import Sequential, File2Image, Resize, CenterCrop +from paddle_serving_app.reader import RGB2BGR, Transpose, Div, Normalize +from paddle_serving_app.local_predict import LocalPredictor +import sys + +predictor = LocalPredictor() +predictor.load_model_config(sys.argv[1], use_lite=True, use_xpu=True, ir_optim=True) + +seq = Sequential([ + File2Image(), Resize(256), CenterCrop(224), RGB2BGR(), Transpose((2, 0, 1)), + Div(255), Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225], True) +]) + +image_file = "daisy.jpg" +img = seq(image_file) +fetch_map = predictor.predict(feed={"image": img}, fetch=["score"]) +print(fetch_map["score"].reshape(-1)) diff --git a/python/examples/xpu/resnet_v2_50_xpu/resnet50_client.py b/python/examples/xpu/resnet_v2_50_xpu/resnet50_client.py new file mode 100644 index 0000000000000000000000000000000000000000..b249d2a6df85f87258f66c96aaa779eb2e299613 --- /dev/null +++ b/python/examples/xpu/resnet_v2_50_xpu/resnet50_client.py @@ -0,0 +1,32 @@ +# 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. + +from paddle_serving_client import Client +from paddle_serving_app.reader import Sequential, File2Image, Resize, CenterCrop +from paddle_serving_app.reader import RGB2BGR, Transpose, Div, Normalize + +client = Client() +client.load_client_config( + "resnet_v2_50_imagenet_client/serving_client_conf.prototxt") +client.connect(["127.0.0.1:9393"]) + +seq = Sequential([ + File2Image(), Resize(256), CenterCrop(224), RGB2BGR(), Transpose((2, 0, 1)), + Div(255), Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225], True) +]) + +image_file = "daisy.jpg" +img = seq(image_file) +fetch_map = client.predict(feed={"image": img}, fetch=["score"]) +print(fetch_map["score"].reshape(-1)) diff --git a/python/paddle_serving_server/serve.py b/python/paddle_serving_server/serve.py index 63354f08ab71c9267388e2b45b3e6f931b6d0720..684af801cfb9c65b96ba4b0299e28444e11672c1 100644 --- a/python/paddle_serving_server/serve.py +++ b/python/paddle_serving_server/serve.py @@ -152,8 +152,8 @@ class MainService(BaseHTTPRequestHandler): if "key" not in post_data: return False else: - key = base64.b64decode(post_data["key"]) - with open(args.model + "/key", "w") as f: + key = base64.b64decode(post_data["key"].encode()) + with open(args.model + "/key", "wb") as f: f.write(key) return True @@ -161,8 +161,8 @@ class MainService(BaseHTTPRequestHandler): if "key" not in post_data: return False else: - key = base64.b64decode(post_data["key"]) - with open(args.model + "/key", "r") as f: + key = base64.b64decode(post_data["key"].encode()) + with open(args.model + "/key", "rb") as f: cur_key = f.read() return (key == cur_key) @@ -203,7 +203,7 @@ class MainService(BaseHTTPRequestHandler): self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() - self.wfile.write(json.dumps(response)) + self.wfile.write(json.dumps(response).encode()) if __name__ == "__main__": diff --git a/python/paddle_serving_server_gpu/serve.py b/python/paddle_serving_server_gpu/serve.py index 88a2909955be1b4342f3d6037655995aed0d7a4c..13f081e7283d4470396896d4ab31a76292498129 100644 --- a/python/paddle_serving_server_gpu/serve.py +++ b/python/paddle_serving_server_gpu/serve.py @@ -155,8 +155,8 @@ class MainService(BaseHTTPRequestHandler): if "key" not in post_data: return False else: - key = base64.b64decode(post_data["key"]) - with open(args.model + "/key", "w") as f: + key = base64.b64decode(post_data["key"].encode()) + with open(args.model + "/key", "wb") as f: f.write(key) return True @@ -164,8 +164,8 @@ class MainService(BaseHTTPRequestHandler): if "key" not in post_data: return False else: - key = base64.b64decode(post_data["key"]) - with open(args.model + "/key", "r") as f: + key = base64.b64decode(post_data["key"].encode()) + with open(args.model + "/key", "rb") as f: cur_key = f.read() return (key == cur_key) @@ -206,7 +206,7 @@ class MainService(BaseHTTPRequestHandler): self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() - self.wfile.write(json.dumps(response)) + self.wfile.write(json.dumps(response).encode()) if __name__ == "__main__": diff --git a/python/setup.py.app.in b/python/setup.py.app.in index 14dcb7b5449dd5aa0967bb845c0ec0df20b01d8f..e65e696564dae37c3032faa133ec143e1a3b8139 100644 --- a/python/setup.py.app.in +++ b/python/setup.py.app.in @@ -33,7 +33,7 @@ if '${PACK}' == 'ON': REQUIRED_PACKAGES = [ 'six >= 1.10.0', 'sentencepiece<=0.1.83', 'opencv-python<=4.2.0.32', 'pillow', - 'pyclipper' + 'pyclipper', 'shapely' ] packages=['paddle_serving_app', diff --git a/tools/Dockerfile b/tools/Dockerfile index bf4254495e5a1163455887008540945d5898182e..ab83229af56c65cb9505b524eb08fe5ce2931a5b 100644 --- a/tools/Dockerfile +++ b/tools/Dockerfile @@ -1,16 +1,187 @@ -FROM centos:7.3.1611 - -RUN yum -y install wget && \ - yum -y install epel-release && yum -y install patchelf && \ - yum -y install gcc gcc-c++ make 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 && \ - yum -y install python3 python3-devel && \ - yum clean all - -RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ - python get-pip.py && rm get-pip.py && \ - 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 +# 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 hub.baidubce.com/ctr/cuda:9.0-cudnn7-devel-ubuntu16.04 +MAINTAINER PaddlePaddle Authors + +# 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 tools/dockerfile/scripts/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 + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + patchelf git python-pip python-dev python-opencv openssh-server bison \ + wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \ + curl sed grep graphviz libjpeg-dev zlib1g-dev \ + python-matplotlib \ + automake locales clang-format swig \ + liblapack-dev liblapacke-dev libcurl4-openssl-dev \ + net-tools libtool module-init-tools vim && \ + apt-get clean -y + +RUN ln -s /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/libssl.so.10 && \ + ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so /usr/lib/libcrypto.so.10 + +RUN wget https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz -O shellcheck-v0.7.1.linux.x86_64.tar.xz && \ + tar -xf shellcheck-v0.7.1.linux.x86_64.tar.xz && cp shellcheck-v0.7.1/shellcheck /usr/bin/shellcheck && \ + rm -rf shellcheck-v0.7.1.linux.x86_64.tar.xz shellcheck-v0.7.1 + +# Downgrade gcc&&g++ +WORKDIR /usr/bin + COPY tools/dockerfile/build_scripts /build_scripts + RUN bash /build_scripts/install_gcc.sh gcc82 && rm -rf /build_scripts + RUN cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/local/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/local/bin/g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/bin/g++ + ENV PATH=/usr/local/gcc-8.2/bin:$PATH + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH + +# 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 && ldconfig + +# 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 && ldconfig + +# Install Python3.8 +RUN wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz && \ + tar -xzf Python-3.8.0.tgz && cd Python-3.8.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig + +# Install Python3.5 +RUN wget -q https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz && \ + tar -xzf Python-3.5.1.tgz && cd Python-3.5.1 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/python3.5.1 --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig +ENV PATH=/usr/local/include/python3.6m/:/usr/local/python3.5.1/include:${PATH} +ENV PATH=/usr/local/bin:/usr/local/python3.5.1/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/python3.5.1/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python3.5.1/include/python3.5:/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/local/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/local/bin/pip3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/bin/pip3.5 && ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 + +RUN rm -r /root/python_build + +# 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 && tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 && apt-get -y install unzip && unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build && python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install && \ + python3.8 setup.py install && \ + python3.7 setup.py install && \ + python3.6 setup.py install && \ + python3.5 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://dl.google.com/go/go1.14.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go +# should not be in the same line with GOROOT definition, otherwise docker build could not find GOROOT. +ENV PATH=usr/local/go/bin:/root/go/bin:${PATH} + +# 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. + +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts + +# 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 + +RUN 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 https://paddle-ci.cdn.bcebos.com/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 && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +CMD source ~/.bashrc + +# ccache 3.7.9 +RUN wget https://paddle-ci.gz.bcebos.com/ccache-3.7.9.tar.gz && \ + tar xf ccache-3.7.9.tar.gz && mkdir /usr/local/ccache-3.7.9 && cd ccache-3.7.9 && \ + ./configure -prefix=/usr/local/ccache-3.7.9 && \ + make -j8 && make install && \ + ln -s /usr/local/ccache-3.7.9/bin/ccache /usr/local/bin/ccache + +RUN python3.8 -m pip install --upgrade pip requests && \ + python3.7 -m pip install --upgrade pip requests && \ + python3.6 -m pip install --upgrade pip requests && \ + python3.5 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + +EXPOSE 22 diff --git a/tools/Dockerfile.cuda10.0-cudnn7 b/tools/Dockerfile.cuda10.0-cudnn7 index c26eaeb986cbd7d66ee51bac1444cf293800d839..74a2846ea80c795808e1de4a0894e77f93bf7312 100644 --- a/tools/Dockerfile.cuda10.0-cudnn7 +++ b/tools/Dockerfile.cuda10.0-cudnn7 @@ -1,24 +1,181 @@ -FROM nvidia/cuda:10.0-cudnn7-devel-centos7 as builder - -FROM nvidia/cuda:10.0-cudnn7-runtime-centos7 -RUN yum -y install wget && \ - yum -y install epel-release && yum -y install patchelf && \ - yum -y install gcc gcc-c++ make 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 && \ - yum -y install python3 python3-devel && \ - yum clean all - -RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ - python get-pip.py && rm get-pip.py - -RUN ln -s /usr/local/cuda-10.0/lib64/libcublas.so.10.0 /usr/local/cuda-10.0/lib64/libcublas.so && \ - echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> /root/.bashrc && \ - ln -s /usr/local/cuda-10.0/targets/x86_64-linux/lib/libcudnn.so.7 /usr/local/cuda-10.0/targets/x86_64-linux/lib/libcudnn.so && \ - echo 'export LD_LIBRARY_PATH=/usr/local/cuda-10.0/targets/x86_64-linux/lib:$LD_LIBRARY_PATH' >> /root/.bashrc && \ - echo "export LANG=en_US.utf8" >> /root/.bashrc && \ - echo "export LANGUAGE=en_US.utf8" >> /root/.bashrc && \ - mkdir -p /usr/local/cuda/extras - -COPY --from=builder /usr/local/cuda/extras/CUPTI /usr/local/cuda/extras/CUPTI +# 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 hub.baidubce.com/ctr/cuda:10.0-cudnn7-devel-ubuntu16.04 +MAINTAINER PaddlePaddle Authors + +# 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 tools/dockerfile/scripts/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 + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + patchelf git python-pip python-dev python-opencv openssh-server bison \ + wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \ + curl sed grep graphviz libjpeg-dev zlib1g-dev \ + python-matplotlib \ + automake locales clang-format swig \ + liblapack-dev liblapacke-dev libcurl4-openssl-dev \ + net-tools libtool module-init-tools vim && \ + apt-get clean -y + +RUN ln -s /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/libssl.so.10 && \ + ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so /usr/lib/libcrypto.so.10 + +RUN wget https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz -O shellcheck-v0.7.1.linux.x86_64.tar.xz && \ + tar -xf shellcheck-v0.7.1.linux.x86_64.tar.xz && cp shellcheck-v0.7.1/shellcheck /usr/bin/shellcheck && \ + rm -rf shellcheck-v0.7.1.linux.x86_64.tar.xz shellcheck-v0.7.1 + +# Downgrade gcc&&g++ +RUN apt-get update + WORKDIR /usr/bin + RUN apt install -y gcc-4.8 g++-4.8 && cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ && ln -s gcc-4.8 gcc && ln -s g++-4.8 g++ + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH + +# 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 && ldconfig + +# 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 && ldconfig + +# Install Python3.8 +RUN wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz && \ + tar -xzf Python-3.8.0.tgz && cd Python-3.8.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig + +# Install Python3.5 +RUN wget -q https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz && \ + tar -xzf Python-3.5.1.tgz && cd Python-3.5.1 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/python3.5.1 --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig +ENV PATH=/usr/local/include/python3.6m/:/usr/local/python3.5.1/include:${PATH} +ENV PATH=/usr/local/bin:/usr/local/python3.5.1/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/python3.5.1/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python3.5.1/include/python3.5:/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/local/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/local/bin/pip3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/bin/pip3.5 && ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 + +RUN rm -r /root/python_build + +# 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 && tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 && apt-get -y install unzip && unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build && python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install && \ + python3.8 setup.py install && \ + python3.7 setup.py install && \ + python3.6 setup.py install && \ + python3.5 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://dl.google.com/go/go1.14.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go +# should not be in the same line with GOROOT definition, otherwise docker build could not find GOROOT. +ENV PATH=usr/local/go/bin:/root/go/bin:${PATH} + +# 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. + +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts + +# 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 + +RUN 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 https://paddle-ci.cdn.bcebos.com/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 && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +CMD source ~/.bashrc + +# ccache 3.7.9 +RUN wget https://paddle-ci.gz.bcebos.com/ccache-3.7.9.tar.gz && \ + tar xf ccache-3.7.9.tar.gz && mkdir /usr/local/ccache-3.7.9 && cd ccache-3.7.9 && \ + ./configure -prefix=/usr/local/ccache-3.7.9 && \ + make -j8 && make install && \ + ln -s /usr/local/ccache-3.7.9/bin/ccache /usr/local/bin/ccache + +RUN python3.8 -m pip install --upgrade pip requests && \ + python3.7 -m pip install --upgrade pip requests && \ + python3.6 -m pip install --upgrade pip requests && \ + python3.5 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + +EXPOSE 22 diff --git a/tools/Dockerfile.cuda10.0-cudnn7.devel b/tools/Dockerfile.cuda10.0-cudnn7.devel index 3215ee7dee0e64a0d5583a7d2024b413d526b000..74a2846ea80c795808e1de4a0894e77f93bf7312 100644 --- a/tools/Dockerfile.cuda10.0-cudnn7.devel +++ b/tools/Dockerfile.cuda10.0-cudnn7.devel @@ -1,45 +1,181 @@ -FROM nvidia/cuda:10.0-cudnn7-devel-centos7 - -RUN 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 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 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 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 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 \ - && 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 \ - && pip3 install requests - -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 +# 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 hub.baidubce.com/ctr/cuda:10.0-cudnn7-devel-ubuntu16.04 +MAINTAINER PaddlePaddle Authors +# 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 tools/dockerfile/scripts/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 + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + patchelf git python-pip python-dev python-opencv openssh-server bison \ + wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \ + curl sed grep graphviz libjpeg-dev zlib1g-dev \ + python-matplotlib \ + automake locales clang-format swig \ + liblapack-dev liblapacke-dev libcurl4-openssl-dev \ + net-tools libtool module-init-tools vim && \ + apt-get clean -y + +RUN ln -s /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/libssl.so.10 && \ + ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so /usr/lib/libcrypto.so.10 + +RUN wget https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz -O shellcheck-v0.7.1.linux.x86_64.tar.xz && \ + tar -xf shellcheck-v0.7.1.linux.x86_64.tar.xz && cp shellcheck-v0.7.1/shellcheck /usr/bin/shellcheck && \ + rm -rf shellcheck-v0.7.1.linux.x86_64.tar.xz shellcheck-v0.7.1 + +# Downgrade gcc&&g++ +RUN apt-get update + WORKDIR /usr/bin + RUN apt install -y gcc-4.8 g++-4.8 && cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ && ln -s gcc-4.8 gcc && ln -s g++-4.8 g++ + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH + +# 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 && ldconfig + +# 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 && ldconfig + +# Install Python3.8 +RUN wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz && \ + tar -xzf Python-3.8.0.tgz && cd Python-3.8.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig + +# Install Python3.5 +RUN wget -q https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz && \ + tar -xzf Python-3.5.1.tgz && cd Python-3.5.1 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/python3.5.1 --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig +ENV PATH=/usr/local/include/python3.6m/:/usr/local/python3.5.1/include:${PATH} +ENV PATH=/usr/local/bin:/usr/local/python3.5.1/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/python3.5.1/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python3.5.1/include/python3.5:/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/local/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/local/bin/pip3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/bin/pip3.5 && ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 + +RUN rm -r /root/python_build + +# 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 && tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 && apt-get -y install unzip && unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build && python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install && \ + python3.8 setup.py install && \ + python3.7 setup.py install && \ + python3.6 setup.py install && \ + python3.5 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://dl.google.com/go/go1.14.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go +# should not be in the same line with GOROOT definition, otherwise docker build could not find GOROOT. +ENV PATH=usr/local/go/bin:/root/go/bin:${PATH} + +# 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. + +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts + +# 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 + +RUN 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 https://paddle-ci.cdn.bcebos.com/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 && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +CMD source ~/.bashrc + +# ccache 3.7.9 +RUN wget https://paddle-ci.gz.bcebos.com/ccache-3.7.9.tar.gz && \ + tar xf ccache-3.7.9.tar.gz && mkdir /usr/local/ccache-3.7.9 && cd ccache-3.7.9 && \ + ./configure -prefix=/usr/local/ccache-3.7.9 && \ + make -j8 && make install && \ + ln -s /usr/local/ccache-3.7.9/bin/ccache /usr/local/bin/ccache + +RUN python3.8 -m pip install --upgrade pip requests && \ + python3.7 -m pip install --upgrade pip requests && \ + python3.6 -m pip install --upgrade pip requests && \ + python3.5 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + +EXPOSE 22 diff --git a/tools/Dockerfile.cuda10.1-cudnn7 b/tools/Dockerfile.cuda10.1-cudnn7 new file mode 100644 index 0000000000000000000000000000000000000000..a87c40f93ba67e9e2791e96b10e7449e70fa62b3 --- /dev/null +++ b/tools/Dockerfile.cuda10.1-cudnn7 @@ -0,0 +1,187 @@ +# 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 hub.baidubce.com/ctr/cuda:10.1-cudnn7-devel-ubuntu16.04 +MAINTAINER PaddlePaddle Authors + +# 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 tools/dockerfile/scripts/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 + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + patchelf git python-pip python-dev python-opencv openssh-server bison \ + wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \ + curl sed grep graphviz libjpeg-dev zlib1g-dev \ + python-matplotlib \ + automake locales clang-format swig \ + liblapack-dev liblapacke-dev libcurl4-openssl-dev \ + net-tools libtool module-init-tools vim && \ + apt-get clean -y + +RUN ln -s /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/libssl.so.10 && \ + ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so /usr/lib/libcrypto.so.10 + +RUN wget https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz -O shellcheck-v0.7.1.linux.x86_64.tar.xz && \ + tar -xf shellcheck-v0.7.1.linux.x86_64.tar.xz && cp shellcheck-v0.7.1/shellcheck /usr/bin/shellcheck && \ + rm -rf shellcheck-v0.7.1.linux.x86_64.tar.xz shellcheck-v0.7.1 + +# Downgrade gcc&&g++ +WORKDIR /usr/bin + COPY tools/dockerfile/build_scripts /build_scripts + RUN bash /build_scripts/install_gcc.sh gcc82 && rm -rf /build_scripts + RUN cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/local/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/local/bin/g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/bin/g++ + ENV PATH=/usr/local/gcc-8.2/bin:$PATH + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH + +# 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 && ldconfig + +# 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 && ldconfig + +# Install Python3.8 +RUN wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz && \ + tar -xzf Python-3.8.0.tgz && cd Python-3.8.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig + +# Install Python3.5 +RUN wget -q https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz && \ + tar -xzf Python-3.5.1.tgz && cd Python-3.5.1 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/python3.5.1 --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig +ENV PATH=/usr/local/include/python3.6m/:/usr/local/python3.5.1/include:${PATH} +ENV PATH=/usr/local/bin:/usr/local/python3.5.1/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/python3.5.1/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python3.5.1/include/python3.5:/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/local/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/local/bin/pip3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/bin/pip3.5 && ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 + +RUN rm -r /root/python_build + +# 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 && tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 && apt-get -y install unzip && unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build && python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install && \ + python3.8 setup.py install && \ + python3.7 setup.py install && \ + python3.6 setup.py install && \ + python3.5 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://dl.google.com/go/go1.14.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go +# should not be in the same line with GOROOT definition, otherwise docker build could not find GOROOT. +ENV PATH=usr/local/go/bin:/root/go/bin:${PATH} + +# 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. + +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts + +# 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 + +RUN 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 https://paddle-ci.cdn.bcebos.com/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 && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +CMD source ~/.bashrc + +# ccache 3.7.9 +RUN wget https://paddle-ci.gz.bcebos.com/ccache-3.7.9.tar.gz && \ + tar xf ccache-3.7.9.tar.gz && mkdir /usr/local/ccache-3.7.9 && cd ccache-3.7.9 && \ + ./configure -prefix=/usr/local/ccache-3.7.9 && \ + make -j8 && make install && \ + ln -s /usr/local/ccache-3.7.9/bin/ccache /usr/local/bin/ccache + +RUN python3.8 -m pip install --upgrade pip requests && \ + python3.7 -m pip install --upgrade pip requests && \ + python3.6 -m pip install --upgrade pip requests && \ + python3.5 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + +EXPOSE 22 diff --git a/tools/Dockerfile.cuda10.1-cudnn7.devel b/tools/Dockerfile.cuda10.1-cudnn7.devel index daab4340e35702b1728a62f3b7cf5d131a20097d..a87c40f93ba67e9e2791e96b10e7449e70fa62b3 100644 --- a/tools/Dockerfile.cuda10.1-cudnn7.devel +++ b/tools/Dockerfile.cuda10.1-cudnn7.devel @@ -1,12 +1,9 @@ # 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 +FROM hub.baidubce.com/ctr/cuda:10.1-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 @@ -16,7 +13,7 @@ ENV WITH_AVX=${WITH_AVX:-ON} ENV HOME /root # Add bash enhancements -COPY ./paddle/scripts/docker/root/ /root/ +COPY tools/dockerfile/scripts/root/ /root/ # Prepare packages for Python RUN apt-get update && \ @@ -24,27 +21,39 @@ RUN apt-get update && \ libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ xz-utils tk-dev libffi-dev liblzma-dev +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + patchelf git python-pip python-dev python-opencv openssh-server bison \ + wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \ + curl sed grep graphviz libjpeg-dev zlib1g-dev \ + python-matplotlib \ + automake locales clang-format swig \ + liblapack-dev liblapacke-dev libcurl4-openssl-dev \ + net-tools libtool module-init-tools vim && \ + apt-get clean -y + +RUN ln -s /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/libssl.so.10 && \ + ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so /usr/lib/libcrypto.so.10 + +RUN wget https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz -O shellcheck-v0.7.1.linux.x86_64.tar.xz && \ + tar -xf shellcheck-v0.7.1.linux.x86_64.tar.xz && cp shellcheck-v0.7.1/shellcheck /usr/bin/shellcheck && \ + rm -rf shellcheck-v0.7.1.linux.x86_64.tar.xz shellcheck-v0.7.1 + # 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 +WORKDIR /usr/bin + COPY tools/dockerfile/build_scripts /build_scripts + RUN bash /build_scripts/install_gcc.sh gcc82 && rm -rf /build_scripts + RUN cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/local/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/local/bin/g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/bin/g++ + ENV PATH=/usr/local/gcc-8.2/bin:$PATH + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH # Install Python3.6 RUN mkdir -p /root/python_build/ && wget -q https://www.sqlite.org/2018/sqlite-autoconf-3250300.tar.gz && \ @@ -53,79 +62,76 @@ RUN mkdir -p /root/python_build/ && wget -q https://www.sqlite.org/2018/sqlite-a 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 + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig # 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 + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig -RUN rm -r /root/python_build +# Install Python3.8 +RUN wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz && \ + tar -xzf Python-3.8.0.tgz && cd Python-3.8.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig + +# Install Python3.5 +RUN wget -q https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz && \ + tar -xzf Python-3.5.1.tgz && cd Python-3.5.1 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/python3.5.1 --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig +ENV PATH=/usr/local/include/python3.6m/:/usr/local/python3.5.1/include:${PATH} +ENV PATH=/usr/local/bin:/usr/local/python3.5.1/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/python3.5.1/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python3.5.1/include/python3.5:/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/local/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/local/bin/pip3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/bin/pip3.5 && ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 -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 +RUN rm -r /root/python_build # 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 +RUN wget https://www.python.org/ftp/python/$version/Python-$version.tgz && 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 +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 +RUN mv /usr/bin/python /usr/bin/python.bak && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 +RUN wget https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip && apt-get -y install unzip && unzip setuptools-40.6.2.zip WORKDIR /home/setuptools-40.6.2 -RUN python setup.py build -RUN python setup.py install +RUN python setup.py build && 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 +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz WORKDIR pip-18.0 -RUN python setup.py install +RUN python setup.py install && \ + python3.8 setup.py install && \ + python3.7 setup.py install && \ + python3.6 setup.py install && \ + python3.5 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 | \ +RUN wget -qO- https://dl.google.com/go/go1.14.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 + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go # 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 +ENV PATH=usr/local/go/bin:/root/go/bin:${PATH} # Install TensorRT # following TensorRT.tar.gz is not the default official one, we do two miny changes: @@ -134,10 +140,10 @@ RUN curl -s -q https://glide.sh/get | sh # 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/ +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts # git credential to skip password typing RUN git config --global credential.helper store @@ -145,75 +151,37 @@ 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 +RUN 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 && \ +RUN wget -q https://paddle-ci.cdn.bcebos.com/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 +RUN mkdir /var/run/sshd && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config CMD source ~/.bashrc + +# ccache 3.7.9 +RUN wget https://paddle-ci.gz.bcebos.com/ccache-3.7.9.tar.gz && \ + tar xf ccache-3.7.9.tar.gz && mkdir /usr/local/ccache-3.7.9 && cd ccache-3.7.9 && \ + ./configure -prefix=/usr/local/ccache-3.7.9 && \ + make -j8 && make install && \ + ln -s /usr/local/ccache-3.7.9/bin/ccache /usr/local/bin/ccache + +RUN python3.8 -m pip install --upgrade pip requests && \ + python3.7 -m pip install --upgrade pip requests && \ + python3.6 -m pip install --upgrade pip requests && \ + python3.5 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + EXPOSE 22 diff --git a/tools/Dockerfile.cuda10.2-cudnn8 b/tools/Dockerfile.cuda10.2-cudnn8 new file mode 100644 index 0000000000000000000000000000000000000000..ad4b4993b5fb0b36ce61a0aca609f2e68be9f2e9 --- /dev/null +++ b/tools/Dockerfile.cuda10.2-cudnn8 @@ -0,0 +1,141 @@ +# 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 hub.baidubce.com/ctr/cuda:10.2-cudnn8-devel-ubuntu16.04 +MAINTAINER PaddlePaddle Authors + +# 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 tools/dockerfile/scripts/root/ /root/ + +# Prepare packages for Python +RUN apt-get update && \ + apt-get install -y make build-essential + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + python-pip python-dev python-opencv \ + wget tar xz-utils bzip2 \ + curl sed grep \ + python-matplotlib \ + vim && \ + apt-get clean -y + +# Downgrade gcc&&g++ +WORKDIR /usr/bin + COPY tools/dockerfile/build_scripts /build_scripts + RUN bash /build_scripts/install_gcc.sh gcc82 && rm -rf /build_scripts + RUN cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/local/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/local/bin/g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/bin/g++ + ENV PATH=/usr/local/gcc-8.2/bin:$PATH + +# install cmake +WORKDIR /home +RUN apt-get install -y make automake + +# 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 && ldconfig + +ENV PATH=/usr/local/include/python3.6m/:${PATH} +ENV PATH=/usr/local/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 + +RUN rm -r /root/python_build + +# 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 && tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 && apt-get -y install unzip && unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build && python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install && \ + python3.6 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://dl.google.com/go/go1.14.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go +# should not be in the same line with GOROOT definition, otherwise docker build could not find GOROOT. +ENV PATH=usr/local/go/bin:/root/go/bin:${PATH} + +# 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. + +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts + +# 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 + +# 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. + +# Configure OpenSSH server. c.f. https://docs.docker.com/engine/examples/running_ssh_service +RUN mkdir /var/run/sshd && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +CMD source ~/.bashrc + +RUN python3.6 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + +EXPOSE 22 diff --git a/tools/Dockerfile.cuda10.2-cudnn8.devel b/tools/Dockerfile.cuda10.2-cudnn8.devel index daab4340e35702b1728a62f3b7cf5d131a20097d..ad4b4993b5fb0b36ce61a0aca609f2e68be9f2e9 100644 --- a/tools/Dockerfile.cuda10.2-cudnn8.devel +++ b/tools/Dockerfile.cuda10.2-cudnn8.devel @@ -1,12 +1,9 @@ # 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 +FROM hub.baidubce.com/ctr/cuda:10.2-cudnn8-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 @@ -16,35 +13,35 @@ ENV WITH_AVX=${WITH_AVX:-ON} ENV HOME /root # Add bash enhancements -COPY ./paddle/scripts/docker/root/ /root/ +COPY tools/dockerfile/scripts/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 + apt-get install -y make build-essential + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + python-pip python-dev python-opencv \ + wget tar xz-utils bzip2 \ + curl sed grep \ + python-matplotlib \ + vim && \ + apt-get clean -y # 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 +WORKDIR /usr/bin + COPY tools/dockerfile/build_scripts /build_scripts + RUN bash /build_scripts/install_gcc.sh gcc82 && rm -rf /build_scripts + RUN cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/local/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/local/bin/g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/bin/g++ + ENV PATH=/usr/local/gcc-8.2/bin:$PATH + +# install cmake +WORKDIR /home +RUN apt-get install -y make automake # Install Python3.6 RUN mkdir -p /root/python_build/ && wget -q https://www.sqlite.org/2018/sqlite-autoconf-3250300.tar.gz && \ @@ -53,79 +50,56 @@ RUN mkdir -p /root/python_build/ && wget -q https://www.sqlite.org/2018/sqlite-a 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 + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig -# 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 +ENV PATH=/usr/local/include/python3.6m/:${PATH} +ENV PATH=/usr/local/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 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 +RUN wget https://www.python.org/ftp/python/$version/Python-$version.tgz && 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 +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 +RUN mv /usr/bin/python /usr/bin/python.bak && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 +RUN wget https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip && apt-get -y install unzip && unzip setuptools-40.6.2.zip WORKDIR /home/setuptools-40.6.2 -RUN python setup.py build -RUN python setup.py install +RUN python setup.py build && 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 +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz WORKDIR pip-18.0 -RUN python setup.py install +RUN python setup.py install && \ + python3.6 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 | \ +RUN wget -qO- https://dl.google.com/go/go1.14.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 + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go # 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 +ENV PATH=usr/local/go/bin:/root/go/bin:${PATH} # Install TensorRT # following TensorRT.tar.gz is not the default official one, we do two miny changes: @@ -134,10 +108,10 @@ RUN curl -s -q https://glide.sh/get | sh # 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/ +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts # git credential to skip password typing RUN git config --global credential.helper store @@ -145,75 +119,23 @@ 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 +RUN mkdir /var/run/sshd && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config CMD source ~/.bashrc + +RUN python3.6 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + EXPOSE 22 diff --git a/tools/Dockerfile.cuda11-cudnn8 b/tools/Dockerfile.cuda11-cudnn8 new file mode 100644 index 0000000000000000000000000000000000000000..07f1ba0f5d387e889843d1f1dc4e108b81e12930 --- /dev/null +++ b/tools/Dockerfile.cuda11-cudnn8 @@ -0,0 +1,189 @@ +# 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 hub.baidubce.com/ctr/cuda:11.0-cudnn8-devel-ubuntu18.04 +MAINTAINER PaddlePaddle Authors + +# ENV variables +ARG WITH_GPU +ARG WITH_AVX + +ENV WITH_GPU=${WITH_GPU:-ON} +ENV WITH_AVX=${WITH_AVX:-ON} +ENV DEBIAN_FRONTEND=noninteractive +ENV LD_LIBRARY_PATH=/usr/local/cuda-11.0/targets/x86_64-linux/lib:$LD_LIBRARY_PATH + +ENV HOME /root +# Add bash enhancements +COPY tools/dockerfile/scripts/root/ /root/ + +RUN apt-get update && \ + apt-get install -y software-properties-common && add-apt-repository ppa:deadsnakes/ppa && \ + apt-get update && \ + apt-get install -y curl wget vim git unzip unrar tar xz-utils libssl-dev bzip2 gzip \ + coreutils ntp language-pack-zh-hans python-qt4 libsm6 libxext6 libxrender-dev libgl1-mesa-glx \ + bison graphviz libjpeg-dev zlib1g-dev automake locales swig net-tools libtool module-init-tools libcurl4-openssl-dev libffi-dev + +RUN ln -s /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0 /usr/lib/libssl.so.10 && \ + ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 /usr/lib/libcrypto.so.10 + +# Downgrade gcc&&g++ +WORKDIR /usr/bin +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN bash /build_scripts/install_gcc.sh gcc82 && rm -rf /build_scripts +RUN cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ +RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/local/bin/gcc +RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/local/bin/g++ +RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/bin/gcc +RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/bin/g++ +ENV PATH=/usr/local/gcc-8.2/bin:$PATH + + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH + +# 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 && ldconfig + +# 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 && ldconfig + +# Install Python3.8 +RUN wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz && \ + tar -xzf Python-3.8.0.tgz && cd Python-3.8.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig + +# Install Python3.5 +RUN wget -q https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz && \ + tar -xzf Python-3.5.1.tgz && cd Python-3.5.1 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/python3.5.1 --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig + +ENV PATH=/usr/local/include/python3.6m/:/usr/local/python3.5.1/include:${PATH} +ENV PATH=/usr/local/bin:/usr/local/python3.5.1/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/python3.5.1/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python3.5.1/include/python3.5:/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/local/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/local/bin/pip3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/bin/pip3.5 && ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 + +RUN rm -r /root/python_build + +# 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 && tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 && apt-get -y install unzip && unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build && python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install && \ + python3.8 setup.py install && \ + python3.7 setup.py install && \ + python3.6 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 + +# remove them when apt-get support 2.27 and higher version +RUN wget -q https://ftp.gnu.org/gnu/binutils/binutils-2.33.1.tar.gz && \ + tar -xzf binutils-2.33.1.tar.gz && \ + cd binutils-2.33.1 && \ + ./configure && make -j && make install && cd .. && rm -rf binutils-2.33.1 binutils-2.33.1.tar.gz + + +# Install Go and glide +RUN wget -qO- https://dl.google.com/go/go1.14.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go +ENV PATH=/usr/local/go/bin:/root/go/bin:$PATH + + +# 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. + +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts + +# 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 + +RUN 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 https://paddle-ci.cdn.bcebos.com/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 && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +#CMD source ~/.bashrc + +# ccache 3.7.9 +RUN wget https://paddle-ci.gz.bcebos.com/ccache-3.7.9.tar.gz && \ + tar xf ccache-3.7.9.tar.gz && mkdir /usr/local/ccache-3.7.9 && cd ccache-3.7.9 && \ + ./configure -prefix=/usr/local/ccache-3.7.9 && \ + make -j8 && make install && \ + ln -s /usr/local/ccache-3.7.9/bin/ccache /usr/local/bin/ccache + +RUN ln -s /usr/share/pyshared/lsb_release.py /usr/bin/lsb_release.py +RUN python3.8 -m pip install --upgrade pip requests && \ + python3.7 -m pip install --upgrade pip requests && \ + python3.6 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + +EXPOSE 22 diff --git a/tools/Dockerfile.cuda11-cudnn8.devel b/tools/Dockerfile.cuda11-cudnn8.devel index daab4340e35702b1728a62f3b7cf5d131a20097d..07f1ba0f5d387e889843d1f1dc4e108b81e12930 100644 --- a/tools/Dockerfile.cuda11-cudnn8.devel +++ b/tools/Dockerfile.cuda11-cudnn8.devel @@ -1,50 +1,54 @@ # 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 +FROM hub.baidubce.com/ctr/cuda:11.0-cudnn8-devel-ubuntu18.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 DEBIAN_FRONTEND=noninteractive +ENV LD_LIBRARY_PATH=/usr/local/cuda-11.0/targets/x86_64-linux/lib:$LD_LIBRARY_PATH ENV HOME /root # Add bash enhancements -COPY ./paddle/scripts/docker/root/ /root/ +COPY tools/dockerfile/scripts/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 + apt-get install -y software-properties-common && add-apt-repository ppa:deadsnakes/ppa && \ + apt-get update && \ + apt-get install -y curl wget vim git unzip unrar tar xz-utils libssl-dev bzip2 gzip \ + coreutils ntp language-pack-zh-hans python-qt4 libsm6 libxext6 libxrender-dev libgl1-mesa-glx \ + bison graphviz libjpeg-dev zlib1g-dev automake locales swig net-tools libtool module-init-tools libcurl4-openssl-dev libffi-dev + +RUN ln -s /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0 /usr/lib/libssl.so.10 && \ + ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 /usr/lib/libcrypto.so.10 # 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 +WORKDIR /usr/bin +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN bash /build_scripts/install_gcc.sh gcc82 && rm -rf /build_scripts +RUN cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ +RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/local/bin/gcc +RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/local/bin/g++ +RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/bin/gcc +RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/bin/g++ +ENV PATH=/usr/local/gcc-8.2/bin:$PATH + + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH # Install Python3.6 RUN mkdir -p /root/python_build/ && wget -q https://www.sqlite.org/2018/sqlite-autoconf-3250300.tar.gz && \ @@ -53,79 +57,83 @@ RUN mkdir -p /root/python_build/ && wget -q https://www.sqlite.org/2018/sqlite-a 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 + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig # 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 + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig -RUN rm -r /root/python_build +# Install Python3.8 +RUN wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz && \ + tar -xzf Python-3.8.0.tgz && cd Python-3.8.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig -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 Python3.5 +RUN wget -q https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz && \ + tar -xzf Python-3.5.1.tgz && cd Python-3.5.1 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/python3.5.1 --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig + +ENV PATH=/usr/local/include/python3.6m/:/usr/local/python3.5.1/include:${PATH} +ENV PATH=/usr/local/bin:/usr/local/python3.5.1/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/python3.5.1/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python3.5.1/include/python3.5:/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/local/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/local/bin/pip3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/bin/pip3.5 && ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 + +RUN rm -r /root/python_build # 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 +RUN wget https://www.python.org/ftp/python/$version/Python-$version.tgz && 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 +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 +RUN mv /usr/bin/python /usr/bin/python.bak && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 +RUN wget https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip && apt-get -y install unzip && unzip setuptools-40.6.2.zip WORKDIR /home/setuptools-40.6.2 -RUN python setup.py build -RUN python setup.py install +RUN python setup.py build && 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 +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz WORKDIR pip-18.0 -RUN python setup.py install +RUN python setup.py install && \ + python3.8 setup.py install && \ + python3.7 setup.py install && \ + python3.6 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 +# remove them when apt-get support 2.27 and higher version +RUN wget -q https://ftp.gnu.org/gnu/binutils/binutils-2.33.1.tar.gz && \ + tar -xzf binutils-2.33.1.tar.gz && \ + cd binutils-2.33.1 && \ + ./configure && make -j && make install && cd .. && rm -rf binutils-2.33.1 binutils-2.33.1.tar.gz + + # Install Go and glide -RUN wget -qO- https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz | \ +RUN wget -qO- https://dl.google.com/go/go1.14.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 + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go +ENV PATH=/usr/local/go/bin:/root/go/bin:$PATH + # Install TensorRT # following TensorRT.tar.gz is not the default official one, we do two miny changes: @@ -134,10 +142,10 @@ RUN curl -s -q https://glide.sh/get | sh # 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/ +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts # git credential to skip password typing RUN git config --global credential.helper store @@ -145,75 +153,37 @@ 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 +RUN 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 && \ +RUN wget -q https://paddle-ci.cdn.bcebos.com/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 +#RUN mkdir /var/run/sshd && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +#CMD source ~/.bashrc + +# ccache 3.7.9 +RUN wget https://paddle-ci.gz.bcebos.com/ccache-3.7.9.tar.gz && \ + tar xf ccache-3.7.9.tar.gz && mkdir /usr/local/ccache-3.7.9 && cd ccache-3.7.9 && \ + ./configure -prefix=/usr/local/ccache-3.7.9 && \ + make -j8 && make install && \ + ln -s /usr/local/ccache-3.7.9/bin/ccache /usr/local/bin/ccache + +RUN ln -s /usr/share/pyshared/lsb_release.py /usr/bin/lsb_release.py +RUN python3.8 -m pip install --upgrade pip requests && \ + python3.7 -m pip install --upgrade pip requests && \ + python3.6 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + EXPOSE 22 diff --git a/tools/Dockerfile.cuda9.0-cudnn7 b/tools/Dockerfile.cuda9.0-cudnn7 index ead1cfe77d7148789d84bc01fb05cedda5ff1fe6..eb715683be9f6da1d8a00eaa085a81688c11a3b3 100644 --- a/tools/Dockerfile.cuda9.0-cudnn7 +++ b/tools/Dockerfile.cuda9.0-cudnn7 @@ -1,24 +1,181 @@ -FROM nvidia/cuda:9.0-cudnn7-devel-centos7 as builder - -FROM nvidia/cuda:9.0-cudnn7-runtime-centos7 -RUN yum -y install wget && \ - yum -y install epel-release && yum -y install patchelf && \ - yum -y install gcc gcc-c++ make 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 && \ - yum -y install python3 python3-devel && \ - yum clean all - -RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ - python get-pip.py && rm get-pip.py - -RUN ln -s /usr/local/cuda-9.0/lib64/libcublas.so.9.0 /usr/local/cuda-9.0/lib64/libcublas.so && \ - echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> /root/.bashrc && \ - ln -s /usr/local/cuda-9.0/targets/x86_64-linux/lib/libcudnn.so.7 /usr/local/cuda-9.0/targets/x86_64-linux/lib/libcudnn.so && \ - echo 'export LD_LIBRARY_PATH=/usr/local/cuda-9.0/targets/x86_64-linux/lib:$LD_LIBRARY_PATH' >> /root/.bashrc && \ - echo "export LANG=en_US.utf8" >> /root/.bashrc && \ - echo "export LANGUAGE=en_US.utf8" >> /root/.bashrc && \ - mkdir -p /usr/local/cuda/extras - -COPY --from=builder /usr/local/cuda/extras/CUPTI /usr/local/cuda/extras/CUPTI +# 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 hub.baidubce.com/ctr/cuda:9.0-cudnn7-devel-ubuntu16.04 +MAINTAINER PaddlePaddle Authors + +# 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 tools/dockerfile/scripts/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 + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + patchelf git python-pip python-dev python-opencv openssh-server bison \ + wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \ + curl sed grep graphviz libjpeg-dev zlib1g-dev \ + python-matplotlib \ + automake locales clang-format swig \ + liblapack-dev liblapacke-dev libcurl4-openssl-dev \ + net-tools libtool module-init-tools vim && \ + apt-get clean -y + +RUN ln -s /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/libssl.so.10 && \ + ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so /usr/lib/libcrypto.so.10 + +RUN wget https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz -O shellcheck-v0.7.1.linux.x86_64.tar.xz && \ + tar -xf shellcheck-v0.7.1.linux.x86_64.tar.xz && cp shellcheck-v0.7.1/shellcheck /usr/bin/shellcheck && \ + rm -rf shellcheck-v0.7.1.linux.x86_64.tar.xz shellcheck-v0.7.1 + +# Downgrade gcc&&g++ +RUN apt-get update + WORKDIR /usr/bin + RUN apt install -y gcc-4.8 g++-4.8 && cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ && ln -s gcc-4.8 gcc && ln -s g++-4.8 g++ + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH + +# 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 && ldconfig + +# 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 && ldconfig + +# Install Python3.8 +RUN wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz && \ + tar -xzf Python-3.8.0.tgz && cd Python-3.8.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig + +# Install Python3.5 +RUN wget -q https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz && \ + tar -xzf Python-3.5.1.tgz && cd Python-3.5.1 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/python3.5.1 --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig +ENV PATH=/usr/local/include/python3.6m/:/usr/local/python3.5.1/include:${PATH} +ENV PATH=/usr/local/bin:/usr/local/python3.5.1/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/python3.5.1/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python3.5.1/include/python3.5:/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/local/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/local/bin/pip3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/bin/pip3.5 && ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 + +RUN rm -r /root/python_build + +# 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 && tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 && apt-get -y install unzip && unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build && python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install && \ + python3.8 setup.py install && \ + python3.7 setup.py install && \ + python3.6 setup.py install && \ + python3.5 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://dl.google.com/go/go1.14.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go +# should not be in the same line with GOROOT definition, otherwise docker build could not find GOROOT. +ENV PATH=usr/local/go/bin:/root/go/bin:${PATH} + +# 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. + +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts + +# 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 + +RUN 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 https://paddle-ci.cdn.bcebos.com/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 && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +CMD source ~/.bashrc + +# ccache 3.7.9 +RUN wget https://paddle-ci.gz.bcebos.com/ccache-3.7.9.tar.gz && \ + tar xf ccache-3.7.9.tar.gz && mkdir /usr/local/ccache-3.7.9 && cd ccache-3.7.9 && \ + ./configure -prefix=/usr/local/ccache-3.7.9 && \ + make -j8 && make install && \ + ln -s /usr/local/ccache-3.7.9/bin/ccache /usr/local/bin/ccache + +RUN python3.8 -m pip install --upgrade pip requests && \ + python3.7 -m pip install --upgrade pip requests && \ + python3.6 -m pip install --upgrade pip requests && \ + python3.5 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + +EXPOSE 22 diff --git a/tools/Dockerfile.cuda9.0-cudnn7.devel b/tools/Dockerfile.cuda9.0-cudnn7.devel index 42b2d7eb5c0766c8a97130ec93ea5945607cf32b..eb715683be9f6da1d8a00eaa085a81688c11a3b3 100644 --- a/tools/Dockerfile.cuda9.0-cudnn7.devel +++ b/tools/Dockerfile.cuda9.0-cudnn7.devel @@ -1,42 +1,181 @@ -FROM nvidia/cuda:9.0-cudnn7-devel-centos7 -RUN 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 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 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 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 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 \ - && 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 \ - && pip3 install requests - -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 +# 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 hub.baidubce.com/ctr/cuda:9.0-cudnn7-devel-ubuntu16.04 +MAINTAINER PaddlePaddle Authors + +# 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 tools/dockerfile/scripts/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 + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + patchelf git python-pip python-dev python-opencv openssh-server bison \ + wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \ + curl sed grep graphviz libjpeg-dev zlib1g-dev \ + python-matplotlib \ + automake locales clang-format swig \ + liblapack-dev liblapacke-dev libcurl4-openssl-dev \ + net-tools libtool module-init-tools vim && \ + apt-get clean -y + +RUN ln -s /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/libssl.so.10 && \ + ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so /usr/lib/libcrypto.so.10 + +RUN wget https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz -O shellcheck-v0.7.1.linux.x86_64.tar.xz && \ + tar -xf shellcheck-v0.7.1.linux.x86_64.tar.xz && cp shellcheck-v0.7.1/shellcheck /usr/bin/shellcheck && \ + rm -rf shellcheck-v0.7.1.linux.x86_64.tar.xz shellcheck-v0.7.1 + +# Downgrade gcc&&g++ +RUN apt-get update + WORKDIR /usr/bin + RUN apt install -y gcc-4.8 g++-4.8 && cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ && ln -s gcc-4.8 gcc && ln -s g++-4.8 g++ + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH + +# 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 && ldconfig + +# 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 && ldconfig + +# Install Python3.8 +RUN wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz && \ + tar -xzf Python-3.8.0.tgz && cd Python-3.8.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig + +# Install Python3.5 +RUN wget -q https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz && \ + tar -xzf Python-3.5.1.tgz && cd Python-3.5.1 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/python3.5.1 --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig +ENV PATH=/usr/local/include/python3.6m/:/usr/local/python3.5.1/include:${PATH} +ENV PATH=/usr/local/bin:/usr/local/python3.5.1/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/python3.5.1/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python3.5.1/include/python3.5:/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/local/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/local/bin/pip3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/bin/pip3.5 && ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 + +RUN rm -r /root/python_build + +# 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 && tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 && apt-get -y install unzip && unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build && python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install && \ + python3.8 setup.py install && \ + python3.7 setup.py install && \ + python3.6 setup.py install && \ + python3.5 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://dl.google.com/go/go1.14.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go +# should not be in the same line with GOROOT definition, otherwise docker build could not find GOROOT. +ENV PATH=usr/local/go/bin:/root/go/bin:${PATH} + +# 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. + +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts + +# 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 + +RUN 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 https://paddle-ci.cdn.bcebos.com/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 && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +CMD source ~/.bashrc + +# ccache 3.7.9 +RUN wget https://paddle-ci.gz.bcebos.com/ccache-3.7.9.tar.gz && \ + tar xf ccache-3.7.9.tar.gz && mkdir /usr/local/ccache-3.7.9 && cd ccache-3.7.9 && \ + ./configure -prefix=/usr/local/ccache-3.7.9 && \ + make -j8 && make install && \ + ln -s /usr/local/ccache-3.7.9/bin/ccache /usr/local/bin/ccache + +RUN python3.8 -m pip install --upgrade pip requests && \ + python3.7 -m pip install --upgrade pip requests && \ + python3.6 -m pip install --upgrade pip requests && \ + python3.5 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + +EXPOSE 22 diff --git a/tools/Dockerfile.devel b/tools/Dockerfile.devel index a0f1d03983466b3ca70ce2d4673ad8874e323a08..ab83229af56c65cb9505b524eb08fe5ce2931a5b 100644 --- a/tools/Dockerfile.devel +++ b/tools/Dockerfile.devel @@ -1,32 +1,187 @@ -FROM centos:7.3.1611 -RUN yum -y install wget \ - && yum -y install gcc gcc-c++ make glibc-static which \ - && yum -y install git openssl-devel curl-devel bzip2-devel python-devel - -RUN 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 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 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 \ - && 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 \ - && pip3 install requests - -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 +# 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 hub.baidubce.com/ctr/cuda:9.0-cudnn7-devel-ubuntu16.04 +MAINTAINER PaddlePaddle Authors + +# 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 tools/dockerfile/scripts/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 + +RUN apt-get update && \ + apt-get install -y --allow-downgrades --allow-change-held-packages \ + patchelf git python-pip python-dev python-opencv openssh-server bison \ + wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \ + curl sed grep graphviz libjpeg-dev zlib1g-dev \ + python-matplotlib \ + automake locales clang-format swig \ + liblapack-dev liblapacke-dev libcurl4-openssl-dev \ + net-tools libtool module-init-tools vim && \ + apt-get clean -y + +RUN ln -s /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/libssl.so.10 && \ + ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so /usr/lib/libcrypto.so.10 + +RUN wget https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz -O shellcheck-v0.7.1.linux.x86_64.tar.xz && \ + tar -xf shellcheck-v0.7.1.linux.x86_64.tar.xz && cp shellcheck-v0.7.1/shellcheck /usr/bin/shellcheck && \ + rm -rf shellcheck-v0.7.1.linux.x86_64.tar.xz shellcheck-v0.7.1 + +# Downgrade gcc&&g++ +WORKDIR /usr/bin + COPY tools/dockerfile/build_scripts /build_scripts + RUN bash /build_scripts/install_gcc.sh gcc82 && rm -rf /build_scripts + RUN cp gcc gcc.bak && cp g++ g++.bak && rm gcc && rm g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/local/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/local/bin/g++ + RUN ln -s /usr/local/gcc-8.2/bin/gcc /usr/bin/gcc + RUN ln -s /usr/local/gcc-8.2/bin/g++ /usr/bin/g++ + ENV PATH=/usr/local/gcc-8.2/bin:$PATH + +# install cmake +WORKDIR /home +RUN wget -q https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.tar.gz && tar -zxvf cmake-3.16.0-Linux-x86_64.tar.gz && rm cmake-3.16.0-Linux-x86_64.tar.gz +ENV PATH=/home/cmake-3.16.0-Linux-x86_64/bin:$PATH + +# 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 && ldconfig + +# 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 && ldconfig + +# Install Python3.8 +RUN wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz && \ + tar -xzf Python-3.8.0.tgz && cd Python-3.8.0 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/ --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig + +# Install Python3.5 +RUN wget -q https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz && \ + tar -xzf Python-3.5.1.tgz && cd Python-3.5.1 && \ + CFLAGS="-Wformat" ./configure --prefix=/usr/local/python3.5.1 --enable-shared > /dev/null && \ + make -j8 > /dev/null && make altinstall > /dev/null && ldconfig +ENV PATH=/usr/local/include/python3.6m/:/usr/local/python3.5.1/include:${PATH} +ENV PATH=/usr/local/bin:/usr/local/python3.5.1/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/python3.5.1/lib:${LD_LIBRARY_PATH} +ENV CPLUS_INCLUDE_PATH=/usr/local/python3.5.1/include/python3.5:/usr/local/include/python3.6m/:$CPLUS_INCLUDE_PATH +RUN ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/local/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/python3.5 /usr/bin/python3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/local/bin/pip3.5 && ln -sf /usr/local/python3.5.1/bin/pip3.5 /usr/bin/pip3.5 && ln -sf /usr/local/bin/python3.6 /usr/local/bin/python3 && ln -sf /usr/local/bin/python3.6 /usr/bin/python3 && ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip3 && ln -sf /usr/local/bin/pip3.6 /usr/bin/pip3 + +RUN rm -r /root/python_build + +# 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 && tar -xvf Python-$version.tgz +WORKDIR /home/Python-$version +RUN ./configure --enable-unicode=ucs4 --enable-shared CFLAGS=-fPIC --prefix=/usr/local/python2.7.15 && make && make install + +RUN echo "export PATH=/usr/local/python2.7.15/include:${PATH}" >> ~/.bashrc && echo "export PATH=/usr/local/python2.7.15/bin:${PATH}" >> ~/.bashrc && echo "export LD_LIBRARY_PATH=/usr/local/python2.7.15/lib:${LD_LIBRARY_PATH}" >> ~/.bashrc && 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 && ln -s /usr/local/python2.7.15/bin/python2.7 /usr/local/bin/python && 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 && apt-get -y install unzip && unzip setuptools-40.6.2.zip +WORKDIR /home/setuptools-40.6.2 +RUN python setup.py build && python setup.py install +WORKDIR /home +RUN wget https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz && tar -zxvf pip-18.0.tar.gz +WORKDIR pip-18.0 +RUN python setup.py install && \ + python3.8 setup.py install && \ + python3.7 setup.py install && \ + python3.6 setup.py install && \ + python3.5 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://dl.google.com/go/go1.14.linux-amd64.tar.gz | \ + tar -xz -C /usr/local && \ + mkdir /root/go && \ + mkdir /root/go/bin && \ + mkdir /root/go/src && \ + echo "GOROOT=/usr/local/go" >> /root/.bashrc && \ + echo "GOPATH=/root/go" >> /root/.bashrc && \ + echo "PATH=/usr/local/go/bin:/root/go/bin:$PATH" >> /root/.bashrc +ENV GOROOT=/usr/local/go GOPATH=/root/go +# should not be in the same line with GOROOT definition, otherwise docker build could not find GOROOT. +ENV PATH=usr/local/go/bin:/root/go/bin:${PATH} + +# 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. + +# Downgrade TensorRT +COPY tools/dockerfile/build_scripts /build_scripts +RUN bash /build_scripts/install_trt.sh +RUN rm -rf /build_scripts + +# 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 + +RUN 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 https://paddle-ci.cdn.bcebos.com/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 && echo 'root:root' | chpasswd && sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config +CMD source ~/.bashrc + +# ccache 3.7.9 +RUN wget https://paddle-ci.gz.bcebos.com/ccache-3.7.9.tar.gz && \ + tar xf ccache-3.7.9.tar.gz && mkdir /usr/local/ccache-3.7.9 && cd ccache-3.7.9 && \ + ./configure -prefix=/usr/local/ccache-3.7.9 && \ + make -j8 && make install && \ + ln -s /usr/local/ccache-3.7.9/bin/ccache /usr/local/bin/ccache + +RUN python3.8 -m pip install --upgrade pip requests && \ + python3.7 -m pip install --upgrade pip requests && \ + python3.6 -m pip install --upgrade pip requests && \ + python3.5 -m pip install --upgrade pip requests && \ + python2.7 -m pip install --upgrade pip requests + +RUN wget https://paddle-serving.bj.bcebos.com/others/centos_ssl.tar && \ + tar xf centos_ssl.tar && rm -rf centos_ssl.tar && \ + mv libcrypto.so.1.0.2k /usr/lib/libcrypto.so.1.0.2k && mv libssl.so.1.0.2k /usr/lib/libssl.so.1.0.2k && \ + ln -sf /usr/lib/libcrypto.so.1.0.2k /usr/lib/libcrypto.so.10 && \ + ln -sf /usr/lib/libssl.so.1.0.2k /usr/lib/libssl.so.10 && \ + ln -sf /usr/lib/libcrypto.so.10 /usr/lib/libcrypto.so && \ + ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so + +EXPOSE 22 diff --git a/tools/dockerfile/build_scripts/build.sh b/tools/dockerfile/build_scripts/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..7d5e019443229e116599f804f714e599fcc72fbc --- /dev/null +++ b/tools/dockerfile/build_scripts/build.sh @@ -0,0 +1,163 @@ +#!/bin/bash + +# 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. + +# Top-level build script called from Dockerfile + +# Stop at any error, show all commands +set -ex + +# Python versions to be installed in /opt/$VERSION_NO +# NOTE Only need python 2.7.11 for nupic.core/nupic.bindings at this time, so +# remove others to expedite build and reduce docker image size. The original +# manylinux docker image project builds many python versions. +# NOTE We added back 3.5.1, since auditwheel requires python 3.3+ +CPYTHON_VERSIONS="3.8.0 3.7.0 3.6.0 3.5.1 2.7.15" + +# openssl version to build, with expected sha256 hash of .tar.gz +# archive +OPENSSL_ROOT=openssl-1.0.2g +OPENSSL_HASH=b784b1b3907ce39abf4098702dade6365522a253ad1552e267a9a0e89594aa33 +PATCHELF_HASH=f2aa40a6148cb3b0ca807a1bf836b081793e55ec9e5540a5356d800132be7e0a +CURL_ROOT=curl-7.49.1 +CURL_HASH=eb63cec4bef692eab9db459033f409533e6d10e20942f4b060b32819e81885f1 +AUTOCONF_ROOT=autoconf-2.69 +AUTOCONF_HASH=954bd69b391edc12d6a4a51a2dd1476543da5c6bbf05a95b59dc0dd6fd4c2969 + +# Dependencies for compiling Python that we want to remove from +# the final image after compiling Python +PYTHON_COMPILE_DEPS="zlib-devel bzip2-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel" + +# Libraries that are allowed as part of the manylinux1 profile +MANYLINUX1_DEPS="glibc-devel libstdc++-devel glib2-devel libX11-devel libXext-devel libXrender-devel mesa-libGL-devel libICE-devel libSM-devel ncurses-devel freetype-devel libpng-devel" + +# Get build utilities +MY_DIR=$(dirname "${BASH_SOURCE[0]}") +source $MY_DIR/build_utils.sh + +# EPEL support +yum -y install wget curl epel-release + +# Development tools and libraries +yum -y install bzip2 make git patch unzip bison yasm diffutils \ + automake which file \ + kernel-devel-`uname -r` \ + devtoolset-2-binutils devtoolset-2-gcc \ + devtoolset-2-gcc-c++ devtoolset-2-gcc-gfortran \ + ${PYTHON_COMPILE_DEPS} + +# Install more recent version of cmake +# curl -O https://cmake.org/files/v3.8/cmake-3.8.1-Linux-x86_64.sh +# /bin/sh cmake-3.8.1-Linux-x86_64.sh --prefix=/usr/local --skip-license +# rm cmake-3.8.1-Linux-x86_64.sh + +wget -q https://cmake.org/files/v3.16/cmake-3.16.0.tar.gz && tar xzf cmake-3.16.0.tar.gz && \ +cd cmake-3.16.0 && ./bootstrap && \ +make -j8 && make install && cd .. && rm cmake-3.16.0.tar.gz && rm -rf cmake-3.16.0 + +# Install newest autoconf +build_autoconf $AUTOCONF_ROOT $AUTOCONF_HASH +autoconf --version + +# Compile the latest Python releases. +# (In order to have a proper SSL module, Python is compiled +# against a recent openssl [see env vars above], which is linked +# statically. We delete openssl afterwards.) +build_openssl $OPENSSL_ROOT $OPENSSL_HASH +mkdir -p /opt/python +build_cpythons $CPYTHON_VERSIONS + +PY35_BIN=/opt/python/cp35-cp35m/bin +PY36_BIN=/opt/python/cp36-cp36m/bin +PY37_BIN=/opt/python/cp37-cp37m/bin +PY38_BIN=/opt/python/cp38-cp38m/bin +# NOTE Since our custom manylinux image builds pythons with shared +# libpython, we need to add libpython's dir to LD_LIBRARY_PATH before running +# python. +ORIGINAL_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" +LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname ${PY35_BIN})/lib:$(dirname ${PY36_BIN})/lib:$(dirname ${PY37_BIN})/lib:$(dirname ${PY38_BIN})/lib" + +# Our openssl doesn't know how to find the system CA trust store +# (https://github.com/pypa/manylinux/issues/53) +# And it's not clear how up-to-date that is anyway +# So let's just use the same one pip and everyone uses +LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname ${PY35_BIN})/lib" $PY35_BIN/pip install certifi +ln -s $($PY35_BIN/python -c 'import certifi; print(certifi.where())') \ + /opt/_internal/certs.pem +# If you modify this line you also have to modify the versions in the +# Dockerfiles: +export SSL_CERT_FILE=/opt/_internal/certs.pem + +# Install newest curl +build_curl $CURL_ROOT $CURL_HASH +rm -rf /usr/local/include/curl /usr/local/lib/libcurl* /usr/local/lib/pkgconfig/libcurl.pc +hash -r +curl --version +curl-config --features + +# Install patchelf (latest with unreleased bug fixes) +# FIXME(typhoonzero): restore this when the link is fixed. +# curl -sLO http://nipy.bic.berkeley.edu/manylinux/patchelf-0.9njs2.tar.gz +# check_sha256sum patchelf-0.9njs2.tar.gz $PATCHELF_HASH +# tar -xzf patchelf-0.9njs2.tar.gz +# (cd patchelf-0.9njs2 && ./configure && make && make install) +# rm -rf patchelf-0.9njs2.tar.gz patchelf-0.9njs2 +yum install -y patchelf + +# Install latest pypi release of auditwheel +LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname ${PY35_BIN})/lib" $PY35_BIN/pip install auditwheel +ln -s $PY35_BIN/auditwheel /usr/local/bin/auditwheel + +# Clean up development headers and other unnecessary stuff for +# final image +yum -y erase wireless-tools gtk2 libX11 hicolor-icon-theme \ + avahi freetype bitstream-vera-fonts \ + ${PYTHON_COMPILE_DEPS} > /dev/null 2>&1 || true +yum -y install ${MANYLINUX1_DEPS} && yum -y clean all > /dev/null 2>&1 || true +yum list installed +# we don't need libpython*.a, and they're many megabytes +find /opt/_internal -name '*.a' -print0 | xargs -0 rm -f +# Strip what we can -- and ignore errors, because this just attempts to strip +# *everything*, including non-ELF files: +find /opt/_internal -type f -print0 \ + | xargs -0 -n1 strip --strip-unneeded 2>/dev/null || true +# We do not need the Python test suites, or indeed the precompiled .pyc and +# .pyo files. Partially cribbed from: +# https://github.com/docker-library/python/blob/master/3.4/slim/Dockerfile +find /opt/_internal \ + \( -type d -a -name test -o -name tests \) \ + -o \( -type f -a -name '*.pyc' -o -name '*.pyo' \) \ + -print0 | xargs -0 rm -f + +for PYTHON in /opt/python/*/bin/python; do + # Add matching directory of libpython shared library to library lookup path + LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname $(dirname ${PYTHON}))/lib" + + # Smoke test to make sure that our Pythons work, and do indeed detect as + # being manylinux compatible: + LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname $(dirname ${PYTHON}))/lib" $PYTHON $MY_DIR/manylinux1-check.py + # Make sure that SSL cert checking works + LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname $(dirname ${PYTHON}))/lib" $PYTHON $MY_DIR/ssl-check.py +done + +# Restore LD_LIBRARY_PATH +LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}" + +# According to ar issues: https://lists.gnu.org/archive/html/bug-binutils/2016-05/msg00211.html +# we should install new version ar with 64-bit supported here +wget https://ftp.gnu.org/gnu/binutils/binutils-2.27.tar.gz +tar xzf binutils-2.27.tar.gz && cd binutils-2.27 +./configure --prefix=/opt/rh/devtoolset-2/root/usr/ --enable-64-bit-archive && make -j `nproc` && make install +cd .. && rm binutils-2.27.tar.gz && rm -rf binutils-2.27 diff --git a/tools/dockerfile/build_scripts/build_utils.sh b/tools/dockerfile/build_scripts/build_utils.sh new file mode 100755 index 0000000000000000000000000000000000000000..b69ef8d628e4638cf07cc238d8b679d2874a5c67 --- /dev/null +++ b/tools/dockerfile/build_scripts/build_utils.sh @@ -0,0 +1,223 @@ +#!/bin/bash + +# 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. + +# Helper utilities for build + +PYTHON_DOWNLOAD_URL=https://www.python.org/ftp/python +# XXX: the official https server at www.openssl.org cannot be reached +# with the old versions of openssl and curl in Centos 5.11 hence the fallback +# to the ftp mirror: +# OPENSSL_DOWNLOAD_URL=ftp://ftp.openssl.org/source +OPENSSL_DOWNLOAD_URL=https://www.openssl.org/source +# Ditto the curl sources +CURL_DOWNLOAD_URL=http://curl.askapache.com/download + +GET_PIP_URL=https://bootstrap.pypa.io/get-pip.py + +AUTOCONF_DOWNLOAD_URL=http://ftp.gnu.org/gnu/autoconf + + +function check_var { + if [ -z "$1" ]; then + echo "required variable not defined" + exit 1 + fi +} + + +function lex_pyver { + # Echoes Python version string padded with zeros + # Thus: + # 3.2.1 -> 003002001 + # 3 -> 003000000 + echo $1 | awk -F "." '{printf "%03d%03d%03d", $1, $2, $3}' +} + + +function do_cpython_build { + local py_ver=$1 + check_var $py_ver + local ucs_setting=$2 + check_var $ucs_setting + tar -xzf Python-$py_ver.tgz + pushd Python-$py_ver + if [ "$ucs_setting" = "none" ]; then + unicode_flags="" + dir_suffix="" + else + local unicode_flags="--enable-unicode=$ucs_setting" + local dir_suffix="-$ucs_setting" + fi + local prefix="/opt/_internal/cpython-${py_ver}${dir_suffix}" + mkdir -p ${prefix}/lib + # -Wformat added for https://bugs.python.org/issue17547 on Python 2.6 + + if [ $(lex_pyver $py_ver) -ge $(lex_pyver 3.6) ]; then + 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 + fi + + # NOTE --enable-shared for generating libpython shared library needed for + # linking of some of the nupic.core test executables. + if [ $(lex_pyver $py_ver) -ge $(lex_pyver 3.7) ]; then + # NOTE python 3.7 should be installed via make altinstall rather than + # make install, and we should specify the location of ssl + CFLAGS="-Wformat" ./configure --prefix=${prefix} --with-openssl=/usr/local/ssl --enable-shared $unicode_flags > /dev/null + make -j8 > /dev/null + make altinstall > /dev/null + else + LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH} CFLAGS="-Wformat" ./configure --prefix=${prefix} --enable-shared $unicode_flags > /dev/null + LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH} make -j8 > /dev/null + LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH} make install > /dev/null + fi + popd + echo "ZZZ looking for libpython" + find / -name 'libpython*.so*' + rm -rf Python-$py_ver + # Some python's install as bin/python3. Make them available as + # bin/python. + if [ -e ${prefix}/bin/python3 ]; then + ln -s python3 ${prefix}/bin/python + fi + if [ -e ${prefix}/bin/python3.7 ]; then + ln -s python3.7 ${prefix}/bin/python + fi + if [ -e ${prefix}/bin/python3.8 ]; then + ln -s python3.8 ${prefix}/bin/python + fi + # NOTE Make libpython shared library visible to python calls below + LD_LIBRARY_PATH="/usr/local/ssl/lib:${prefix}/lib" ${prefix}/bin/python get-pip.py + LD_LIBRARY_PATH="/usr/local/ssl/lib:${prefix}/lib" ${prefix}/bin/pip install wheel==0.32.2 + cd / + ls ${MY_DIR} + local abi_tag=$(LD_LIBRARY_PATH="${prefix}/lib" ${prefix}/bin/python ${MY_DIR}/python-tag-abi-tag.py) + ln -s ${prefix} /opt/python/${abi_tag} +} + + +function build_cpython { + local py_ver=$1 + check_var $py_ver + check_var $PYTHON_DOWNLOAD_URL + wget -q $PYTHON_DOWNLOAD_URL/$py_ver/Python-$py_ver.tgz + if [ $(lex_pyver $py_ver) -lt $(lex_pyver 3.3) ]; then + # NOTE We only need wide unicode for nupic.bindings wheel + do_cpython_build $py_ver ucs2 + do_cpython_build $py_ver ucs4 + else + do_cpython_build $py_ver none + fi + rm -f Python-$py_ver.tgz +} + + +function build_cpythons { + for py_ver in $@; do + check_var $GET_PIP_URL + curl -sLO $GET_PIP_URL + if [ $py_ver == "2.7.15" ]; then + curl -sLO https://bootstrap.pypa.io/2.7/get-pip.py + fi + if [ $py_ver == "3.5.1" ]; then + curl -sLO https://bootstrap.pypa.io/3.5/get-pip.py + fi + build_cpython $py_ver + done + rm get-pip.py +} + + +function do_openssl_build { + ./config -fPIC --prefix=/usr/local/ssl > /dev/null + make > /dev/null + make install > /dev/null + +} + + +function check_sha256sum { + local fname=$1 + check_var ${fname} + local sha256=$2 + check_var ${sha256} + + echo "${sha256} ${fname}" > ${fname}.sha256 + sha256sum -c ${fname}.sha256 + rm ${fname}.sha256 +} + + +function build_openssl { + local openssl_fname=$1 + check_var ${openssl_fname} + local openssl_sha256=$2 + check_var ${openssl_sha256} + check_var ${OPENSSL_DOWNLOAD_URL} + curl -sLO ${OPENSSL_DOWNLOAD_URL}/${openssl_fname}.tar.gz + check_sha256sum ${openssl_fname}.tar.gz ${openssl_sha256} + tar -xzf ${openssl_fname}.tar.gz + (cd ${openssl_fname} && do_openssl_build) + rm -rf ${openssl_fname} ${openssl_fname}.tar.gz +} + + +function do_curl_build { + LIBS=-ldl ./configure --with-ssl --disable-shared > /dev/null + make > /dev/null + make install > /dev/null + ln -s /usr/local/ssl/lib/libcrypto.so /usr/lib/libcrypto.so + ln -s /usr/local/ssl/lib/libssl.so /usr/lib/libssl.so + ln -s /usr/local/ssl/bin/openssl /usr/local/bin/openssl +} + + +function build_curl { + local curl_fname=$1 + check_var ${curl_fname} + local curl_sha256=$2 + check_var ${curl_sha256} + check_var ${CURL_DOWNLOAD_URL} + curl -sLO ${CURL_DOWNLOAD_URL}/${curl_fname}.tar.bz2 + check_sha256sum ${curl_fname}.tar.bz2 ${curl_sha256} + tar -jxf ${curl_fname}.tar.bz2 + (cd ${curl_fname} && do_curl_build) + rm -rf ${curl_fname} ${curl_fname}.tar.bz2 +} + + +function do_standard_install { + ./configure > /dev/null + make > /dev/null + make install > /dev/null +} + + +function build_autoconf { + local autoconf_fname=$1 + check_var ${autoconf_fname} + local autoconf_sha256=$2 + check_var ${autoconf_sha256} + check_var ${AUTOCONF_DOWNLOAD_URL} + curl -sLO ${AUTOCONF_DOWNLOAD_URL}/${autoconf_fname}.tar.gz + check_sha256sum ${autoconf_fname}.tar.gz ${autoconf_sha256} + tar -zxf ${autoconf_fname}.tar.gz + (cd ${autoconf_fname} && do_standard_install) + rm -rf ${autoconf_fname} ${autoconf_fname}.tar.gz +} diff --git a/tools/dockerfile/build_scripts/install_gcc.sh b/tools/dockerfile/build_scripts/install_gcc.sh new file mode 100644 index 0000000000000000000000000000000000000000..e75021b2a9b6531701ef1365e9e6195b61770632 --- /dev/null +++ b/tools/dockerfile/build_scripts/install_gcc.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# 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. + +# Top-level build script called from Dockerfile + +# Stop at any error, show all commands +set -ex + +if [ -f "/etc/redhat-release" ];then + lib_so_5=/usr/lib64/libgfortran.so.5 + lib_so_6=/usr/lib64/libstdc++.so.6 + lib_path=/usr/lib64 +else + lib_so_5=/usr/lib/x86_64-linux-gnu/libstdc++.so.5 + lib_so_6=/usr/lib/x86_64-linux-gnu/libstdc++.so.6 + lib_path=/usr/lib/x86_64-linux-gnu +fi + +if [ "$1" == "gcc82" ]; then + wget -q https://paddle-ci.gz.bcebos.com/gcc-8.2.0.tar.xz + tar -xvf gcc-8.2.0.tar.xz && \ + cd gcc-8.2.0 && \ + unset LIBRARY_PATH CPATH C_INCLUDE_PATH PKG_CONFIG_PATH CPLUS_INCLUDE_PATH INCLUDE && \ + ./contrib/download_prerequisites && \ + cd .. && mkdir temp_gcc82 && cd temp_gcc82 && \ + ../gcc-8.2.0/configure --prefix=/usr/local/gcc-8.2 --enable-threads=posix --disable-checking --disable-multilib && \ + make -j8 && make install + cd .. && rm -rf temp_gcc82 + cp ${lib_so_6} ${lib_so_6}.bak && rm -f ${lib_so_6} && + ln -s /usr/local/gcc-8.2/lib64/libgfortran.so.5 ${lib_so_5} && \ + ln -s /usr/local/gcc-8.2/lib64/libstdc++.so.6 ${lib_so_6} && \ + cp /usr/local/gcc-8.2/lib64/libstdc++.so.6.0.25 ${lib_path} +fi diff --git a/tools/dockerfile/build_scripts/install_nccl2.sh b/tools/dockerfile/build_scripts/install_nccl2.sh new file mode 100644 index 0000000000000000000000000000000000000000..b06b3d44c6ec6b32688521a76f26b82acb4e0998 --- /dev/null +++ b/tools/dockerfile/build_scripts/install_nccl2.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +# 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. + +VERSION=$(nvcc --version | grep release | grep -oEi "release ([0-9]+)\.([0-9])"| sed "s/release //") +if [ "$VERSION" == "10.0" ]; then + DEB="nccl-repo-ubuntu1604-2.4.7-ga-cuda10.0_1-1_amd64.deb" +elif [ "$VERSION" == "10.2" ] || [ "$VERSION" == "10.1" ] || [ "$VERSION" == "11.0" ]; then + if [ -f "/etc/redhat-release" ];then + rm -f /usr/local/lib/libnccl.so + wget --no-check-certificate -q https://nccl2-deb.cdn.bcebos.com/libnccl-2.7.8-1+cuda10.2.x86_64.rpm + wget --no-check-certificate -q https://nccl2-deb.cdn.bcebos.com/libnccl-devel-2.7.8-1+cuda10.2.x86_64.rpm + wget --no-check-certificate -q https://nccl2-deb.cdn.bcebos.com/libnccl-static-2.7.8-1+cuda10.2.x86_64.rpm + rpm -ivh libnccl-2.7.8-1+cuda10.2.x86_64.rpm + rpm -ivh libnccl-devel-2.7.8-1+cuda10.2.x86_64.rpm + rpm -ivh libnccl-static-2.7.8-1+cuda10.2.x86_64.rpm && rm -f libnccl-* + exit 0 + fi + DEB="nccl-repo-ubuntu1604-2.7.8-ga-cuda10.2_1-1_amd64.deb" +elif [ "$VERSION" == "9.0" ]; then + DEB="nccl-repo-ubuntu1604-2.3.7-ga-cuda9.0_1-1_amd64.deb" +else + echo "nccl not found" + exit 2 +fi + +URL="http://nccl2-deb.cdn.bcebos.com/$DEB" + +DIR="/nccl2" +mkdir -p $DIR +# we cached the nccl2 deb package in BOS, so we can download it with wget +# install nccl2: http://docs.nvidia.com/deeplearning/sdk/nccl-install-guide/index.html#down +wget -q -O $DIR/$DEB $URL + +cd $DIR && ar x $DEB && tar xf data.tar.xz +DEBS=$(find ./var/ -name "*.deb") +for sub_deb in $DEBS; do + echo $sub_deb + ar x $sub_deb && tar xf data.tar.xz +done +mv -f usr/include/nccl.h /usr/local/include/ +mv -f usr/lib/x86_64-linux-gnu/libnccl* /usr/local/lib/ +rm /usr/include/nccl.h +rm -rf $DIR diff --git a/tools/dockerfile/build_scripts/install_trt.sh b/tools/dockerfile/build_scripts/install_trt.sh new file mode 100644 index 0000000000000000000000000000000000000000..e5ec70d2f378d180a08a86d705f3e662a211dc91 --- /dev/null +++ b/tools/dockerfile/build_scripts/install_trt.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# 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. + +VERSION=$(nvcc --version | grep release | grep -oEi "release ([0-9]+)\.([0-9])"| sed "s/release //") + +if [[ "$VERSION" == "10.1" ]];then + wget -q https://paddle-ci.gz.bcebos.com/TRT/TensorRT6-cuda10.1-cudnn7.tar.gz --no-check-certificate + tar -zxf TensorRT6-cuda10.1-cudnn7.tar.gz -C /usr/local + cp -rf /usr/local/TensorRT6-cuda10.1-cudnn7/include/* /usr/include/ && cp -rf /usr/local/TensorRT6-cuda10.1-cudnn7/lib/* /usr/lib/ + rm TensorRT6-cuda10.1-cudnn7.tar.gz +elif [[ "$VERSION" == "11.0" ]];then + wget -q https://paddle-ci.cdn.bcebos.com/TRT/TensorRT-7.1.3.4.Ubuntu-16.04.x86_64-gnu.cuda-11.0.cudnn8.0.tar.gz --no-check-certificate + tar -zxf TensorRT-7.1.3.4.Ubuntu-16.04.x86_64-gnu.cuda-11.0.cudnn8.0.tar.gz -C /usr/local + cp -rf /usr/local/TensorRT-7.1.3.4/include/* /usr/include/ && cp -rf /usr/local/TensorRT-7.1.3.4/lib/* /usr/lib/ + rm TensorRT-7.1.3.4.Ubuntu-16.04.x86_64-gnu.cuda-11.0.cudnn8.0.tar.gz +elif [[ "$VERSION" == "10.2" ]];then + wget https://paddle-ci.gz.bcebos.com/TRT/TensorRT7-cuda10.2-cudnn8.tar.gz --no-check-certificate + tar -zxf TensorRT7-cuda10.2-cudnn8.tar.gz -C /usr/local + cp -rf /usr/local/TensorRT-7.1.3.4/include/* /usr/include/ && cp -rf /usr/local/TensorRT-7.1.3.4/lib/* /usr/lib/ + rm TensorRT7-cuda10.2-cudnn8.tar.gz +elif [[ "$VERSION" == "10.0" ]];then + wget -q https://paddle-ci.gz.bcebos.com/TRT/TensorRT6-cuda10.0-cudnn7.tar.gz --no-check-certificate + tar -zxf TensorRT6-cuda10.0-cudnn7.tar.gz -C /usr/local + cp -rf /usr/local/TensorRT6-cuda10.0-cudnn7/include/* /usr/include/ && cp -rf /usr/local/TensorRT6-cuda10.0-cudnn7/lib/* /usr/lib/ + rm TensorRT6-cuda10.0-cudnn7.tar.gz +elif [[ "$VERSION" == "9.0" ]];then + wget -q https://paddle-ci.gz.bcebos.com/TRT/TensorRT6-cuda9.0-cudnn7.tar.gz --no-check-certificate + tar -zxf TensorRT6-cuda9.0-cudnn7.tar.gz -C /usr/local + cp -rf /usr/local/TensorRT6-cuda9.0-cudnn7/include/* /usr/include/ && cp -rf /usr/local/TensorRT6-cuda9.0-cudnn7/lib/* /usr/lib/ + rm TensorRT6-cuda9.0-cudnn7.tar.gz +fi diff --git a/tools/dockerfile/build_scripts/manylinux1-check.py b/tools/dockerfile/build_scripts/manylinux1-check.py new file mode 100644 index 0000000000000000000000000000000000000000..0d1a6df4eec98c72e493517d54fae7c416727d38 --- /dev/null +++ b/tools/dockerfile/build_scripts/manylinux1-check.py @@ -0,0 +1,70 @@ +# Copyright (c) 2018 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. + +# Logic copied from PEP 513 + + +def is_manylinux1_compatible(): + # Only Linux, and only x86-64 / i686 + from distutils.util import get_platform + if get_platform() not in ["linux-x86_64", "linux-i686"]: + return False + + # Check for presence of _manylinux module + try: + import _manylinux + return bool(_manylinux.manylinux1_compatible) + except (ImportError, AttributeError): + # Fall through to heuristic check below + pass + + # Check glibc version. CentOS 5 uses glibc 2.5. + return have_compatible_glibc(2, 5) + + +def have_compatible_glibc(major, minimum_minor): + import ctypes + + process_namespace = ctypes.CDLL(None) + try: + gnu_get_libc_version = process_namespace.gnu_get_libc_version + except AttributeError: + # Symbol doesn't exist -> therefore, we are not linked to + # glibc. + return False + + # Call gnu_get_libc_version, which returns a string like "2.5". + gnu_get_libc_version.restype = ctypes.c_char_p + version_str = gnu_get_libc_version() + # py2 / py3 compatibility: + if not isinstance(version_str, str): + version_str = version_str.decode("ascii") + + # Parse string and check against requested version. + version = [int(piece) for piece in version_str.split(".")] + assert len(version) == 2 + if major != version[0]: + return False + if minimum_minor > version[1]: + return False + return True + + +import sys +if is_manylinux1_compatible(): + print("%s is manylinux1 compatible" % (sys.executable, )) + sys.exit(0) +else: + print("%s is NOT manylinux1 compatible" % (sys.executable, )) + sys.exit(1) diff --git a/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube_prepare.sh b/tools/dockerfile/build_scripts/python-tag-abi-tag.py old mode 100755 new mode 100644 similarity index 52% rename from python/examples/grpc_impl_example/criteo_ctr_with_cube/cube_prepare.sh rename to tools/dockerfile/build_scripts/python-tag-abi-tag.py index 1417254a54e2194ab3a0194f2ec970f480787acd..0364ab3659e49dd59ff57764251408ae4359a43f --- a/python/examples/grpc_impl_example/criteo_ctr_with_cube/cube_prepare.sh +++ b/tools/dockerfile/build_scripts/python-tag-abi-tag.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# Copyright (c) 2018 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. @@ -11,12 +11,11 @@ # 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 -#! /bin/bash -mkdir -p cube_model -mkdir -p cube/data -./seq_generator ctr_serving_model/SparseFeatFactors ./cube_model/feature -./cube/cube-builder -dict_name=test_dict -job_mode=base -last_version=0 -cur_version=0 -depend_version=0 -input_path=./cube_model -output_path=${PWD}/cube/data -shard_num=1 -only_build=false -mv ./cube/data/0_0/test_dict_part0/* ./cube/data/ -cd cube && ./cube +# Utility script to print the python tag + the abi tag for a Python +# See PEP 425 for exactly what these are, but an example would be: +# cp27-cp27mu + +from wheel.pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag + +print("{0}{1}-{2}".format(get_abbr_impl(), get_impl_ver(), get_abi_tag())) diff --git a/tools/dockerfile/build_scripts/ssl-check.py b/tools/dockerfile/build_scripts/ssl-check.py new file mode 100644 index 0000000000000000000000000000000000000000..afef2812f3fb4e9298ec8ab2d97e790ecc455d1c --- /dev/null +++ b/tools/dockerfile/build_scripts/ssl-check.py @@ -0,0 +1,46 @@ +# Copyright (c) 2018 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. + +# cf. https://github.com/pypa/manylinux/issues/53 + +GOOD_SSL = "https://google.com" +BAD_SSL = "https://self-signed.badssl.com" + +import sys + +print("Testing SSL certificate checking for Python:", sys.version) + +if (sys.version_info[:2] < (2, 7) or sys.version_info[:2] < (3, 4)): + print("This version never checks SSL certs; skipping tests") + sys.exit(0) + +if sys.version_info[0] >= 3: + from urllib.request import urlopen + EXC = OSError +else: + from urllib import urlopen + EXC = IOError + +print("Connecting to %s should work" % (GOOD_SSL, )) +urlopen(GOOD_SSL) +print("...it did, yay.") + +print("Connecting to %s should fail" % (BAD_SSL, )) +try: + urlopen(BAD_SSL) + # If we get here then we failed: + print("...it DIDN'T!!!!!11!!1one!") + sys.exit(1) +except EXC: + print("...it did, yay.") diff --git a/tools/dockerfile/root/.bashrc b/tools/dockerfile/root/.bashrc new file mode 100755 index 0000000000000000000000000000000000000000..4b3024e4e81a0fa206a796c12a8b9d72f1a8f5d9 --- /dev/null +++ b/tools/dockerfile/root/.bashrc @@ -0,0 +1,46 @@ +# Locales + +export LC_ALL=en_US.UTF-8 +export LANG=en_US.UTF-8 +export LANGUAGE=en_US.UTF-8 + +# Aliases + +alias rm='rm -i' +alias cp='cp -i' +alias mv='mv -i' + +alias ls='ls -hFG' +alias l='ls -lF' +alias ll='ls -alF' +alias lt='ls -ltrF' +alias ll='ls -alF' +alias lls='ls -alSrF' +alias llt='ls -altrF' + +# Colorize directory listing + +alias ls="ls -ph --color=auto" + +# Colorize grep + +if echo hello|grep --color=auto l >/dev/null 2>&1; then + export GREP_OPTIONS="--color=auto" GREP_COLOR="1;31" +fi + +# Shell + +export CLICOLOR="1" + +YELLOW="\[\033[1;33m\]" +NO_COLOUR="\[\033[0m\]" +GREEN="\[\033[1;32m\]" +WHITE="\[\033[1;37m\]" + +source ~/.scripts/git-prompt.sh + +export PS1="\[\033[1;33m\]λ $WHITE\h $GREEN\w$YELLOW\$(__git_ps1 \" \[\033[35m\]{\[\033[36m\]%s\[\033[35m\]}\")$NO_COLOUR " + +# Git + +source ~/.scripts/git-completion.sh diff --git a/tools/dockerfile/root/.gitconfig b/tools/dockerfile/root/.gitconfig new file mode 100755 index 0000000000000000000000000000000000000000..6c249803a50403b9b79e36a13abe7fe88a35729d --- /dev/null +++ b/tools/dockerfile/root/.gitconfig @@ -0,0 +1,43 @@ +[user] + name = + email = + +[alias] + st = status --branch --short + ci = commit + br = branch + co = checkout + df = diff + l = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short + ll = log --stat + +[merge] + tool = vimdiff + +[core] + excludesfile = ~/.gitignore + editor = vim + +[color] + branch = auto + diff = auto + status = auto + +[color "branch"] + current = yellow reverse + local = yellow + remote = green + +[color "diff"] + meta = yellow bold + frag = magenta bold + old = red bold + new = green bold + +[color "status"] + added = yellow + changed = green + untracked = cyan + +[push] + default = matching \ No newline at end of file diff --git a/tools/dockerfile/root/.scripts/git-completion.sh b/tools/dockerfile/root/.scripts/git-completion.sh new file mode 100755 index 0000000000000000000000000000000000000000..bdddef5ac2faf50b47dd03539dae8912bec8a16c --- /dev/null +++ b/tools/dockerfile/root/.scripts/git-completion.sh @@ -0,0 +1,2663 @@ +#!bash +# +# bash/zsh completion support for core Git. +# +# Copyright (C) 2006,2007 Shawn O. Pearce +# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/). +# Distributed under the GNU General Public License, version 2.0. +# +# The contained completion routines provide support for completing: +# +# *) local and remote branch names +# *) local and remote tag names +# *) .git/remotes file names +# *) git 'subcommands' +# *) tree paths within 'ref:path/to/file' expressions +# *) file paths within current working directory and index +# *) common --long-options +# +# To use these routines: +# +# 1) Copy this file to somewhere (e.g. ~/.git-completion.sh). +# 2) Add the following line to your .bashrc/.zshrc: +# source ~/.git-completion.sh +# 3) Consider changing your PS1 to also show the current branch, +# see git-prompt.sh for details. + +case "$COMP_WORDBREAKS" in +*:*) : great ;; +*) COMP_WORDBREAKS="$COMP_WORDBREAKS:" +esac + +# __gitdir accepts 0 or 1 arguments (i.e., location) +# returns location of .git repo +__gitdir () +{ + if [ -z "${1-}" ]; then + if [ -n "${__git_dir-}" ]; then + echo "$__git_dir" + elif [ -n "${GIT_DIR-}" ]; then + test -d "${GIT_DIR-}" || return 1 + echo "$GIT_DIR" + elif [ -d .git ]; then + echo .git + else + git rev-parse --git-dir 2>/dev/null + fi + elif [ -d "$1/.git" ]; then + echo "$1/.git" + else + echo "$1" + fi +} + +# The following function is based on code from: +# +# bash_completion - programmable completion functions for bash 3.2+ +# +# Copyright © 2006-2008, Ian Macdonald +# © 2009-2010, Bash Completion Maintainers +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The latest version of this software can be obtained here: +# +# http://bash-completion.alioth.debian.org/ +# +# RELEASE: 2.x + +# This function can be used to access a tokenized list of words +# on the command line: +# +# __git_reassemble_comp_words_by_ref '=:' +# if test "${words_[cword_-1]}" = -w +# then +# ... +# fi +# +# The argument should be a collection of characters from the list of +# word completion separators (COMP_WORDBREAKS) to treat as ordinary +# characters. +# +# This is roughly equivalent to going back in time and setting +# COMP_WORDBREAKS to exclude those characters. The intent is to +# make option types like --date= and : easy to +# recognize by treating each shell word as a single token. +# +# It is best not to set COMP_WORDBREAKS directly because the value is +# shared with other completion scripts. By the time the completion +# function gets called, COMP_WORDS has already been populated so local +# changes to COMP_WORDBREAKS have no effect. +# +# Output: words_, cword_, cur_. + +__git_reassemble_comp_words_by_ref() +{ + local exclude i j first + # Which word separators to exclude? + exclude="${1//[^$COMP_WORDBREAKS]}" + cword_=$COMP_CWORD + if [ -z "$exclude" ]; then + words_=("${COMP_WORDS[@]}") + return + fi + # List of word completion separators has shrunk; + # re-assemble words to complete. + for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do + # Append each nonempty word consisting of just + # word separator characters to the current word. + first=t + while + [ $i -gt 0 ] && + [ -n "${COMP_WORDS[$i]}" ] && + # word consists of excluded word separators + [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] + do + # Attach to the previous token, + # unless the previous token is the command name. + if [ $j -ge 2 ] && [ -n "$first" ]; then + ((j--)) + fi + first= + words_[$j]=${words_[j]}${COMP_WORDS[i]} + if [ $i = $COMP_CWORD ]; then + cword_=$j + fi + if (($i < ${#COMP_WORDS[@]} - 1)); then + ((i++)) + else + # Done. + return + fi + done + words_[$j]=${words_[j]}${COMP_WORDS[i]} + if [ $i = $COMP_CWORD ]; then + cword_=$j + fi + done +} + +if ! type _get_comp_words_by_ref >/dev/null 2>&1; then +_get_comp_words_by_ref () +{ + local exclude cur_ words_ cword_ + if [ "$1" = "-n" ]; then + exclude=$2 + shift 2 + fi + __git_reassemble_comp_words_by_ref "$exclude" + cur_=${words_[cword_]} + while [ $# -gt 0 ]; do + case "$1" in + cur) + cur=$cur_ + ;; + prev) + prev=${words_[$cword_-1]} + ;; + words) + words=("${words_[@]}") + ;; + cword) + cword=$cword_ + ;; + esac + shift + done +} +fi + +__gitcompadd () +{ + local i=0 + for x in $1; do + if [[ "$x" == "$3"* ]]; then + COMPREPLY[i++]="$2$x$4" + fi + done +} + +# Generates completion reply, appending a space to possible completion words, +# if necessary. +# It accepts 1 to 4 arguments: +# 1: List of possible completion words. +# 2: A prefix to be added to each possible completion word (optional). +# 3: Generate possible completion matches for this word (optional). +# 4: A suffix to be appended to each possible completion word (optional). +__gitcomp () +{ + local cur_="${3-$cur}" + + case "$cur_" in + --*=) + ;; + *) + local c i=0 IFS=$' \t\n' + for c in $1; do + c="$c${4-}" + if [[ $c == "$cur_"* ]]; then + case $c in + --*=*|*.) ;; + *) c="$c " ;; + esac + COMPREPLY[i++]="${2-}$c" + fi + done + ;; + esac +} + +# Generates completion reply from newline-separated possible completion words +# by appending a space to all of them. +# It accepts 1 to 4 arguments: +# 1: List of possible completion words, separated by a single newline. +# 2: A prefix to be added to each possible completion word (optional). +# 3: Generate possible completion matches for this word (optional). +# 4: A suffix to be appended to each possible completion word instead of +# the default space (optional). If specified but empty, nothing is +# appended. +__gitcomp_nl () +{ + local IFS=$'\n' + __gitcompadd "$1" "${2-}" "${3-$cur}" "${4- }" +} + +# Generates completion reply with compgen from newline-separated possible +# completion filenames. +# It accepts 1 to 3 arguments: +# 1: List of possible completion filenames, separated by a single newline. +# 2: A directory prefix to be added to each possible completion filename +# (optional). +# 3: Generate possible completion matches for this word (optional). +__gitcomp_file () +{ + local IFS=$'\n' + + # XXX does not work when the directory prefix contains a tilde, + # since tilde expansion is not applied. + # This means that COMPREPLY will be empty and Bash default + # completion will be used. + __gitcompadd "$1" "${2-}" "${3-$cur}" "" + + # use a hack to enable file mode in bash < 4 + compopt -o filenames +o nospace 2>/dev/null || + compgen -f /non-existing-dir/ > /dev/null +} + +# Execute 'git ls-files', unless the --committable option is specified, in +# which case it runs 'git diff-index' to find out the files that can be +# committed. It return paths relative to the directory specified in the first +# argument, and using the options specified in the second argument. +__git_ls_files_helper () +{ + ( + test -n "${CDPATH+set}" && unset CDPATH + cd "$1" + if [ "$2" == "--committable" ]; then + git diff-index --name-only --relative HEAD + else + # NOTE: $2 is not quoted in order to support multiple options + git ls-files --exclude-standard $2 + fi + ) 2>/dev/null +} + + +# __git_index_files accepts 1 or 2 arguments: +# 1: Options to pass to ls-files (required). +# 2: A directory path (optional). +# If provided, only files within the specified directory are listed. +# Sub directories are never recursed. Path must have a trailing +# slash. +__git_index_files () +{ + local dir="$(__gitdir)" root="${2-.}" file + + if [ -d "$dir" ]; then + __git_ls_files_helper "$root" "$1" | + while read -r file; do + case "$file" in + ?*/*) echo "${file%%/*}" ;; + *) echo "$file" ;; + esac + done | sort | uniq + fi +} + +__git_heads () +{ + local dir="$(__gitdir)" + if [ -d "$dir" ]; then + git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ + refs/heads + return + fi +} + +__git_tags () +{ + local dir="$(__gitdir)" + if [ -d "$dir" ]; then + git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ + refs/tags + return + fi +} + +# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments +# presence of 2nd argument means use the guess heuristic employed +# by checkout for tracking branches +__git_refs () +{ + local i hash dir="$(__gitdir "${1-}")" track="${2-}" + local format refs + if [ -d "$dir" ]; then + case "$cur" in + refs|refs/*) + format="refname" + refs="${cur%/*}" + track="" + ;; + *) + for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do + if [ -e "$dir/$i" ]; then echo $i; fi + done + format="refname:short" + refs="refs/tags refs/heads refs/remotes" + ;; + esac + git --git-dir="$dir" for-each-ref --format="%($format)" \ + $refs + if [ -n "$track" ]; then + # employ the heuristic used by git checkout + # Try to find a remote branch that matches the completion word + # but only output if the branch name is unique + local ref entry + git --git-dir="$dir" for-each-ref --shell --format="ref=%(refname:short)" \ + "refs/remotes/" | \ + while read -r entry; do + eval "$entry" + ref="${ref#*/}" + if [[ "$ref" == "$cur"* ]]; then + echo "$ref" + fi + done | sort | uniq -u + fi + return + fi + case "$cur" in + refs|refs/*) + git ls-remote "$dir" "$cur*" 2>/dev/null | \ + while read -r hash i; do + case "$i" in + *^{}) ;; + *) echo "$i" ;; + esac + done + ;; + *) + echo "HEAD" + git for-each-ref --format="%(refname:short)" -- "refs/remotes/$dir/" | sed -e "s#^$dir/##" + ;; + esac +} + +# __git_refs2 requires 1 argument (to pass to __git_refs) +__git_refs2 () +{ + local i + for i in $(__git_refs "$1"); do + echo "$i:$i" + done +} + +# __git_refs_remotes requires 1 argument (to pass to ls-remote) +__git_refs_remotes () +{ + local i hash + git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \ + while read -r hash i; do + echo "$i:refs/remotes/$1/${i#refs/heads/}" + done +} + +__git_remotes () +{ + local i IFS=$'\n' d="$(__gitdir)" + test -d "$d/remotes" && ls -1 "$d/remotes" + for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do + i="${i#remote.}" + echo "${i/.url*/}" + done +} + +__git_list_merge_strategies () +{ + git merge -s help 2>&1 | + sed -n -e '/[Aa]vailable strategies are: /,/^$/{ + s/\.$// + s/.*:// + s/^[ ]*// + s/[ ]*$// + p + }' +} + +__git_merge_strategies= +# 'git merge -s help' (and thus detection of the merge strategy +# list) fails, unfortunately, if run outside of any git working +# tree. __git_merge_strategies is set to the empty string in +# that case, and the detection will be repeated the next time it +# is needed. +__git_compute_merge_strategies () +{ + test -n "$__git_merge_strategies" || + __git_merge_strategies=$(__git_list_merge_strategies) +} + +__git_complete_revlist_file () +{ + local pfx ls ref cur_="$cur" + case "$cur_" in + *..?*:*) + return + ;; + ?*:*) + ref="${cur_%%:*}" + cur_="${cur_#*:}" + case "$cur_" in + ?*/*) + pfx="${cur_%/*}" + cur_="${cur_##*/}" + ls="$ref:$pfx" + pfx="$pfx/" + ;; + *) + ls="$ref" + ;; + esac + + case "$COMP_WORDBREAKS" in + *:*) : great ;; + *) pfx="$ref:$pfx" ;; + esac + + __gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" 2>/dev/null \ + | sed '/^100... blob /{ + s,^.* ,, + s,$, , + } + /^120000 blob /{ + s,^.* ,, + s,$, , + } + /^040000 tree /{ + s,^.* ,, + s,$,/, + } + s/^.* //')" \ + "$pfx" "$cur_" "" + ;; + *...*) + pfx="${cur_%...*}..." + cur_="${cur_#*...}" + __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_" + ;; + *..*) + pfx="${cur_%..*}.." + cur_="${cur_#*..}" + __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_" + ;; + *) + __gitcomp_nl "$(__git_refs)" + ;; + esac +} + + +# __git_complete_index_file requires 1 argument: +# 1: the options to pass to ls-file +# +# The exception is --committable, which finds the files appropriate commit. +__git_complete_index_file () +{ + local pfx="" cur_="$cur" + + case "$cur_" in + ?*/*) + pfx="${cur_%/*}" + cur_="${cur_##*/}" + pfx="${pfx}/" + ;; + esac + + __gitcomp_file "$(__git_index_files "$1" "$pfx")" "$pfx" "$cur_" +} + +__git_complete_file () +{ + __git_complete_revlist_file +} + +__git_complete_revlist () +{ + __git_complete_revlist_file +} + +__git_complete_remote_or_refspec () +{ + local cur_="$cur" cmd="${words[1]}" + local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0 + if [ "$cmd" = "remote" ]; then + ((c++)) + fi + while [ $c -lt $cword ]; do + i="${words[c]}" + case "$i" in + --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;; + --all) + case "$cmd" in + push) no_complete_refspec=1 ;; + fetch) + return + ;; + *) ;; + esac + ;; + -*) ;; + *) remote="$i"; break ;; + esac + ((c++)) + done + if [ -z "$remote" ]; then + __gitcomp_nl "$(__git_remotes)" + return + fi + if [ $no_complete_refspec = 1 ]; then + return + fi + [ "$remote" = "." ] && remote= + case "$cur_" in + *:*) + case "$COMP_WORDBREAKS" in + *:*) : great ;; + *) pfx="${cur_%%:*}:" ;; + esac + cur_="${cur_#*:}" + lhs=0 + ;; + +*) + pfx="+" + cur_="${cur_#+}" + ;; + esac + case "$cmd" in + fetch) + if [ $lhs = 1 ]; then + __gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_" + else + __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_" + fi + ;; + pull|remote) + if [ $lhs = 1 ]; then + __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_" + else + __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_" + fi + ;; + push) + if [ $lhs = 1 ]; then + __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_" + else + __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_" + fi + ;; + esac +} + +__git_complete_strategy () +{ + __git_compute_merge_strategies + case "$prev" in + -s|--strategy) + __gitcomp "$__git_merge_strategies" + return 0 + esac + case "$cur" in + --strategy=*) + __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}" + return 0 + ;; + esac + return 1 +} + +__git_commands () { + if test -n "${GIT_TESTING_COMMAND_COMPLETION:-}" + then + printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" + else + git help -a|egrep '^ [a-zA-Z0-9]' + fi +} + +__git_list_all_commands () +{ + local i IFS=" "$'\n' + for i in $(__git_commands) + do + case $i in + *--*) : helper pattern;; + *) echo $i;; + esac + done +} + +__git_all_commands= +__git_compute_all_commands () +{ + test -n "$__git_all_commands" || + __git_all_commands=$(__git_list_all_commands) +} + +__git_list_porcelain_commands () +{ + local i IFS=" "$'\n' + __git_compute_all_commands + for i in $__git_all_commands + do + case $i in + *--*) : helper pattern;; + applymbox) : ask gittus;; + applypatch) : ask gittus;; + archimport) : import;; + cat-file) : plumbing;; + check-attr) : plumbing;; + check-ignore) : plumbing;; + check-mailmap) : plumbing;; + check-ref-format) : plumbing;; + checkout-index) : plumbing;; + commit-tree) : plumbing;; + count-objects) : infrequent;; + credential-cache) : credentials helper;; + credential-store) : credentials helper;; + cvsexportcommit) : export;; + cvsimport) : import;; + cvsserver) : daemon;; + daemon) : daemon;; + diff-files) : plumbing;; + diff-index) : plumbing;; + diff-tree) : plumbing;; + fast-import) : import;; + fast-export) : export;; + fsck-objects) : plumbing;; + fetch-pack) : plumbing;; + fmt-merge-msg) : plumbing;; + for-each-ref) : plumbing;; + hash-object) : plumbing;; + http-*) : transport;; + index-pack) : plumbing;; + init-db) : deprecated;; + local-fetch) : plumbing;; + lost-found) : infrequent;; + ls-files) : plumbing;; + ls-remote) : plumbing;; + ls-tree) : plumbing;; + mailinfo) : plumbing;; + mailsplit) : plumbing;; + merge-*) : plumbing;; + mktree) : plumbing;; + mktag) : plumbing;; + pack-objects) : plumbing;; + pack-redundant) : plumbing;; + pack-refs) : plumbing;; + parse-remote) : plumbing;; + patch-id) : plumbing;; + peek-remote) : plumbing;; + prune) : plumbing;; + prune-packed) : plumbing;; + quiltimport) : import;; + read-tree) : plumbing;; + receive-pack) : plumbing;; + remote-*) : transport;; + repo-config) : deprecated;; + rerere) : plumbing;; + rev-list) : plumbing;; + rev-parse) : plumbing;; + runstatus) : plumbing;; + sh-setup) : internal;; + shell) : daemon;; + show-ref) : plumbing;; + send-pack) : plumbing;; + show-index) : plumbing;; + ssh-*) : transport;; + stripspace) : plumbing;; + symbolic-ref) : plumbing;; + tar-tree) : deprecated;; + unpack-file) : plumbing;; + unpack-objects) : plumbing;; + update-index) : plumbing;; + update-ref) : plumbing;; + update-server-info) : daemon;; + upload-archive) : plumbing;; + upload-pack) : plumbing;; + write-tree) : plumbing;; + var) : infrequent;; + verify-pack) : infrequent;; + verify-tag) : plumbing;; + *) echo $i;; + esac + done +} + +__git_porcelain_commands= +__git_compute_porcelain_commands () +{ + __git_compute_all_commands + test -n "$__git_porcelain_commands" || + __git_porcelain_commands=$(__git_list_porcelain_commands) +} + +__git_pretty_aliases () +{ + local i IFS=$'\n' + for i in $(git --git-dir="$(__gitdir)" config --get-regexp "pretty\..*" 2>/dev/null); do + case "$i" in + pretty.*) + i="${i#pretty.}" + echo "${i/ */}" + ;; + esac + done +} + +__git_aliases () +{ + local i IFS=$'\n' + for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do + case "$i" in + alias.*) + i="${i#alias.}" + echo "${i/ */}" + ;; + esac + done +} + +# __git_aliased_command requires 1 argument +__git_aliased_command () +{ + local word cmdline=$(git --git-dir="$(__gitdir)" \ + config --get "alias.$1") + for word in $cmdline; do + case "$word" in + \!gitk|gitk) + echo "gitk" + return + ;; + \!*) : shell command alias ;; + -*) : option ;; + *=*) : setting env ;; + git) : git itself ;; + *) + echo "$word" + return + esac + done +} + +# __git_find_on_cmdline requires 1 argument +__git_find_on_cmdline () +{ + local word subcommand c=1 + while [ $c -lt $cword ]; do + word="${words[c]}" + for subcommand in $1; do + if [ "$subcommand" = "$word" ]; then + echo "$subcommand" + return + fi + done + ((c++)) + done +} + +__git_has_doubledash () +{ + local c=1 + while [ $c -lt $cword ]; do + if [ "--" = "${words[c]}" ]; then + return 0 + fi + ((c++)) + done + return 1 +} + +# Try to count non option arguments passed on the command line for the +# specified git command. +# When options are used, it is necessary to use the special -- option to +# tell the implementation were non option arguments begin. +# XXX this can not be improved, since options can appear everywhere, as +# an example: +# git mv x -n y +# +# __git_count_arguments requires 1 argument: the git command executed. +__git_count_arguments () +{ + local word i c=0 + + # Skip "git" (first argument) + for ((i=1; i < ${#words[@]}; i++)); do + word="${words[i]}" + + case "$word" in + --) + # Good; we can assume that the following are only non + # option arguments. + ((c = 0)) + ;; + "$1") + # Skip the specified git command and discard git + # main options + ((c = 0)) + ;; + ?*) + ((c++)) + ;; + esac + done + + printf "%d" $c +} + +__git_whitespacelist="nowarn warn error error-all fix" + +_git_am () +{ + local dir="$(__gitdir)" + if [ -d "$dir"/rebase-apply ]; then + __gitcomp "--skip --continue --resolved --abort" + return + fi + case "$cur" in + --whitespace=*) + __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" + return + ;; + --*) + __gitcomp " + --3way --committer-date-is-author-date --ignore-date + --ignore-whitespace --ignore-space-change + --interactive --keep --no-utf8 --signoff --utf8 + --whitespace= --scissors + " + return + esac +} + +_git_apply () +{ + case "$cur" in + --whitespace=*) + __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" + return + ;; + --*) + __gitcomp " + --stat --numstat --summary --check --index + --cached --index-info --reverse --reject --unidiff-zero + --apply --no-add --exclude= + --ignore-whitespace --ignore-space-change + --whitespace= --inaccurate-eof --verbose + " + return + esac +} + +_git_add () +{ + case "$cur" in + --*) + __gitcomp " + --interactive --refresh --patch --update --dry-run + --ignore-errors --intent-to-add + " + return + esac + + # XXX should we check for --update and --all options ? + __git_complete_index_file "--others --modified" +} + +_git_archive () +{ + case "$cur" in + --format=*) + __gitcomp "$(git archive --list)" "" "${cur##--format=}" + return + ;; + --remote=*) + __gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}" + return + ;; + --*) + __gitcomp " + --format= --list --verbose + --prefix= --remote= --exec= + " + return + ;; + esac + __git_complete_file +} + +_git_bisect () +{ + __git_has_doubledash && return + + local subcommands="start bad good skip reset visualize replay log run" + local subcommand="$(__git_find_on_cmdline "$subcommands")" + if [ -z "$subcommand" ]; then + if [ -f "$(__gitdir)"/BISECT_START ]; then + __gitcomp "$subcommands" + else + __gitcomp "replay start" + fi + return + fi + + case "$subcommand" in + bad|good|reset|skip|start) + __gitcomp_nl "$(__git_refs)" + ;; + *) + ;; + esac +} + +_git_branch () +{ + local i c=1 only_local_ref="n" has_r="n" + + while [ $c -lt $cword ]; do + i="${words[c]}" + case "$i" in + -d|-m) only_local_ref="y" ;; + -r) has_r="y" ;; + esac + ((c++)) + done + + case "$cur" in + --set-upstream-to=*) + __gitcomp "$(__git_refs)" "" "${cur##--set-upstream-to=}" + ;; + --*) + __gitcomp " + --color --no-color --verbose --abbrev= --no-abbrev + --track --no-track --contains --merged --no-merged + --set-upstream-to= --edit-description --list + --unset-upstream + " + ;; + *) + if [ $only_local_ref = "y" -a $has_r = "n" ]; then + __gitcomp_nl "$(__git_heads)" + else + __gitcomp_nl "$(__git_refs)" + fi + ;; + esac +} + +_git_bundle () +{ + local cmd="${words[2]}" + case "$cword" in + 2) + __gitcomp "create list-heads verify unbundle" + ;; + 3) + # looking for a file + ;; + *) + case "$cmd" in + create) + __git_complete_revlist + ;; + esac + ;; + esac +} + +_git_checkout () +{ + __git_has_doubledash && return + + case "$cur" in + --conflict=*) + __gitcomp "diff3 merge" "" "${cur##--conflict=}" + ;; + --*) + __gitcomp " + --quiet --ours --theirs --track --no-track --merge + --conflict= --orphan --patch + " + ;; + *) + # check if --track, --no-track, or --no-guess was specified + # if so, disable DWIM mode + local flags="--track --no-track --no-guess" track=1 + if [ -n "$(__git_find_on_cmdline "$flags")" ]; then + track='' + fi + __gitcomp_nl "$(__git_refs '' $track)" + ;; + esac +} + +_git_cherry () +{ + __gitcomp "$(__git_refs)" +} + +_git_cherry_pick () +{ + local dir="$(__gitdir)" + if [ -f "$dir"/CHERRY_PICK_HEAD ]; then + __gitcomp "--continue --quit --abort" + return + fi + case "$cur" in + --*) + __gitcomp "--edit --no-commit --signoff --strategy= --mainline" + ;; + *) + __gitcomp_nl "$(__git_refs)" + ;; + esac +} + +_git_clean () +{ + case "$cur" in + --*) + __gitcomp "--dry-run --quiet" + return + ;; + esac + + # XXX should we check for -x option ? + __git_complete_index_file "--others" +} + +_git_clone () +{ + case "$cur" in + --*) + __gitcomp " + --local + --no-hardlinks + --shared + --reference + --quiet + --no-checkout + --bare + --mirror + --origin + --upload-pack + --template= + --depth + --single-branch + --branch + " + return + ;; + esac +} + +_git_commit () +{ + case "$prev" in + -c|-C) + __gitcomp_nl "$(__git_refs)" "" "${cur}" + return + ;; + esac + + case "$cur" in + --cleanup=*) + __gitcomp "default strip verbatim whitespace + " "" "${cur##--cleanup=}" + return + ;; + --reuse-message=*|--reedit-message=*|\ + --fixup=*|--squash=*) + __gitcomp_nl "$(__git_refs)" "" "${cur#*=}" + return + ;; + --untracked-files=*) + __gitcomp "all no normal" "" "${cur##--untracked-files=}" + return + ;; + --*) + __gitcomp " + --all --author= --signoff --verify --no-verify + --edit --no-edit + --amend --include --only --interactive + --dry-run --reuse-message= --reedit-message= + --reset-author --file= --message= --template= + --cleanup= --untracked-files --untracked-files= + --verbose --quiet --fixup= --squash= + " + return + esac + + if git rev-parse --verify --quiet HEAD >/dev/null; then + __git_complete_index_file "--committable" + else + # This is the first commit + __git_complete_index_file "--cached" + fi +} + +_git_describe () +{ + case "$cur" in + --*) + __gitcomp " + --all --tags --contains --abbrev= --candidates= + --exact-match --debug --long --match --always + " + return + esac + __gitcomp_nl "$(__git_refs)" +} + +__git_diff_algorithms="myers minimal patience histogram" + +__git_diff_common_options="--stat --numstat --shortstat --summary + --patch-with-stat --name-only --name-status --color + --no-color --color-words --no-renames --check + --full-index --binary --abbrev --diff-filter= + --find-copies-harder + --text --ignore-space-at-eol --ignore-space-change + --ignore-all-space --exit-code --quiet --ext-diff + --no-ext-diff + --no-prefix --src-prefix= --dst-prefix= + --inter-hunk-context= + --patience --histogram --minimal + --raw --word-diff + --dirstat --dirstat= --dirstat-by-file + --dirstat-by-file= --cumulative + --diff-algorithm= +" + +_git_diff () +{ + __git_has_doubledash && return + + case "$cur" in + --diff-algorithm=*) + __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}" + return + ;; + --*) + __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex + --base --ours --theirs --no-index + $__git_diff_common_options + " + return + ;; + esac + __git_complete_revlist_file +} + +__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff + tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3 codecompare +" + +_git_difftool () +{ + __git_has_doubledash && return + + case "$cur" in + --tool=*) + __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}" + return + ;; + --*) + __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex + --base --ours --theirs + --no-renames --diff-filter= --find-copies-harder + --relative --ignore-submodules + --tool=" + return + ;; + esac + __git_complete_revlist_file +} + +__git_fetch_options=" + --quiet --verbose --append --upload-pack --force --keep --depth= + --tags --no-tags --all --prune --dry-run +" + +_git_fetch () +{ + case "$cur" in + --*) + __gitcomp "$__git_fetch_options" + return + ;; + esac + __git_complete_remote_or_refspec +} + +__git_format_patch_options=" + --stdout --attach --no-attach --thread --thread= --no-thread + --numbered --start-number --numbered-files --keep-subject --signoff + --signature --no-signature --in-reply-to= --cc= --full-index --binary + --not --all --cover-letter --no-prefix --src-prefix= --dst-prefix= + --inline --suffix= --ignore-if-in-upstream --subject-prefix= + --output-directory --reroll-count --to= --quiet --notes +" + +_git_format_patch () +{ + case "$cur" in + --thread=*) + __gitcomp " + deep shallow + " "" "${cur##--thread=}" + return + ;; + --*) + __gitcomp "$__git_format_patch_options" + return + ;; + esac + __git_complete_revlist +} + +_git_fsck () +{ + case "$cur" in + --*) + __gitcomp " + --tags --root --unreachable --cache --no-reflogs --full + --strict --verbose --lost-found + " + return + ;; + esac +} + +_git_gc () +{ + case "$cur" in + --*) + __gitcomp "--prune --aggressive" + return + ;; + esac +} + +_git_gitk () +{ + _gitk +} + +__git_match_ctag() { + awk "/^${1////\\/}/ { print \$1 }" "$2" +} + +_git_grep () +{ + __git_has_doubledash && return + + case "$cur" in + --*) + __gitcomp " + --cached + --text --ignore-case --word-regexp --invert-match + --full-name --line-number + --extended-regexp --basic-regexp --fixed-strings + --perl-regexp + --files-with-matches --name-only + --files-without-match + --max-depth + --count + --and --or --not --all-match + " + return + ;; + esac + + case "$cword,$prev" in + 2,*|*,-*) + if test -r tags; then + __gitcomp_nl "$(__git_match_ctag "$cur" tags)" + return + fi + ;; + esac + + __gitcomp_nl "$(__git_refs)" +} + +_git_help () +{ + case "$cur" in + --*) + __gitcomp "--all --info --man --web" + return + ;; + esac + __git_compute_all_commands + __gitcomp "$__git_all_commands $(__git_aliases) + attributes cli core-tutorial cvs-migration + diffcore gitk glossary hooks ignore modules + namespaces repository-layout tutorial tutorial-2 + workflows + " +} + +_git_init () +{ + case "$cur" in + --shared=*) + __gitcomp " + false true umask group all world everybody + " "" "${cur##--shared=}" + return + ;; + --*) + __gitcomp "--quiet --bare --template= --shared --shared=" + return + ;; + esac +} + +_git_ls_files () +{ + case "$cur" in + --*) + __gitcomp "--cached --deleted --modified --others --ignored + --stage --directory --no-empty-directory --unmerged + --killed --exclude= --exclude-from= + --exclude-per-directory= --exclude-standard + --error-unmatch --with-tree= --full-name + --abbrev --ignored --exclude-per-directory + " + return + ;; + esac + + # XXX ignore options like --modified and always suggest all cached + # files. + __git_complete_index_file "--cached" +} + +_git_ls_remote () +{ + __gitcomp_nl "$(__git_remotes)" +} + +_git_ls_tree () +{ + __git_complete_file +} + +# Options that go well for log, shortlog and gitk +__git_log_common_options=" + --not --all + --branches --tags --remotes + --first-parent --merges --no-merges + --max-count= + --max-age= --since= --after= + --min-age= --until= --before= + --min-parents= --max-parents= + --no-min-parents --no-max-parents +" +# Options that go well for log and gitk (not shortlog) +__git_log_gitk_options=" + --dense --sparse --full-history + --simplify-merges --simplify-by-decoration + --left-right --notes --no-notes +" +# Options that go well for log and shortlog (not gitk) +__git_log_shortlog_options=" + --author= --committer= --grep= + --all-match +" + +__git_log_pretty_formats="oneline short medium full fuller email raw format:" +__git_log_date_formats="relative iso8601 rfc2822 short local default raw" + +_git_log () +{ + __git_has_doubledash && return + + local g="$(git rev-parse --git-dir 2>/dev/null)" + local merge="" + if [ -f "$g/MERGE_HEAD" ]; then + merge="--merge" + fi + case "$cur" in + --pretty=*|--format=*) + __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases) + " "" "${cur#*=}" + return + ;; + --date=*) + __gitcomp "$__git_log_date_formats" "" "${cur##--date=}" + return + ;; + --decorate=*) + __gitcomp "long short" "" "${cur##--decorate=}" + return + ;; + --*) + __gitcomp " + $__git_log_common_options + $__git_log_shortlog_options + $__git_log_gitk_options + --root --topo-order --date-order --reverse + --follow --full-diff + --abbrev-commit --abbrev= + --relative-date --date= + --pretty= --format= --oneline + --cherry-pick + --graph + --decorate --decorate= + --walk-reflogs + --parents --children + $merge + $__git_diff_common_options + --pickaxe-all --pickaxe-regex + " + return + ;; + esac + __git_complete_revlist +} + +__git_merge_options=" + --no-commit --no-stat --log --no-log --squash --strategy + --commit --stat --no-squash --ff --no-ff --ff-only --edit --no-edit +" + +_git_merge () +{ + __git_complete_strategy && return + + case "$cur" in + --*) + __gitcomp "$__git_merge_options" + return + esac + __gitcomp_nl "$(__git_refs)" +} + +_git_mergetool () +{ + case "$cur" in + --tool=*) + __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}" + return + ;; + --*) + __gitcomp "--tool=" + return + ;; + esac +} + +_git_merge_base () +{ + __gitcomp_nl "$(__git_refs)" +} + +_git_mv () +{ + case "$cur" in + --*) + __gitcomp "--dry-run" + return + ;; + esac + + if [ $(__git_count_arguments "mv") -gt 0 ]; then + # We need to show both cached and untracked files (including + # empty directories) since this may not be the last argument. + __git_complete_index_file "--cached --others --directory" + else + __git_complete_index_file "--cached" + fi +} + +_git_name_rev () +{ + __gitcomp "--tags --all --stdin" +} + +_git_notes () +{ + local subcommands='add append copy edit list prune remove show' + local subcommand="$(__git_find_on_cmdline "$subcommands")" + + case "$subcommand,$cur" in + ,--*) + __gitcomp '--ref' + ;; + ,*) + case "$prev" in + --ref) + __gitcomp_nl "$(__git_refs)" + ;; + *) + __gitcomp "$subcommands --ref" + ;; + esac + ;; + add,--reuse-message=*|append,--reuse-message=*|\ + add,--reedit-message=*|append,--reedit-message=*) + __gitcomp_nl "$(__git_refs)" "" "${cur#*=}" + ;; + add,--*|append,--*) + __gitcomp '--file= --message= --reedit-message= + --reuse-message=' + ;; + copy,--*) + __gitcomp '--stdin' + ;; + prune,--*) + __gitcomp '--dry-run --verbose' + ;; + prune,*) + ;; + *) + case "$prev" in + -m|-F) + ;; + *) + __gitcomp_nl "$(__git_refs)" + ;; + esac + ;; + esac +} + +_git_pull () +{ + __git_complete_strategy && return + + case "$cur" in + --*) + __gitcomp " + --rebase --no-rebase + $__git_merge_options + $__git_fetch_options + " + return + ;; + esac + __git_complete_remote_or_refspec +} + +_git_push () +{ + case "$prev" in + --repo) + __gitcomp_nl "$(__git_remotes)" + return + esac + case "$cur" in + --repo=*) + __gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}" + return + ;; + --*) + __gitcomp " + --all --mirror --tags --dry-run --force --verbose + --receive-pack= --repo= --set-upstream + " + return + ;; + esac + __git_complete_remote_or_refspec +} + +_git_rebase () +{ + local dir="$(__gitdir)" + if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then + __gitcomp "--continue --skip --abort" + return + fi + __git_complete_strategy && return + case "$cur" in + --whitespace=*) + __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" + return + ;; + --*) + __gitcomp " + --onto --merge --strategy --interactive + --preserve-merges --stat --no-stat + --committer-date-is-author-date --ignore-date + --ignore-whitespace --whitespace= + --autosquash + " + + return + esac + __gitcomp_nl "$(__git_refs)" +} + +_git_reflog () +{ + local subcommands="show delete expire" + local subcommand="$(__git_find_on_cmdline "$subcommands")" + + if [ -z "$subcommand" ]; then + __gitcomp "$subcommands" + else + __gitcomp_nl "$(__git_refs)" + fi +} + +__git_send_email_confirm_options="always never auto cc compose" +__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all" + +_git_send_email () +{ + case "$cur" in + --confirm=*) + __gitcomp " + $__git_send_email_confirm_options + " "" "${cur##--confirm=}" + return + ;; + --suppress-cc=*) + __gitcomp " + $__git_send_email_suppresscc_options + " "" "${cur##--suppress-cc=}" + + return + ;; + --smtp-encryption=*) + __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}" + return + ;; + --thread=*) + __gitcomp " + deep shallow + " "" "${cur##--thread=}" + return + ;; + --*) + __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to + --compose --confirm= --dry-run --envelope-sender + --from --identity + --in-reply-to --no-chain-reply-to --no-signed-off-by-cc + --no-suppress-from --no-thread --quiet + --signed-off-by-cc --smtp-pass --smtp-server + --smtp-server-port --smtp-encryption= --smtp-user + --subject --suppress-cc= --suppress-from --thread --to + --validate --no-validate + $__git_format_patch_options" + return + ;; + esac + __git_complete_revlist +} + +_git_stage () +{ + _git_add +} + +__git_config_get_set_variables () +{ + local prevword word config_file= c=$cword + while [ $c -gt 1 ]; do + word="${words[c]}" + case "$word" in + --system|--global|--local|--file=*) + config_file="$word" + break + ;; + -f|--file) + config_file="$word $prevword" + break + ;; + esac + prevword=$word + c=$((--c)) + done + + git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null | + while read -r line + do + case "$line" in + *.*=*) + echo "${line/=*/}" + ;; + esac + done +} + +_git_config () +{ + case "$prev" in + branch.*.remote|branch.*.pushremote) + __gitcomp_nl "$(__git_remotes)" + return + ;; + branch.*.merge) + __gitcomp_nl "$(__git_refs)" + return + ;; + branch.*.rebase) + __gitcomp "false true" + return + ;; + remote.pushdefault) + __gitcomp_nl "$(__git_remotes)" + return + ;; + remote.*.fetch) + local remote="${prev#remote.}" + remote="${remote%.fetch}" + if [ -z "$cur" ]; then + __gitcomp_nl "refs/heads/" "" "" "" + return + fi + __gitcomp_nl "$(__git_refs_remotes "$remote")" + return + ;; + remote.*.push) + local remote="${prev#remote.}" + remote="${remote%.push}" + __gitcomp_nl "$(git --git-dir="$(__gitdir)" \ + for-each-ref --format='%(refname):%(refname)' \ + refs/heads)" + return + ;; + pull.twohead|pull.octopus) + __git_compute_merge_strategies + __gitcomp "$__git_merge_strategies" + return + ;; + color.branch|color.diff|color.interactive|\ + color.showbranch|color.status|color.ui) + __gitcomp "always never auto" + return + ;; + color.pager) + __gitcomp "false true" + return + ;; + color.*.*) + __gitcomp " + normal black red green yellow blue magenta cyan white + bold dim ul blink reverse + " + return + ;; + diff.submodule) + __gitcomp "log short" + return + ;; + help.format) + __gitcomp "man info web html" + return + ;; + log.date) + __gitcomp "$__git_log_date_formats" + return + ;; + sendemail.aliasesfiletype) + __gitcomp "mutt mailrc pine elm gnus" + return + ;; + sendemail.confirm) + __gitcomp "$__git_send_email_confirm_options" + return + ;; + sendemail.suppresscc) + __gitcomp "$__git_send_email_suppresscc_options" + return + ;; + --get|--get-all|--unset|--unset-all) + __gitcomp_nl "$(__git_config_get_set_variables)" + return + ;; + *.*) + return + ;; + esac + case "$cur" in + --*) + __gitcomp " + --system --global --local --file= + --list --replace-all + --get --get-all --get-regexp + --add --unset --unset-all + --remove-section --rename-section + " + return + ;; + branch.*.*) + local pfx="${cur%.*}." cur_="${cur##*.}" + __gitcomp "remote pushremote merge mergeoptions rebase" "$pfx" "$cur_" + return + ;; + branch.*) + local pfx="${cur%.*}." cur_="${cur#*.}" + __gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "." + return + ;; + guitool.*.*) + local pfx="${cur%.*}." cur_="${cur##*.}" + __gitcomp " + argprompt cmd confirm needsfile noconsole norescan + prompt revprompt revunmerged title + " "$pfx" "$cur_" + return + ;; + difftool.*.*) + local pfx="${cur%.*}." cur_="${cur##*.}" + __gitcomp "cmd path" "$pfx" "$cur_" + return + ;; + man.*.*) + local pfx="${cur%.*}." cur_="${cur##*.}" + __gitcomp "cmd path" "$pfx" "$cur_" + return + ;; + mergetool.*.*) + local pfx="${cur%.*}." cur_="${cur##*.}" + __gitcomp "cmd path trustExitCode" "$pfx" "$cur_" + return + ;; + pager.*) + local pfx="${cur%.*}." cur_="${cur#*.}" + __git_compute_all_commands + __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" + return + ;; + remote.*.*) + local pfx="${cur%.*}." cur_="${cur##*.}" + __gitcomp " + url proxy fetch push mirror skipDefaultUpdate + receivepack uploadpack tagopt pushurl + " "$pfx" "$cur_" + return + ;; + remote.*) + local pfx="${cur%.*}." cur_="${cur#*.}" + __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "." + return + ;; + url.*.*) + local pfx="${cur%.*}." cur_="${cur##*.}" + __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" + return + ;; + esac + __gitcomp " + add.ignoreErrors + advice.commitBeforeMerge + advice.detachedHead + advice.implicitIdentity + advice.pushNonFastForward + advice.resolveConflict + advice.statusHints + alias. + am.keepcr + apply.ignorewhitespace + apply.whitespace + branch.autosetupmerge + branch.autosetuprebase + browser. + clean.requireForce + color.branch + color.branch.current + color.branch.local + color.branch.plain + color.branch.remote + color.decorate.HEAD + color.decorate.branch + color.decorate.remoteBranch + color.decorate.stash + color.decorate.tag + color.diff + color.diff.commit + color.diff.frag + color.diff.func + color.diff.meta + color.diff.new + color.diff.old + color.diff.plain + color.diff.whitespace + color.grep + color.grep.context + color.grep.filename + color.grep.function + color.grep.linenumber + color.grep.match + color.grep.selected + color.grep.separator + color.interactive + color.interactive.error + color.interactive.header + color.interactive.help + color.interactive.prompt + color.pager + color.showbranch + color.status + color.status.added + color.status.changed + color.status.header + color.status.nobranch + color.status.untracked + color.status.updated + color.ui + commit.status + commit.template + core.abbrev + core.askpass + core.attributesfile + core.autocrlf + core.bare + core.bigFileThreshold + core.compression + core.createObject + core.deltaBaseCacheLimit + core.editor + core.eol + core.excludesfile + core.fileMode + core.fsyncobjectfiles + core.gitProxy + core.ignoreStat + core.ignorecase + core.logAllRefUpdates + core.loosecompression + core.notesRef + core.packedGitLimit + core.packedGitWindowSize + core.pager + core.preferSymlinkRefs + core.preloadindex + core.quotepath + core.repositoryFormatVersion + core.safecrlf + core.sharedRepository + core.sparseCheckout + core.symlinks + core.trustctime + core.warnAmbiguousRefs + core.whitespace + core.worktree + diff.autorefreshindex + diff.external + diff.ignoreSubmodules + diff.mnemonicprefix + diff.noprefix + diff.renameLimit + diff.renames + diff.statGraphWidth + diff.submodule + diff.suppressBlankEmpty + diff.tool + diff.wordRegex + diff.algorithm + difftool. + difftool.prompt + fetch.recurseSubmodules + fetch.unpackLimit + format.attach + format.cc + format.headers + format.numbered + format.pretty + format.signature + format.signoff + format.subjectprefix + format.suffix + format.thread + format.to + gc. + gc.aggressiveWindow + gc.auto + gc.autopacklimit + gc.packrefs + gc.pruneexpire + gc.reflogexpire + gc.reflogexpireunreachable + gc.rerereresolved + gc.rerereunresolved + gitcvs.allbinary + gitcvs.commitmsgannotation + gitcvs.dbTableNamePrefix + gitcvs.dbdriver + gitcvs.dbname + gitcvs.dbpass + gitcvs.dbuser + gitcvs.enabled + gitcvs.logfile + gitcvs.usecrlfattr + guitool. + gui.blamehistoryctx + gui.commitmsgwidth + gui.copyblamethreshold + gui.diffcontext + gui.encoding + gui.fastcopyblame + gui.matchtrackingbranch + gui.newbranchtemplate + gui.pruneduringfetch + gui.spellingdictionary + gui.trustmtime + help.autocorrect + help.browser + help.format + http.lowSpeedLimit + http.lowSpeedTime + http.maxRequests + http.minSessions + http.noEPSV + http.postBuffer + http.proxy + http.sslCAInfo + http.sslCAPath + http.sslCert + http.sslCertPasswordProtected + http.sslKey + http.sslVerify + http.useragent + i18n.commitEncoding + i18n.logOutputEncoding + imap.authMethod + imap.folder + imap.host + imap.pass + imap.port + imap.preformattedHTML + imap.sslverify + imap.tunnel + imap.user + init.templatedir + instaweb.browser + instaweb.httpd + instaweb.local + instaweb.modulepath + instaweb.port + interactive.singlekey + log.date + log.decorate + log.showroot + mailmap.file + man. + man.viewer + merge. + merge.conflictstyle + merge.log + merge.renameLimit + merge.renormalize + merge.stat + merge.tool + merge.verbosity + mergetool. + mergetool.keepBackup + mergetool.keepTemporaries + mergetool.prompt + notes.displayRef + notes.rewrite. + notes.rewrite.amend + notes.rewrite.rebase + notes.rewriteMode + notes.rewriteRef + pack.compression + pack.deltaCacheLimit + pack.deltaCacheSize + pack.depth + pack.indexVersion + pack.packSizeLimit + pack.threads + pack.window + pack.windowMemory + pager. + pretty. + pull.octopus + pull.twohead + push.default + rebase.autosquash + rebase.stat + receive.autogc + receive.denyCurrentBranch + receive.denyDeleteCurrent + receive.denyDeletes + receive.denyNonFastForwards + receive.fsckObjects + receive.unpackLimit + receive.updateserverinfo + remote.pushdefault + remotes. + repack.usedeltabaseoffset + rerere.autoupdate + rerere.enabled + sendemail. + sendemail.aliasesfile + sendemail.aliasfiletype + sendemail.bcc + sendemail.cc + sendemail.cccmd + sendemail.chainreplyto + sendemail.confirm + sendemail.envelopesender + sendemail.from + sendemail.identity + sendemail.multiedit + sendemail.signedoffbycc + sendemail.smtpdomain + sendemail.smtpencryption + sendemail.smtppass + sendemail.smtpserver + sendemail.smtpserveroption + sendemail.smtpserverport + sendemail.smtpuser + sendemail.suppresscc + sendemail.suppressfrom + sendemail.thread + sendemail.to + sendemail.validate + showbranch.default + status.relativePaths + status.showUntrackedFiles + status.submodulesummary + submodule. + tar.umask + transfer.unpackLimit + url. + user.email + user.name + user.signingkey + web.browser + branch. remote. + " +} + +_git_remote () +{ + local subcommands="add rename remove set-head set-branches set-url show prune update" + local subcommand="$(__git_find_on_cmdline "$subcommands")" + if [ -z "$subcommand" ]; then + __gitcomp "$subcommands" + return + fi + + case "$subcommand" in + rename|remove|set-url|show|prune) + __gitcomp_nl "$(__git_remotes)" + ;; + set-head|set-branches) + __git_complete_remote_or_refspec + ;; + update) + local i c='' IFS=$'\n' + for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do + i="${i#remotes.}" + c="$c ${i/ */}" + done + __gitcomp "$c" + ;; + *) + ;; + esac +} + +_git_replace () +{ + __gitcomp_nl "$(__git_refs)" +} + +_git_reset () +{ + __git_has_doubledash && return + + case "$cur" in + --*) + __gitcomp "--merge --mixed --hard --soft --patch" + return + ;; + esac + __gitcomp_nl "$(__git_refs)" +} + +_git_revert () +{ + case "$cur" in + --*) + __gitcomp "--edit --mainline --no-edit --no-commit --signoff" + return + ;; + esac + __gitcomp_nl "$(__git_refs)" +} + +_git_rm () +{ + case "$cur" in + --*) + __gitcomp "--cached --dry-run --ignore-unmatch --quiet" + return + ;; + esac + + __git_complete_index_file "--cached" +} + +_git_shortlog () +{ + __git_has_doubledash && return + + case "$cur" in + --*) + __gitcomp " + $__git_log_common_options + $__git_log_shortlog_options + --numbered --summary + " + return + ;; + esac + __git_complete_revlist +} + +_git_show () +{ + __git_has_doubledash && return + + case "$cur" in + --pretty=*|--format=*) + __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases) + " "" "${cur#*=}" + return + ;; + --diff-algorithm=*) + __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}" + return + ;; + --*) + __gitcomp "--pretty= --format= --abbrev-commit --oneline + $__git_diff_common_options + " + return + ;; + esac + __git_complete_revlist_file +} + +_git_show_branch () +{ + case "$cur" in + --*) + __gitcomp " + --all --remotes --topo-order --current --more= + --list --independent --merge-base --no-name + --color --no-color + --sha1-name --sparse --topics --reflog + " + return + ;; + esac + __git_complete_revlist +} + +_git_stash () +{ + local save_opts='--keep-index --no-keep-index --quiet --patch' + local subcommands='save list show apply clear drop pop create branch' + local subcommand="$(__git_find_on_cmdline "$subcommands")" + if [ -z "$subcommand" ]; then + case "$cur" in + --*) + __gitcomp "$save_opts" + ;; + *) + if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then + __gitcomp "$subcommands" + fi + ;; + esac + else + case "$subcommand,$cur" in + save,--*) + __gitcomp "$save_opts" + ;; + apply,--*|pop,--*) + __gitcomp "--index --quiet" + ;; + show,--*|drop,--*|branch,--*) + ;; + show,*|apply,*|drop,*|pop,*|branch,*) + __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \ + | sed -n -e 's/:.*//p')" + ;; + *) + ;; + esac + fi +} + +_git_submodule () +{ + __git_has_doubledash && return + + local subcommands="add status init deinit update summary foreach sync" + if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then + case "$cur" in + --*) + __gitcomp "--quiet --cached" + ;; + *) + __gitcomp "$subcommands" + ;; + esac + return + fi +} + +_git_svn () +{ + local subcommands=" + init fetch clone rebase dcommit log find-rev + set-tree commit-diff info create-ignore propget + proplist show-ignore show-externals branch tag blame + migrate mkdirs reset gc + " + local subcommand="$(__git_find_on_cmdline "$subcommands")" + if [ -z "$subcommand" ]; then + __gitcomp "$subcommands" + else + local remote_opts="--username= --config-dir= --no-auth-cache" + local fc_opts=" + --follow-parent --authors-file= --repack= + --no-metadata --use-svm-props --use-svnsync-props + --log-window-size= --no-checkout --quiet + --repack-flags --use-log-author --localtime + --ignore-paths= --include-paths= $remote_opts + " + local init_opts=" + --template= --shared= --trunk= --tags= + --branches= --stdlayout --minimize-url + --no-metadata --use-svm-props --use-svnsync-props + --rewrite-root= --prefix= --use-log-author + --add-author-from $remote_opts + " + local cmt_opts=" + --edit --rmdir --find-copies-harder --copy-similarity= + " + + case "$subcommand,$cur" in + fetch,--*) + __gitcomp "--revision= --fetch-all $fc_opts" + ;; + clone,--*) + __gitcomp "--revision= $fc_opts $init_opts" + ;; + init,--*) + __gitcomp "$init_opts" + ;; + dcommit,--*) + __gitcomp " + --merge --strategy= --verbose --dry-run + --fetch-all --no-rebase --commit-url + --revision --interactive $cmt_opts $fc_opts + " + ;; + set-tree,--*) + __gitcomp "--stdin $cmt_opts $fc_opts" + ;; + create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\ + show-externals,--*|mkdirs,--*) + __gitcomp "--revision=" + ;; + log,--*) + __gitcomp " + --limit= --revision= --verbose --incremental + --oneline --show-commit --non-recursive + --authors-file= --color + " + ;; + rebase,--*) + __gitcomp " + --merge --verbose --strategy= --local + --fetch-all --dry-run $fc_opts + " + ;; + commit-diff,--*) + __gitcomp "--message= --file= --revision= $cmt_opts" + ;; + info,--*) + __gitcomp "--url" + ;; + branch,--*) + __gitcomp "--dry-run --message --tag" + ;; + tag,--*) + __gitcomp "--dry-run --message" + ;; + blame,--*) + __gitcomp "--git-format" + ;; + migrate,--*) + __gitcomp " + --config-dir= --ignore-paths= --minimize + --no-auth-cache --username= + " + ;; + reset,--*) + __gitcomp "--revision= --parent" + ;; + *) + ;; + esac + fi +} + +_git_tag () +{ + local i c=1 f=0 + while [ $c -lt $cword ]; do + i="${words[c]}" + case "$i" in + -d|-v) + __gitcomp_nl "$(__git_tags)" + return + ;; + -f) + f=1 + ;; + esac + ((c++)) + done + + case "$prev" in + -m|-F) + ;; + -*|tag) + if [ $f = 1 ]; then + __gitcomp_nl "$(__git_tags)" + fi + ;; + *) + __gitcomp_nl "$(__git_refs)" + ;; + esac +} + +_git_whatchanged () +{ + _git_log +} + +__git_main () +{ + local i c=1 command __git_dir + + while [ $c -lt $cword ]; do + i="${words[c]}" + case "$i" in + --git-dir=*) __git_dir="${i#--git-dir=}" ;; + --git-dir) ((c++)) ; __git_dir="${words[c]}" ;; + --bare) __git_dir="." ;; + --help) command="help"; break ;; + -c|--work-tree|--namespace) ((c++)) ;; + -*) ;; + *) command="$i"; break ;; + esac + ((c++)) + done + + if [ -z "$command" ]; then + case "$cur" in + --*) __gitcomp " + --paginate + --no-pager + --git-dir= + --bare + --version + --exec-path + --exec-path= + --html-path + --man-path + --info-path + --work-tree= + --namespace= + --no-replace-objects + --help + " + ;; + *) __git_compute_porcelain_commands + __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;; + esac + return + fi + + local completion_func="_git_${command//-/_}" + declare -f $completion_func >/dev/null && $completion_func && return + + local expansion=$(__git_aliased_command "$command") + if [ -n "$expansion" ]; then + completion_func="_git_${expansion//-/_}" + declare -f $completion_func >/dev/null && $completion_func + fi +} + +__gitk_main () +{ + __git_has_doubledash && return + + local g="$(__gitdir)" + local merge="" + if [ -f "$g/MERGE_HEAD" ]; then + merge="--merge" + fi + case "$cur" in + --*) + __gitcomp " + $__git_log_common_options + $__git_log_gitk_options + $merge + " + return + ;; + esac + __git_complete_revlist +} + +if [[ -n ${ZSH_VERSION-} ]]; then + echo "WARNING: this script is deprecated, please see git-completion.zsh" 1>&2 + + autoload -U +X compinit && compinit + + __gitcomp () + { + emulate -L zsh + + local cur_="${3-$cur}" + + case "$cur_" in + --*=) + ;; + *) + local c IFS=$' \t\n' + local -a array + for c in ${=1}; do + c="$c${4-}" + case $c in + --*=*|*.) ;; + *) c="$c " ;; + esac + array[$#array+1]="$c" + done + compset -P '*[=:]' + compadd -Q -S '' -p "${2-}" -a -- array && _ret=0 + ;; + esac + } + + __gitcomp_nl () + { + emulate -L zsh + + local IFS=$'\n' + compset -P '*[=:]' + compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0 + } + + __gitcomp_file () + { + emulate -L zsh + + local IFS=$'\n' + compset -P '*[=:]' + compadd -Q -p "${2-}" -f -- ${=1} && _ret=0 + } + + _git () + { + local _ret=1 cur cword prev + cur=${words[CURRENT]} + prev=${words[CURRENT-1]} + let cword=CURRENT-1 + emulate ksh -c __${service}_main + let _ret && _default && _ret=0 + return _ret + } + + compdef _git git gitk + return +fi + +__git_func_wrap () +{ + local cur words cword prev + _get_comp_words_by_ref -n =: cur words cword prev + $1 +} + +# Setup completion for certain functions defined above by setting common +# variables and workarounds. +# This is NOT a public function; use at your own risk. +__git_complete () +{ + local wrapper="__git_wrap${2}" + eval "$wrapper () { __git_func_wrap $2 ; }" + complete -o bashdefault -o default -o nospace -F $wrapper $1 2>/dev/null \ + || complete -o default -o nospace -F $wrapper $1 +} + +# wrapper for backwards compatibility +_git () +{ + __git_wrap__git_main +} + +# wrapper for backwards compatibility +_gitk () +{ + __git_wrap__gitk_main +} + +__git_complete git __git_main +__git_complete gitk __gitk_main + +# The following are necessary only for Cygwin, and only are needed +# when the user has tab-completed the executable name and consequently +# included the '.exe' suffix. +# +if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then +__git_complete git.exe __git_main +fi diff --git a/tools/dockerfile/root/.scripts/git-prompt.sh b/tools/dockerfile/root/.scripts/git-prompt.sh new file mode 100755 index 0000000000000000000000000000000000000000..576f4ec14c94a24ebffa9e2620acf881e6b5ddaa --- /dev/null +++ b/tools/dockerfile/root/.scripts/git-prompt.sh @@ -0,0 +1,445 @@ +# bash/zsh git prompt support +# +# Copyright (C) 2006,2007 Shawn O. Pearce +# Distributed under the GNU General Public License, version 2.0. +# +# This script allows you to see repository status in your prompt. +# +# To enable: +# +# 1) Copy this file to somewhere (e.g. ~/.git-prompt.sh). +# 2) Add the following line to your .bashrc/.zshrc: +# source ~/.git-prompt.sh +# 3a) Change your PS1 to call __git_ps1 as +# command-substitution: +# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' +# ZSH: setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ ' +# the optional argument will be used as format string. +# 3b) Alternatively, for a slightly faster prompt, __git_ps1 can +# be used for PROMPT_COMMAND in Bash or for precmd() in Zsh +# with two parameters,
 and , which are strings
+#        you would put in $PS1 before and after the status string
+#        generated by the git-prompt machinery.  e.g.
+#        Bash: PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
+#          will show username, at-sign, host, colon, cwd, then
+#          various status string, followed by dollar and SP, as
+#          your prompt.
+#        ZSH:  precmd () { __git_ps1 "%n" ":%~$ " "|%s" }
+#          will show username, pipe, then various status string,
+#          followed by colon, cwd, dollar and SP, as your prompt.
+#        Optionally, you can supply a third argument with a printf
+#        format string to finetune the output of the branch status
+#
+# The repository status will be displayed only if you are currently in a
+# git repository. The %s token is the placeholder for the shown status.
+#
+# The prompt status always includes the current branch name.
+#
+# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty value,
+# unstaged (*) and staged (+) changes will be shown next to the branch
+# name.  You can configure this per-repository with the
+# bash.showDirtyState variable, which defaults to true once
+# GIT_PS1_SHOWDIRTYSTATE is enabled.
+#
+# You can also see if currently something is stashed, by setting
+# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
+# then a '$' will be shown next to the branch name.
+#
+# If you would like to see if there're untracked files, then you can set
+# GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're untracked
+# files, then a '%' will be shown next to the branch name.  You can
+# configure this per-repository with the bash.showUntrackedFiles
+# variable, which defaults to true once GIT_PS1_SHOWUNTRACKEDFILES is
+# enabled.
+#
+# If you would like to see the difference between HEAD and its upstream,
+# set GIT_PS1_SHOWUPSTREAM="auto".  A "<" indicates you are behind, ">"
+# indicates you are ahead, "<>" indicates you have diverged and "="
+# indicates that there is no difference. You can further control
+# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated list
+# of values:
+#
+#     verbose       show number of commits ahead/behind (+/-) upstream
+#     legacy        don't use the '--count' option available in recent
+#                   versions of git-rev-list
+#     git           always compare HEAD to @{upstream}
+#     svn           always compare HEAD to your SVN upstream
+#
+# By default, __git_ps1 will compare HEAD to your SVN upstream if it can
+# find one, or @{upstream} otherwise.  Once you have set
+# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
+# setting the bash.showUpstream config variable.
+#
+# If you would like to see more information about the identity of
+# commits checked out as a detached HEAD, set GIT_PS1_DESCRIBE_STYLE
+# to one of these values:
+#
+#     contains      relative to newer annotated tag (v1.6.3.2~35)
+#     branch        relative to newer tag or branch (master~4)
+#     describe      relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
+#     default       exactly matching tag
+#
+# If you would like a colored hint about the current dirty state, set
+# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
+# the colored output of "git status -sb" and are available only when
+# using __git_ps1 for PROMPT_COMMAND or precmd.
+
+# stores the divergence from upstream in $p
+# used by GIT_PS1_SHOWUPSTREAM
+__git_ps1_show_upstream ()
+{
+  local key value
+  local svn_remote svn_url_pattern count n
+  local upstream=git legacy="" verbose=""
+
+  svn_remote=()
+  # get some config options from git-config
+  local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
+  while read -r key value; do
+    case "$key" in
+    bash.showupstream)
+      GIT_PS1_SHOWUPSTREAM="$value"
+      if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
+        p=""
+        return
+      fi
+      ;;
+    svn-remote.*.url)
+      svn_remote[$((${#svn_remote[@]} + 1))]="$value"
+      svn_url_pattern+="\\|$value"
+      upstream=svn+git # default upstream is SVN if available, else git
+      ;;
+    esac
+  done <<< "$output"
+
+  # parse configuration values
+  for option in ${GIT_PS1_SHOWUPSTREAM}; do
+    case "$option" in
+    git|svn) upstream="$option" ;;
+    verbose) verbose=1 ;;
+    legacy)  legacy=1  ;;
+    esac
+  done
+
+  # Find our upstream
+  case "$upstream" in
+  git)    upstream="@{upstream}" ;;
+  svn*)
+    # get the upstream from the "git-svn-id: ..." in a commit message
+    # (git-svn uses essentially the same procedure internally)
+    local -a svn_upstream
+    svn_upstream=($(git log --first-parent -1 \
+          --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
+    if [[ 0 -ne ${#svn_upstream[@]} ]]; then
+      svn_upstream=${svn_upstream[${#svn_upstream[@]} - 2]}
+      svn_upstream=${svn_upstream%@*}
+      local n_stop="${#svn_remote[@]}"
+      for ((n=1; n <= n_stop; n++)); do
+        svn_upstream=${svn_upstream#${svn_remote[$n]}}
+      done
+
+      if [[ -z "$svn_upstream" ]]; then
+        # default branch name for checkouts with no layout:
+        upstream=${GIT_SVN_ID:-git-svn}
+      else
+        upstream=${svn_upstream#/}
+      fi
+    elif [[ "svn+git" = "$upstream" ]]; then
+      upstream="@{upstream}"
+    fi
+    ;;
+  esac
+
+  # Find how many commits we are ahead/behind our upstream
+  if [[ -z "$legacy" ]]; then
+    count="$(git rev-list --count --left-right \
+        "$upstream"...HEAD 2>/dev/null)"
+  else
+    # produce equivalent output to --count for older versions of git
+    local commits
+    if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)"
+    then
+      local commit behind=0 ahead=0
+      for commit in $commits
+      do
+        case "$commit" in
+        "<"*) ((behind++)) ;;
+        *)    ((ahead++))  ;;
+        esac
+      done
+      count="$behind  $ahead"
+    else
+      count=""
+    fi
+  fi
+
+  # calculate the result
+  if [[ -z "$verbose" ]]; then
+    case "$count" in
+    "") # no upstream
+      p="" ;;
+    "0  0") # equal to upstream
+      p="=" ;;
+    "0  "*) # ahead of upstream
+      p=">" ;;
+    *"  0") # behind upstream
+      p="<" ;;
+    *)      # diverged from upstream
+      p="<>" ;;
+    esac
+  else
+    case "$count" in
+    "") # no upstream
+      p="" ;;
+    "0  0") # equal to upstream
+      p=" u=" ;;
+    "0  "*) # ahead of upstream
+      p=" u+${count#0 }" ;;
+    *"  0") # behind upstream
+      p=" u-${count%  0}" ;;
+    *)      # diverged from upstream
+      p=" u+${count#* }-${count%  *}" ;;
+    esac
+  fi
+
+}
+
+# Helper function that is meant to be called from __git_ps1.  It
+# injects color codes into the appropriate gitstring variables used
+# to build a gitstring.
+__git_ps1_colorize_gitstring ()
+{
+  if [[ -n ${ZSH_VERSION-} ]]; then
+    local c_red='%F{red}'
+    local c_green='%F{green}'
+    local c_lblue='%F{blue}'
+    local c_clear='%f'
+  else
+    # Using \[ and \] around colors is necessary to prevent
+    # issues with command line editing/browsing/completion!
+    local c_red='\[\e[31m\]'
+    local c_green='\[\e[32m\]'
+    local c_lblue='\[\e[1;34m\]'
+    local c_clear='\[\e[0m\]'
+  fi
+  local bad_color=$c_red
+  local ok_color=$c_green
+  local flags_color="$c_lblue"
+
+  local branch_color=""
+  if [ $detached = no ]; then
+    branch_color="$ok_color"
+  else
+    branch_color="$bad_color"
+  fi
+  c="$branch_color$c"
+
+  z="$c_clear$z"
+  if [ "$w" = "*" ]; then
+    w="$bad_color$w"
+  fi
+  if [ -n "$i" ]; then
+    i="$ok_color$i"
+  fi
+  if [ -n "$s" ]; then
+    s="$flags_color$s"
+  fi
+  if [ -n "$u" ]; then
+    u="$bad_color$u"
+  fi
+  r="$c_clear$r"
+}
+
+# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
+# when called from PS1 using command substitution
+# in this mode it prints text to add to bash PS1 prompt (includes branch name)
+#
+# __git_ps1 requires 2 or 3 arguments when called from PROMPT_COMMAND (pc)
+# in that case it _sets_ PS1. The arguments are parts of a PS1 string.
+# when two arguments are given, the first is prepended and the second appended
+# to the state string when assigned to PS1.
+# The optional third parameter will be used as printf format string to further
+# customize the output of the git-status string.
+# In this mode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true
+__git_ps1 ()
+{
+  local pcmode=no
+  local detached=no
+  local ps1pc_start='\u@\h:\w '
+  local ps1pc_end='\$ '
+  local printf_format=' (%s)'
+
+  case "$#" in
+    2|3)  pcmode=yes
+      ps1pc_start="$1"
+      ps1pc_end="$2"
+      printf_format="${3:-$printf_format}"
+    ;;
+    0|1)  printf_format="${1:-$printf_format}"
+    ;;
+    *)  return
+    ;;
+  esac
+
+  local repo_info rev_parse_exit_code
+  repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
+    --is-bare-repository --is-inside-work-tree \
+    --short HEAD 2>/dev/null)"
+  rev_parse_exit_code="$?"
+
+  if [ -z "$repo_info" ]; then
+    if [ $pcmode = yes ]; then
+      #In PC mode PS1 always needs to be set
+      PS1="$ps1pc_start$ps1pc_end"
+    fi
+    return
+  fi
+
+  local short_sha
+  if [ "$rev_parse_exit_code" = "0" ]; then
+    short_sha="${repo_info##*$'\n'}"
+    repo_info="${repo_info%$'\n'*}"
+  fi
+  local inside_worktree="${repo_info##*$'\n'}"
+  repo_info="${repo_info%$'\n'*}"
+  local bare_repo="${repo_info##*$'\n'}"
+  repo_info="${repo_info%$'\n'*}"
+  local inside_gitdir="${repo_info##*$'\n'}"
+  local g="${repo_info%$'\n'*}"
+
+  local r=""
+  local b=""
+  local step=""
+  local total=""
+  if [ -d "$g/rebase-merge" ]; then
+    read b 2>/dev/null <"$g/rebase-merge/head-name"
+    read step 2>/dev/null <"$g/rebase-merge/msgnum"
+    read total 2>/dev/null <"$g/rebase-merge/end"
+    if [ -f "$g/rebase-merge/interactive" ]; then
+      r="|REBASE-i"
+    else
+      r="|REBASE-m"
+    fi
+  else
+    if [ -d "$g/rebase-apply" ]; then
+      read step 2>/dev/null <"$g/rebase-apply/next"
+      read total 2>/dev/null <"$g/rebase-apply/last"
+      if [ -f "$g/rebase-apply/rebasing" ]; then
+        read b 2>/dev/null <"$g/rebase-apply/head-name"
+        r="|REBASE"
+      elif [ -f "$g/rebase-apply/applying" ]; then
+        r="|AM"
+      else
+        r="|AM/REBASE"
+      fi
+    elif [ -f "$g/MERGE_HEAD" ]; then
+      r="|MERGING"
+    elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
+      r="|CHERRY-PICKING"
+    elif [ -f "$g/REVERT_HEAD" ]; then
+      r="|REVERTING"
+    elif [ -f "$g/BISECT_LOG" ]; then
+      r="|BISECTING"
+    fi
+
+    if [ -n "$b" ]; then
+      :
+    elif [ -h "$g/HEAD" ]; then
+      # symlink symbolic ref
+      b="$(git symbolic-ref HEAD 2>/dev/null)"
+    else
+      local head=""
+      if ! read head 2>/dev/null <"$g/HEAD"; then
+        if [ $pcmode = yes ]; then
+          PS1="$ps1pc_start$ps1pc_end"
+        fi
+        return
+      fi
+      # is it a symbolic ref?
+      b="${head#ref: }"
+      if [ "$head" = "$b" ]; then
+        detached=yes
+        b="$(
+        case "${GIT_PS1_DESCRIBE_STYLE-}" in
+        (contains)
+          git describe --contains HEAD ;;
+        (branch)
+          git describe --contains --all HEAD ;;
+        (describe)
+          git describe HEAD ;;
+        (* | default)
+          git describe --tags --exact-match HEAD ;;
+        esac 2>/dev/null)" ||
+
+        b="$short_sha..."
+        b="($b)"
+      fi
+    fi
+  fi
+
+  if [ -n "$step" ] && [ -n "$total" ]; then
+    r="$r $step/$total"
+  fi
+
+  local w=""
+  local i=""
+  local s=""
+  local u=""
+  local c=""
+  local p=""
+
+  if [ "true" = "$inside_gitdir" ]; then
+    if [ "true" = "$bare_repo" ]; then
+      c="BARE:"
+    else
+      b="GIT_DIR!"
+    fi
+  elif [ "true" = "$inside_worktree" ]; then
+    if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
+       [ "$(git config --bool bash.showDirtyState)" != "false" ]
+    then
+      git diff --no-ext-diff --quiet --exit-code || w="*"
+      if [ -n "$short_sha" ]; then
+        git diff-index --cached --quiet HEAD -- || i="+"
+      else
+        i="#"
+      fi
+    fi
+    if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ] &&
+       [ -r "$g/refs/stash" ]; then
+      s="$"
+    fi
+
+    if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ] &&
+       [ "$(git config --bool bash.showUntrackedFiles)" != "false" ] &&
+       git ls-files --others --exclude-standard --error-unmatch -- '*' >/dev/null 2>/dev/null
+    then
+      u="%${ZSH_VERSION+%}"
+    fi
+
+    if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
+      __git_ps1_show_upstream
+    fi
+  fi
+
+  local z="${GIT_PS1_STATESEPARATOR-" "}"
+
+  # NO color option unless in PROMPT_COMMAND mode
+  if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
+    __git_ps1_colorize_gitstring
+  fi
+
+  local f="$w$i$s$u"
+  local gitstring="$c${b##refs/heads/}${f:+$z$f}$r$p"
+
+  if [ $pcmode = yes ]; then
+    if [[ -n ${ZSH_VERSION-} ]]; then
+      gitstring=$(printf -- "$printf_format" "$gitstring")
+    else
+      printf -v gitstring -- "$printf_format" "$gitstring"
+    fi
+    PS1="$ps1pc_start$gitstring$ps1pc_end"
+  else
+    printf -- "$printf_format" "$gitstring"
+  fi
+}