提交 02e4dad0 编写于 作者: D Dong Daxiang 提交者: GitHub

Merge pull request #124 from PaddlePaddle/merge_longteng

 add server python API
...@@ -46,11 +46,11 @@ set(THIRD_PARTY_PATH "${CMAKE_BINARY_DIR}/third_party" CACHE STRING ...@@ -46,11 +46,11 @@ set(THIRD_PARTY_PATH "${CMAKE_BINARY_DIR}/third_party" CACHE STRING
set(THIRD_PARTY_BUILD_TYPE Release) set(THIRD_PARTY_BUILD_TYPE Release)
option(WITH_AVX "Compile Paddle Serving with AVX intrinsics" ${AVX_FOUND}) option(WITH_AVX "Compile Paddle Serving with AVX intrinsics" OFF)
option(WITH_MKL "Compile Paddle Serving with MKL support." ${AVX_FOUND}) option(WITH_MKL "Compile Paddle Serving with MKL support." OFF)
option(WITH_GPU "Compile Paddle Serving with NVIDIA GPU" ${CUDA_FOUND}) option(WITH_GPU "Compile Paddle Serving with NVIDIA GPU" OFF)
option(CLIENT_ONLY "Compile client libraries and demos only" FALSE) option(CLIENT_ONLY "Compile client libraries and demos only" OFF)
option(WITH_ELASTIC_CTR "Compile ELASITC-CTR solution" FALSE) option(WITH_ELASTIC_CTR "Compile ELASITC-CTR solution" OFF)
set(WITH_MKLML ${WITH_MKL}) set(WITH_MKLML ${WITH_MKL})
if (NOT DEFINED WITH_MKLDNN) if (NOT DEFINED WITH_MKLDNN)
...@@ -128,14 +128,10 @@ if (NOT CLIENT_ONLY) ...@@ -128,14 +128,10 @@ if (NOT CLIENT_ONLY)
endif() endif()
add_subdirectory(core) add_subdirectory(core)
if(NOT CLIENT_ONLY) if(NOT CLIENT_ONLY)
add_subdirectory(paddle_inference) add_subdirectory(paddle_inference)
endif() endif()
if(CLIENT_ONLY)
add_subdirectory(python) add_subdirectory(python)
set(PYTHON_INCLUDE_DIR ${PYTHON_INCLUDE}) #add_subdirectory(examples)
set(PYTHON_LIBRARIES ${PYTHON_LIB})
endif()
add_subdirectory(examples)
...@@ -36,7 +36,7 @@ SET(PADDLE_VERSION "latest") ...@@ -36,7 +36,7 @@ SET(PADDLE_VERSION "latest")
if (WITH_GPU) if (WITH_GPU)
SET(PADDLE_LIB_VERSION "${PADDLE_VERSION}-gpu-cuda${CUDA_VERSION_MAJOR}-cudnn7-avx-mkl") SET(PADDLE_LIB_VERSION "${PADDLE_VERSION}-gpu-cuda${CUDA_VERSION_MAJOR}-cudnn7-avx-mkl")
else() else()
if (AVX_FOUND) if (WITH_AVX)
if (WITH_MKLML) if (WITH_MKLML)
SET(PADDLE_LIB_VERSION "${PADDLE_VERSION}-cpu-avx-mkl") SET(PADDLE_LIB_VERSION "${PADDLE_VERSION}-cpu-avx-mkl")
else() else()
...@@ -62,10 +62,13 @@ ExternalProject_Add( ...@@ -62,10 +62,13 @@ ExternalProject_Add(
INSTALL_COMMAND INSTALL_COMMAND
${CMAKE_COMMAND} -E copy_directory ${PADDLE_DOWNLOAD_DIR}/paddle/include ${PADDLE_INSTALL_DIR}/include && ${CMAKE_COMMAND} -E copy_directory ${PADDLE_DOWNLOAD_DIR}/paddle/include ${PADDLE_INSTALL_DIR}/include &&
${CMAKE_COMMAND} -E copy_directory ${PADDLE_DOWNLOAD_DIR}/paddle/lib ${PADDLE_INSTALL_DIR}/lib && ${CMAKE_COMMAND} -E copy_directory ${PADDLE_DOWNLOAD_DIR}/paddle/lib ${PADDLE_INSTALL_DIR}/lib &&
${CMAKE_COMMAND} -E copy_directory ${PADDLE_DOWNLOAD_DIR}/third_party ${PADDLE_INSTALL_DIR}/third_party && ${CMAKE_COMMAND} -E copy_directory ${PADDLE_DOWNLOAD_DIR}/third_party ${PADDLE_INSTALL_DIR}/third_party
${CMAKE_COMMAND} -E copy ${PADDLE_INSTALL_DIR}/third_party/install/mkldnn/lib/libmkldnn.so.0 ${PADDLE_INSTALL_DIR}/third_party/install/mkldnn/lib/libmkldnn.so
) )
if (WITH_MKLML)
file(COPY ${PADDLE_INSTALL_DIR}/third_party/install/mkldnn/lib/libmkldnn.so.0 DESTINATION ${PADDLE_INSTALL_DIR}/third_party/install/mkldnn/lib/libmkldnn.so FOLLOW_SYMLINK_CHAIN)
endif()
INCLUDE_DIRECTORIES(${PADDLE_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${PADDLE_INCLUDE_DIR})
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}" "${PADDLE_INSTALL_DIR}/third_party/install/mklml/lib") SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}" "${PADDLE_INSTALL_DIR}/third_party/install/mklml/lib")
LINK_DIRECTORIES(${PADDLE_INSTALL_DIR}/third_party/install/mklml/lib) LINK_DIRECTORIES(${PADDLE_INSTALL_DIR}/third_party/install/mklml/lib)
...@@ -73,6 +76,9 @@ LINK_DIRECTORIES(${PADDLE_INSTALL_DIR}/third_party/install/mklml/lib) ...@@ -73,6 +76,9 @@ LINK_DIRECTORIES(${PADDLE_INSTALL_DIR}/third_party/install/mklml/lib)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}" "${PADDLE_INSTALL_DIR}/third_party/install/mkldnn/lib") SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}" "${PADDLE_INSTALL_DIR}/third_party/install/mkldnn/lib")
LINK_DIRECTORIES(${PADDLE_INSTALL_DIR}/third_party/install/mkldnn/lib) LINK_DIRECTORIES(${PADDLE_INSTALL_DIR}/third_party/install/mkldnn/lib)
ADD_LIBRARY(openblas STATIC IMPORTED GLOBAL)
SET_PROPERTY(TARGET openblas PROPERTY IMPORTED_LOCATION ${PADDLE_INSTALL_DIR}/third_party/install/openblas/lib/libopenblas.a)
ADD_LIBRARY(paddle_fluid STATIC IMPORTED GLOBAL) ADD_LIBRARY(paddle_fluid STATIC IMPORTED GLOBAL)
SET_PROPERTY(TARGET paddle_fluid PROPERTY IMPORTED_LOCATION ${PADDLE_INSTALL_DIR}/lib/libpaddle_fluid.a) SET_PROPERTY(TARGET paddle_fluid PROPERTY IMPORTED_LOCATION ${PADDLE_INSTALL_DIR}/lib/libpaddle_fluid.a)
......
# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
INCLUDE(ExternalProject)
SET(PADDLE_SOURCES_DIR ${THIRD_PARTY_PATH}/Paddle)
SET(PADDLE_INSTALL_DIR ${THIRD_PARTY_PATH}/install/Paddle/)
SET(PADDLE_INCLUDE_DIR "${PADDLE_INSTALL_DIR}/include" CACHE PATH "PaddlePaddle include directory." FORCE)
SET(PADDLE_LIBRARIES "${PADDLE_INSTALL_DIR}/lib/libpaddle_fluid.a" CACHE FILEPATH "Paddle library." FORCE)
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/Paddle/fluid_install_dir)
# Reference https://stackoverflow.com/questions/45414507/pass-a-list-of-prefix-paths-to-externalproject-add-in-cmake-args
set(prefix_path "${THIRD_PARTY_PATH}/install/gflags|${THIRD_PARTY_PATH}/install/leveldb|${THIRD_PARTY_PATH}/install/snappy|${THIRD_PARTY_PATH}/install/gtest|${THIRD_PARTY_PATH}/install/protobuf|${THIRD_PARTY_PATH}/install/zlib|${THIRD_PARTY_PATH}/install/glog")
message( "WITH_GPU = ${WITH_GPU}")
# If minimal .a is need, you can set WITH_DEBUG_SYMBOLS=OFF
ExternalProject_Add(
extern_paddle
${EXTERNAL_PROJECT_LOG_ARGS}
# TODO(wangguibao): change to de newst repo when they changed.
GIT_REPOSITORY "https://github.com/PaddlePaddle/Paddle"
GIT_TAG "v1.5.1"
PREFIX ${PADDLE_SOURCES_DIR}
UPDATE_COMMAND ""
BINARY_DIR ${CMAKE_BINARY_DIR}/Paddle
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_INSTALL_PREFIX=${PADDLE_INSTALL_DIR}
-DCMAKE_INSTALL_LIBDIR=${PADDLE_INSTALL_DIR}/lib
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_BUILD_TYPE=${THIRD_PARTY_BUILD_TYPE}
-DCMAKE_PREFIX_PATH=${prefix_path}
-DCMAKE_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
-DWITH_SWIG_PY=OFF
-DWITH_PYTHON=OFF
-DWITH_MKL=OFF
-DWITH_AVX=OFF
-DWITH_MKLDNN=OFF
-DWITH_GPU=OFF
-DWITH_FLUID_ONLY=ON
-DWITH_TESTING=OFF
-DWITH_DISTRIBUTE=OFF
-DON_INFER=ON
${EXTERNAL_OPTIONAL_ARGS}
LIST_SEPARATOR |
CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${PADDLE_INSTALL_DIR}
-DCMAKE_INSTALL_LIBDIR:PATH=${PADDLE_INSTALL_DIR}/lib
-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON
-DCMAKE_BUILD_TYPE:STRING=${THIRD_PARTY_BUILD_TYPE}
BUILD_COMMAND $(MAKE)
INSTALL_COMMAND $(MAKE) fluid_lib_dist
)
ExternalProject_Get_Property(extern_paddle BINARY_DIR)
ADD_LIBRARY(paddle_fluid STATIC IMPORTED GLOBAL)
SET_PROPERTY(TARGET paddle_fluid PROPERTY IMPORTED_LOCATION ${BINARY_DIR}/fluid_install_dir/paddle/fluid/inference/libpaddle_fluid.a)
LIST(APPEND external_project_dependencies paddle)
ADD_LIBRARY(snappystream STATIC IMPORTED GLOBAL)
SET_PROPERTY(TARGET snappystream PROPERTY IMPORTED_LOCATION ${BINARY_DIR}/fluid_install_dir/third_party/install/snappystream/lib/libsnappystream.a)
ADD_LIBRARY(openblas STATIC IMPORTED GLOBAL)
SET_PROPERTY(TARGET openblas PROPERTY IMPORTED_LOCATION ${BINARY_DIR}/fluid_install_dir/third_party/install/openblas/lib/libopenblas.a)
ADD_LIBRARY(xxhash STATIC IMPORTED GLOBAL)
SET_PROPERTY(TARGET xxhash PROPERTY IMPORTED_LOCATION ${BINARY_DIR}/fluid_install_dir/third_party/install/xxhash/lib/libxxhash.a)
LIST(APPEND paddle_depend_libs
snappystream
snappy
xxhash
openblas)
...@@ -25,4 +25,5 @@ endif() ...@@ -25,4 +25,5 @@ endif()
if (NOT CLIENT_ONLY) if (NOT CLIENT_ONLY)
add_subdirectory(predictor) add_subdirectory(predictor)
add_subdirectory(general-server)
endif() endif()
...@@ -29,11 +29,43 @@ FILE(GLOB inc ${CMAKE_CURRENT_BINARY_DIR}/*.pb.h) ...@@ -29,11 +29,43 @@ FILE(GLOB inc ${CMAKE_CURRENT_BINARY_DIR}/*.pb.h)
install(FILES ${inc} install(FILES ${inc}
DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/include/configure) DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/include/configure)
py_proto_compile(general_model_config_py_proto SRCS proto/general_model_config.proto)
add_custom_target(general_model_config_py_proto_init ALL COMMAND ${CMAKE_COMMAND} -E touch __init__.py)
add_dependencies(general_model_config_py_proto general_model_config_py_proto_init)
if (CLIENT_ONLY)
py_proto_compile(sdk_configure_py_proto SRCS proto/sdk_configure.proto) py_proto_compile(sdk_configure_py_proto SRCS proto/sdk_configure.proto)
add_custom_target(sdk_configure_py_proto_init ALL COMMAND ${CMAKE_COMMAND} -E touch __init__.py) add_custom_target(sdk_configure_py_proto_init ALL COMMAND ${CMAKE_COMMAND} -E touch __init__.py)
add_dependencies(sdk_configure_py_proto sdk_configure_py_proto_init) add_dependencies(sdk_configure_py_proto sdk_configure_py_proto_init)
add_custom_command(TARGET sdk_configure_py_proto POST_BUILD add_custom_command(TARGET sdk_configure_py_proto POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving/proto COMMAND ${CMAKE_COMMAND} -E make_directory ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_client/proto
COMMAND cp *.py ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving/proto COMMAND cp *.py ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_client/proto
COMMENT "Copy generated python proto into directory paddle_serving/proto." COMMENT "Copy generated python proto into directory paddle_serving_client/proto."
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_custom_command(TARGET general_model_config_py_proto POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_client/proto
COMMAND cp *.py ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_client/proto
COMMENT "Copy generated general_model_config proto file into directory paddle_serving_client/proto."
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()
if (NOT CLIENT_ONLY)
py_proto_compile(server_config_py_proto SRCS proto/server_configure.proto)
add_custom_target(server_config_py_proto_init ALL COMMAND ${CMAKE_COMMAND} -E touch __init__.py)
add_dependencies(server_config_py_proto server_config_py_proto_init)
add_custom_command(TARGET server_config_py_proto POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_server/proto
COMMAND cp *.py ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_server/proto
COMMENT "Copy generated python proto into directory paddle_serving_server/proto."
WORKING_DIRECTORY ${CMAKE_CURRENT_BINRARY_DIR})
add_custom_command(TARGET general_model_config_py_proto POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_server/proto
COMMAND cp *.py ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_server/proto
COMMENT "Copy generated general_model_config proto file into directory paddle_serving_server/proto."
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()
...@@ -19,13 +19,17 @@ ...@@ -19,13 +19,17 @@
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
namespace configure { namespace configure {
int read_proto_conf(const std::string &conf_path,
const std::string &conf_file,
google::protobuf::Message *conf);
int write_proto_conf(google::protobuf::Message *message, int read_proto_conf(const std::string &conf_full_path,
const std::string &output_path, google::protobuf::Message *conf);
const std::string &output_file);
int read_proto_conf(const std::string &conf_path,
const std::string &conf_file,
google::protobuf::Message *conf);
int write_proto_conf(google::protobuf::Message *message,
const std::string &output_path,
const std::string &output_file);
} // namespace configure } // namespace configure
} // namespace paddle_serving } // namespace paddle_serving
......
...@@ -16,14 +16,16 @@ syntax = "proto2"; ...@@ -16,14 +16,16 @@ syntax = "proto2";
package baidu.paddle_serving.configure; package baidu.paddle_serving.configure;
message FeedVar { message FeedVar {
required string name = 1; optional string name = 1;
required bool is_lod_tensor = 2; optional string alias_name = 2;
required int32 feed_type = 3; optional bool is_lod_tensor = 3 [ default = false ];
repeated int32 shape = 4; optional int32 feed_type = 4 [ default = 0 ];
repeated int32 shape = 5;
} }
message FetchVar { message FetchVar {
required string name = 1; optional string name = 1;
repeated int32 shape = 2; optional string alias_name = 2;
repeated int32 shape = 3;
} }
message GeneralModelConfig { message GeneralModelConfig {
repeated FeedVar feed_var = 1; repeated FeedVar feed_var = 1;
......
...@@ -31,6 +31,24 @@ namespace baidu { ...@@ -31,6 +31,24 @@ namespace baidu {
namespace paddle_serving { namespace paddle_serving {
namespace configure { namespace configure {
int read_proto_conf(const std::string &conf_file_full_path,
google::protobuf::Message *conf) {
int fd = open(conf_file_full_path.c_str(), O_RDONLY);
if (fd == -1) {
LOG(WARNING) << "File not found: " << conf_file_full_path.c_str();
return -1;
}
google::protobuf::io::FileInputStream input(fd);
bool success = google::protobuf::TextFormat::Parse(&input, conf);
close(fd);
if (!success) {
return -1;
}
return 0;
}
int read_proto_conf(const std::string &conf_path, int read_proto_conf(const std::string &conf_path,
const std::string &conf_file, const std::string &conf_file,
google::protobuf::Message *conf) { google::protobuf::Message *conf) {
......
# Copyright (c) 2019 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
set(SOURCE_FILE cube-agent.go)
add_go_executable(cube-agent ${SOURCE_FILE})
add_dependencies(cube-agent agent-docopt-go)
add_dependencies(cube-agent agent-logex)
add_dependencies(cube-agent agent-pipeline)
// Copyright (c) 2019 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.
package agent
import (
"errors"
_ "github.com/Badangel/logex"
"strings"
"sync"
)
var (
Dir string
WorkerNum int
QueueCapacity int32
MasterHost []string
MasterPort []string
TestHostname string
TestIdc string
ShardLock sync.RWMutex
CmdWorkPool *WorkPool
CmdWorkFilter sync.Map
)
type (
Status struct {
Status string `json:"status"`
Version string `json:"version"`
}
MasterResp struct {
Success string `json:"success"`
Message string `json:"message"`
Data string `json:"data"`
}
ShardInfo struct {
DictName string
ShardSeq int
SlotIdList string
DataDir string
Service string `json:"service,omitempty"`
Libcube string `json:"libcube,omitempty"`
}
CubeResp struct {
Status int `json:"status"`
CurVersion string `json:"cur_version"`
BgVersion string `json:"bg_version"`
}
)
var BUILTIN_STATUS = Status{"RUNNING", "3.0.0.1"}
var ShardInfoMap map[string]map[string]*ShardInfo
var disks []string
func GetMaster(master string) (host, port string, err error) {
if len(ShardInfoMap) < 1 {
return "", "", errors.New("empty master list.")
}
if master == "" {
return MasterHost[0], MasterPort[0], nil
}
if _, ok := ShardInfoMap[master]; ok {
m := strings.Split(master, ":")
if len(m) != 2 {
return MasterHost[0], MasterPort[0], nil
}
return m[0], m[1], nil
} else {
return MasterHost[0], MasterPort[0], nil
}
}
// Copyright (c) 2019 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.
package agent
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/Badangel/logex"
)
type handlerFunc func(subpath string, m map[string]string, b []byte) (string, string, error)
var ( // key = subpath; eg: path="/checker/job", key="job"
getHandler map[string]handlerFunc
putHandler map[string]handlerFunc
deleteHandler map[string]handlerFunc
postHandler map[string]handlerFunc
)
func StartHttp(addr string) error {
// init handlers:
initGetHandlers()
initPostHandlers()
http.HandleFunc("/agent/", handleRest)
logex.Notice("start http ", addr)
return http.ListenAndServe(addr, nil)
}
func handleRest(w http.ResponseWriter, r *http.Request) {
var (
req_log string
status int32
)
time_begin := time.Now()
cont_type := make([]string, 1, 1)
cont_type[0] = "application/json"
header := w.Header()
header["Content-Type"] = cont_type
w.Header().Add("Access-Control-Allow-Origin", "*")
m := parseHttpKv(r)
b, _ := ioutil.ReadAll(r.Body)
req_log = fmt.Sprintf("handle %v %v %v from %v, len(m)=%v, m=%+v",
r.Method, r.URL.Path, r.URL.RawQuery, r.RemoteAddr, len(m), m)
api := r.URL.Path
var showHandler map[string]handlerFunc
switch r.Method {
case "GET":
showHandler = getHandler
case "POST": // create
showHandler = postHandler
case "PUT": // update
showHandler = putHandler
case "DELETE":
showHandler = deleteHandler
default:
logex.Warningf(`{"error":1, "message":"unsupport method %v"}`, r.Method)
}
handler, ok := showHandler[api]
if !ok {
key_list := make([]string, 0, len(showHandler))
for key := range showHandler {
key_list = append(key_list, key)
}
status = 2
fmt.Fprintf(w, `{"success":"%v", "message":"wrong api", "method":"%s", "api":"%s", "api_list":"%v"}`,
status, r.Method, api, key_list)
logex.Noticef(`%v, time=%v, status=%v`,
req_log, time.Now().Sub(time_begin).Nanoseconds()/1000000, status)
return
}
var s string
rst, handle_log, err := handler(api, m, b)
if err == nil {
status = 0
s = fmt.Sprintf(`{"success":"%v", "message":"query ok", "data":%s}`, status, rst)
} else {
status = 255
s = fmt.Sprintf(`{"success":"%v", "message":%v, "data":%s}`,
status, quote(err.Error()), rst)
}
if isJsonDict(s) {
fmt.Fprintln(w, s)
} else {
logex.Fatalf("invalid json: %v", s)
}
if err == nil {
logex.Noticef(`%v, time=%v, status=%v, handle_log=%v`,
req_log, time.Now().Sub(time_begin).Nanoseconds()/1000000,
status, quote(handle_log))
} else {
logex.Noticef(`%v, time=%v, status=%v, err=%v, handle_log=%v`,
req_log, time.Now().Sub(time_begin).Nanoseconds()/1000000,
status, quote(err.Error()), quote(handle_log))
}
}
func parseHttpKv(r *http.Request) map[string]string {
r.ParseForm()
m := make(map[string]string)
for k, v := range r.Form {
switch k {
case "user": // remove @baidu.com for user
m[k] = strings.Split(v[0], "@")[0]
default:
m[k] = v[0]
}
}
// allow passing hostname for debug
if _, ok := m["hostname"]; !ok {
ip := r.RemoteAddr[:strings.Index(r.RemoteAddr, ":")]
m["hostname"], _ = getHostname(ip)
}
return m
}
// restReq sends a restful request to requrl and returns response body.
func restReq(method, requrl string, timeout int, kv *map[string]string) (string, error) {
logex.Debug("####restReq####")
logex.Debug(*kv)
data := url.Values{}
if kv != nil {
for k, v := range *kv {
logex.Trace("req set:", k, v)
data.Set(k, v)
}
}
if method == "GET" || method == "DELETE" {
requrl = requrl + "?" + data.Encode()
data = url.Values{}
}
logex.Notice(method, requrl)
req, err := http.NewRequest(method, requrl, bytes.NewBufferString(data.Encode()))
if err != nil {
logex.Warning("NewRequest failed:", err)
return "", err
}
if method == "POST" || method == "PUT" {
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
}
client := &http.Client{}
client.Timeout = time.Duration(timeout) * time.Second
resp, err := client.Do(req)
if err != nil {
logex.Warning("Do failed:", err)
return "", err
}
if resp.StatusCode < 200 || resp.StatusCode > 299 {
logex.Warning("resp status: " + resp.Status)
return "", errors.New("resp status: " + resp.Status)
}
body, err := ioutil.ReadAll(resp.Body)
return string(body), err
}
// Copyright (c) 2019 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.
package agent
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/Badangel/logex"
)
// restReq sends a restful request to requrl and returns response body.
func RestReq(method, requrl string, timeout int, kv *map[string]string) (string, error) {
data := url.Values{}
if kv != nil {
for k, v := range *kv {
//logex.Trace("req set:", k, v)
data.Set(k, v)
}
}
if method == "GET" || method == "DELETE" {
requrl = requrl + "?" + data.Encode()
data = url.Values{}
}
//logex.Notice(method, requrl)
req, err := http.NewRequest(method, requrl, bytes.NewBufferString(data.Encode()))
if err != nil {
logex.Warning("NewRequest failed:", err)
return "", err
}
if method == "POST" || method == "PUT" {
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
}
client := &http.Client{}
client.Timeout = time.Duration(timeout) * time.Second
resp, err := client.Do(req)
if err != nil {
logex.Warning("Do failed:", err)
return "", err
}
if resp.StatusCode < 200 || resp.StatusCode > 299 {
logex.Warning("resp status: " + resp.Status)
return "", errors.New("resp status: " + resp.Status)
}
body, err := ioutil.ReadAll(resp.Body)
return string(body), err
}
// restReq sends a restful request to requrl and returns response body as json.
func JsonReq(method, requrl string, timeout int, kv *map[string]string,
out interface{}) error {
s, err := RestReq(method, requrl, timeout, kv)
logex.Debugf("json request method:[%v], requrl:[%s], timeout:[%v], map[%v], out_str:[%s]", method, requrl, timeout, kv, s)
if err != nil {
return err
}
return json.Unmarshal([]byte(s), out)
}
func GetHdfsMeta(src string) (master, ugi, path string, err error) {
//src = "hdfs://root:rootpasst@st1-inf-platform0.st01.baidu.com:54310/user/mis_user/news_dnn_ctr_cube_1/1501836820/news_dnn_ctr_cube_1_part54.tar"
//src = "hdfs://st1-inf-platform0.st01.baidu.com:54310/user/mis_user/news_dnn_ctr_cube_1/1501836820/news_dnn_ctr_cube_1_part54.tar"
ugiBegin := strings.Index(src, "//")
ugiPos := strings.LastIndex(src, "@")
if ugiPos != -1 && ugiBegin != -1 {
ugi = src[ugiBegin+2 : ugiPos]
}
src1 := strings.Replace(strings.Replace(src, "hdfs://", "", 1), ugi, "", 1)
if ugi != "" {
src1 = src1[1:]
}
pos := strings.Index(src1, "/")
if pos != -1 {
master = src1[0:pos]
path = src1[pos:]
} else {
logex.Warningf("failed to get the master or path for (%s)", src)
err = errors.New("invalid master or path found")
}
logex.Debugf("parse the (%s) succ, master is %s, ugi is (%s), path is %s", src, master, ugi, path)
return
}
func getHostIp() (string, error) {
if addrs, err := net.InterfaceAddrs(); err == nil {
for _, addr := range addrs {
ips := addr.String()
logex.Debugf("get host ip: %v", ips)
if strings.HasPrefix(ips, "127") {
continue
} else {
list := strings.Split(ips, "/")
if len(list) != 2 {
continue
}
return list[0], nil
}
}
}
return "unkown ip", errors.New("get host ip failed")
}
func getHostname(ip string) (hostname string, err error) {
if hostnames, err := net.LookupAddr(ip); err != nil {
hostname = ip
//logex.Warningf("cannot find the hostname of ip (%s), error (%v)", ip, err)
} else {
if len(hostnames) > 0 {
hostname = hostnames[0]
} else {
hostname = ip
}
}
return hostname, err
}
func GetLocalHostname() (hostname string, err error) {
if ip, err := getHostIp(); err == nil {
return getHostname(ip)
} else {
return "unkown ip", err
}
}
func GetLocalHostnameCmd() (hostname string, err error) {
cmd := "hostname"
stdout, _, err := RetryCmd(cmd, RETRY_TIMES)
if stdout != "" && err == nil {
hostname := strings.TrimSpace(stdout)
index := strings.LastIndex(hostname, ".baidu.com")
if index > 0 {
return hostname[:strings.LastIndex(hostname, ".baidu.com")], nil
} else {
return hostname, nil
}
} else {
logex.Debugf("using hostname cmd failed. err:%v", err)
return GetLocalHostname()
}
}
// quote quotes string for json output. eg: s="123", quote(s)=`"123"`
func quote(s string) string {
return fmt.Sprintf("%q", s)
}
// quoteb quotes byte array for json output.
func quoteb(b []byte) string {
return quote(string(b))
}
// quotea quotes string array for json output
func quotea(a []string) string {
b, _ := json.Marshal(a)
return string(b)
}
func isJsonDict(s string) bool {
var js map[string]interface{}
return json.Unmarshal([]byte(s), &js) == nil
}
此差异已折叠。
// Copyright (c) 2019 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.
package agent
import (
"errors"
"fmt"
"sync"
"sync/atomic"
)
type (
workType struct {
poolWorker PoolWorker
resultChannel chan error
}
WorkPool struct {
queueChannel chan workType
workChannel chan PoolWorker
queuedWorkNum int32
activeWorkerNum int32
queueCapacity int32
workFilter sync.Map
}
)
type PoolWorker interface {
Token() string
DoWork()
}
func NewWorkPool(workerNum int, queueCapacity int32) *WorkPool {
workPool := WorkPool{
queueChannel: make(chan workType),
workChannel: make(chan PoolWorker, queueCapacity),
queuedWorkNum: 0,
activeWorkerNum: 0,
queueCapacity: queueCapacity,
}
for i := 0; i < workerNum; i++ {
go workPool.startWorkRoutine()
}
go workPool.startQueueRoutine()
return &workPool
}
func (workPool *WorkPool) startWorkRoutine() {
for {
select {
case work := <-workPool.workChannel:
workPool.doWork(work)
break
}
}
}
func (workPool *WorkPool) startQueueRoutine() {
for {
select {
case queueItem := <-workPool.queueChannel:
if atomic.AddInt32(&workPool.queuedWorkNum, 0) == workPool.queueCapacity {
queueItem.resultChannel <- fmt.Errorf("work pool fulled with %v pending works", QueueCapacity)
continue
}
atomic.AddInt32(&workPool.queuedWorkNum, 1)
workPool.workChannel <- queueItem.poolWorker
queueItem.resultChannel <- nil
break
}
}
}
func (workPool *WorkPool) doWork(poolWorker PoolWorker) {
defer atomic.AddInt32(&workPool.activeWorkerNum, -1)
defer workPool.workFilter.Delete(poolWorker.Token())
atomic.AddInt32(&workPool.queuedWorkNum, -1)
atomic.AddInt32(&workPool.activeWorkerNum, 1)
poolWorker.DoWork()
}
func (workPool *WorkPool) PostWorkWithToken(poolWorker PoolWorker) (err error) {
if _, ok := workPool.workFilter.Load(poolWorker.Token()); ok {
return errors.New("another work with same key is doing.")
}
workPool.workFilter.Store(poolWorker.Token(), true)
return workPool.PostWork(poolWorker)
}
func (workPool *WorkPool) PostWork(poolWorker PoolWorker) (err error) {
work := workType{poolWorker, make(chan error)}
defer close(work.resultChannel)
workPool.queueChannel <- work
err = <-work.resultChannel
return err
}
// Copyright (c) 2019 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.
package main
import (
"agent"
"fmt"
"github.com/Badangel/logex"
"github.com/docopt/docopt-go"
"os"
"path/filepath"
"runtime"
"strconv"
)
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
agent.Dir, _ = filepath.Abs(filepath.Dir(os.Args[0]))
usage := fmt.Sprintf(`Usage: ./m_master [options]
Options:
-n WORKERNUM set worker num.
-q QUEUENUM set queue num.
-P LISTEN_PORT agent listen port
Log options:
-l LOG_LEVEL set log level, values: 0,1,2,4,8,16. [default: 16]
--log_dir=DIR set log output dir. [default: ./log]
--log_name=NAME set log name. [default: m_agent]`, agent.Dir)
opts, err := docopt.Parse(usage, nil, true, "Cube Agent Checker 1.0.0", false)
if err != nil {
fmt.Println("ERROR:", err)
os.Exit(1)
}
log_level, _ := strconv.Atoi(opts["-l"].(string))
log_name := opts["--log_name"].(string)
log_dir := opts["--log_dir"].(string)
logex.SetLevel(getLogLevel(log_level))
if err := logex.SetUpFileLogger(log_dir, log_name, nil); err != nil {
fmt.Println("ERROR:", err)
}
logex.Notice("--- NEW SESSION -------------------------")
logex.Notice(">>> log_level:", log_level)
agent.WorkerNum = 10
if opts["-n"] != nil {
n, err := strconv.Atoi(opts["-n"].(string))
if err == nil {
agent.WorkerNum = n
}
}
agent.QueueCapacity = 20
if opts["-q"] != nil {
q, err := strconv.Atoi(opts["-q"].(string))
if err == nil {
agent.QueueCapacity = int32(q)
}
}
agent.CmdWorkPool = agent.NewWorkPool(agent.WorkerNum, agent.QueueCapacity)
if opts["-P"] == nil {
logex.Fatalf("ERROR: -P LISTEN PORT must be set!")
os.Exit(255)
}
agentPort := opts["-P"].(string)
logex.Notice(">>> starting server...")
addr := ":" + agentPort
if agent.StartHttp(addr) != nil {
logex.Noticef("cant start http(addr=%v). quit.", addr)
os.Exit(0)
}
}
func getLogLevel(log_level int) logex.Level {
switch log_level {
case 16:
return logex.DEBUG
case 8:
return logex.TRACE
case 4:
return logex.NOTICE
case 2:
return logex.WARNING
case 1:
return logex.FATAL
case 0:
return logex.NONE
}
return logex.DEBUG
}
...@@ -45,7 +45,7 @@ class PredictorClient { ...@@ -45,7 +45,7 @@ class PredictorClient {
PredictorClient() {} PredictorClient() {}
~PredictorClient() {} ~PredictorClient() {}
void init(const std::string& client_conf); int init(const std::string& client_conf);
void set_predictor_conf(const std::string& conf_path, void set_predictor_conf(const std::string& conf_path,
const std::string& conf_file); const std::string& conf_file);
......
...@@ -27,45 +27,42 @@ using baidu::paddle_serving::predictor::general_model::FetchInst; ...@@ -27,45 +27,42 @@ using baidu::paddle_serving::predictor::general_model::FetchInst;
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
namespace general_model { namespace general_model {
using configure::GeneralModelConfig;
void PredictorClient::init(const std::string &conf_file) { int PredictorClient::init(const std::string &conf_file) {
_conf_file = conf_file; try {
std::ifstream fin(conf_file); GeneralModelConfig model_config;
if (!fin) { if (configure::read_proto_conf(conf_file.c_str(),
LOG(ERROR) << "Your inference conf file can not be found"; &model_config) != 0) {
exit(-1); LOG(ERROR) << "Failed to load general model config"
} << ", file path: " << conf_file;
_feed_name_to_idx.clear(); return -1;
_fetch_name_to_idx.clear(); }
_shape.clear(); _feed_name_to_idx.clear();
int feed_var_num = 0; _fetch_name_to_idx.clear();
int fetch_var_num = 0; _shape.clear();
fin >> feed_var_num >> fetch_var_num; int feed_var_num = model_config.feed_var_size();
std::string name; int fetch_var_num = model_config.fetch_var_size();
std::string fetch_var_name; for (int i = 0; i < feed_var_num; ++i) {
int shape_num = 0; _feed_name_to_idx[model_config.feed_var(i).alias_name()] = i;
int dim = 0; std::vector<int> tmp_feed_shape;
int type_value = 0; for (int j = 0; j < model_config.feed_var(i).shape_size(); ++j) {
for (int i = 0; i < feed_var_num; ++i) { tmp_feed_shape.push_back(model_config.feed_var(i).shape(j));
fin >> name; }
_feed_name_to_idx[name] = i; _type.push_back(model_config.feed_var(i).feed_type());
fin >> shape_num; _shape.push_back(tmp_feed_shape);
std::vector<int> tmp_feed_shape;
for (int j = 0; j < shape_num; ++j) {
fin >> dim;
tmp_feed_shape.push_back(dim);
} }
fin >> type_value;
_type.push_back(type_value);
_shape.push_back(tmp_feed_shape);
}
for (int i = 0; i < fetch_var_num; ++i) { for (int i = 0; i < fetch_var_num; ++i) {
fin >> name; _fetch_name_to_idx[model_config.fetch_var(i).alias_name()] = i;
fin >> fetch_var_name; _fetch_name_to_var_name[model_config.fetch_var(i).alias_name()] =
_fetch_name_to_idx[name] = i; model_config.fetch_var(i).name();
_fetch_name_to_var_name[name] = fetch_var_name; }
} catch (std::exception& e) {
LOG(ERROR) << "Failed load general model config" << e.what();
return -1;
} }
return 0;
} }
void PredictorClient::set_predictor_conf(const std::string &conf_path, void PredictorClient::set_predictor_conf(const std::string &conf_path,
......
...@@ -33,7 +33,7 @@ PYBIND11_MODULE(serving_client, m) { ...@@ -33,7 +33,7 @@ PYBIND11_MODULE(serving_client, m) {
.def(py::init()) .def(py::init())
.def("init", .def("init",
[](PredictorClient &self, const std::string &conf) { [](PredictorClient &self, const std::string &conf) {
self.init(conf); return self.init(conf);
}) })
.def("set_predictor_conf", .def("set_predictor_conf",
[](PredictorClient &self, [](PredictorClient &self,
......
include_directories(SYSTEM ${CMAKE_CURRENT_LIST_DIR}/../kvdb/include)
include(op/CMakeLists.txt)
include(proto/CMakeLists.txt)
add_executable(serving ${serving_srcs})
add_dependencies(serving pdcodegen fluid_cpu_engine pdserving paddle_fluid
opencv_imgcodecs cube-api)
if (WITH_GPU)
add_dependencies(serving fluid_gpu_engine)
endif()
target_include_directories(serving PUBLIC
${CMAKE_CURRENT_BINARY_DIR}/../../core/predictor
)
if(WITH_GPU)
target_link_libraries(serving -Wl,--whole-archive fluid_gpu_engine
-Wl,--no-whole-archive)
endif()
target_link_libraries(serving -Wl,--whole-archive fluid_cpu_engine
-Wl,--no-whole-archive)
target_link_libraries(serving paddle_fluid ${paddle_depend_libs})
target_link_libraries(serving pdserving)
target_link_libraries(serving cube-api)
target_link_libraries(serving kvdb rocksdb)
if(WITH_GPU)
target_link_libraries(serving ${CUDA_LIBRARIES})
endif()
if(WITH_MKL)
target_link_libraries(serving -liomp5 -lmklml_intel -lmkldnn -lpthread -lcrypto -lm -lrt -lssl -ldl -lz -lbz2)
else()
target_link_libraries(serving openblas -lpthread -lcrypto -lm -lrt -lssl -ldl -lz -lbz2)
endif()
install(TARGETS serving
RUNTIME DESTINATION
${PADDLE_SERVING_INSTALL_DIR}/demo/serving/bin)
install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/conf DESTINATION
${PADDLE_SERVING_INSTALL_DIR}/demo/serving/)
FILE(GLOB inc ${CMAKE_CURRENT_BINARY_DIR}/*.pb.h)
install(FILES ${inc}
DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/include/serving)
if (${WITH_MKL})
install(FILES
${CMAKE_BINARY_DIR}/third_party/install/Paddle/third_party/install/mklml/lib/libmklml_intel.so
${CMAKE_BINARY_DIR}/third_party/install/Paddle/third_party/install/mklml/lib/libiomp5.so
${CMAKE_BINARY_DIR}/third_party/install/Paddle/third_party/install/mkldnn/lib/libmkldnn.so.0
DESTINATION
${PADDLE_SERVING_INSTALL_DIR}/demo/serving/bin)
endif()
FILE(GLOB op_srcs ${CMAKE_CURRENT_LIST_DIR}/*.cpp)
LIST(APPEND serving_srcs ${op_srcs})
...@@ -12,15 +12,16 @@ ...@@ -12,15 +12,16 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "examples/demo-serving/op/general_infer_op.h"
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include "core/general-server/op/general_infer_op.h"
#include "core/general-server/op/general_reader_op.h"
#include "core/predictor/framework/infer.h" #include "core/predictor/framework/infer.h"
#include "core/predictor/framework/memory.h" #include "core/predictor/framework/memory.h"
#include "core/predictor/framework/resource.h" #include "core/predictor/framework/resource.h"
#include "examples/demo-serving/op/general_reader_op.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#else #else
#include "paddle_inference_api.h" // NOLINT #include "paddle_inference_api.h" // NOLINT
#endif #endif
#include "examples/demo-serving/general_model_service.pb.h" #include "core/general-server/general_model_service.pb.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
......
...@@ -12,11 +12,11 @@ ...@@ -12,11 +12,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "examples/demo-serving/op/general_reader_op.h"
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include "core/general-server/op/general_reader_op.h"
#include "core/predictor/framework/infer.h" #include "core/predictor/framework/infer.h"
#include "core/predictor/framework/memory.h" #include "core/predictor/framework/memory.h"
...@@ -34,6 +34,8 @@ int conf_check(const Request *req, ...@@ -34,6 +34,8 @@ int conf_check(const Request *req,
const std::shared_ptr<PaddleGeneralModelConfig> &model_config) { const std::shared_ptr<PaddleGeneralModelConfig> &model_config) {
int var_num = req->insts(0).tensor_array_size(); int var_num = req->insts(0).tensor_array_size();
if (var_num != model_config->_feed_type.size()) { if (var_num != model_config->_feed_type.size()) {
VLOG(2) << "var num: " << var_num;
VLOG(2) << "model config var num: " << model_config->_feed_type.size();
LOG(ERROR) << "feed var number not match."; LOG(ERROR) << "feed var number not match.";
return -1; return -1;
} }
...@@ -84,7 +86,7 @@ int GeneralReaderOp::inference() { ...@@ -84,7 +86,7 @@ int GeneralReaderOp::inference() {
} }
int var_num = req->insts(0).tensor_array_size(); int var_num = req->insts(0).tensor_array_size();
VLOG(3) << "var num: " << var_num; VLOG(2) << "var num: " << var_num;
// read config // read config
LOG(INFO) << "start to call load general model_conf op"; LOG(INFO) << "start to call load general model_conf op";
...@@ -112,7 +114,7 @@ int GeneralReaderOp::inference() { ...@@ -112,7 +114,7 @@ int GeneralReaderOp::inference() {
paddle::PaddleTensor lod_tensor; paddle::PaddleTensor lod_tensor;
for (int i = 0; i < var_num; ++i) { for (int i = 0; i < var_num; ++i) {
elem_type[i] = req->insts(0).tensor_array(i).elem_type(); elem_type[i] = req->insts(0).tensor_array(i).elem_type();
VLOG(3) << "var[" << i << "] has elem type: " << elem_type[i]; VLOG(2) << "var[" << i << "] has elem type: " << elem_type[i];
if (elem_type[i] == 0) { // int64 if (elem_type[i] == 0) { // int64
elem_size[i] = sizeof(int64_t); elem_size[i] = sizeof(int64_t);
lod_tensor.dtype = paddle::PaddleDType::INT64; lod_tensor.dtype = paddle::PaddleDType::INT64;
...@@ -124,17 +126,17 @@ int GeneralReaderOp::inference() { ...@@ -124,17 +126,17 @@ int GeneralReaderOp::inference() {
if (req->insts(0).tensor_array(i).shape(0) == -1) { if (req->insts(0).tensor_array(i).shape(0) == -1) {
lod_tensor.lod.resize(1); lod_tensor.lod.resize(1);
lod_tensor.lod[0].push_back(0); lod_tensor.lod[0].push_back(0);
VLOG(3) << "var[" << i << "] is lod_tensor"; VLOG(2) << "var[" << i << "] is lod_tensor";
} else { } else {
lod_tensor.shape.push_back(batch_size); lod_tensor.shape.push_back(batch_size);
capacity[i] = 1; capacity[i] = 1;
for (int k = 0; k < req->insts(0).tensor_array(i).shape_size(); ++k) { for (int k = 0; k < req->insts(0).tensor_array(i).shape_size(); ++k) {
int dim = req->insts(0).tensor_array(i).shape(k); int dim = req->insts(0).tensor_array(i).shape(k);
VLOG(3) << "shape for var[" << i << "]: " << dim; VLOG(2) << "shape for var[" << i << "]: " << dim;
capacity[i] *= dim; capacity[i] *= dim;
lod_tensor.shape.push_back(dim); lod_tensor.shape.push_back(dim);
} }
VLOG(3) << "var[" << i << "] is tensor, capacity: " << capacity[i]; VLOG(2) << "var[" << i << "] is tensor, capacity: " << capacity[i];
} }
if (i == 0) { if (i == 0) {
lod_tensor.name = "words"; lod_tensor.name = "words";
...@@ -149,19 +151,19 @@ int GeneralReaderOp::inference() { ...@@ -149,19 +151,19 @@ int GeneralReaderOp::inference() {
for (int j = 0; j < batch_size; ++j) { for (int j = 0; j < batch_size; ++j) {
const Tensor &tensor = req->insts(j).tensor_array(i); const Tensor &tensor = req->insts(j).tensor_array(i);
int data_len = tensor.data_size(); int data_len = tensor.data_size();
VLOG(3) << "tensor size for var[" << i << "]: " << tensor.data_size(); VLOG(2) << "tensor size for var[" << i << "]: " << tensor.data_size();
int cur_len = in->at(i).lod[0].back(); int cur_len = in->at(i).lod[0].back();
VLOG(3) << "current len: " << cur_len; VLOG(2) << "current len: " << cur_len;
in->at(i).lod[0].push_back(cur_len + data_len); in->at(i).lod[0].push_back(cur_len + data_len);
VLOG(3) << "new len: " << cur_len + data_len; VLOG(2) << "new len: " << cur_len + data_len;
} }
in->at(i).data.Resize(in->at(i).lod[0].back() * elem_size[i]); in->at(i).data.Resize(in->at(i).lod[0].back() * elem_size[i]);
in->at(i).shape = {in->at(i).lod[0].back(), 1}; in->at(i).shape = {in->at(i).lod[0].back(), 1};
VLOG(3) << "var[" << i VLOG(2) << "var[" << i
<< "] is lod_tensor and len=" << in->at(i).lod[0].back(); << "] is lod_tensor and len=" << in->at(i).lod[0].back();
} else { } else {
in->at(i).data.Resize(batch_size * capacity[i] * elem_size[i]); in->at(i).data.Resize(batch_size * capacity[i] * elem_size[i]);
VLOG(3) << "var[" << i VLOG(2) << "var[" << i
<< "] is tensor and capacity=" << batch_size * capacity[i]; << "] is tensor and capacity=" << batch_size * capacity[i];
} }
} }
...@@ -198,14 +200,14 @@ int GeneralReaderOp::inference() { ...@@ -198,14 +200,14 @@ int GeneralReaderOp::inference() {
} }
} }
VLOG(3) << "read data from client success"; VLOG(2) << "read data from client success";
// print request // print request
std::ostringstream oss; std::ostringstream oss;
int64_t *example = reinterpret_cast<int64_t *>((*in)[0].data.data()); int64_t *example = reinterpret_cast<int64_t *>((*in)[0].data.data());
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
oss << *(example + i) << " "; oss << *(example + i) << " ";
} }
VLOG(3) << "head element of first feed var : " << oss.str(); VLOG(2) << "head element of first feed var : " << oss.str();
// //
return 0; return 0;
} }
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#endif #endif
#include <string> #include <string>
#include "core/predictor/framework/resource.h" #include "core/predictor/framework/resource.h"
#include "examples/demo-serving/general_model_service.pb.h" #include "core/general-server/general_model_service.pb.h"
#include "examples/demo-serving/load_general_model_service.pb.h" #include "core/general-server/load_general_model_service.pb.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
......
LIST(APPEND protofiles
${CMAKE_CURRENT_LIST_DIR}/load_general_model_service.proto
${CMAKE_CURRENT_LIST_DIR}/general_model_service.proto
)
PROTOBUF_GENERATE_SERVING_CPP(TRUE PROTO_SRCS PROTO_HDRS ${protofiles})
LIST(APPEND serving_srcs ${PROTO_SRCS})
...@@ -12,39 +12,37 @@ ...@@ -12,39 +12,37 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package agent syntax = "proto2";
import "pds_option.proto";
import ( import "builtin_format.proto";
"encoding/json" package baidu.paddle_serving.predictor.general_model;
"fmt"
"github.com/Badangel/logex" option cc_generic_services = true;
)
message Tensor {
func initPostHandlers() { repeated bytes data = 1;
postHandler = map[string]handlerFunc{ optional int32 elem_type = 2;
"/agent/cmd": PostCmd, repeated int32 shape = 3;
} };
}
message FeedInst {
func PostCmd(subpath string, m map[string]string, b []byte) (string, string, error) { repeated Tensor tensor_array = 1;
var work Work };
err := json.Unmarshal(b, &work)
if err != nil { message FetchInst {
logex.Warningf("Unmarshal from %s error (+%v)", string(b), err) repeated Tensor tensor_array = 1;
return quote(""), "", fmt.Errorf("Work json unmarshal work failed, %v", err) };
}
message Request {
if _, ok := CmdWorkFilter.Load(work.Token()); ok { repeated FeedInst insts = 1;
logex.Warningf("Another work with same token is doing. Token(%s)", work.Token()) };
return quote(""), "", fmt.Errorf("Another work with same key is doing.", err)
} message Response {
repeated FetchInst insts = 1;
CmdWorkFilter.Store(work.Token(), true) };
err = work.DoWork()
CmdWorkFilter.Delete(work.Token()) service GeneralModelService {
if err != nil { rpc inference(Request) returns (Response);
return quote(""), "", fmt.Errorf("Do work failed.", err) rpc debug(Request) returns (Response);
} option (pds.options).generate_impl = true;
};
return quote(""), "", err
}
...@@ -12,24 +12,19 @@ ...@@ -12,24 +12,19 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package agent syntax = "proto2";
import "pds_option.proto";
package baidu.paddle_serving.predictor.load_general_model_service;
import ( option cc_generic_services = true;
"encoding/json"
"fmt"
)
func initGetHandlers() { message RequestAndResponse {
getHandler = map[string]handlerFunc{ required int32 a = 1;
"/agent/status": GetStatus, required float b = 2;
} };
}
func GetStatus(subpath string, m map[string]string, b []byte) (string, string, error) { service LoadGeneralModelService {
b, err := json.Marshal(BUILTIN_STATUS) rpc inference(RequestAndResponse) returns (RequestAndResponse);
if err != nil { rpc debug(RequestAndResponse) returns (RequestAndResponse);
return quote(""), "", fmt.Errorf("json marshal failed, %v", err) option (pds.options).generate_impl = true;
} };
return string(b), "", err
}
...@@ -38,12 +38,12 @@ DEFINE_int32( ...@@ -38,12 +38,12 @@ DEFINE_int32(
0, 0,
"Number of pthreads that server runs on, not change if this value <= 0"); "Number of pthreads that server runs on, not change if this value <= 0");
DEFINE_int32(reload_interval_s, 10, ""); DEFINE_int32(reload_interval_s, 10, "");
DEFINE_bool(enable_model_toolkit, false, "enable model toolkit"); DEFINE_bool(enable_model_toolkit, true, "enable model toolkit");
DEFINE_string(enable_protocol_list, "baidu_std", "set protocol list"); DEFINE_string(enable_protocol_list, "baidu_std", "set protocol list");
DEFINE_bool(enable_cube, false, "enable cube"); DEFINE_bool(enable_cube, false, "enable cube");
DEFINE_string(general_model_path, "./conf", ""); DEFINE_string(general_model_path, "./conf", "");
DEFINE_string(general_model_file, "general_model.prototxt", ""); DEFINE_string(general_model_file, "general_model.prototxt", "");
DEFINE_bool(enable_general_model, false, "enable general model"); DEFINE_bool(enable_general_model, true, "enable general model");
const char* START_OP_NAME = "startup_op"; const char* START_OP_NAME = "startup_op";
} // namespace predictor } // namespace predictor
......
...@@ -155,8 +155,11 @@ int Resource::initialize(const std::string& path, const std::string& file) { ...@@ -155,8 +155,11 @@ int Resource::initialize(const std::string& path, const std::string& file) {
// model config // model config
int Resource::general_model_initialize(const std::string& path, int Resource::general_model_initialize(const std::string& path,
const std::string& file) { const std::string& file) {
VLOG(2) << "general model path: " << path;
VLOG(2) << "general model file: " << file;
if (!FLAGS_enable_general_model) { if (!FLAGS_enable_general_model) {
return 0; LOG(ERROR) << "general model is not enabled";
return -1;
} }
ResourceConf resource_conf; ResourceConf resource_conf;
if (configure::read_proto_conf(path, file, &resource_conf) != 0) { if (configure::read_proto_conf(path, file, &resource_conf) != 0) {
...@@ -183,6 +186,8 @@ int Resource::general_model_initialize(const std::string& path, ...@@ -183,6 +186,8 @@ int Resource::general_model_initialize(const std::string& path,
_config.reset(new PaddleGeneralModelConfig()); _config.reset(new PaddleGeneralModelConfig());
int feed_var_num = model_config.feed_var_size(); int feed_var_num = model_config.feed_var_size();
VLOG(2) << "load general model config";
VLOG(2) << "feed var num: " << feed_var_num;
_config->_feed_name.resize(feed_var_num); _config->_feed_name.resize(feed_var_num);
_config->_feed_type.resize(feed_var_num); _config->_feed_type.resize(feed_var_num);
_config->_is_lod_feed.resize(feed_var_num); _config->_is_lod_feed.resize(feed_var_num);
...@@ -190,15 +195,23 @@ int Resource::general_model_initialize(const std::string& path, ...@@ -190,15 +195,23 @@ int Resource::general_model_initialize(const std::string& path,
_config->_feed_shape.resize(feed_var_num); _config->_feed_shape.resize(feed_var_num);
for (int i = 0; i < feed_var_num; ++i) { for (int i = 0; i < feed_var_num; ++i) {
_config->_feed_name[i] = model_config.feed_var(i).name(); _config->_feed_name[i] = model_config.feed_var(i).name();
VLOG(2) << "feed var[" << i << "]: "
<< _config->_feed_name[i];
_config->_feed_type[i] = model_config.feed_var(i).feed_type(); _config->_feed_type[i] = model_config.feed_var(i).feed_type();
VLOG(2) << "feed type[" << i << "]: "
<< _config->_feed_type[i];
if (model_config.feed_var(i).is_lod_tensor()) { if (model_config.feed_var(i).is_lod_tensor()) {
VLOG(2) << "var[" << i << "] is lod tensor";
_config->_feed_shape[i] = {-1}; _config->_feed_shape[i] = {-1};
_config->_is_lod_feed[i] = true; _config->_is_lod_feed[i] = true;
} else { } else {
VLOG(2) << "var[" << i << "] is tensor";
_config->_capacity[i] = 1; _config->_capacity[i] = 1;
_config->_is_lod_feed[i] = false; _config->_is_lod_feed[i] = false;
for (int j = 0; j < model_config.feed_var(i).shape_size(); ++j) { for (int j = 0; j < model_config.feed_var(i).shape_size(); ++j) {
int32_t dim = model_config.feed_var(i).shape(j); int32_t dim = model_config.feed_var(i).shape(j);
VLOG(2) << "var[" << i << "].shape[" << i << "]: " << dim;
_config->_feed_shape[i].push_back(dim); _config->_feed_shape[i].push_back(dim);
_config->_capacity[i] *= dim; _config->_capacity[i] *= dim;
} }
......
...@@ -126,10 +126,6 @@ int main(int argc, char** argv) { ...@@ -126,10 +126,6 @@ int main(int argc, char** argv) {
return 0; return 0;
} }
if (!FLAGS_g) {
google::SetCommandLineOption("flagfile", "conf/gflags.conf");
}
google::ParseCommandLineFlags(&argc, &argv, true); google::ParseCommandLineFlags(&argc, &argv, true);
g_change_server_port(); g_change_server_port();
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include "core/configure/include/configure_parser.h" #include "core/configure/include/configure_parser.h"
#include "core/configure/sdk_configure.pb.h" #include "core/configure/sdk_configure.pb.h"
#include "core/configure/general_model_config.pb.h"
#include "core/sdk-cpp/include/utils.h" #include "core/sdk-cpp/include/utils.h"
......
...@@ -71,8 +71,14 @@ target_link_libraries(serving kvdb rocksdb) ...@@ -71,8 +71,14 @@ target_link_libraries(serving kvdb rocksdb)
if(WITH_GPU) if(WITH_GPU)
target_link_libraries(serving ${CUDA_LIBRARIES}) target_link_libraries(serving ${CUDA_LIBRARIES})
endif() endif()
target_link_libraries(serving -liomp5 -lmklml_intel -lmkldnn -lpthread
-lcrypto -lm -lrt -lssl -ldl -lz -lbz2) if(WITH_MKL)
message("lalalala: " ${WITH_MKL})
target_link_libraries(serving -liomp5 -lmklml_intel -lmkldnn -lpthread -lcrypto -lm -lrt -lssl -ldl -lz -lbz2)
else()
message("hehehehe: " ${WITH_MKL})
target_link_libraries(serving openblas -lpthread -lcrypto -lm -lrt -lssl -ldl -lz -lbz2)
endif()
install(TARGETS serving install(TARGETS serving
RUNTIME DESTINATION RUNTIME DESTINATION
...@@ -85,10 +91,10 @@ install(FILES ${inc} ...@@ -85,10 +91,10 @@ install(FILES ${inc}
DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/include/serving) DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/include/serving)
if (${WITH_MKL}) if (${WITH_MKL})
install(FILES install(FILES
${CMAKE_BINARY_DIR}/third_party/install/Paddle/third_party/install/mklml/lib/libmklml_intel.so ${CMAKE_BINARY_DIR}/third_party/install/Paddle/third_party/install/mklml/lib/libmklml_intel.so
${CMAKE_BINARY_DIR}/third_party/install/Paddle/third_party/install/mklml/lib/libiomp5.so ${CMAKE_BINARY_DIR}/third_party/install/Paddle/third_party/install/mklml/lib/libiomp5.so
${CMAKE_BINARY_DIR}/third_party/install/Paddle/third_party/install/mkldnn/lib/libmkldnn.so.0 ${CMAKE_BINARY_DIR}/third_party/install/Paddle/third_party/install/mkldnn/lib/libmkldnn.so.0
DESTINATION DESTINATION
${PADDLE_SERVING_INSTALL_DIR}/demo/serving/bin) ${PADDLE_SERVING_INSTALL_DIR}/demo/serving/bin)
endif() endif()
feed_var { is_lod_feed: true
name: "words" is_lod_feed: false
is_lod_tensor: true is_lod_feed: true
feed_type: 0 feed_type: 1
feed_type: 0
feed_type: 1
feed_shape {
shape: -1 shape: -1
} }
feed_var {
name: "label" feed_shape {
is_lod_tensor: false
feed_type: 0
shape: 1
}
fetch_var {
name: "cost"
shape: 1
}
fetch_var {
name: "acc"
shape: 1 shape: 1
}
fetch_var {
name: "prediction"
shape: 2 shape: 2
shape: 3
}
feed_shape {
shape: -1
} }
--enable_model_toolkit --enable_model_toolkit
--enable_cube=false --enable_cube=false
--enable_general_model=true --enable_general_model=true
--general_model_path=./conf
--general_model_file=general_model.prototxt
model_toolkit_path: "./conf/" model_toolkit_path: "./conf/"
model_toolkit_file: "model_toolkit.prototxt" model_toolkit_file: "model_toolkit.prototxt"
cube_config_file: "./conf/cube.conf" cube_config_file: "./conf/cube.conf"
general_model_path: "./conf/"
general_model_file: "general_model.prototxt"
...@@ -40,6 +40,6 @@ services { ...@@ -40,6 +40,6 @@ services {
workflows: "workflow9" workflows: "workflow9"
} }
services { services {
name: "GeneralModelService" name: "LoadGeneralModelService"
workflows: "workflow11" workflows: "workflow10"
} }
\ No newline at end of file
...@@ -95,24 +95,7 @@ workflows { ...@@ -95,24 +95,7 @@ workflows {
name: "workflow10" name: "workflow10"
workflow_type: "Sequence" workflow_type: "Sequence"
nodes { nodes {
name: "general_model_op" name: "load_general_model_conf_op"
type: "GeneralModelOp" type: "LoadGeneralModelConfOp"
}
}
workflows {
name: "workflow11"
workflow_type: "Sequence"
nodes {
name: "general_reader_op"
type: "GeneralReaderOp"
}
nodes {
name: "general_infer_op"
type: "GeneralInferOp"
dependencies {
name: "general_reader_op"
mode: "RO"
}
} }
} }
13d73780-de4f-4b8c-9040-34e5adc9f9ae
此差异已折叠。
# This is a RocksDB option file.
#
# For detailed file format spec, please refer to the example file
# in examples/rocksdb_option_file_example.ini
#
[Version]
rocksdb_version=6.2.4
options_file_version=1.1
[DBOptions]
avoid_unnecessary_blocking_io=false
allow_mmap_reads=false
allow_fallocate=true
WAL_size_limit_MB=0
writable_file_max_buffer_size=1048576
allow_mmap_writes=false
allow_concurrent_memtable_write=true
use_direct_reads=false
max_open_files=-1
strict_bytes_per_sync=false
db_write_buffer_size=0
max_background_jobs=2
WAL_ttl_seconds=0
enable_thread_tracking=false
error_if_exists=false
is_fd_close_on_exec=true
recycle_log_file_num=0
max_manifest_file_size=1073741824
skip_log_error_on_recovery=false
skip_stats_update_on_db_open=false
max_total_wal_size=0
new_table_reader_for_compaction_inputs=false
manual_wal_flush=false
compaction_readahead_size=0
atomic_flush=false
random_access_max_buffer_size=1048576
create_missing_column_families=false
wal_bytes_per_sync=0
use_adaptive_mutex=false
use_direct_io_for_flush_and_compaction=false
max_background_compactions=-1
advise_random_on_open=true
base_background_compactions=-1
max_background_flushes=-1
two_write_queues=false
table_cache_numshardbits=6
keep_log_file_num=1000
write_thread_slow_yield_usec=3
stats_dump_period_sec=600
avoid_flush_during_recovery=false
log_file_time_to_roll=0
delayed_write_rate=16777216
manifest_preallocation_size=4194304
paranoid_checks=true
max_log_file_size=0
allow_2pc=false
wal_dir=kvdb
db_log_dir=
max_subcompactions=1
create_if_missing=true
enable_pipelined_write=false
bytes_per_sync=0
stats_persist_period_sec=600
stats_history_buffer_size=1048576
fail_if_options_file_error=false
use_fsync=false
wal_recovery_mode=kPointInTimeRecovery
delete_obsolete_files_period_micros=21600000000
enable_write_thread_adaptive_yield=true
avoid_flush_during_shutdown=false
write_thread_max_yield_usec=100
info_log_level=INFO_LEVEL
max_file_opening_threads=16
dump_malloc_stats=false
allow_ingest_behind=false
access_hint_on_compaction_start=NORMAL
preserve_deletes=false
[CFOptions "default"]
sample_for_compression=0
compaction_pri=kMinOverlappingRatio
merge_operator=nullptr
compaction_filter_factory=nullptr
memtable_factory=SkipListFactory
memtable_insert_with_hint_prefix_extractor=nullptr
comparator=leveldb.BytewiseComparator
target_file_size_base=67108864
max_sequential_skip_in_iterations=8
compaction_style=kCompactionStyleLevel
max_bytes_for_level_base=268435456
bloom_locality=0
write_buffer_size=67108864
compression_per_level=
memtable_huge_page_size=0
max_successive_merges=0
arena_block_size=8388608
memtable_whole_key_filtering=false
target_file_size_multiplier=1
max_bytes_for_level_multiplier_additional=1:1:1:1:1:1:1
snap_refresh_nanos=0
num_levels=7
min_write_buffer_number_to_merge=1
max_write_buffer_number_to_maintain=0
max_write_buffer_number=2
compression=kNoCompression
level0_stop_writes_trigger=36
level0_slowdown_writes_trigger=20
compaction_filter=nullptr
level0_file_num_compaction_trigger=4
max_compaction_bytes=1677721600
compaction_options_universal={allow_trivial_move=false;size_ratio=1;min_merge_width=2;max_size_amplification_percent=200;max_merge_width=4294967295;compression_size_percent=-1;stop_style=kCompactionStopStyleTotalSize;}
memtable_prefix_bloom_size_ratio=0.000000
hard_pending_compaction_bytes_limit=274877906944
ttl=0
table_factory=BlockBasedTable
soft_pending_compaction_bytes_limit=68719476736
prefix_extractor=nullptr
bottommost_compression=kDisableCompressionOption
force_consistency_checks=false
paranoid_file_checks=false
compaction_options_fifo={allow_compaction=false;max_table_files_size=1073741824;}
max_bytes_for_level_multiplier=10.000000
optimize_filters_for_hits=false
level_compaction_dynamic_level_bytes=false
inplace_update_num_locks=10000
inplace_update_support=false
periodic_compaction_seconds=0
disable_auto_compactions=false
report_bg_io_stats=false
[TableOptions/BlockBasedTable "default"]
pin_top_level_index_and_filter=true
enable_index_compression=true
read_amp_bytes_per_bit=8589934592
format_version=2
block_align=false
metadata_block_size=4096
block_size_deviation=10
partition_filters=false
block_size=4096
index_block_restart_interval=1
no_block_cache=false
checksum=kCRC32c
whole_key_filtering=true
index_shortening=kShortenSeparators
data_block_index_type=kDataBlockBinarySearch
index_type=kBinarySearch
verify_compression=false
filter_policy=nullptr
data_block_hash_table_util_ratio=0.750000
pin_l0_filter_and_index_blocks_in_cache=false
block_restart_interval=16
cache_index_and_filter_blocks_with_high_priority=false
cache_index_and_filter_blocks=false
hash_index_allow_collision=true
flush_block_policy_factory=FlushBlockBySizePolicyFactory
# This is a RocksDB option file.
#
# For detailed file format spec, please refer to the example file
# in examples/rocksdb_option_file_example.ini
#
[Version]
rocksdb_version=6.2.4
options_file_version=1.1
[DBOptions]
avoid_unnecessary_blocking_io=false
allow_mmap_reads=false
allow_fallocate=true
WAL_size_limit_MB=0
writable_file_max_buffer_size=1048576
allow_mmap_writes=false
allow_concurrent_memtable_write=true
use_direct_reads=false
max_open_files=-1
strict_bytes_per_sync=false
db_write_buffer_size=0
max_background_jobs=2
WAL_ttl_seconds=0
enable_thread_tracking=false
error_if_exists=false
is_fd_close_on_exec=true
recycle_log_file_num=0
max_manifest_file_size=1073741824
skip_log_error_on_recovery=false
skip_stats_update_on_db_open=false
max_total_wal_size=0
new_table_reader_for_compaction_inputs=false
manual_wal_flush=false
compaction_readahead_size=0
atomic_flush=false
random_access_max_buffer_size=1048576
create_missing_column_families=false
wal_bytes_per_sync=0
use_adaptive_mutex=false
use_direct_io_for_flush_and_compaction=false
max_background_compactions=-1
advise_random_on_open=true
base_background_compactions=-1
max_background_flushes=-1
two_write_queues=false
table_cache_numshardbits=6
keep_log_file_num=1000
write_thread_slow_yield_usec=3
stats_dump_period_sec=600
avoid_flush_during_recovery=false
log_file_time_to_roll=0
delayed_write_rate=16777216
manifest_preallocation_size=4194304
paranoid_checks=true
max_log_file_size=0
allow_2pc=false
wal_dir=kvdb
db_log_dir=
max_subcompactions=1
create_if_missing=true
enable_pipelined_write=false
bytes_per_sync=0
stats_persist_period_sec=600
stats_history_buffer_size=1048576
fail_if_options_file_error=false
use_fsync=false
wal_recovery_mode=kPointInTimeRecovery
delete_obsolete_files_period_micros=21600000000
enable_write_thread_adaptive_yield=true
avoid_flush_during_shutdown=false
write_thread_max_yield_usec=100
info_log_level=INFO_LEVEL
max_file_opening_threads=16
dump_malloc_stats=false
allow_ingest_behind=false
access_hint_on_compaction_start=NORMAL
preserve_deletes=false
[CFOptions "default"]
sample_for_compression=0
compaction_pri=kMinOverlappingRatio
merge_operator=nullptr
compaction_filter_factory=nullptr
memtable_factory=SkipListFactory
memtable_insert_with_hint_prefix_extractor=nullptr
comparator=leveldb.BytewiseComparator
target_file_size_base=67108864
max_sequential_skip_in_iterations=8
compaction_style=kCompactionStyleLevel
max_bytes_for_level_base=268435456
bloom_locality=0
write_buffer_size=67108864
compression_per_level=
memtable_huge_page_size=0
max_successive_merges=0
arena_block_size=8388608
memtable_whole_key_filtering=false
target_file_size_multiplier=1
max_bytes_for_level_multiplier_additional=1:1:1:1:1:1:1
snap_refresh_nanos=0
num_levels=7
min_write_buffer_number_to_merge=1
max_write_buffer_number_to_maintain=0
max_write_buffer_number=2
compression=kNoCompression
level0_stop_writes_trigger=36
level0_slowdown_writes_trigger=20
compaction_filter=nullptr
level0_file_num_compaction_trigger=4
max_compaction_bytes=1677721600
compaction_options_universal={allow_trivial_move=false;size_ratio=1;min_merge_width=2;max_size_amplification_percent=200;max_merge_width=4294967295;compression_size_percent=-1;stop_style=kCompactionStopStyleTotalSize;}
memtable_prefix_bloom_size_ratio=0.000000
hard_pending_compaction_bytes_limit=274877906944
ttl=0
table_factory=BlockBasedTable
soft_pending_compaction_bytes_limit=68719476736
prefix_extractor=nullptr
bottommost_compression=kDisableCompressionOption
force_consistency_checks=false
paranoid_file_checks=false
compaction_options_fifo={allow_compaction=false;max_table_files_size=1073741824;}
max_bytes_for_level_multiplier=10.000000
optimize_filters_for_hits=false
level_compaction_dynamic_level_bytes=false
inplace_update_num_locks=10000
inplace_update_support=false
periodic_compaction_seconds=0
disable_auto_compactions=false
report_bg_io_stats=false
[TableOptions/BlockBasedTable "default"]
pin_top_level_index_and_filter=true
enable_index_compression=true
read_amp_bytes_per_bit=8589934592
format_version=2
block_align=false
metadata_block_size=4096
block_size_deviation=10
partition_filters=false
block_size=4096
index_block_restart_interval=1
no_block_cache=false
checksum=kCRC32c
whole_key_filtering=true
index_shortening=kShortenSeparators
data_block_index_type=kDataBlockBinarySearch
index_type=kBinarySearch
verify_compression=false
filter_policy=nullptr
data_block_hash_table_util_ratio=0.750000
pin_l0_filter_and_index_blocks_in_cache=false
block_restart_interval=16
cache_index_and_filter_blocks_with_high_priority=false
cache_index_and_filter_blocks=false
hash_index_allow_collision=true
flush_block_policy_factory=FlushBlockBySizePolicyFactory
...@@ -51,14 +51,14 @@ int GeneralModelOp::inference() { ...@@ -51,14 +51,14 @@ int GeneralModelOp::inference() {
// infer // infer
if (batch_size > 0) { if (batch_size > 0) {
int var_num = req->insts(0).tensor_array_size(); int var_num = req->insts(0).tensor_array_size();
VLOG(3) << "var num: " << var_num; VLOG(2) << "var num: " << var_num;
elem_type.resize(var_num); elem_type.resize(var_num);
elem_size.resize(var_num); elem_size.resize(var_num);
capacity.resize(var_num); capacity.resize(var_num);
paddle::PaddleTensor lod_tensor; paddle::PaddleTensor lod_tensor;
for (int i = 0; i < var_num; ++i) { for (int i = 0; i < var_num; ++i) {
elem_type[i] = req->insts(0).tensor_array(i).elem_type(); elem_type[i] = req->insts(0).tensor_array(i).elem_type();
VLOG(3) << "var[" << i << "] has elem type: " << elem_type[i]; VLOG(2) << "var[" << i << "] has elem type: " << elem_type[i];
if (elem_type[i] == 0) { // int64 if (elem_type[i] == 0) { // int64
elem_size[i] = sizeof(int64_t); elem_size[i] = sizeof(int64_t);
lod_tensor.dtype = paddle::PaddleDType::INT64; lod_tensor.dtype = paddle::PaddleDType::INT64;
...@@ -70,17 +70,17 @@ int GeneralModelOp::inference() { ...@@ -70,17 +70,17 @@ int GeneralModelOp::inference() {
if (req->insts(0).tensor_array(i).shape(0) == -1) { if (req->insts(0).tensor_array(i).shape(0) == -1) {
lod_tensor.lod.resize(1); lod_tensor.lod.resize(1);
lod_tensor.lod[0].push_back(0); lod_tensor.lod[0].push_back(0);
VLOG(3) << "var[" << i << "] is lod_tensor"; VLOG(2) << "var[" << i << "] is lod_tensor";
} else { } else {
lod_tensor.shape.push_back(batch_size); lod_tensor.shape.push_back(batch_size);
capacity[i] = 1; capacity[i] = 1;
for (int k = 0; k < req->insts(0).tensor_array(i).shape_size(); ++k) { for (int k = 0; k < req->insts(0).tensor_array(i).shape_size(); ++k) {
int dim = req->insts(0).tensor_array(i).shape(k); int dim = req->insts(0).tensor_array(i).shape(k);
VLOG(3) << "shape for var[" << i << "]: " << dim; VLOG(2) << "shape for var[" << i << "]: " << dim;
capacity[i] *= dim; capacity[i] *= dim;
lod_tensor.shape.push_back(dim); lod_tensor.shape.push_back(dim);
} }
VLOG(3) << "var[" << i << "] is tensor, capacity: " << capacity[i]; VLOG(2) << "var[" << i << "] is tensor, capacity: " << capacity[i];
} }
if (i == 0) { if (i == 0) {
lod_tensor.name = "words"; lod_tensor.name = "words";
...@@ -95,19 +95,19 @@ int GeneralModelOp::inference() { ...@@ -95,19 +95,19 @@ int GeneralModelOp::inference() {
for (int j = 0; j < batch_size; ++j) { for (int j = 0; j < batch_size; ++j) {
const Tensor &tensor = req->insts(j).tensor_array(i); const Tensor &tensor = req->insts(j).tensor_array(i);
int data_len = tensor.data_size(); int data_len = tensor.data_size();
VLOG(3) << "tensor size for var[" << i << "]: " << tensor.data_size(); VLOG(2) << "tensor size for var[" << i << "]: " << tensor.data_size();
int cur_len = in->at(i).lod[0].back(); int cur_len = in->at(i).lod[0].back();
VLOG(3) << "current len: " << cur_len; VLOG(2) << "current len: " << cur_len;
in->at(i).lod[0].push_back(cur_len + data_len); in->at(i).lod[0].push_back(cur_len + data_len);
VLOG(3) << "new len: " << cur_len + data_len; VLOG(2) << "new len: " << cur_len + data_len;
} }
in->at(i).data.Resize(in->at(i).lod[0].back() * elem_size[i]); in->at(i).data.Resize(in->at(i).lod[0].back() * elem_size[i]);
in->at(i).shape = {in->at(i).lod[0].back(), 1}; in->at(i).shape = {in->at(i).lod[0].back(), 1};
VLOG(3) << "var[" << i VLOG(2) << "var[" << i
<< "] is lod_tensor and len=" << in->at(i).lod[0].back(); << "] is lod_tensor and len=" << in->at(i).lod[0].back();
} else { } else {
in->at(i).data.Resize(batch_size * capacity[i] * elem_size[i]); in->at(i).data.Resize(batch_size * capacity[i] * elem_size[i]);
VLOG(3) << "var[" << i VLOG(2) << "var[" << i
<< "] is tensor and capacity=" << batch_size * capacity[i]; << "] is tensor and capacity=" << batch_size * capacity[i];
} }
} }
...@@ -144,7 +144,7 @@ int GeneralModelOp::inference() { ...@@ -144,7 +144,7 @@ int GeneralModelOp::inference() {
} }
} }
VLOG(3) << "going to infer"; VLOG(2) << "going to infer";
TensorVector *out = butil::get_object<TensorVector>(); TensorVector *out = butil::get_object<TensorVector>();
if (!out) { if (!out) {
LOG(ERROR) << "Failed get tls output object"; LOG(ERROR) << "Failed get tls output object";
...@@ -157,7 +157,7 @@ int GeneralModelOp::inference() { ...@@ -157,7 +157,7 @@ int GeneralModelOp::inference() {
for (uint32_t i = 0; i < 10; i++) { for (uint32_t i = 0; i < 10; i++) {
oss << *(example + i) << " "; oss << *(example + i) << " ";
} }
VLOG(3) << "msg: " << oss.str(); VLOG(2) << "msg: " << oss.str();
// infer // infer
if (predictor::InferManager::instance().infer( if (predictor::InferManager::instance().infer(
...@@ -167,7 +167,7 @@ int GeneralModelOp::inference() { ...@@ -167,7 +167,7 @@ int GeneralModelOp::inference() {
} }
// print response // print response
float *example_1 = reinterpret_cast<float *>((*out)[0].data.data()); float *example_1 = reinterpret_cast<float *>((*out)[0].data.data());
VLOG(3) << "result: " << *example_1; VLOG(2) << "result: " << *example_1;
Response *res = mutable_data<Response>(); Response *res = mutable_data<Response>();
......
...@@ -3,7 +3,7 @@ add_library(fluid_cpu_engine ${fluid_cpu_engine_srcs}) ...@@ -3,7 +3,7 @@ add_library(fluid_cpu_engine ${fluid_cpu_engine_srcs})
target_include_directories(fluid_cpu_engine PUBLIC target_include_directories(fluid_cpu_engine PUBLIC
${CMAKE_BINARY_DIR}/Paddle/fluid_install_dir/) ${CMAKE_BINARY_DIR}/Paddle/fluid_install_dir/)
add_dependencies(fluid_cpu_engine pdserving extern_paddle configure kvdb) add_dependencies(fluid_cpu_engine pdserving extern_paddle configure kvdb)
target_link_libraries(fluid_cpu_engine pdserving paddle_fluid iomp5 mklml_intel -lpthread -lcrypto -lm -lrt -lssl -ldl -lz) target_link_libraries(fluid_cpu_engine pdserving paddle_fluid -lpthread -lcrypto -lm -lrt -lssl -ldl -lz)
install(TARGETS fluid_cpu_engine install(TARGETS fluid_cpu_engine
ARCHIVE DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/lib ARCHIVE DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/lib
......
file(GLOB_RECURSE SERVING_CLIENT_PY_FILES serving_client/*.py) if (CLIENT_ONLY)
file(GLOB_RECURSE SERVING_CLIENT_PY_FILES paddle_serving_client/*.py)
set(PY_FILES ${SERVING_CLIENT_PY_FILES}) set(PY_FILES ${SERVING_CLIENT_PY_FILES})
SET(PACKAGE_NAME "serving_client") SET(PACKAGE_NAME "serving_client")
set(SETUP_LOG_FILE "setup.py.log") set(SETUP_LOG_FILE "setup.py.client.log")
endif()
if (NOT CLIENT_ONLY)
file(GLOB_RECURSE SERVING_SERVER_PY_FILES paddle_serving_server/*.py)
set(PY_FILES ${SERVING_SERVER_PY_FILES})
SET(PACKAGE_NAME "serving_server")
set(SETUP_LOG_FILE "setup.py.server.log")
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in if (CLIENT_ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.client.in
${CMAKE_CURRENT_BINARY_DIR}/setup.py) ${CMAKE_CURRENT_BINARY_DIR}/setup.py)
endif()
if (NOT CLIENT_ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.server.in
${CMAKE_CURRENT_BINARY_DIR}/setup.py)
endif()
set(SERVING_CLIENT_CORE ${PADDLE_SERVING_BINARY_DIR}/core/general-client/serving_client.so) set(SERVING_CLIENT_CORE ${PADDLE_SERVING_BINARY_DIR}/core/general-client/serving_client.so)
message("python env: " ${py_env}) message("python env: " ${py_env})
if (CLIENT_ONLY)
add_custom_command( add_custom_command(
OUTPUT ${PADDLE_SERVING_BINARY_DIR}/.timestamp OUTPUT ${PADDLE_SERVING_BINARY_DIR}/.timestamp
COMMAND cp -r ${CMAKE_CURRENT_SOURCE_DIR}/paddle_serving/ ${PADDLE_SERVING_BINARY_DIR}/python/ COMMAND cp -r ${CMAKE_CURRENT_SOURCE_DIR}/paddle_serving_client/ ${PADDLE_SERVING_BINARY_DIR}/python/
COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_SERVING_BINARY_DIR}/core/general-client/serving_client.so ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving/serving_client/ COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_SERVING_BINARY_DIR}/core/general-client/serving_client.so ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_client/
COMMAND env ${py_env} ${PYTHON_EXECUTABLE} setup.py bdist_wheel COMMAND env ${py_env} ${PYTHON_EXECUTABLE} setup.py bdist_wheel
DEPENDS ${SERVING_CLIENT_CORE} sdk_configure_py_proto ${PY_FILES}) DEPENDS ${SERVING_CLIENT_CORE} sdk_configure_py_proto ${PY_FILES})
add_custom_target(paddle_python ALL DEPENDS serving_client ${PADDLE_SERVING_BINARY_DIR}/.timestamp) add_custom_target(paddle_python ALL DEPENDS serving_client ${PADDLE_SERVING_BINARY_DIR}/.timestamp)
endif()
if (NOT CLIENT_ONLY)
add_custom_command(
OUTPUT ${PADDLE_SERVING_BINARY_DIR}/.timestamp
COMMAND cp -r ${CMAKE_CURRENT_SOURCE_DIR}/paddle_serving_server/ ${PADDLE_SERVING_BINARY_DIR}/python/
COMMAND env ${py_env} ${PYTHON_EXECUTABLE} setup.py bdist_wheel
DEPENDS ${SERVING_SERVER_CORE} server_config_py_proto ${PY_FILES})
add_custom_target(paddle_python ALL DEPENDS ${PADDLE_SERVING_BINARY_DIR}/.timestamp)
endif()
set(SERVING_CLIENT_PYTHON_PACKAGE_DIR ${CMAKE_CURRENT_BINARY_DIR}/dist/) set(SERVING_CLIENT_PYTHON_PACKAGE_DIR ${CMAKE_CURRENT_BINARY_DIR}/dist/)
set(SERVING_SERVER_PYTHON_PACKAGE_DIR ${CMAKE_CURRENT_BINARY_DIR}/dist/)
if (CLIENT_ONLY)
install(DIRECTORY ${SERVING_CLIENT_PYTHON_PACKAGE_DIR} install(DIRECTORY ${SERVING_CLIENT_PYTHON_PACKAGE_DIR}
DESTINATION opt/serving_client/share/wheels DESTINATION opt/serving_client/share/wheels
) )
endif()
if (NOT CLIENT_ONLY)
install(DIRECTORY ${SERVING_SERVER_PYTHON_PACKAGE_DIR}
DESTINATION opt/serving_server/share/wheels
)
endif()
find_program(PATCHELF_EXECUTABLE patchelf) find_program(PATCHELF_EXECUTABLE patchelf)
if(NOT PATCHELF_EXECUTABLE) if(NOT PATCHELF_EXECUTABLE)
......
rm -rf imdb.vocab kvdb log *.pyc serving_client_conf serving_server_model test_data text_classification_data.tar.gz train_data work_dir1
wget https://fleet.bj.bcebos.com/text_classification_data.tar.gz wget --no-check-certificate https://fleet.bj.bcebos.com/text_classification_data.tar.gz
tar -zxvf text_classification_data.tar.gz tar -zxvf text_classification_data.tar.gz
#wget --no-check-certificate https://paddle-serving.bj.bcebos.com/imdb-demo%2Fimdb.tar.gz
#tar -xzf imdb-demo%2Fimdb.tar.gz
...@@ -16,7 +16,6 @@ import sys ...@@ -16,7 +16,6 @@ import sys
import paddle import paddle
import logging import logging
import paddle.fluid as fluid import paddle.fluid as fluid
import paddle_serving as serving
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s') logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger("fluid") logger = logging.getLogger("fluid")
...@@ -42,7 +41,7 @@ if __name__ == "__main__": ...@@ -42,7 +41,7 @@ if __name__ == "__main__":
dataset = fluid.DatasetFactory().create_dataset() dataset = fluid.DatasetFactory().create_dataset()
filelist = ["train_data/%s" % x for x in os.listdir("train_data")] filelist = ["train_data/%s" % x for x in os.listdir("train_data")]
dataset.set_use_var([data, label]) dataset.set_use_var([data, label])
pipe_command = "python imdb_reader.py" pipe_command = "/home/users/dongdaxiang/paddle_whls/custom_op/paddle_release_home/python/bin/python imdb_reader.py"
dataset.set_pipe_command(pipe_command) dataset.set_pipe_command(pipe_command)
dataset.set_batch_size(4) dataset.set_batch_size(4)
dataset.set_filelist(filelist) dataset.set_filelist(filelist)
...@@ -54,15 +53,22 @@ if __name__ == "__main__": ...@@ -54,15 +53,22 @@ if __name__ == "__main__":
exe = fluid.Executor(fluid.CPUPlace()) exe = fluid.Executor(fluid.CPUPlace())
exe.run(fluid.default_startup_program()) exe.run(fluid.default_startup_program())
epochs = 30 epochs = 6
save_dirname = "cnn_model" save_dirname = "cnn_model"
import paddle_serving_client.io as serving_io
for i in range(epochs): for i in range(epochs):
exe.train_from_dataset(program=fluid.default_main_program(), exe.train_from_dataset(program=fluid.default_main_program(),
dataset=dataset, debug=False) dataset=dataset, debug=False)
logger.info("TRAIN --> pass: {}".format(i)) logger.info("TRAIN --> pass: {}".format(i))
fluid.io.save_inference_model("%s/epoch%d.model" % (save_dirname, i), if i == 5:
[data.name, label.name], [acc], exe) serving_io.save_model("serving_server_model",
serving.save_model("%s/epoch%d.model" % (save_dirname, i), "client_config{}".format(i), "serving_client_conf",
{"words": data, "label": label}, {"words": data, "label": label},
{"acc": acc, "cost": avg_cost, "prediction": prediction}) {"cost": avg_cost, "acc": acc,
"prediction": prediction},
fluid.default_main_program())
from paddle_serving import Client from paddle_serving_client import Client
import sys import sys
client = Client() client = Client()
...@@ -7,7 +7,7 @@ client.connect(["127.0.0.1:9292"]) ...@@ -7,7 +7,7 @@ client.connect(["127.0.0.1:9292"])
for line in sys.stdin: for line in sys.stdin:
group = line.strip().split() group = line.strip().split()
words = [int(x) for x in group[1:int(group[0])]] words = [int(x) for x in group[1:int(group[0]) + 1]]
label = [int(group[-1])] label = [int(group[-1])]
feed = {"words": words, "label": label} feed = {"words": words, "label": label}
fetch = ["acc", "cost", "prediction"] fetch = ["acc", "cost", "prediction"]
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from paddle_serving import Client from paddle_serving_client import Client
import sys import sys
import subprocess import subprocess
from multiprocessing import Pool from multiprocessing import Pool
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from paddle_serving import Client from paddle_serving_client import Client
import sys import sys
import subprocess import subprocess
from multiprocessing import Pool from multiprocessing import Pool
......
import os
import sys
from paddle_serving_server import OpMaker
from paddle_serving_server import OpSeqMaker
from paddle_serving_server import Server
op_maker = OpMaker()
read_op = op_maker.create('general_reader')
general_infer_op = op_maker.create('general_infer')
op_seq_maker = OpSeqMaker()
op_seq_maker.add_op(read_op)
op_seq_maker.add_op(general_infer_op)
server = Server()
server.set_op_sequence(op_seq_maker.get_op_sequence())
server.load_model_config(sys.argv[1])
server.prepare_server(workdir="work_dir1", port=9292, device="cpu")
server.run_server()
...@@ -13,7 +13,9 @@ ...@@ -13,7 +13,9 @@
# limitations under the License. # limitations under the License.
from .serving_client import PredictorClient from .serving_client import PredictorClient
from ..proto import sdk_configure_pb2 as sdk from .proto import sdk_configure_pb2 as sdk
from .proto import general_model_config_pb2 as m_config
import google.protobuf.text_format
import time import time
int_type = 0 int_type = 0
...@@ -74,34 +76,25 @@ class Client(object): ...@@ -74,34 +76,25 @@ class Client(object):
self.feed_names_to_idx_ = {} self.feed_names_to_idx_ = {}
def load_client_config(self, path): def load_client_config(self, path):
model_conf = m_config.GeneralModelConfig()
f = open(path, 'r')
model_conf = google.protobuf.text_format.Merge(
str(f.read()), model_conf)
# load configuraion here # load configuraion here
# get feed vars, fetch vars # get feed vars, fetch vars
# get feed shapes, feed types # get feed shapes, feed types
# map feed names to index # map feed names to index
self.client_handle_ = PredictorClient() self.client_handle_ = PredictorClient()
self.client_handle_.init(path) self.client_handle_.init(path)
self.feed_names_ = [] self.feed_names_ = [var.alias_name for var in model_conf.feed_var]
self.fetch_names_ = [] self.fetch_names_ = [var.alias_name for var in model_conf.fetch_var]
self.feed_shapes_ = [] self.feed_shapes_ = [var.shape for var in model_conf.feed_var]
self.feed_types_ = {}
self.feed_names_to_idx_ = {} self.feed_names_to_idx_ = {}
for i, var in enumerate(model_conf.feed_var):
self.feed_names_to_idx_[var.alias_name] = i
self.feed_types_[var.alias_name] = var.feed_type
with open(path) as fin:
group = fin.readline().strip().split()
feed_num = int(group[0])
fetch_num = int(group[1])
for i in range(feed_num):
group = fin.readline().strip().split()
self.feed_names_.append(group[0])
tmp_shape = []
for s in group[2:-1]:
tmp_shape.append(int(s))
self.feed_shapes_.append(tmp_shape)
self.feed_types_[group[0]] = int(group[-1])
self.feed_names_to_idx_[group[0]] = i
for i in range(fetch_num):
group = fin.readline().strip().split()
self.fetch_names_.append(group[0])
return return
def connect(self, endpoints): def connect(self, endpoints):
...@@ -148,6 +141,9 @@ class Client(object): ...@@ -148,6 +141,9 @@ class Client(object):
result = self.client_handle_.predict( result = self.client_handle_.predict(
float_slot, float_feed_names, int_slot, int_feed_names, fetch_names) float_slot, float_feed_names, int_slot, int_feed_names, fetch_names)
# TODO(guru4elephant): the order of fetch var name should be consistent with
# general_model_config, this is not friendly
# In the future, we need make the number of fetched variable changable
result_map = {} result_map = {}
for i, name in enumerate(fetch_names): for i, name in enumerate(fetch_names):
result_map[name] = result[i] result_map[name] = result[i]
......
...@@ -13,4 +13,5 @@ ...@@ -13,4 +13,5 @@
# limitations under the License. # limitations under the License.
""" Paddle Serving Client version string """ """ Paddle Serving Client version string """
serving_client_version = "0.1.0" serving_client_version = "0.1.0"
serving_server_version = "0.1.0"
module_proto_version = "0.1.0" module_proto_version = "0.1.0"
此差异已折叠。
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
...@@ -11,5 +11,7 @@ ...@@ -11,5 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from .serving_client import Client """ Paddle Serving Client version string """
from .io import save_model serving_client_version = "0.1.0"
serving_server_version = "0.1.0"
module_proto_version = "0.1.0"
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册