提交 0daa6344 编写于 作者: W wangguibao

Elastic CTR

上级 87e5ae3e
...@@ -76,11 +76,6 @@ include(external/gtest) ...@@ -76,11 +76,6 @@ include(external/gtest)
include(generic) include(generic)
include(flags) include(flags)
if(WITH_ELASTIC_CTR)
include(external/python)
include(external/pybind11)
endif()
if (NOT CLIENT_ONLY) if (NOT CLIENT_ONLY)
include(external/cudnn) include(external/cudnn)
include(paddlepaddle) include(paddlepaddle)
......
# Copyright (c) 2016 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(PYBIND_SOURCE_DIR ${THIRD_PARTY_PATH}/pybind)
include_directories(${PYBIND_SOURCE_DIR}/src/extern_pybind/include)
ExternalProject_Add(
extern_pybind
${EXTERNAL_PROJECT_LOG_ARGS}
GIT_REPOSITORY "https://github.com/pybind/pybind11.git"
GIT_TAG "v2.2.4"
PREFIX ${PYBIND_SOURCE_DIR}
UPDATE_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
if(${CMAKE_VERSION} VERSION_LESS "3.3.0")
set(dummyfile ${CMAKE_CURRENT_BINARY_DIR}/pybind_dummy.c)
file(WRITE ${dummyfile} "const char * dummy_pybind = \"${dummyfile}\";")
add_library(pybind STATIC ${dummyfile})
else()
add_library(pybind INTERFACE)
endif()
add_dependencies(pybind extern_pybind)
# Copyright (c) 2016 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.
FIND_PACKAGE(PythonInterp ${PY_VERSION} REQUIRED)
FIND_PACKAGE(PythonLibs ${PY_VERSION} REQUIRED)
if(WIN32)
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c"
"from distutils import sysconfig as s;import sys;import struct;
print(sys.prefix);
print(s.get_config_var('LDVERSION') or s.get_config_var('VERSION'));
"
RESULT_VARIABLE _PYTHON_SUCCESS
OUTPUT_VARIABLE _PYTHON_VALUES
ERROR_VARIABLE _PYTHON_ERROR_VALUE)
if(NOT _PYTHON_SUCCESS MATCHES 0)
set(PYTHONLIBS_FOUND FALSE)
return()
endif()
# Convert the process output into a list
string(REGEX REPLACE ";" "\\\\;" _PYTHON_VALUES ${_PYTHON_VALUES})
string(REGEX REPLACE "\n" ";" _PYTHON_VALUES ${_PYTHON_VALUES})
list(GET _PYTHON_VALUES 0 PYTHON_PREFIX)
list(GET _PYTHON_VALUES 1 PYTHON_LIBRARY_SUFFIX)
# Make sure all directory separators are '/'
string(REGEX REPLACE "\\\\" "/" PYTHON_PREFIX ${PYTHON_PREFIX})
set(PYTHON_LIBRARY
"${PYTHON_PREFIX}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib")
# when run in a venv, PYTHON_PREFIX points to it. But the libraries remain in the
# original python installation. They may be found relative to PYTHON_INCLUDE_DIR.
if(NOT EXISTS "${PYTHON_LIBRARY}")
get_filename_component(_PYTHON_ROOT ${PYTHON_INCLUDE_DIR} DIRECTORY)
set(PYTHON_LIBRARY
"${_PYTHON_ROOT}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib")
endif()
# raise an error if the python libs are still not found.
if(NOT EXISTS "${PYTHON_LIBRARY}")
message(FATAL_ERROR "Python libraries not found")
endif()
SET(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
endif(WIN32)
# Fixme: Maybe find a static library. Get SHARED/STATIC by FIND_PACKAGE.
ADD_LIBRARY(python SHARED IMPORTED GLOBAL)
SET_PROPERTY(TARGET python PROPERTY IMPORTED_LOCATION ${PYTHON_LIBRARIES})
SET(py_env "")
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIR})
...@@ -4,11 +4,9 @@ file(GLOB sdk_cpp_srcs ${CMAKE_SOURCE_DIR}/sdk-cpp/src/*.cpp) ...@@ -4,11 +4,9 @@ file(GLOB sdk_cpp_srcs ${CMAKE_SOURCE_DIR}/sdk-cpp/src/*.cpp)
list(APPEND elasticctr_srcs ${elastic_ctr_cpp_srcs}) list(APPEND elasticctr_srcs ${elastic_ctr_cpp_srcs})
list(APPEND elasticctr_srcs ${sdk_cpp_srcs}) list(APPEND elasticctr_srcs ${sdk_cpp_srcs})
list(APPEND elasticctr_srcs list(APPEND elasticctr_srcs
${CMAKE_CURRENT_LIST_DIR}/api/elastic_ctr_api.cpp ${CMAKE_CURRENT_LIST_DIR}/api/elastic_ctr_api.cpp)
${CMAKE_CURRENT_LIST_DIR}/api/pybind.cpp)
add_library(elasticctr SHARED ${elasticctr_srcs}) add_library(elasticctr SHARED ${elasticctr_srcs})
add_dependencies(elasticctr pybind)
target_link_libraries(elasticctr brpc configure protobuf leveldb -lcrypto target_link_libraries(elasticctr brpc configure protobuf leveldb -lcrypto
-lssl -lz -lrt) -lssl -lz -lrt)
...@@ -16,19 +14,15 @@ set_target_properties(elasticctr PROPERTIES INTERFACE_LINK_LIBRARIES "") ...@@ -16,19 +14,15 @@ set_target_properties(elasticctr PROPERTIES INTERFACE_LINK_LIBRARIES "")
add_executable(elastic_ctr_demo ${CMAKE_CURRENT_LIST_DIR}/demo/demo.cpp) add_executable(elastic_ctr_demo ${CMAKE_CURRENT_LIST_DIR}/demo/demo.cpp)
set_target_properties(elastic_ctr_demo PROPERTIES LINK_LIBRARIES "") set_target_properties(elastic_ctr_demo PROPERTIES LINK_LIBRARIES "")
target_link_libraries(elastic_ctr_demo elasticctr python -lpthread -lcrypto -lm -lrt target_link_libraries(elastic_ctr_demo elasticctr -lpthread -lcrypto -lm -lrt
-lssl -ldl -lz) -lssl -ldl -lz)
get_filename_component(PYTHON_LIBRARY_REAL_PATH ${PYTHON_LIBRARY} REALPATH)
# install # install
install(TARGETS elasticctr elastic_ctr_demo install(TARGETS elasticctr elastic_ctr_demo
RUNTIME DESTINATION RUNTIME DESTINATION
${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin
LIBRARY DESTINATION LIBRARY DESTINATION
${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin) ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin)
install(FILES ${PYTHON_LIBRARY_REAL_PATH}
DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin)
install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/demo/conf DESTINATION install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/demo/conf DESTINATION
${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/) ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/)
install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/demo/data/ctr_prediction DESTINATION install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/demo/data/ctr_prediction DESTINATION
...@@ -37,9 +31,6 @@ install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/demo/data/ctr_prediction DESTINATION ...@@ -37,9 +31,6 @@ install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/demo/data/ctr_prediction DESTINATION
install(TARGETS elasticctr install(TARGETS elasticctr
LIBRARY DESTINATION LIBRARY DESTINATION
${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib) ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib)
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib/libelasticctr.so
${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib/elasticctr.so)")
install(FILES ${CMAKE_CURRENT_LIST_DIR}/api/elastic_ctr_api.h install(FILES ${CMAKE_CURRENT_LIST_DIR}/api/elastic_ctr_api.h
DESTINATION DESTINATION
...@@ -76,11 +67,12 @@ install(DIRECTORY ...@@ -76,11 +67,12 @@ install(DIRECTORY
${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/include) ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/include)
# Python client API # Python client API
install(FILES ${CMAKE_CURRENT_LIST_DIR}/api/python/elasticctr/__init__.py install(FILES ${CMAKE_CURRENT_LIST_DIR}/api/python/elasticctr/elastic_ctr_api.py
${CMAKE_CURRENT_LIST_DIR}/api/python/elasticctr/elasticctr.py
DESTINATION DESTINATION
${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib) ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib)
install(FILES ${CMAKE_CURRENT_LIST_DIR}/demo/demo.py
DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin) install(FILES ${CMAKE_CURRENT_LIST_DIR}/api/python/elasticctr/elastic_ctr_api.py
DESTINATION
${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin)
install(FILES ${CMAKE_CURRENT_LIST_DIR}/demo/elastic_ctr.py install(FILES ${CMAKE_CURRENT_LIST_DIR}/demo/elastic_ctr.py
DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin) DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin)
/* 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 <Python.h>
#include <algorithm>
#include <cstdlib>
#include <map>
#include <memory>
#include <mutex> // NOLINT // for call_once
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include "elastic-ctr/client/api/elastic_ctr_api.h"
#include "pybind11/pybind11.h"
#include "pybind11/stl.h"
namespace baidu {
namespace paddle_serving {
namespace elastic_ctr {
namespace py = pybind11;
using baidu::paddle_serving::predictor::elastic_ctr::ReqInstance;
PYBIND11_MODULE(elasticctr, m) {
m.doc() = "C++ core of ElasticCTRPredictorApi";
py::class_<ReqInstance>(m, "ReqInstance", py::buffer_protocol())
.def(py::init<>());
py::class_<ElasticCTRPredictorApi>(
m, "ElasticCTRPredictorApi", py::buffer_protocol())
.def(py::init<>())
.def("init", &ElasticCTRPredictorApi::init)
.def("thrd_initialize", &ElasticCTRPredictorApi::thrd_initialize)
.def("thrd_clear", &ElasticCTRPredictorApi::thrd_clear)
.def("thrd_finalize", &ElasticCTRPredictorApi::thrd_finalize)
.def("destroy", &ElasticCTRPredictorApi::destroy)
.def("add_instance", &ElasticCTRPredictorApi::add_instance)
.def("add_slot", &ElasticCTRPredictorApi::add_slot)
.def("inference",
[](ElasticCTRPredictorApi &self) -> std::vector<std::vector<float>> {
std::vector<std::vector<float>> results_vec;
self.inference(results_vec);
return results_vec;
});
}
} // namespace elastic_ctr
} // namespace paddle_serving
} // namespace baidu
# 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.
def __bootstrap__():
"""
Returns:
None
"""
import sys
import os
import platform
from . import elasticctr
# 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.
import json
import httplib
import sys
import os
class ElasticCTRAPI(object):
def __init__(self, serving_ip, serving_port):
self._instances = []
self._slots = []
self._conn = self.conn(serving_ip, serving_port)
def read_slots_conf(self, slots_conf_file):
if not os.path.exists(slots_conf_file):
print "Path %s not exist" % sltos_conf_file
return -1
with open(slots_conf_file, "r") as f:
for line in f:
self._slots.append(line.rstrip('\n'))
return 0
def conn(self, ip, port):
return httplib.HTTPConnection(ip, port)
def add_instance(self):
feature_slots = []
instance = [{"slots": feature_slots}]
self._instances += instance
return instance
def add_slot(self, instance, slot, feasigns):
if not isinstance(instance, list):
print "add slot: parameter invalid: instance should be list"
return -1
if not isinstance(feasigns, list):
print "add slot: value format invalid: feasigns should be list"
return -1
kv = [{"slot_name": slot, "feasigns": feasigns}]
instance[0]["slots"] += kv
def inference(self):
for instance in self._instances:
feature_slots = instance["slots"]
keys = []
for x in feature_slots:
keys += [x["slot_name"]]
for slot in self._slots:
if not slot in keys:
feature_slots += [{"slot_name": slot, "feasigns": [0]}]
req = {"instances": self._instances}
request_json = json.dumps(req)
try:
self._conn.request('POST', "/ElasticCTRPredictionService/inference",
request_json,
{"Content-Type": "application/json"})
response = self._conn.getresponse()
return response.read()
except httplib.HTTPException as e:
print e.reason
# 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.
import elasticctr
class ElasticCTRPredictorApi(object):
"""
A ElasticCTRPredictorApi Wrapper class
"""
def __init__(self):
self.api = elasticctr.ElasticCTRPredictorApi
print "Init OK"
def init(conf_dir, slot_conf_file, serving_conf_file):
self.api.init(conf_dir, slot_conf_file, serving_conf_file)
def thrd_initialize():
self.api.thrd_initialize()
def thrd_clear():
self.api.thrd_clear()
def destroy():
self.api.destroy()
def add_instance():
return self.api.add_instance()
def add_slot(instance, slot_name, value):
return self.api.add_slot(instance, slot_name, value)
def inference():
self.api.inferene()
def get_results():
return self.api.get_results()
# 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.
import os
import os.path
import sys
path = os.path.abspath(os.path.curdir) + '/../api'
print path
sys.path.append(path)
import lib
from lib import elasticctr
api = elasticctr.ElasticCTRPredictorApi()
ret = api.init("./conf", "slot.conf", "predictors.prototxt")
if ret != 0:
print "api.init fail"
sys.exit(-1)
api.thrd_initialize()
api.thrd_clear()
instance = api.add_instance()
api.add_slot(instance, "0", 1234)
api.add_slot(instance, "1", 1234)
api.add_slot(instance, "2", 1234)
api.add_slot(instance, "3", 1234)
api.add_slot(instance, "4", 1234)
api.add_slot(instance, "5", 1234)
api.add_slot(instance, "6", 1234)
ret = api.inference()
print ret
api.destroy()
...@@ -17,6 +17,8 @@ import httplib ...@@ -17,6 +17,8 @@ import httplib
import sys import sys
import os import os
from elastic_ctr_api import ElasticCTRAPI
BATCH_SIZE = 3 BATCH_SIZE = 3
SERVING_IP = "127.0.0.1" SERVING_IP = "127.0.0.1"
SLOT_CONF_FILE = "./conf/slot.conf" SLOT_CONF_FILE = "./conf/slot.conf"
...@@ -53,60 +55,36 @@ def data_reader(data_file, samples, labels): ...@@ -53,60 +55,36 @@ def data_reader(data_file, samples, labels):
samples.append(sample) samples.append(sample)
def read_slots_conf(slots_conf_file, slots):
if not os.path.exists(slots_conf_file):
print "Path %s not exist" % sltos_conf_file
return -1
with open(slots_conf_file, "r") as f:
for line in f:
slots.append(line.rstrip('\n'))
print slots
return 0
if __name__ == "__main__": if __name__ == "__main__":
""" main """ main
""" """
if len(sys.argv) != 4: if len(sys.argv) != 5:
print "Usage: python elastic_ctr.py SERVING_IP SLOT_CONF_FILE DATA_FILE" print "Usage: python elastic_ctr.py SERVING_IP SERVING_PORT SLOT_CONF_FILE DATA_FILE"
sys.exit(-1) sys.exit(-1)
samples = [] samples = []
labels = [] labels = []
SERVING_IP = sys.argv[1] SERVING_IP = sys.argv[1]
SLOT_CONF_FILE = sys.argv[2] SERVING_PORT = sys.argv[2]
SLOT_CONF_FILE = sys.argv[3]
ret = read_slots_conf(SLOT_CONF_FILE, SLOTS) api = ElasticCTRAPI(SERVING_IP, SERVING_PORT)
ret = api.read_slots_conf(SLOT_CONF_FILE)
if ret != 0: if ret != 0:
sys.exit(-1) sys.exit(-1)
print SLOTS
ret = data_reader(sys.argv[3], samples, labels)
conn = httplib.HTTPConnection(SERVING_IP, 8010) ret = data_reader(sys.argv[4], samples, labels)
for i in range(0, len(samples) - BATCH_SIZE, BATCH_SIZE): for i in range(0, len(samples) - BATCH_SIZE, BATCH_SIZE):
batch = samples[i:i + BATCH_SIZE] batch = samples[i:i + BATCH_SIZE]
instances = [] instances = []
for sample in batch: for sample in batch:
instance = [] instance = api.add_instance()
kv = [] kv = []
for k, v in sample.iteritems(): for k, v in sample.iteritems():
kv += [{"slot_name": k, "feasigns": v}] api.add_slot(instance, k, v)
print kv
instance = [{"slots": kv}] ret = api.inference()
instances += instance print ret
req = {"instances": instances}
request_json = json.dumps(req)
print request_json
try:
conn.request('POST', "/ElasticCTRPredictionService/inference",
request_json, {"Content-Type": "application/json"})
response = conn.getresponse()
print response.read()
except httplib.HTTPException as e:
print e.reason
sys.exit(0) sys.exit(0)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册