diff --git a/doc/COMPILE.md b/doc/COMPILE.md index aaf205eb3eeddc5d099384262fd26f31b291b370..51f2cc28ad959603b2f72d4bf32898023b940c08 100644 --- a/doc/COMPILE.md +++ b/doc/COMPILE.md @@ -12,7 +12,7 @@ ``` python git clone https://github.com/PaddlePaddle/Serving -git submodule update --init --recursive +cd Serving && git submodule update --init --recursive ``` ### 编译Server部分 @@ -44,3 +44,6 @@ make -j10 ### 安装wheel包 无论是client端还是server端,编译完成后,安装python/dist/下的whl包即可 + +### 注意事项 +运行python端server时,会检查`SERVING_BIN`环境变量,如果想使用自己编译的二进制文件,请将设置该环境变量为对应二进制文件的路径,通常是`export SERVING_BIN=${BUILD_PATH}/core/general-server/serving`。 diff --git a/doc/DESIGN_DOC.md b/doc/DESIGN_DOC.md index 7c460c129e74423eb94b4beb010a277778f62900..f6da3770acfce58cfa8a19fa683d246a4390350e 100644 --- a/doc/DESIGN_DOC.md +++ b/doc/DESIGN_DOC.md @@ -50,7 +50,6 @@ serving_io.save_model("serving_model", "client_conf", 服务端的预测逻辑可以通过Paddle Serving Server端的API进行人工定义,一个例子: ``` python -``` python import paddle_serving_server as serving op_maker = serving.OpMaker() read_op = op_maker.create('general_reader') @@ -221,6 +220,3 @@ imdb_service.run_server() ### 5.3 向量检索、树结构检索 在推荐与广告场景的召回系统中,通常需要采用基于向量的快速检索或者基于树结构的快速检索,Paddle Serving会对这方面的检索引擎进行集成或扩展。 - - - diff --git a/python/paddle_serving_server_gpu/serve.py b/python/paddle_serving_server_gpu/serve.py index 5d9d96d517d64b21313fda0b44a83b34142b014b..39d7a914b180d60442b0aa766a85115d7cc0c38c 100644 --- a/python/paddle_serving_server_gpu/serve.py +++ b/python/paddle_serving_server_gpu/serve.py @@ -91,15 +91,15 @@ if __name__ == "__main__": if args.name == "None": start_multi_card(args) else: + from .web_service import WebService web_service = WebService(name=args.name) web_service.load_model_config(args.model) - gpu_ids = [] - if args.gpu_ids == "": + gpu_ids = args.gpu_ids + if gpu_ids == "": if "CUDA_VISIBLE_DEVICES" in os.environ: gpu_ids = os.environ["CUDA_VISIBLE_DEVICES"] if len(gpu_ids) > 0: - gpus = [int(x) for x in gpu_ids.split(",")] - web_service.set_gpus(gpus) + web_service.set_gpus(gpu_ids) web_service.prepare_server( workdir=args.workdir, port=args.port, device=args.device) web_service.run_server() diff --git a/tools/Dockerfile.gpu b/tools/Dockerfile.gpu index 427ae83bcb805ec70c1e6d575e84234f17e9fb30..091f4a546b549a3dd53645e78ab49b1cd46bf5b3 100644 --- a/tools/Dockerfile.gpu +++ b/tools/Dockerfile.gpu @@ -10,6 +10,6 @@ RUN yum -y install wget && \ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ python get-pip.py && rm get-pip.py && \ 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 && \ + 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 diff --git a/tools/Dockerfile.gpu.devel b/tools/Dockerfile.gpu.devel new file mode 100644 index 0000000000000000000000000000000000000000..a2233908dbcff4f2f2bbd3edad24b83cb5252e16 --- /dev/null +++ b/tools/Dockerfile.gpu.devel @@ -0,0 +1,23 @@ +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 >/dev/null \ + && yum -y install git openssl-devel curl-devel bzip2-devel python-devel >/dev/null \ + && 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 \ + && 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 \ + && yum -y install python-devel sqlite-devel >/dev/null \ + && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py >/dev/null \ + && python get-pip.py >/dev/null \ + && pip install google protobuf setuptools wheel flask >/dev/null \ + && rm get-pip.py \ + && yum -y install epel-release && yum -y install patchelf \ + && yum clean all diff --git a/tools/serving_build.sh b/tools/serving_build.sh index dd6a3f6da8b3e40f2e379cb9457c4e5f00bc900c..8bb305c750b7b6a60eaeb44bcbfa87746f7f25dc 100644 --- a/tools/serving_build.sh +++ b/tools/serving_build.sh @@ -1,12 +1,23 @@ #!/usr/bin/env bash +function unsetproxy() { + HTTP_PROXY_TEMP=$http_proxy + HTTPS_PROXY_TEMP=$https_proxy + unset http_proxy + unset https_proxy +} + +function setproxy() { + export http_proxy=$HTTP_PROXY_TEMP + export https_proxy=$HTTPS_PROXY_TEMP +} + function init() { source /root/.bashrc set -v - #export http_proxy=http://172.19.56.199:3128 - #export https_proxy=http://172.19.56.199:3128 export PYTHONROOT=/usr cd Serving + export SERVING_WORKDIR=$PWD } function check_cmd() { @@ -16,18 +27,40 @@ function check_cmd() { fi } +function rerun() { + if [ $# -ne 2 ]; then + echo "usage: rerun command rerun-times" + exit 1 + fi + local command=$1 + local times=$2 + for((i=1;i<=${times};i++)) + do + if [ ${i} != 1 ]; then + echo "${i}-th run command: ${command}..." + fi + eval $command + if [ $? -eq 0 ]; then + return 0 + fi + echo "${i}-th run(command: ${command}) failed." + done + exit 1 +} + function build_client() { local TYPE=$1 local DIRNAME=build-client-$TYPE - mkdir $DIRNAME && cd $DIRNAME + mkdir $DIRNAME # pwd: /Serving + cd $DIRNAME # pwd: /Serving/build-client-$TYPE case $TYPE in CPU|GPU) cmake -DPYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ \ -DPYTHON_LIBRARIES=$PYTHONROOT/lib64/libpython2.7.so \ -DPYTHON_EXECUTABLE=$PYTHONROOT/bin/python \ -DCLIENT_ONLY=ON .. - check_cmd "make -j2 >/dev/null" - pip install python/dist/paddle_serving_client* >/dev/null + rerun "make -j2 >/dev/null" 3 # due to some network reasons, compilation may fail + pip install -U python/dist/paddle_serving_client* >/dev/null ;; *) echo "error type" @@ -35,22 +68,24 @@ function build_client() { ;; esac echo "build client $TYPE part finished as expected." - cd .. - rm -rf $DIRNAME + cd .. # pwd: /Serving + # rm -rf $DIRNAME } function build_server() { local TYPE=$1 local DIRNAME=build-server-$TYPE - mkdir $DIRNAME && cd $DIRNAME + mkdir $DIRNAME # pwd: /Serving + cd $DIRNAME # pwd: /Serving/build-server-$TYPE case $TYPE in CPU) cmake -DPYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ \ -DPYTHON_LIBRARIES=$PYTHONROOT/lib64/libpython2.7.so \ -DPYTHON_EXECUTABLE=$PYTHONROOT/bin/python \ -DCLIENT_ONLY=OFF .. - check_cmd "make -j2 >/dev/null && make install -j2 >/dev/null" - pip install python/dist/paddle_serving_server* >/dev/null + rerun "make -j2 >/dev/null" 3 # due to some network reasons, compilation may fail + check_cmd "make install -j2 >/dev/null" + pip install -U python/dist/paddle_serving_server* >/dev/null ;; GPU) cmake -DPYTHON_INCLUDE_DIR=$PYTHONROOT/include/python2.7/ \ @@ -58,8 +93,9 @@ function build_server() { -DPYTHON_EXECUTABLE=$PYTHONROOT/bin/python \ -DCLIENT_ONLY=OFF \ -DWITH_GPU=ON .. - check_cmd "make -j2 >/dev/null && make install -j2 >/dev/null" - pip install python/dist/paddle_serving_server* >/dev/null + rerun "make -j2 >/dev/null" 3 # due to some network reasons, compilation may fail + check_cmd "make install -j2 >/dev/null" + pip install -U python/dist/paddle_serving_server* >/dev/null ;; *) echo "error type" @@ -67,30 +103,62 @@ function build_server() { ;; esac echo "build server $TYPE part finished as expected." - cd .. + cd .. # pwd: /Serving + # rm -rf $DIRNAME for export SERVING_BIN +} + +function kill_server_process() { + ps -ef | grep "serving" | grep -v serving_build | grep -v grep | awk '{print $2}' | xargs kill } function python_test_fit_a_line() { - cd fit_a_line + # pwd: /Serving/python/examples + cd fit_a_line # pwd: /Serving/python/examples/fit_a_line sh get_data.sh local TYPE=$1 - echo $TYPE + export SERVING_BIN=${SERVING_WORKDIR}/build-server-${TYPE}/core/general-server/serving case $TYPE in CPU) # test rpc - check_cmd "python test_server.py uci_housing_model/ > /dev/null &" - sleep 5 + check_cmd "python -m paddle_serving_server.serve --model uci_housing_model --port 9393 --thread 4 > /dev/null &" + sleep 5 # wait for the server to start check_cmd "python test_client.py uci_housing_client/serving_client_conf.prototxt > /dev/null" - ps -ef | grep "paddle_serving_server" | grep -v grep | awk '{print $2}' | xargs kill + kill_server_process + # test web - check_cmd "python -m paddle_serving_server.serve --model uci_housing_model/ --name uci --port 9399 --name uci > /dev/null &" - sleep 5 - check_cmd "curl -H \"Content-Type:application/json\" -X POST -d '{\"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:9399/uci/prediction" - ps -ef | grep "paddle_serving_server" | grep -v grep | awk '{print $2}' | xargs kill + unsetproxy # maybe the proxy is used on iPipe, which makes web-test failed. + check_cmd "python -m paddle_serving_server.serve --model uci_housing_model --name uci --port 9393 --thread 4 --name uci > /dev/null &" + sleep 5 # wait for the server to start + check_cmd "curl -H \"Content-Type:application/json\" -X POST -d '{\"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:9393/uci/prediction" + # check http code + http_code=`curl -H "Content-Type:application/json" -X POST -d '{"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"]}' -s -w "%{http_code}" -o /dev/null http://127.0.0.1:9393/uci/prediction` + setproxy # recover proxy state + kill_server_process + if [ ${http_code} -ne 200 ]; then + echo "HTTP status code -ne 200" + exit 1 + fi ;; GPU) - echo "not support yet" - exit 1 + # test rpc + check_cmd "python -m paddle_serving_server_gpu.serve --model uci_housing_model --port 9393 --thread 4 --gpu_ids 0 > /dev/null &" + sleep 5 # wait for the server to start + check_cmd "python test_client.py uci_housing_client/serving_client_conf.prototxt > /dev/null" + kill_server_process + + # test web + unsetproxy # maybe the proxy is used on iPipe, which makes web-test failed. + check_cmd "python -m paddle_serving_server_gpu.serve --model uci_housing_model --port 9393 --thread 2 --gpu_ids 0 --name uci > /dev/null &" + sleep 5 # wait for the server to start + check_cmd "curl -H \"Content-Type:application/json\" -X POST -d '{\"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:9393/uci/prediction" + # check http code + http_code=`curl -H "Content-Type:application/json" -X POST -d '{"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"]}' -s -w "%{http_code}" -o /dev/null http://127.0.0.1:9393/uci/prediction` + setproxy # recover proxy state + kill_server_process + if [ ${http_code} -ne 200 ]; then + echo "HTTP status code -ne 200" + exit 1 + fi ;; *) echo "error type" @@ -99,57 +167,69 @@ function python_test_fit_a_line() { esac echo "test fit_a_line $TYPE part finished as expected." rm -rf image kvdb log uci_housing* work* - cd .. + unset SERVING_BIN + cd .. # pwd: /Serving/python/examples } function python_run_criteo_ctr_with_cube() { + # pwd: /Serving/python/examples local TYPE=$1 yum install -y bc >/dev/null - cd criteo_ctr_with_cube - check_cmd "wget https://paddle-serving.bj.bcebos.com/unittest/ctr_cube_unittest.tar.gz" - check_cmd "tar xf ctr_cube_unittest.tar.gz" - check_cmd "mv models/ctr_client_conf ./" - check_cmd "mv models/ctr_serving_model_kv ./" - check_cmd "mv models/data ./cube/" - check_cmd "mv models/ut_data ./" - cp ../../../build-server-$TYPE/output/bin/cube* ./cube/ - mkdir -p $PYTHONROOT/lib/python2.7/site-packages/paddle_serving_server/serving-cpu-avx-openblas-0.1.3/ - yes | cp ../../../build-server-$TYPE/output/demo/serving/bin/serving $PYTHONROOT/lib/python2.7/site-packages/paddle_serving_server/serving-cpu-avx-openblas-0.1.3/ + cd criteo_ctr_with_cube # pwd: /Serving/python/examples/criteo_ctr_with_cube + case $TYPE in + CPU) + check_cmd "wget https://paddle-serving.bj.bcebos.com/unittest/ctr_cube_unittest.tar.gz" + check_cmd "tar xf ctr_cube_unittest.tar.gz" + check_cmd "mv models/ctr_client_conf ./" + check_cmd "mv models/ctr_serving_model_kv ./" + check_cmd "mv models/data ./cube/" + check_cmd "mv models/ut_data ./" + cp ../../../build-server-$TYPE/output/bin/cube* ./cube/ + mkdir -p $PYTHONROOT/lib/python2.7/site-packages/paddle_serving_server/serving-cpu-avx-openblas-0.1.3/ + yes | cp ../../../build-server-$TYPE/output/demo/serving/bin/serving $PYTHONROOT/lib/python2.7/site-packages/paddle_serving_server/serving-cpu-avx-openblas-0.1.3/ - sh cube_prepare.sh & - check_cmd "mkdir work_dir1 && cp cube/conf/cube.conf ./work_dir1/" - python test_server.py ctr_serving_model_kv & - check_cmd "python test_client.py ctr_client_conf/serving_client_conf.prototxt ./ut_data >score" - AUC=$(tail -n 2 score | awk 'NR==1') - VAR2="0.70" - RES=$( echo "$AUC>$VAR2" | bc ) - if [[ $RES -eq 0 ]]; then - echo "error with criteo_ctr_with_cube inference auc test, auc should > 0.70" - exit 1 - fi - echo "criteo_ctr_with_cube inference auc test success" - ps -ef | grep "paddle_serving_server" | grep -v grep | awk '{print $2}' | xargs kill - ps -ef | grep "cube" | grep -v grep | awk '{print $2}' | xargs kill + sh cube_prepare.sh & + check_cmd "mkdir work_dir1 && cp cube/conf/cube.conf ./work_dir1/" + python test_server.py ctr_serving_model_kv & + check_cmd "python test_client.py ctr_client_conf/serving_client_conf.prototxt ./ut_data >score" + AUC=$(tail -n 2 score | awk 'NR==1') + VAR2="0.70" + RES=$( echo "$AUC>$VAR2" | bc ) + if [[ $RES -eq 0 ]]; then + echo "error with criteo_ctr_with_cube inference auc test, auc should > 0.70" + exit 1 + fi + echo "criteo_ctr_with_cube inference auc test success" + ps -ef | grep "paddle_serving_server" | grep -v grep | awk '{print $2}' | xargs kill + ps -ef | grep "cube" | grep -v grep | awk '{print $2}' | xargs kill + ;; + GPU) + ;; + *) + echo "error type" + exit 1 + ;; + esac + echo "test criteo_ctr_with_cube $TYPE part finished as expected." + cd .. # pwd: /Serving/python/examples } function python_run_test() { - cd python/examples - local TYPE=$1 - # Frist time run, downloading PaddleServing components ... - python -c "from paddle_serving_server import Server; server = Server(); server.download_bin()" - python_test_fit_a_line $TYPE - python_run_criteo_ctr_with_cube $TYPE + # Using the compiled binary + local TYPE=$1 # pwd: /Serving + cd python/examples # pwd: /Serving/python/examples + python_test_fit_a_line $TYPE # pwd: /Serving/python/examples + python_run_criteo_ctr_with_cube $TYPE # pwd: /Serving/python/examples echo "test python $TYPE part finished as expected." - cd ../.. + cd ../.. # pwd: /Serving } function main() { - local TYPE=$1 - init - build_client $TYPE - build_server $TYPE - cd Serving/ - python_run_test $TYPE + local TYPE=$1 # pwd: / + init # pwd: /Serving + build_client $TYPE # pwd: /Serving + build_server $TYPE # pwd: /Serving + python_run_test $TYPE # pwd: /Serving echo "serving $TYPE part finished as expected." }