diff --git a/CMakeLists.txt b/CMakeLists.txt index 75e4d7728967cfe595888f058a7845d161d56d29..dbccc0249991a298ec91b08a3c6d5e0e01d79e41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ option(WITH_AVX "Compile Paddle Serving with AVX intrinsics" ${AVX_FOUND} option(WITH_MKL "Compile Paddle Serving with MKL support." ${AVX_FOUND}) option(WITH_GPU "Compile Paddle Serving with NVIDIA GPU" ${CUDA_FOUND}) option(CLIENT_ONLY "Compile client libraries and demos only" FALSE) +option(WITH_ELASTIC_CTR "Compile ELASITC-CTR solution" FALSE) set(WITH_MKLML ${WITH_MKL}) if (NOT DEFINED WITH_MKLDNN) @@ -123,3 +124,8 @@ add_subdirectory(inferencer-fluid-gpu) endif() add_subdirectory(demo-serving) endif() + +# Paddle Serving Solutions +if (WITH_ELASTIC_CTR) +add_subdirectory(elastic-ctr) +endif() diff --git a/demo-serving/scripts/start.sh b/demo-serving/scripts/start.sh deleted file mode 100755 index 5083ba04dbbb29ec0c07428a7e04912ec68120e5..0000000000000000000000000000000000000000 --- a/demo-serving/scripts/start.sh +++ /dev/null @@ -1 +0,0 @@ -/home/work/image-class/bin/image_class --workflow_path=/home/work/image-class/conf/ --inferservice_path=/home/work/image-class/conf/ --logger_path=/home/work/image-class/conf/ --resource_path=/home/work/image-class/conf/ diff --git a/doc/INSTALL.md b/doc/INSTALL.md index 88e052db3538410f338c11467aecca30b0243168..b7886bbe9bc16a7f49fe23a7992decbd2ed316f8 100644 --- a/doc/INSTALL.md +++ b/doc/INSTALL.md @@ -20,10 +20,12 @@ bzip2-devel ## 编译 -推荐使用Docker编译Paddle Serving, [Docker编译使用说明](./DOCKER.md) +推荐使用Docker准备Paddle Serving编译环境. [Docker编译使用说明](./DOCKER.md) + +以下命令将会下载Paddle Serving最新代码,并执行编译 ```shell -$ git clone https://github.com/PaddlePaddle/serving.git +$ git clone https://github.com/PaddlePaddle/Serving.git $ cd serving $ mkdir build $ cd build @@ -32,39 +34,31 @@ $ make -j4 $ make install ``` -`make install`将把目标产出放在/path/to/paddle-serving/build/output/目录下,目录结构: +`make install`将把目标产出放在/path/to/Paddle-Serving/build/output/目录下,目录结构: ``` . -|-- bin # Paddle Serving protobuf编译插件pdcodegen所在目录 +|-- bin # Paddle Serving工具和protobuf编译插件pdcodegen所在目录 +|-- conf |-- demo # demo总目录 -| |-- client +| |-- client # Demo client端 +| | |-- bert # bert模型客户端 +| | |-- ctr_prediction # CTR prediction模型客户端 | | |-- dense_format # dense_format客户端 -| | | |-- bin # bin/dense_format是dense_format客户端bin -| | | `-- conf -| | |-- echo # echo服务客户端 -| | | |-- bin # bin/echo是echo客户端bin -| | | \-- conf -| | |-- image_classification # image_classification服务客户端 -| | | |-- bin # bin/ximage是image_classification客户端bin -| | | |-- conf -| | | |-- data -| | | `-- images -| | |-- int64tensor_format # int64tensor_format服务客户端 -| | | |-- bin # bin/int64tensor_format是客户端bin -| | | `-- conf -| | `-- sparse_format # sparse_format客户端 -| | |-- bin # bin/sparse_format是客户端bin -| | `-- conf -| `-- serving # serving端,同时提供echo/dense_format/sparse_format/int64tensor_format/image_class等5种服务 -| |-- bin # bin/serving是serving端可执行bin -| |-- conf # 配置文件目录 -| |-- data -| | `-- model -| | `-- paddle -| | `-- fluid -| | `-- SE_ResNeXt50_32x4d # image_classification模型 -`-- lib # Paddle Serving产出的静态库文件: libpdseving.a, libsdk-cpp.a, libconfigure.a, libfluid_cpu_engine.a +| | |-- echo # 最简单的echo service客户端 +| | |-- echo_kvdb # local KV读取demo客户端 +| | |-- image_classification # 图像分类任务客户端 +| | |-- int64tensor_format # int64tensor_format示例客户端 +| | |-- sparse_format # sparse_format示例客户端 +| | `-- text_classification # 文本分类任务示例客户端 +| |-- db_func +| |-- db_thread +| |-- kvdb_test +| `-- serving # Demo serving端;该serving可同时响应所有demo client请求 +|-- include # Paddle Serving发布的头文件 +|-- lib # Paddle Serving发布的libs +`-- tool # Paddle Serving发布的工具目录 + ``` 如要编写新的预测服务,请参考[从零开始写一个预测服务](CREATING.md) diff --git a/elastic-ctr/CMakeLists.txt b/elastic-ctr/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..efaf744d946b6a9336e5207918763b7852512649 --- /dev/null +++ b/elastic-ctr/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(client) +add_subdirectory(serving) diff --git a/elastic-ctr/client/CMakeLists.txt b/elastic-ctr/client/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c844b9755704d5e9a45dda366dff463458425cd6 --- /dev/null +++ b/elastic-ctr/client/CMakeLists.txt @@ -0,0 +1,78 @@ +include(proto/CMakeLists.txt) + +file(GLOB sdk_cpp_srcs ${CMAKE_SOURCE_DIR}/sdk-cpp/src/*.cpp) +list(APPEND elasticctr_srcs ${elastic_ctr_cpp_srcs}) +list(APPEND elasticctr_srcs ${sdk_cpp_srcs}) +list(APPEND elasticctr_srcs + ${CMAKE_CURRENT_LIST_DIR}/api/elastic_ctr_api.cpp) + +add_library(elasticctr SHARED ${elasticctr_srcs}) +target_link_libraries(elasticctr brpc configure protobuf leveldb -lcrypto + -lssl -lz -lrt) + +set_target_properties(elasticctr PROPERTIES INTERFACE_LINK_LIBRARIES "") + +add_executable(elastic_ctr_demo ${CMAKE_CURRENT_LIST_DIR}/demo/demo.cpp) +set_target_properties(elastic_ctr_demo PROPERTIES LINK_LIBRARIES "") +target_link_libraries(elastic_ctr_demo elasticctr -lpthread -lcrypto -lm -lrt + -lssl -ldl -lz) + +# install +install(TARGETS elasticctr elastic_ctr_demo + RUNTIME DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin + LIBRARY DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin) +install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/demo/conf DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/) +install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/demo/data/ctr_prediction DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/data) + +install(TARGETS elasticctr + LIBRARY DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib) + +install(FILES ${CMAKE_CURRENT_LIST_DIR}/api/elastic_ctr_api.h + DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/include/elastic-ctr/client/api/) +install(FILES + ${CMAKE_BINARY_DIR}/elastic-ctr/client/elastic_ctr_prediction.pb.h + ${CMAKE_BINARY_DIR}/elastic-ctr/client/pds_option.pb.h + ${CMAKE_BINARY_DIR}/elastic-ctr/client/builtin_format.pb.h + DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/include/elastic-ctr/client/) +install(DIRECTORY + ${CMAKE_SOURCE_DIR}/sdk-cpp/include + DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/include/sdk-cpp/) +install(DIRECTORY + ${CMAKE_SOURCE_DIR}/configure/include + DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/include/configure) +install(FILES + ${CMAKE_BINARY_DIR}/configure/sdk_configure.pb.h + DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/include/configure) + +install(DIRECTORY + ${CMAKE_BINARY_DIR}/third_party/install/protobuf/include/google + ${CMAKE_BINARY_DIR}/third_party/install/brpc/include/brpc + ${CMAKE_BINARY_DIR}/third_party/install/brpc/include/butil + ${CMAKE_BINARY_DIR}/third_party/install/brpc/include/bthread + ${CMAKE_BINARY_DIR}/third_party/install/brpc/include/bvar + ${CMAKE_BINARY_DIR}/third_party/install/brpc/include/json2pb + ${CMAKE_BINARY_DIR}/third_party/install/gflags/include/gflags + ${CMAKE_BINARY_DIR}/third_party/install/glog/include/glog + DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/include) + +# Python client API +install(FILES ${CMAKE_CURRENT_LIST_DIR}/api/python/elasticctr/elastic_ctr_api.py + DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib) + +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 + DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin) diff --git a/elastic-ctr/client/api/elastic_ctr_api.cpp b/elastic-ctr/client/api/elastic_ctr_api.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9596ae14ee17fdc4f8db850520191a1bb8abe67c --- /dev/null +++ b/elastic-ctr/client/api/elastic_ctr_api.cpp @@ -0,0 +1,285 @@ +// 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 "elastic-ctr/client/api/elastic_ctr_api.h" +#include +#include +#include +#include +#include + +namespace baidu { +namespace paddle_serving { +namespace elastic_ctr { + +const int VARIABLE_NAME_LEN = 256; + +static void thread_resource_delete(void *d) { +#if 1 + LOG(INFO) << "thread_resource_delete on " << bthread_self(); +#endif + delete static_cast(d); +} + +std::set ElasticCTRPredictorApi::slot_names_; + +int ThreadResource::clear() { + request_.clear_instances(); + response_.clear_predictions(); + + for (auto it : instance_map_) { + delete it.second; + } + return 0; +} + +ReqInstance *ThreadResource::add_instance() { + ReqInstance *instance = request_.add_instances(); + + InstanceInfo *instance_info = new InstanceInfo(); + instance_map_[instance] = instance_info; + + return instance; +} + +int ThreadResource::add_slot(ReqInstance *instance, + const std::string &slot_name, + uint64_t value) { + auto instance_it = instance_map_.find(instance); + if (instance_it == instance_map_.end()) { + return -1; + } + + InstanceInfo *instance_info = instance_it->second; + + auto slot_it = instance_info->slot_map_.find(slot_name); + Slot *slot = NULL; + + if (slot_it == instance_info->slot_map_.end()) { + slot = instance->add_slots(); + instance_info->slot_map_[slot_name] = slot; + } else { + slot = slot_it->second; + } + slot->set_slot_name(slot_name); + slot->add_feasigns(value); + + return 0; +} + +void ThreadResource::validate_request(const std::set &slot_names) { + for (auto it : instance_map_) { + ReqInstance *req_instance = it.first; + InstanceInfo *instance_info = it.second; + + for (auto slot_name : slot_names) { + if (instance_info->slot_map_.find(slot_name) == + instance_info->slot_map_.end()) { + LOG(INFO) << "Missing values for slot " << slot_name.c_str(); + add_slot(req_instance, slot_name, 0); + } + } + } +} + +int ElasticCTRPredictorApi::read_slot_conf(const char *path, + const char *slot_conf_file) { + struct stat stat_buf; + char name[VARIABLE_NAME_LEN]; + snprintf(name, VARIABLE_NAME_LEN, "%s/%s", path, slot_conf_file); + if (stat(name, &stat_buf) != 0) { + LOG(ERROR) << "Error stating file" << name; + return -1; + } + + std::ifstream fs(name); + for (std::string line; std::getline(fs, line);) { + slot_names_.insert(line); + } + +#if 1 + for (auto x : slot_names_) { + LOG(INFO) << "slot: " << x.c_str(); + } +#endif + + return 0; +} + +int ElasticCTRPredictorApi::init(const char *path, + const char *slot_conf_file, + const char *serving_conf_file) { + int ret = api_.create(path, serving_conf_file); + if (ret != 0) { + return ret; + } + + ret = read_slot_conf(path, slot_conf_file); + if (ret != 0) { + return ret; + } + + // Thread-local storage + if (pthread_key_create(&tls_bspec_key_, thread_resource_delete) != 0) { + LOG(ERROR) << "unable to create tls_bthread_key of thrd_data"; + return -1; + } + + return 0; +} + +int ElasticCTRPredictorApi::thrd_initialize() { + api_.thrd_initialize(); + + ThreadResource *thread_resource = + reinterpret_cast(pthread_getspecific(tls_bspec_key_)); + if (thread_resource == NULL) { + thread_resource = new (std::nothrow) ThreadResource; + + if (thread_resource == NULL) { + LOG(ERROR) << "failed to create thread local resource"; + return -1; + } + + if (pthread_setspecific(tls_bspec_key_, thread_resource) != 0) { + LOG(ERROR) << "unable to set tls thread local resource"; + delete thread_resource; + thread_resource = NULL; + return -1; + } + } + + return 0; +} + +int ElasticCTRPredictorApi::thrd_clear() { + api_.thrd_clear(); + + ThreadResource *thread_resource = + reinterpret_cast(pthread_getspecific(tls_bspec_key_)); + if (thread_resource == NULL) { + if (thread_resource == NULL) { + LOG(ERROR) << "ERROR: thread local resource is null"; + return -1; + } + } + + if (thread_resource->clear() != 0) { + LOG(ERROR) << "ElasticCTRPredictorApi: thrd_clear() fail"; + } + + return 0; +} + +int ElasticCTRPredictorApi::thrd_finalize() { + api_.thrd_finalize(); + return 0; +} + +void ElasticCTRPredictorApi::destroy() { + pthread_key_delete(tls_bspec_key_); + return; +} + +ReqInstance *ElasticCTRPredictorApi::add_instance() { + ThreadResource *thread_resource = + reinterpret_cast(pthread_getspecific(tls_bspec_key_)); + if (thread_resource == NULL) { + if (thread_resource == NULL) { + LOG(ERROR) << "ERROR: thread local resource is null"; + return NULL; + } + } + + ReqInstance *instance = thread_resource->add_instance(); + return instance; +} + +int ElasticCTRPredictorApi::add_slot(ReqInstance *instance, + const std::string slot_name, + int64_t value) { + ThreadResource *thread_resource = + reinterpret_cast(pthread_getspecific(tls_bspec_key_)); + if (thread_resource == NULL) { + if (thread_resource == NULL) { + LOG(ERROR) << "ERROR: thread local resource is null"; + return -1; + } + } + + if (slot_names_.find(slot_name) == slot_names_.end()) { + LOG(ERROR) << "Slot name not match with those in slot.conf: " + << slot_name.c_str(); + return -1; + } + + return thread_resource->add_slot(instance, slot_name, value); +} + +void ElasticCTRPredictorApi::validate_request() { + ThreadResource *thread_resource = + reinterpret_cast(pthread_getspecific(tls_bspec_key_)); + if (thread_resource == NULL) { + if (thread_resource == NULL) { + LOG(ERROR) << "ERROR: thread local resource is null"; + return; + } + } + + thread_resource->validate_request(slot_names_); +} + +int ElasticCTRPredictorApi::inference( + std::vector> &results_vec) { + ThreadResource *thread_resource = + reinterpret_cast(pthread_getspecific(tls_bspec_key_)); + if (thread_resource == NULL) { + if (thread_resource == NULL) { + LOG(ERROR) << "ERROR: thread local resource is null"; + return -1; + } + } + + Predictor *predictor = api_.fetch_predictor("ctr_prediction_service"); + if (!predictor) { + LOG(ERROR) << "Failed fetch predictor: ctr_prediction_service"; + return -1; + } + + validate_request(); + + int ret = predictor->inference(thread_resource->get_request(), + thread_resource->get_response()); + if (ret != 0) { + LOG(ERROR) << "Failed call predictor with req " + << thread_resource->get_request()->ShortDebugString(); + return ret; + } + + Response *response = thread_resource->get_response(); + + for (int i = 0; i < response->predictions_size(); ++i) { + const ResInstance &res_instance = response->predictions(i); + std::vector res; + res.push_back(res_instance.prob0()); + res.push_back(res_instance.prob1()); + results_vec.push_back(res); + } + + return 0; +} + +} // namespace elastic_ctr +} // namespace paddle_serving +} // namespace baidu diff --git a/elastic-ctr/client/api/elastic_ctr_api.h b/elastic-ctr/client/api/elastic_ctr_api.h new file mode 100644 index 0000000000000000000000000000000000000000..d2bfabe7b1380647b3137398f0ac572271dbc8a3 --- /dev/null +++ b/elastic-ctr/client/api/elastic_ctr_api.h @@ -0,0 +1,108 @@ +// 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. + +#pragma once + +#define BRPC_WITH_GLOG 1 // To make sure prpoer glog inclusion + +#include +#include +#include +#include +#include "elastic-ctr/client/elastic_ctr_prediction.pb.h" +#include "sdk-cpp/include/predictor_sdk.h" + +using baidu::paddle_serving::sdk_cpp::Predictor; +using baidu::paddle_serving::sdk_cpp::PredictorApi; +using baidu::paddle_serving::predictor::elastic_ctr::Slot; +using baidu::paddle_serving::predictor::elastic_ctr::Request; +using baidu::paddle_serving::predictor::elastic_ctr::ReqInstance; +using baidu::paddle_serving::predictor::elastic_ctr::Response; +using baidu::paddle_serving::predictor::elastic_ctr::ResInstance; + +namespace baidu { +namespace paddle_serving { +namespace elastic_ctr { + +struct InstanceInfo { + std::map slot_map_; +}; + +class ThreadResource { + public: + int clear(); + + Request *get_request() { return &request_; } + + Response *get_response() { return &response_; } + + ReqInstance *add_instance(); + int add_slot(ReqInstance *instance, + const std::string &slot_name, + uint64_t value); + void validate_request(const std::set &slot_names); + + private: + Request request_; + Response response_; + + std::map instance_map_; +}; + +struct Prediction { + float prob0; + float prob1; +}; + +class ElasticCTRPredictorApi { + public: + ElasticCTRPredictorApi() {} + + int init(const char *path, + const char *slot_conf_file, + const char *serving_conf_file); + + int thrd_initialize(); + + int thrd_clear(); + + int thrd_finalize(); + + void destroy(); + + static ElasticCTRPredictorApi &instance() { + static ElasticCTRPredictorApi api; + return api; + } + + public: + ReqInstance *add_instance(); + int add_slot(ReqInstance *instance, + const std::string slot_name, + int64_t value); + int inference(std::vector> &results_vec); // NOLINT + + private: + static int read_slot_conf(const char *path, const char *slot_conf_file); + void validate_request(); + + private: + PredictorApi api_; + pthread_key_t tls_bspec_key_; + static std::set slot_names_; +}; + +} // namespace elastic_ctr +} // namespace paddle_serving +} // namespace baidu diff --git a/elastic-ctr/client/api/python/elasticctr/elastic_ctr_api.py b/elastic-ctr/client/api/python/elasticctr/elastic_ctr_api.py new file mode 100644 index 0000000000000000000000000000000000000000..b9ef7ef402bcb5dc92d1a6f21ec875e6ef85c8d7 --- /dev/null +++ b/elastic-ctr/client/api/python/elasticctr/elastic_ctr_api.py @@ -0,0 +1,98 @@ +# 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. + +from __future__ import print_function +import json +import sys +import os + +if sys.version_info[0] == 2: + import httplib +elif sys.version_info[0] == 3: + import http.client + + +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): + if sys.version_info[0] == 2: + return httplib.HTTPConnection(ip, port) + elif sys.version_info[0] == 3: + return http.client.HTTPConnection(ip, port) + + def add_instance(self): + feature_slots = [] + instance = [{"slots": feature_slots}] + self._instances += instance + return instance + + def clear(self): + self._instances = [] + + 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) + + if sys.version_info[0] == 2: + 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) + elif sys.version_info[0] == 3: + try: + self._conn.request( + 'POST', "/ElasticCTRPredictionService/inference", + request_json, {"Content-Type": "application/json"}) + response = self._conn.getresponse() + return response.read() + except http.clinet.HTTPException as e: + print(e.reason) diff --git a/elastic-ctr/client/demo/conf/predictors.prototxt b/elastic-ctr/client/demo/conf/predictors.prototxt new file mode 100644 index 0000000000000000000000000000000000000000..61c304ccb7019ba94436f1b882fc945a18b5f367 --- /dev/null +++ b/elastic-ctr/client/demo/conf/predictors.prototxt @@ -0,0 +1,36 @@ +default_variant_conf { + tag: "default" + connection_conf { + connect_timeout_ms: 2000 + rpc_timeout_ms: 20000 + connect_retry_count: 2 + max_connection_per_host: 100 + hedge_request_timeout_ms: -1 + hedge_fetch_retry_count: 2 + connection_type: "pooled" + } + naming_conf { + cluster_filter_strategy: "Default" + load_balance_strategy: "la" + } + rpc_parameter { + compress_type: 0 + package_size: 20 + protocol: "baidu_std" + max_channel_per_request: 3 + } +} +predictors { + name: "ctr_prediction_service" + service_name: "baidu.paddle_serving.predictor.elastic_ctr.ElasticCTRPredictionService" + endpoint_router: "WeightedRandomRender" + weighted_random_render_conf { + variant_weight_list: "50" + } + variants { + tag: "var1" + naming_conf { + cluster: "list://127.0.0.1:8010" + } + } +} diff --git a/elastic-ctr/client/demo/conf/slot.conf b/elastic-ctr/client/demo/conf/slot.conf new file mode 100644 index 0000000000000000000000000000000000000000..53d92ae6580e5d5b330fa410c25f8e1acf5c83c3 --- /dev/null +++ b/elastic-ctr/client/demo/conf/slot.conf @@ -0,0 +1,27 @@ +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 diff --git a/elastic-ctr/client/demo/data/ctr_prediction/data.txt b/elastic-ctr/client/demo/data/ctr_prediction/data.txt new file mode 100644 index 0000000000000000000000000000000000000000..004f613ee823790f7ad3ec544dd515480f093afe --- /dev/null +++ b/elastic-ctr/client/demo/data/ctr_prediction/data.txt @@ -0,0 +1,100 @@ +1 0 6927017134761466251:0 6718470718629228516:1 13269072425766530826:2 4716523811429044439:3 13082382022140897056:4 15218982276382079900:5 11163313789190369446:6 2862867910291820749:7 11053760986033849339:8 10502870772583566854:9 2124556436191220259:10 9785506636498967227:11 11192516382072790924:12 8807115620238838348:13 17995078462363758872:14 10382497101983282355:15 16754133082265779776:16 304257334858494316:17 15720168260628638326:18 6674055552811657342:19 8243359970626135167:20 15787226800440587041:21 17241709254077376921:22 9596905073876765726:23 2790018448824600319:24 3613283134603402626:25 6397718522477982172:26 +1 0 10464417414901951369:0 6718470718629228516:1 9179429492816205016:2 13676622477856975702:3 3286191063564561647:4 15218982276382079900:5 12219910503415112001:6 5844921059192075884:7 16705280652459417397:8 10502870772583566854:9 13175866100369809054:10 9263190458225192516:11 4266371886186239285:12 11945162612181776727:13 17063534181803794493:14 4354228603469696964:15 12148918327299807724:16 7214965342802508003:17 673372825355324337:18 6674055552811657342:19 17448608490400648307:20 3349135020277955702:21 17241709254077376921:22 9596905073876765726:23 11768418306406963895:24 3613283134603402626:25 18046364706790889106:26 +1 0 18259870924294394882:0 7926934355403741575:1 1778885384708968565:2 10047289093984926440:3 8904989556311027751:4 15218982276382079900:5 11163313789190369446:6 15481040064803050827:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 2024160023045377795:11 10053031071814030523:12 15703750054742521685:13 14643263989734319679:14 9919260370661433660:15 15203515116826900154:16 5923634413866883174:17 16749168151358928664:18 17241709254077376921:19 17241709254077376921:20 14140506767829083971:21 5666677101597231609:22 9596905073876765726:23 3767297468498765274:24 +1 0 17241709254077376921:0 6718470718629228516:1 6907281343774280101:2 11759673712270006187:3 4118309569338760275:4 15218982276382079900:5 12219910503415112001:6 16943826576216803194:7 16705280652459417397:8 10502870772583566854:9 13713908212120537905:10 700492901176585495:11 6059397185486721393:12 888592242675254215:13 14643263989734319679:14 9661584506590972764:15 18205506194066348403:16 11455583154613207504:17 14802349586823085503:18 17241709254077376921:19 17241709254077376921:20 13531621461153817732:21 17241709254077376921:22 9596905073876765726:23 2496960796842971748:24 +1 0 7148434200721666028:0 17433040772822544485:1 1107762186306793885:2 18163012018653214493:3 15294713434719486333:4 15218982276382079900:5 9630582567144824550:6 15183274508769830484:7 16705280652459417397:8 10502870772583566854:9 1223989198202660467:10 13016347094912498810:11 1501638003805635312:12 15368041789475197909:13 17995078462363758872:14 18389378052457170731:15 16201993636138692864:16 11455583154613207504:17 4186049538830404914:18 17241709254077376921:19 17241709254077376921:20 10946611799884353646:21 17241709254077376921:22 11162666878533603762:23 9008292542607610184:24 +1 0 17241709254077376921:0 132683728328325035:1 9878834515792997342:2 11380942336101970490:3 1783733297169330482:4 14669113407484985090:5 16604931673559730414:6 1151521833841701280:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 11471538872319732880:11 6159851880783390255:12 8345868733258616845:13 14643263989734319679:14 9825544215843793104:15 11057739430758424260:16 6932058406762394060:17 5802476668582561065:18 17241709254077376921:19 17241709254077376921:20 2589136076946269828:21 15225822399263889742:22 10610591363390850070:23 17344032937842889734:24 +1 0 17241709254077376921:0 15209504892615885284:1 15700428036256333758:2 11861876803960528482:3 13982612809544027114:4 14669113407484985090:5 12219910503415112001:6 1917311332865131635:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 7557811442566408881:11 2660233397818919068:12 5883618680467675950:13 14643263989734319679:14 7618795044156816860:15 11907467542688733617:16 6932058406762394060:17 3017257153289738061:18 17241709254077376921:19 17241709254077376921:20 10288183625953528372:21 17241709254077376921:22 3737242667984714764:23 3441016006405463335:24 +1 1 7148434200721666028:0 6718470718629228516:1 6907281343774280101:2 3053743611132167362:3 14555014367769717036:4 6609445196442839881:5 9630582567144824550:6 12824208005498741289:7 11053760986033849339:8 10502870772583566854:9 6597088772170499071:10 7856412937977050057:11 1891095274901020120:12 12618002768285189399:13 14643263989734319679:14 9661584506590972764:15 17855570972874293332:16 304257334858494316:17 14802349586823085503:18 17241709254077376921:19 17241709254077376921:20 12806982889865979921:21 17241709254077376921:22 11162666878533603762:23 2496960796842971748:24 +1 0 12485775574321252452:0 132683728328325035:1 16661495110910303502:2 3074368415590455844:3 8904989556311027751:4 15218982276382079900:5 11163313789190369446:6 11923057388420984245:7 16705280652459417397:8 10502870772583566854:9 7171076840194666165:10 2094933755936510892:11 5461414925766068262:12 3465889447608886364:13 17063534181803794493:14 18271887029749773133:15 1101066663604879927:16 304257334858494316:17 11361347596796230131:18 17241709254077376921:19 17241709254077376921:20 16228061434981101242:21 17241709254077376921:22 11162666878533603762:23 3767297468498765274:24 +1 0 13237225503670494420:0 132683728328325035:1 12379855725162006335:2 6074644261212226397:3 4596341914073759138:4 15218982276382079900:5 17241709254077376921:6 7497940997956148496:7 16705280652459417397:8 10502870772583566854:9 3021779155663915969:10 700492901176585495:11 4298977842768597523:12 888592242675254215:13 14643263989734319679:14 16023222668447088896:15 3371375212725266231:16 1187841073466173462:17 11941593174888892430:18 17241709254077376921:19 17241709254077376921:20 11692050119657422863:21 17241709254077376921:22 11162666878533603762:23 8839615097223058291:24 +1 0 6927017134761466251:0 132683728328325035:1 10347279397112858233:2 14839005752061317576:3 11643462142079559806:4 15218982276382079900:5 11163313789190369446:6 9915797641434557402:7 16705280652459417397:8 5275575326790214142:9 9116963774439914137:10 2489870094069298004:11 16691266054645198741:12 11385501165283893086:13 17063534181803794493:14 12702100553493906816:15 9868549944644069825:16 6932058406762394060:17 7176777661971465827:18 6674055552811657342:19 17448608490400648307:20 16671638717570212599:21 17241709254077376921:22 9596905073876765726:23 8654884481043531114:24 9026989529823845647:25 15841982015093426084:26 +1 0 1310192797669293303:0 132683728328325035:1 4525871349710877017:2 17241709254077376921:3 17241709254077376921:4 7239340616520487435:5 17241709254077376921:6 3679002119163610755:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 11218057536677162506:11 17241709254077376921:12 16350770227650797371:13 14643263989734319679:14 7652545525870866588:15 17241709254077376921:16 1187841073466173462:17 3917691649488249040:18 17241709254077376921:19 17241709254077376921:20 17241709254077376921:21 17241709254077376921:22 11162666878533603762:23 +1 1 17241709254077376921:0 5886642295555720176:1 2302007180625858651:2 3522395746448527778:3 2805783828848712657:4 15218982276382079900:5 12219910503415112001:6 1268285911768541945:7 11053760986033849339:8 10502870772583566854:9 6143237717931161494:10 9637316102620415512:11 14196558684519731586:12 1225582077137166504:13 14643263989734319679:14 13112879913003496586:15 7545078501456903577:16 304257334858494316:17 16747724740464524161:18 17241709254077376921:19 17241709254077376921:20 347598151995767353:21 17241709254077376921:22 11162666878533603762:23 9008292542607610184:24 +1 1 7674613650421074157:0 7324272953288436219:1 11725014094608043127:2 8803639408734925858:3 1220362653046102507:4 15218982276382079900:5 17241709254077376921:6 3878571312485518757:7 1920186525784302087:8 10502870772583566854:9 11648837483459045015:10 16964067792457588528:11 11139776027905272755:12 10931274492845838224:13 17995078462363758872:14 2882784002226225948:15 10592424308493458658:16 7214965342802508003:17 6489109027974645363:18 14824971285521433284:19 13903136866082777265:20 6209214591281588946:21 17241709254077376921:22 11162666878533603762:23 3864802563280438997:24 16289510092137203187:25 1143328503493968665:26 +1 0 10464417414901951369:0 2725392301144350401:1 13269072425766530826:2 9340936592426343633:3 11607812542444855181:4 13061831759115026268:5 9630582567144824550:6 11684333772387618712:7 16705280652459417397:8 10502870772583566854:9 858103900590211222:10 2405475863815797309:11 10117123305461389642:12 1866649320189135820:13 17995078462363758872:14 18231693188453206193:15 7670149246223096137:16 12702162550489317753:17 3760431104103189667:18 6674055552811657342:19 8243359970626135167:20 5810191645665591538:21 17241709254077376921:22 11419070899087401463:23 11940139939806103414:24 3613283134603402626:25 11488888525484967944:26 +1 0 18421644133257438848:0 132683728328325035:1 15296625554996690440:2 6460096976460959722:3 5151100674755853378:4 7239340616520487435:5 11163313789190369446:6 16238191574805953955:7 118720139541262076:8 10502870772583566854:9 9116963774439914137:10 16457356537362114607:11 6318549872891452918:12 2269348080352524802:13 11725792966931771710:14 16598043686953869187:15 8523338795451265391:16 6932058406762394060:17 17303720831352440113:18 17241709254077376921:19 17241709254077376921:20 14407037351922272955:21 17241709254077376921:22 9596905073876765726:23 15777325756826686259:24 +1 1 6927017134761466251:0 6718470718629228516:1 13812071245874841815:2 8369163560705844602:3 801357380150787769:4 14669113407484985090:5 11163313789190369446:6 17793779049215302883:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 14718017702897407632:11 3209425260585266535:12 2492063417888556224:13 14643263989734319679:14 10966027886771057503:15 17295743869407193057:16 1187841073466173462:17 6734693422874215969:18 6674055552811657342:19 8243359970626135167:20 139482499327938777:21 17241709254077376921:22 11162666878533603762:23 8986115834532843425:24 1212354230547063649:25 11921475662408304750:26 +1 0 13237225503670494420:0 17433040772822544485:1 1249352555698790157:2 6598874905195514554:3 3851538550409232565:4 7239340616520487435:5 8545055878216481300:6 5396822049332454302:7 16705280652459417397:8 10502870772583566854:9 6363466516423560187:10 11742149585588302477:11 1472616606809977294:12 13262001584124104287:13 17063534181803794493:14 17386800219881813582:15 1184590423286429205:16 304257334858494316:17 11746042240980974055:18 17241709254077376921:19 17241709254077376921:20 13624892508265615348:21 5666677101597231609:22 11162666878533603762:23 11847417109351225181:24 +1 0 6927017134761466251:0 132683728328325035:1 9179429492816205016:2 12419927172070481052:3 16671678693872619409:4 17756465370064782659:5 8545055878216481300:6 2045728908485389207:7 4138847090351627078:8 10502870772583566854:9 624423715505587893:10 12718524099270024168:11 3882570943592267952:12 10781054518172359479:13 17995078462363758872:14 1390991494269790816:15 10983444501041401410:16 304257334858494316:17 673372825355324337:18 6674055552811657342:19 8243359970626135167:20 2189564446769495792:21 17241709254077376921:22 11162666878533603762:23 13220987151312695470:24 9026989529823845647:25 3034715851719530798:26 +1 0 2744517546871237796:0 556544228763852288:1 8481262454092976260:2 4285960921148380086:3 13539253269495735736:4 7239340616520487435:5 9630582567144824550:6 12592895141281845869:7 16705280652459417397:8 10502870772583566854:9 17613298579766747861:10 16294710391255798824:11 17119319932275946669:12 16099645876152503593:13 14989216248460247009:14 1669199932227554795:15 773390050937845162:16 304257334858494316:17 11636838557479375654:18 17241709254077376921:19 17241709254077376921:20 15199286621432794054:21 17241709254077376921:22 12431040719102188135:23 11285526042152906113:24 +1 1 1310192797669293303:0 15010597255987710479:1 2302007180625858651:2 1251912094623613011:3 8522350885443931925:4 15218982276382079900:5 11163313789190369446:6 2047382364755587755:7 991491529160202440:8 10502870772583566854:9 9116963774439914137:10 7146496797683784011:11 1624394027251615434:12 1468720105145813976:13 17995078462363758872:14 14610776272202945736:15 2051660839140268666:16 304257334858494316:17 8703513102941686805:18 17241709254077376921:19 17241709254077376921:20 16353039357050006708:21 17241709254077376921:22 11162666878533603762:23 1662435709620374852:24 +1 0 10464417414901951369:0 132683728328325035:1 7761720401600392176:2 18114723123959769805:3 13390725149381271337:4 15218982276382079900:5 11163313789190369446:6 15410654408295982340:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 11893228565340993044:11 16811862145746373167:12 15906580571062931567:13 14643263989734319679:14 17417746869860111491:15 6820615658552164193:16 1187841073466173462:17 11710860182646955307:18 5687057810081340784:19 13903136866082777265:20 16744507119825703441:21 17241709254077376921:22 11162666878533603762:23 14943488082984001954:24 3613283134603402626:25 7604332626579472805:26 +1 0 1310192797669293303:0 132683728328325035:1 2302007180625858651:2 10897719044254269746:3 5925846051782389161:4 15218982276382079900:5 8545055878216481300:6 13714358487444275641:7 991491529160202440:8 10502870772583566854:9 7778077206090334959:10 7388416915218585967:11 4591077158912775099:12 7506644265205420368:13 17063534181803794493:14 3705801579907156743:15 17085522217548379788:16 7214965342802508003:17 18154360331214990224:18 17241709254077376921:19 17241709254077376921:20 10963044268547670158:21 17241709254077376921:22 9596905073876765726:23 17414791962410575054:24 +1 0 4515155089025077856:0 132683728328325035:1 11405409102603512372:2 8251945709297840525:3 7543223253778120235:4 15218982276382079900:5 11163313789190369446:6 2246324634435112644:7 16705280652459417397:8 10502870772583566854:9 9377127350574299749:10 8139166123436103210:11 13689654574437186097:12 11294956118538932177:13 14643263989734319679:14 8919898324792675572:15 2378680629806545058:16 11455583154613207504:17 6931488981881357525:18 17241709254077376921:19 17241709254077376921:20 16169389805558479250:21 17241709254077376921:22 14895502180141653390:23 9380115577475751377:24 +1 0 17241709254077376921:0 2725392301144350401:1 10121931627885813714:2 3074368415590455844:3 8904989556311027751:4 15218982276382079900:5 11163313789190369446:6 17382075769804193277:7 16705280652459417397:8 10502870772583566854:9 12627544959104597769:10 1263308814507219723:11 5461414925766068262:12 3581508654345215642:13 14643263989734319679:14 9943212798300089479:15 1101066663604879927:16 1187841073466173462:17 12228204936486541205:18 17241709254077376921:19 17241709254077376921:20 16228061434981101242:21 14702504267520853429:22 9596905073876765726:23 3767297468498765274:24 +1 0 17241709254077376921:0 2725392301144350401:1 7761720401600392176:2 11564561306807028662:3 15613298054424122150:4 15218982276382079900:5 17241709254077376921:6 10574792713779585457:7 16705280652459417397:8 10502870772583566854:9 6835349046682511653:10 11450198402057045659:11 7939464828829647706:12 6249927819966478852:13 7830116631536757802:14 5291175334204734932:15 14168143301350297163:16 7214965342802508003:17 11710860182646955307:18 1904009232434063178:19 13903136866082777265:20 15218713873994451489:21 17241709254077376921:22 11162666878533603762:23 5075464188083089464:24 3613283134603402626:25 6420753415704873062:26 +1 1 12522305586339984642:0 17433040772822544485:1 11610205181468921922:2 12495413138988957243:3 14514583139797418816:4 15218982276382079900:5 11163313789190369446:6 1024676000316375047:7 11053760986033849339:8 10502870772583566854:9 16615750646632226979:10 8918896465005633300:11 9604668264211240048:12 10101989200715543075:13 14643263989734319679:14 3316745331177704448:15 13068263067076303846:16 11990012572963238042:17 10571811563118485420:18 6674055552811657342:19 13903136866082777265:20 5452194489244847065:21 17241709254077376921:22 11162666878533603762:23 8554804225766097854:24 13073481964273803881:25 3011175035015983684:26 +1 1 6927017134761466251:0 6718470718629228516:1 2302007180625858651:2 16646566645713148609:3 8842147488328088793:4 7239340616520487435:5 11163313789190369446:6 7308362630242429461:7 16705280652459417397:8 10502870772583566854:9 11981115407209600669:10 16019080599479355057:11 7534128559857757061:12 8524159296168860913:13 14643263989734319679:14 18318827611950119257:15 3926699863293873238:16 12702162550489317753:17 4145364840174650918:18 17241709254077376921:19 17241709254077376921:20 7049434558429390848:21 17241709254077376921:22 9596905073876765726:23 14035356172170531840:24 +1 1 17181926294437511708:0 6718470718629228516:1 5532134615375792653:2 5982899062617373488:3 8574179624883972242:4 7239340616520487435:5 16604931673559730414:6 9957622867904136669:7 16705280652459417397:8 10502870772583566854:9 7288041857773198145:10 12867563715192712027:11 15668081095363425709:12 15634626493901516249:13 17063534181803794493:14 6595409912005001338:15 16246751017073483244:16 304257334858494316:17 12114569828945163324:18 17241709254077376921:19 17241709254077376921:20 13214684022665073004:21 17241709254077376921:22 11162666878533603762:23 2836226778862690321:24 +1 1 2515344368701119404:0 132683728328325035:1 16022881555416999883:2 14905174545263472017:3 14514404294664920713:4 15218982276382079900:5 9630582567144824550:6 14473553880688237330:7 16705280652459417397:8 10502870772583566854:9 7909506806877050790:10 700492901176585495:11 3239561746203967292:12 888592242675254215:13 7830116631536757802:14 14437248923152261292:15 7346608955167379841:16 304257334858494316:17 13739989172691280302:18 17241709254077376921:19 17241709254077376921:20 7850582845043555360:21 17241709254077376921:22 9596905073876765726:23 14282093253411701637:24 +1 1 2744517546871237796:0 17433040772822544485:1 1325795336450945050:2 1273041429893930252:3 7496206612731460364:4 7239340616520487435:5 12219910503415112001:6 12331751569608134940:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 8033853962316844090:11 16745769382145216455:12 7876683170645847226:13 14643263989734319679:14 17376323974655968040:15 11742382316912349910:16 304257334858494316:17 11402365575022235878:18 17241709254077376921:19 17241709254077376921:20 13804780290152816225:21 17241709254077376921:22 9596905073876765726:23 12625173738661007962:24 +1 0 17241709254077376921:0 7324272953288436219:1 13638147752706036569:2 3074368415590455844:3 8904989556311027751:4 15218982276382079900:5 12219910503415112001:6 384139667903776154:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 16598510211540031812:11 5461414925766068262:12 5718563564474677932:13 10635807090093424908:14 3922542365398847669:15 1101066663604879927:16 6932058406762394060:17 523783748084120554:18 17241709254077376921:19 17241709254077376921:20 16228061434981101242:21 17241709254077376921:22 9516923928322464298:23 3767297468498765274:24 +1 0 17241709254077376921:0 132683728328325035:1 6959743776458474126:2 14424470049749894883:3 8005244996750823827:4 7239340616520487435:5 11163313789190369446:6 1024676000316375047:7 16705280652459417397:8 10502870772583566854:9 16881259423969557990:10 8918896465005633300:11 1061055799094912692:12 10101989200715543075:13 14643263989734319679:14 1383314317141920805:15 7793114640966478292:16 12702162550489317753:17 7209367094585708084:18 17241709254077376921:19 17241709254077376921:20 909388936747680086:21 17241709254077376921:22 11162666878533603762:23 16991424487007093566:24 +1 0 12485775574321252452:0 132683728328325035:1 7756736608808612461:2 11577167303561283088:3 11607812542444855181:4 15218982276382079900:5 17241709254077376921:6 15410654408295982340:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 5392140113819433218:11 6997068159145122057:12 15906580571062931567:13 17485091878519158637:14 9555789384938451448:15 7670149246223096137:16 6932058406762394060:17 11266289668075112357:18 6674055552811657342:19 13903136866082777265:20 10091184306909033270:21 17241709254077376921:22 11162666878533603762:23 11940139939806103414:24 3613283134603402626:25 4560520958389071443:26 +1 1 13237225503670494420:0 132683728328325035:1 7869373560102816254:2 10656729542438180977:3 16660288238169217524:4 15218982276382079900:5 17241709254077376921:6 7078992212226069630:7 16705280652459417397:8 10502870772583566854:9 2917400784138383462:10 13766608908513013628:11 4140848663537918691:12 3505527365334819935:13 17063534181803794493:14 80851017785285077:15 15531219999041518193:16 304257334858494316:17 10223771578267841980:18 17241709254077376921:19 17241709254077376921:20 379885792831848099:21 17241709254077376921:22 11162666878533603762:23 13507591849647755113:24 +1 1 2744517546871237796:0 132683728328325035:1 2568470288720291233:2 7194489148694036722:3 6604426708968873079:4 7239340616520487435:5 8545055878216481300:6 17690669239570722078:7 16705280652459417397:8 10502870772583566854:9 1317134747613085835:10 5129648633975577085:11 10615548322336250981:12 13288734802378361721:13 14643263989734319679:14 3666714016737623396:15 15553709248581595649:16 5923634413866883174:17 11252861524791023509:18 2539435020450717756:19 13903136866082777265:20 7627118189590369514:21 5666677101597231609:22 14895502180141653390:23 5075464188083089464:24 9545123730527789043:25 6420753415704873062:26 +1 0 17241709254077376921:0 16707040802038577899:1 16661495110910303502:2 5417495491599040800:3 3851538550409232565:4 15218982276382079900:5 11163313789190369446:6 10662314431050571660:7 11053760986033849339:8 10502870772583566854:9 9116963774439914137:10 8765734899149507447:11 10476933088170757261:12 9314838448007602968:13 17063534181803794493:14 12708386797627152534:15 1319185336447062834:16 6932058406762394060:17 1868988231257466985:18 17241709254077376921:19 17241709254077376921:20 1685454248563167127:21 17241709254077376921:22 11162666878533603762:23 11847417109351225181:24 +1 0 17241709254077376921:0 14155721711170412399:1 17142147528445973487:2 309337549254456223:3 15650484392488235370:4 15218982276382079900:5 8545055878216481300:6 311225110694346085:7 16705280652459417397:8 10502870772583566854:9 7512753248695961857:10 789011181240346650:11 4689488607513039466:12 14329525652244951778:13 17063534181803794493:14 3114316559132996799:15 3493914413622711205:16 304257334858494316:17 2685465578393107277:18 6674055552811657342:19 13903136866082777265:20 183903379593608337:21 14702504267520853429:22 9419421512119490042:23 15707147566107585215:24 1212354230547063649:25 16322571623044823521:26 +1 0 6080128442901703586:0 6718470718629228516:1 1325795336450945050:2 5081130028485875212:3 16183188853307284423:4 7239340616520487435:5 11163313789190369446:6 13588677844043420585:7 16705280652459417397:8 10502870772583566854:9 4653293388811748114:10 16372184753895583572:11 9970377938399320317:12 12474407437585636151:13 17995078462363758872:14 2154498555344425901:15 2514726800494388784:16 304257334858494316:17 13396841265939349009:18 17241709254077376921:19 17241709254077376921:20 2577543406825224159:21 17241709254077376921:22 11162666878533603762:23 12625173738661007962:24 +1 0 18421644133257438848:0 2725392301144350401:1 6974293052959110895:2 15433061552422749716:3 7645359936682228524:4 15218982276382079900:5 17241709254077376921:6 18010627938646841509:7 16705280652459417397:8 10502870772583566854:9 9325814154323450115:10 10732935658775168222:11 14218201933603660697:12 13820288385413778690:13 17995078462363758872:14 18000658703715585342:15 9346827588225243975:16 5923634413866883174:17 10580802880289134283:18 6674055552811657342:19 8243359970626135167:20 8081392395287237696:21 17241709254077376921:22 11162666878533603762:23 16132620102982681109:24 9545123730527789043:25 3253737704730139202:26 +1 0 10464417414901951369:0 132683728328325035:1 6959743776458474126:2 3074368415590455844:3 8904989556311027751:4 7239340616520487435:5 8545055878216481300:6 1024676000316375047:7 11053760986033849339:8 10502870772583566854:9 16615750646632226979:10 8918896465005633300:11 5461414925766068262:12 10101989200715543075:13 14643263989734319679:14 17679098502651198491:15 1101066663604879927:16 5923634413866883174:17 14978393120498354338:18 17241709254077376921:19 17241709254077376921:20 16228061434981101242:21 17241709254077376921:22 11162666878533603762:23 3767297468498765274:24 +1 1 10464417414901951369:0 132683728328325035:1 11405409102603512372:2 17521105332861035085:3 15696811749211935437:4 15218982276382079900:5 8545055878216481300:6 7995709161350464776:7 16705280652459417397:8 10502870772583566854:9 8972257840302114602:10 2277686576113039246:11 3581840317011793591:12 12204173254688087823:13 17063534181803794493:14 3454666637371315104:15 5755484633992816039:16 5923634413866883174:17 12442700095681125561:18 17241709254077376921:19 17241709254077376921:20 5235658467977583426:21 17241709254077376921:22 11162666878533603762:23 13216860939962807533:24 +1 0 7674613650421074157:0 132683728328325035:1 7761720401600392176:2 8469104618800065557:3 14648424205675448851:4 15218982276382079900:5 17241709254077376921:6 18162361451095511218:7 16705280652459417397:8 10502870772583566854:9 7859210876267311457:10 936474412636531367:11 172138924868194437:12 833956697717950326:13 17995078462363758872:14 8926080012733512439:15 883905295314056489:16 12702162550489317753:17 8117304531237350068:18 8819009507283715567:19 13903136866082777265:20 4574862061147892267:21 17241709254077376921:22 11162666878533603762:23 17414791962410575054:24 3613283134603402626:25 18333160135461364208:26 +1 0 17241709254077376921:0 2725392301144350401:1 2302007180625858651:2 11497197735685607883:3 14678136854556310063:4 15218982276382079900:5 11163313789190369446:6 4540976613599653853:7 991491529160202440:8 5275575326790214142:9 9116963774439914137:10 3559315722260084772:11 14845566131754782335:12 10695095974431628238:13 14643263989734319679:14 10593381915738125194:15 2901804296254959117:16 1187841073466173462:17 10783949422666782912:18 17241709254077376921:19 17241709254077376921:20 7157991049882411293:21 17241709254077376921:22 9596905073876765726:23 11177134726796456344:24 +1 0 17241709254077376921:0 132683728328325035:1 13638147752706036569:2 3074368415590455844:3 8904989556311027751:4 14669113407484985090:5 11163313789190369446:6 8556504194464356700:7 16705280652459417397:8 10502870772583566854:9 17834893318925711613:10 10314616971867983483:11 5461414925766068262:12 1172247109089069239:13 10635807090093424908:14 3922542365398847669:15 1101066663604879927:16 7214965342802508003:17 523783748084120554:18 17241709254077376921:19 17241709254077376921:20 16228061434981101242:21 14702504267520853429:22 9596905073876765726:23 3767297468498765274:24 +1 0 13237225503670494420:0 132683728328325035:1 16661495110910303502:2 1896203452519532245:3 3851538550409232565:4 15218982276382079900:5 11163313789190369446:6 12807306182975078013:7 991491529160202440:8 10502870772583566854:9 9116963774439914137:10 17245004084799800418:11 1357724897190789423:12 16928674665660501381:13 17063534181803794493:14 12708386797627152534:15 403578019026461591:16 12702162550489317753:17 1868988231257466985:18 17241709254077376921:19 17241709254077376921:20 12694187641533714018:21 17241709254077376921:22 11162666878533603762:23 11847417109351225181:24 +1 0 7885493856155582604:0 132683728328325035:1 10778118909304089744:2 3074368415590455844:3 8904989556311027751:4 7239340616520487435:5 11163313789190369446:6 14070589390653787841:7 6278115880124280497:8 10502870772583566854:9 9116963774439914137:10 16457356537362114607:11 5461414925766068262:12 2269348080352524802:13 17995078462363758872:14 2904196646018580026:15 1101066663604879927:16 304257334858494316:17 12412539170032122490:18 17241709254077376921:19 17241709254077376921:20 16228061434981101242:21 17241709254077376921:22 11162666878533603762:23 3767297468498765274:24 +1 0 2489716146917121730:0 132683728328325035:1 17142147528445973487:2 11731712469714370552:3 16068800663921896502:4 15218982276382079900:5 8545055878216481300:6 2721940599734264845:7 16705280652459417397:8 10502870772583566854:9 15569061900063125436:10 10128672630056248315:11 18196391687378076903:12 9397555878993963837:13 14643263989734319679:14 4207359405239731256:15 13930716292907012619:16 304257334858494316:17 2685465578393107277:18 13884179104666065155:19 13903136866082777265:20 10518581636251048878:21 15641088087303452745:22 2889020552648910850:23 15041414959391718373:24 1212354230547063649:25 13996985142559576937:26 +1 0 10464417414901951369:0 132683728328325035:1 2302007180625858651:2 14520649193439426780:3 15838390496681904262:4 15218982276382079900:5 12219910503415112001:6 1019471316359140639:7 11053760986033849339:8 10502870772583566854:9 16852185604723469529:10 11714595700715893218:11 2919821707309641602:12 6451082234801926718:13 17063534181803794493:14 6532587202758115977:15 7392598919204943076:16 304257334858494316:17 930413416427421657:18 17241709254077376921:19 17241709254077376921:20 254411386241374525:21 17241709254077376921:22 14895502180141653390:23 16019062971771971394:24 +1 0 17241709254077376921:0 6718470718629228516:1 15793601865269415752:2 4415549998256817150:3 13862888586835434227:4 15218982276382079900:5 17241709254077376921:6 3874040758317561930:7 16705280652459417397:8 10502870772583566854:9 16537231773771350523:10 16620497602680476516:11 14290328798218203616:12 299766009414260151:13 17063534181803794493:14 16254155403319323417:15 3033065783430161494:16 304257334858494316:17 5885659819938670107:18 17241709254077376921:19 17241709254077376921:20 7608683087502877813:21 17241709254077376921:22 11162666878533603762:23 4447435252162465088:24 +1 0 2104849252515447450:0 132683728328325035:1 2568470288720291233:2 9220353264788412283:3 11961315514967285277:4 1270111884358453186:5 11163313789190369446:6 12828435744279702426:7 6278115880124280497:8 10502870772583566854:9 9116963774439914137:10 7543252018161894567:11 2620322913300808617:12 14286354118342488235:13 17063534181803794493:14 2080111411455573937:15 17857733346223087027:16 5923634413866883174:17 11252861524791023509:18 7633813901422151913:19 13903136866082777265:20 13204446223212041104:21 17241709254077376921:22 9419421512119490042:23 5232670654339416318:24 9545123730527789043:25 13595181148984071975:26 +1 1 2744517546871237796:0 2725392301144350401:1 2302007180625858651:2 249368224523449598:3 16737671921008133548:4 15218982276382079900:5 8545055878216481300:6 6166217781917718354:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 11575803860721327984:11 6488483739913062335:12 14891795159246543839:13 14643263989734319679:14 3713619133079082266:15 12118325671211587077:16 1187841073466173462:17 4413643969382843884:18 17241709254077376921:19 17241709254077376921:20 17849614474163407466:21 5666677101597231609:22 9596905073876765726:23 12271817899803072298:24 +1 0 2744517546871237796:0 2556070921675172938:1 9831410514477038641:2 14409896190396645695:3 16435981311880596528:4 17756465370064782659:5 17241709254077376921:6 1418067059371300333:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 12402666635098576898:11 8779903365955772183:12 2701229318996507578:13 17995078462363758872:14 1880891991909007115:15 10785715091001021530:16 5923634413866883174:17 14211833462300942432:18 6674055552811657342:19 17448608490400648307:20 17197118316423679236:21 17241709254077376921:22 9516923928322464298:23 3767297468498765274:24 7968176428150426131:25 5909423592700275632:26 +1 0 2744517546871237796:0 132683728328325035:1 11725014094608043127:2 6726966574958754102:3 16458791879951329218:4 15218982276382079900:5 9630582567144824550:6 17293010697459386247:7 4138847090351627078:8 10502870772583566854:9 2665116241244973724:10 2977282149199928954:11 2961072396289871319:12 14698203746985923458:13 17063534181803794493:14 15130080775503074076:15 8017149473582916519:16 5923634413866883174:17 6489109027974645363:18 2621219481720594487:19 8243359970626135167:20 3837798764716463050:21 17241709254077376921:22 9596905073876765726:23 1353937445816974199:24 3613283134603402626:25 5819539240603206806:26 +1 0 1750302349509622455:0 1399035476613128213:1 17229753468900380177:2 7043770294042418930:3 10566002751857054807:4 15218982276382079900:5 11163313789190369446:6 5740590945386362916:7 991491529160202440:8 10502870772583566854:9 17091716463194279034:10 7886110891812946531:11 15659163698846131538:12 1992204986776921674:13 17995078462363758872:14 5846085299175120524:15 15544525090671103642:16 304257334858494316:17 12372331349497572863:18 17933444987208371535:19 13903136866082777265:20 11940518710504691557:21 17241709254077376921:22 2889020552648910850:23 16707091133635332751:24 15247174146344178271:25 9893080987624171859:26 +1 0 7148434200721666028:0 17433040772822544485:1 11725014094608043127:2 11620790130793768247:3 13143543288151247360:4 15218982276382079900:5 11163313789190369446:6 9242147045642447424:7 15351441355156184373:8 10502870772583566854:9 12509085737619438205:10 11194098499946258502:11 4164599856737299371:12 8147856953322073385:13 14643263989734319679:14 8715524256750344983:15 18244293659739398429:16 304257334858494316:17 6489109027974645363:18 10731979616508713592:19 17448608490400648307:20 4762820616795212702:21 17241709254077376921:22 14895502180141653390:23 17414791962410575054:24 3613283134603402626:25 7418222241202479616:26 +1 0 2744517546871237796:0 7324272953288436219:1 7761720401600392176:2 7616194583075143326:3 13656423230124312275:4 15218982276382079900:5 11163313789190369446:6 16893141893281011546:7 13022504441432371752:8 10502870772583566854:9 2665116241244973724:10 5502979128277945668:11 608927956349318034:12 7278718362455314919:13 14643263989734319679:14 17417746869860111491:15 14722425693660425498:16 5923634413866883174:17 11710860182646955307:18 6674055552811657342:19 13903136866082777265:20 12574198784123194788:21 17241709254077376921:22 9596905073876765726:23 5075464188083089464:24 4164242000176313026:25 6420753415704873062:26 +1 0 12485775574321252452:0 132683728328325035:1 14974255340142203411:2 13377067912027368632:3 716915617347112283:4 10169647874801131836:5 17241709254077376921:6 9171950032060297506:7 16705280652459417397:8 10502870772583566854:9 17676350714988466998:10 80880752506730415:11 10485267817975729682:12 16717872495103086821:13 17063534181803794493:14 5046868444379245870:15 4891860215039680349:16 7214965342802508003:17 1270486826908984041:18 14410197339552347946:19 8243359970626135167:20 4135348783020685250:21 17241709254077376921:22 11162666878533603762:23 15528981002398622203:24 11407693399809036763:25 9289715309199872261:26 +1 0 13237225503670494420:0 5323223840226363228:1 2466867873114963287:2 12508842808485958116:3 13294771143862183618:4 15218982276382079900:5 11163313789190369446:6 5758609254184218890:7 17800761078682202115:8 5275575326790214142:9 7028886165996453002:10 4783829069681126648:11 8627622133409266852:12 6352573541654064750:13 14643263989734319679:14 15151267823035334295:15 4063389965279697996:16 304257334858494316:17 11462684987225336497:18 6674055552811657342:19 8243359970626135167:20 7622620960530016907:21 17241709254077376921:22 9596905073876765726:23 10578268012249422077:24 1212354230547063649:25 9906784755286772302:26 +1 0 7674613650421074157:0 132683728328325035:1 18118575695108702441:2 17870723487728888346:3 6051353402763117205:4 15218982276382079900:5 11163313789190369446:6 2657982605007273743:7 16705280652459417397:8 10502870772583566854:9 801225010036599221:10 13389528138579273588:11 9444119813502811919:12 16584709323650129467:13 14643263989734319679:14 17699869981965015733:15 9689085085025960584:16 1187841073466173462:17 6143817112501550397:18 10981353452324818237:19 8243359970626135167:20 4306915228772435959:21 17241709254077376921:22 14895502180141653390:23 15365807293045474131:24 16289510092137203187:25 6215821982819220266:26 +1 0 17241709254077376921:0 2725392301144350401:1 11806389861194829656:2 10047289093984926440:3 8904989556311027751:4 15218982276382079900:5 8545055878216481300:6 2264132778128398737:7 991491529160202440:8 5275575326790214142:9 9116963774439914137:10 4066270391623260703:11 10053031071814030523:12 15706636664096529694:13 17063534181803794493:14 10112199529490531606:15 15203515116826900154:16 14420458785251292117:17 8426463912967849489:18 17241709254077376921:19 17241709254077376921:20 14140506767829083971:21 17241709254077376921:22 10610591363390850070:23 3767297468498765274:24 +1 0 17241709254077376921:0 6718470718629228516:1 11725014094608043127:2 7180501115911047871:3 50577678532249152:4 15218982276382079900:5 11163313789190369446:6 1297539762829889239:7 16705280652459417397:8 5275575326790214142:9 13696153240998294823:10 14315004402354702865:11 728623140706371361:12 15472813378402936260:13 14643263989734319679:14 8715524256750344983:15 11741677503292249699:16 12702162550489317753:17 6489109027974645363:18 6674055552811657342:19 17448608490400648307:20 10461271632826393502:21 17241709254077376921:22 14895502180141653390:23 11343452967512485516:24 9026989529823845647:25 18411746252820545969:26 +1 0 13502581747159608329:0 132683728328325035:1 17402298575104256725:2 1199794993295631561:3 16727454980856778451:4 7239340616520487435:5 11163313789190369446:6 11894650094606280030:7 5309180186429543442:8 10502870772583566854:9 9116963774439914137:10 13096552226142886957:11 14450942906612809792:12 1589578729598937869:13 17995078462363758872:14 14677332338842706407:15 9971292664384749376:16 304257334858494316:17 6442100751087523915:18 6674055552811657342:19 17448608490400648307:20 9526599691994542147:21 17241709254077376921:22 11162666878533603762:23 3044705928769459271:24 9026989529823845647:25 9758373975411238298:26 +1 1 7674613650421074157:0 132683728328325035:1 7761720401600392176:2 1292685001554764182:3 14796365443935494402:4 15218982276382079900:5 11163313789190369446:6 3456464600341375816:7 16705280652459417397:8 5275575326790214142:9 6352440304741952019:10 6661130404281083290:11 8107169145060874815:12 6440170955840433752:13 7830116631536757802:14 5291175334204734932:15 15442972206696868777:16 304257334858494316:17 11710860182646955307:18 9516923928322464298:19 17448608490400648307:20 8473700175986405275:21 17241709254077376921:22 9596905073876765726:23 5075464188083089464:24 3613283134603402626:25 3907931301678453009:26 +1 0 12485775574321252452:0 132683728328325035:1 1576968520803882157:2 17241709254077376921:3 17241709254077376921:4 15218982276382079900:5 9630582567144824550:6 9510110403709908673:7 4213013683184994876:8 10502870772583566854:9 14213800323646090430:10 11854946685387400574:11 17241709254077376921:12 2642876139876797206:13 14643263989734319679:14 7833066576263021265:15 17241709254077376921:16 1187841073466173462:17 11362728554186900248:18 17241709254077376921:19 17241709254077376921:20 17241709254077376921:21 17241709254077376921:22 9596905073876765726:23 +1 1 2744517546871237796:0 132683728328325035:1 14974255340142203411:2 5280162267361520113:3 10835326980553883460:4 15218982276382079900:5 9630582567144824550:6 14378129877604253715:7 7983294729707680427:8 10502870772583566854:9 17662846678829858094:10 3635099069814814390:11 1930175532629274928:12 10640210903656608664:13 14643263989734319679:14 4151041093059368577:15 15656625461489990278:16 304257334858494316:17 1270486826908984041:18 11947010392505993133:19 17448608490400648307:20 6870538487473709226:21 17241709254077376921:22 9596905073876765726:23 17414791962410575054:24 3613283134603402626:25 7178132097474487233:26 +1 0 17241709254077376921:0 6718470718629228516:1 13269072425766530826:2 1395163352158263842:3 14648424205675448851:4 15218982276382079900:5 11163313789190369446:6 5658718796175039254:7 16341758872098761751:8 10502870772583566854:9 9116963774439914137:10 8182142699941220847:11 7646715363715996367:12 4121498275813634865:13 17063534181803794493:14 5487039979342708444:15 506441678635694603:16 304257334858494316:17 11487055308647903360:18 6674055552811657342:19 17448608490400648307:20 2203634787932175703:21 17241709254077376921:22 11162666878533603762:23 17414791962410575054:24 3613283134603402626:25 7140162492810714387:26 +1 0 6927017134761466251:0 7324272953288436219:1 7756736608808612461:2 9071747527450988064:3 16847758086157631864:4 15218982276382079900:5 9630582567144824550:6 6937632795904720388:7 991491529160202440:8 10502870772583566854:9 9116963774439914137:10 4191138115126463527:11 6631179764405548968:12 10850130783794118172:13 14643263989734319679:14 12563625388453916341:15 14590181483463994230:16 6932058406762394060:17 11266289668075112357:18 6674055552811657342:19 8243359970626135167:20 15803635232853491676:21 17241709254077376921:22 11162666878533603762:23 14582518184021979285:24 3613283134603402626:25 15171962259945101721:26 +1 0 7674613650421074157:0 8307575886820000061:1 6832149244291977250:2 4828044233854946899:3 6231861218167722999:4 15218982276382079900:5 11163313789190369446:6 1164950462972037251:7 16705280652459417397:8 10502870772583566854:9 624423715505587893:10 12718524099270024168:11 16075274640427798475:12 10781054518172359479:13 14643263989734319679:14 502422259278661079:15 6389945652329230419:16 12702162550489317753:17 16082873749429812321:18 2831866874659088171:19 13903136866082777265:20 3641918716505547940:21 5666677101597231609:22 14895502180141653390:23 9449052154607698195:24 9026989529823845647:25 13137340396808512530:26 +1 0 16165765826633870759:0 132683728328325035:1 1778885384708968565:2 10047289093984926440:3 8904989556311027751:4 15218982276382079900:5 11163313789190369446:6 13618674763255378568:7 16705280652459417397:8 10502870772583566854:9 13641010552752080966:10 13771837509339570707:11 10053031071814030523:12 17578796369335553211:13 14643263989734319679:14 5967065745499582085:15 15203515116826900154:16 1187841073466173462:17 16962405167368546489:18 17241709254077376921:19 17241709254077376921:20 14140506767829083971:21 17241709254077376921:22 3737242667984714764:23 3767297468498765274:24 +1 0 2744517546871237796:0 17433040772822544485:1 2466867873114963287:2 4696662055267481940:3 6914357846170958885:4 17756465370064782659:5 12219910503415112001:6 1517397597806723283:7 991491529160202440:8 10502870772583566854:9 12685532390119019197:10 6118978426529077903:11 10188272821748722262:12 15060520146375100587:13 17063534181803794493:14 672067804737030601:15 16381144673291763394:16 304257334858494316:17 4457562282959834066:18 6674055552811657342:19 13903136866082777265:20 18317918161877220099:21 17241709254077376921:22 11162666878533603762:23 15415232719988304698:24 1212354230547063649:25 12437855719361950508:26 +1 0 10464417414901951369:0 132683728328325035:1 2568470288720291233:2 7353149597890168493:3 3415974251850056442:4 14669113407484985090:5 11163313789190369446:6 16928786756096626718:7 15468584758257870698:8 10502870772583566854:9 18351367845515181951:10 13161858962265644485:11 1026205338118059637:12 2114436741547958504:13 17995078462363758872:14 13588026454452555230:15 10152652251931920111:16 1187841073466173462:17 11252861524791023509:18 7034290778595812200:19 13903136866082777265:20 8400999747568180310:21 17241709254077376921:22 9419421512119490042:23 6027051460244190386:24 3613283134603402626:25 12018654587113426299:26 +1 1 13237225503670494420:0 132683728328325035:1 5932022704695318284:2 15338726294620142906:3 7008849814068303796:4 1270111884358453186:5 12219910503415112001:6 3364076609796475041:7 991491529160202440:8 10502870772583566854:9 4645044546999593874:10 16112702416248776197:11 16949756502384858239:12 12027372293967910024:13 17063534181803794493:14 3502613326304026218:15 15387726488145974818:16 304257334858494316:17 5307420297479553628:18 17241709254077376921:19 17241709254077376921:20 10992697529523616075:21 5666677101597231609:22 9596905073876765726:23 45394345549210920:24 +1 0 6927017134761466251:0 6718470718629228516:1 11725014094608043127:2 7761350506110750551:3 13869542625789249208:4 17756465370064782659:5 9630582567144824550:6 6879105878256856368:7 15351441355156184373:8 10502870772583566854:9 3707395226754083209:10 3015442190685524539:11 13283098451516033670:12 3580010520686773783:13 17063534181803794493:14 15130080775503074076:15 4102433882877379022:16 12702162550489317753:17 6489109027974645363:18 6522591285950556830:19 17448608490400648307:20 11677689939317426763:21 17241709254077376921:22 11162666878533603762:23 16905424653322530816:24 9026989529823845647:25 11938823204540837359:26 +1 0 17241709254077376921:0 17433040772822544485:1 13638147752706036569:2 3074368415590455844:3 8904989556311027751:4 15218982276382079900:5 8545055878216481300:6 12666300008347941267:7 16705280652459417397:8 5275575326790214142:9 6004785798427717350:10 9529269963964830945:11 5461414925766068262:12 7896428522860688413:13 10635807090093424908:14 3922542365398847669:15 1101066663604879927:16 7214965342802508003:17 523783748084120554:18 17241709254077376921:19 17241709254077376921:20 16228061434981101242:21 17241709254077376921:22 9596905073876765726:23 3767297468498765274:24 +1 1 2744517546871237796:0 132683728328325035:1 9179429492816205016:2 13676622477856975702:3 3286191063564561647:4 15218982276382079900:5 17241709254077376921:6 8271641783481038513:7 16705280652459417397:8 10502870772583566854:9 11504631205878159170:10 10905155235958484624:11 4266371886186239285:12 18211955286933215227:13 17063534181803794493:14 4354228603469696964:15 12148918327299807724:16 7214965342802508003:17 673372825355324337:18 6674055552811657342:19 17448608490400648307:20 3349135020277955702:21 17241709254077376921:22 11162666878533603762:23 11768418306406963895:24 9026989529823845647:25 18046364706790889106:26 +1 0 6927017134761466251:0 1399035476613128213:1 2302007180625858651:2 17241709254077376921:3 17241709254077376921:4 15218982276382079900:5 11163313789190369446:6 17628281450774980356:7 118720139541262076:8 5275575326790214142:9 9116963774439914137:10 15286906736036235427:11 17241709254077376921:12 12474407437585636151:13 14643263989734319679:14 13411286546173046030:15 17241709254077376921:16 14420458785251292117:17 3564255790878271039:18 17241709254077376921:19 17241709254077376921:20 17241709254077376921:21 5666677101597231609:22 11162666878533603762:23 +1 0 1750302349509622455:0 556544228763852288:1 2302007180625858651:2 5222147763739822057:3 11160309835392871911:4 14669113407484985090:5 8545055878216481300:6 158843167301945739:7 16705280652459417397:8 10502870772583566854:9 13820913050860618742:10 15890621597037366531:11 7540237752362850982:12 15835536966732180213:13 17063534181803794493:14 12262937348670547054:15 13470973610771554304:16 5923634413866883174:17 11942720253262047320:18 17241709254077376921:19 17241709254077376921:20 13273297550853785901:21 17241709254077376921:22 11162666878533603762:23 8239366509781549266:24 +1 1 16720874773084141888:0 132683728328325035:1 11610205181468921922:2 14815259582660166791:3 7741748769461086:4 7239340616520487435:5 11163313789190369446:6 1024676000316375047:7 16705280652459417397:8 10502870772583566854:9 16615750646632226979:10 8918896465005633300:11 15711120967935245452:12 10101989200715543075:13 17995078462363758872:14 14901153342134929630:15 7651583244965785325:16 5923634413866883174:17 10571811563118485420:18 7107665592721051702:19 13903136866082777265:20 6953765994808807944:21 17241709254077376921:22 9419421512119490042:23 5075464188083089464:24 13073481964273803881:25 6420753415704873062:26 +1 0 7919287270473417401:0 132683728328325035:1 6907281343774280101:2 14597193782547881073:3 16594469583671977279:4 15218982276382079900:5 17241709254077376921:6 13829687067688901029:7 991491529160202440:8 10502870772583566854:9 2874105284374992107:10 14025102470145611417:11 15971037547368253528:12 12209057626933818569:13 17063534181803794493:14 6383130323232768411:15 17782866767648588701:16 304257334858494316:17 6547881841675310326:18 17241709254077376921:19 17241709254077376921:20 8135927885760076416:21 17241709254077376921:22 11162666878533603762:23 2496960796842971748:24 +1 0 17241709254077376921:0 132683728328325035:1 13638147752706036569:2 3074368415590455844:3 8904989556311027751:4 17756465370064782659:5 12219910503415112001:6 18102164505069627973:7 118720139541262076:8 10502870772583566854:9 9116963774439914137:10 3545838982158047583:11 5461414925766068262:12 5020602360612712927:13 10635807090093424908:14 3922542365398847669:15 1101066663604879927:16 11455583154613207504:17 523783748084120554:18 17241709254077376921:19 17241709254077376921:20 16228061434981101242:21 17241709254077376921:22 9596905073876765726:23 3767297468498765274:24 +1 0 13237225503670494420:0 6718470718629228516:1 1107762186306793885:2 10272705063907639836:3 15294713434719486333:4 7239340616520487435:5 8545055878216481300:6 2525361608634214349:7 16705280652459417397:8 10502870772583566854:9 7668041901685895197:10 14711812896288403100:11 13727223093358058013:12 14541195072869641051:13 10635807090093424908:14 2312215631457552335:15 15975511992187702157:16 1187841073466173462:17 14430508837400541970:18 17241709254077376921:19 17241709254077376921:20 12089347766744514758:21 17241709254077376921:22 9516923928322464298:23 9008292542607610184:24 +1 0 7257727411320405062:0 2725392301144350401:1 17142147528445973487:2 16106155864716345900:3 3107479524066090589:4 15218982276382079900:5 11163313789190369446:6 13402960549627629483:7 16705280652459417397:8 10502870772583566854:9 7540202334272243846:10 10725535261626137590:11 18088433734111540314:12 17128735678207281795:13 10635807090093424908:14 16673262170570482650:15 16045358100534419239:16 304257334858494316:17 12990093021150865413:18 15764142131713189694:19 17448608490400648307:20 2654336549919000075:21 5666677101597231609:22 11162666878533603762:23 16974399985483225991:24 1212354230547063649:25 6316577074117164822:26 +1 0 10464417414901951369:0 132683728328325035:1 18118575695108702441:2 1956175051945281541:3 5033632780235688047:4 7239340616520487435:5 11163313789190369446:6 1097546976239385393:7 4138847090351627078:8 10502870772583566854:9 5086843973960666202:10 4850247641092899286:11 10225428296035378596:12 11699327217983376859:13 17995078462363758872:14 733372832589336138:15 11997318947514300189:16 11990012572963238042:17 6143817112501550397:18 6674055552811657342:19 13903136866082777265:20 5195076967538993364:21 17241709254077376921:22 2889020552648910850:23 11311118934595296456:24 16289510092137203187:25 13723928875114193756:26 +1 0 17241709254077376921:0 132683728328325035:1 7761720401600392176:2 15806312004458499178:3 3833211328834912524:4 14669113407484985090:5 8545055878216481300:6 5780088464155013567:7 11053760986033849339:8 10502870772583566854:9 13463820798879422386:10 7214577557421996743:11 3713811935587769057:12 8598220869698531116:13 14643263989734319679:14 17417746869860111491:15 10671158401465245444:16 12702162550489317753:17 11710860182646955307:18 8807673727521545548:19 13903136866082777265:20 10652030633986194442:21 17241709254077376921:22 11162666878533603762:23 17796640343097536367:24 13073481964273803881:25 14408626082386998136:26 +1 0 5424679272531918615:0 132683728328325035:1 2466867873114963287:2 4909779727030499274:3 7825834245353241169:4 15218982276382079900:5 16604931673559730414:6 2090573799971559719:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 14718017702897407632:11 15564585302896094665:12 2492063417888556224:13 14643263989734319679:14 15151267823035334295:15 2476910834974969203:16 304257334858494316:17 11462684987225336497:18 6674055552811657342:19 8243359970626135167:20 12443816753509496829:21 17241709254077376921:22 11162666878533603762:23 12296019248434685433:24 1212354230547063649:25 14516232280245646272:26 +1 1 7148434200721666028:0 132683728328325035:1 7761720401600392176:2 6478641606093460331:3 13354423438281543465:4 15218982276382079900:5 11163313789190369446:6 8745984515037464789:7 991491529160202440:8 10502870772583566854:9 10132068100858439007:10 6661130404281083290:11 6614533895548380348:12 6440170955840433752:13 14643263989734319679:14 17417746869860111491:15 16668761583331094378:16 304257334858494316:17 11710860182646955307:18 4125162040286893714:19 13903136866082777265:20 2610767721428036499:21 17241709254077376921:22 9596905073876765726:23 5075464188083089464:24 3613283134603402626:25 6420753415704873062:26 +1 1 2744517546871237796:0 132683728328325035:1 10198864999521895765:2 14283694510759628225:3 2475795949097338748:4 15218982276382079900:5 17241709254077376921:6 8182508895590474658:7 11053760986033849339:8 10502870772583566854:9 1703925832953300463:10 7784648955879333569:11 15859859550692373464:12 9957688304180513910:13 14643263989734319679:14 16208220921135040219:15 12721390130629769734:16 11455583154613207504:17 1546438911232186867:18 17241709254077376921:19 17241709254077376921:20 1022042687804050137:21 17241709254077376921:22 11162666878533603762:23 3119876655139837962:24 +1 0 17181926294437511708:0 7324272953288436219:1 2302007180625858651:2 17241709254077376921:3 17241709254077376921:4 15218982276382079900:5 17241709254077376921:6 7815158906760658264:7 16705280652459417397:8 10502870772583566854:9 12135733045742782117:10 10172095931249584156:11 17241709254077376921:12 6750732004941059120:13 14643263989734319679:14 10773596562833364693:15 17241709254077376921:16 304257334858494316:17 4986364358089708342:18 17241709254077376921:19 17241709254077376921:20 17241709254077376921:21 17241709254077376921:22 11162666878533603762:23 +1 0 1884361412985708340:0 1399035476613128213:1 7761720401600392176:2 8469104618800065557:3 14648424205675448851:4 7239340616520487435:5 17241709254077376921:6 16447247161022698326:7 991491529160202440:8 10502870772583566854:9 3041898498511578252:10 9023709591144843013:11 172138924868194437:12 15415852953478515155:13 10635807090093424908:14 16268454291327340268:15 883905295314056489:16 7214965342802508003:17 8117304531237350068:18 8819009507283715567:19 17448608490400648307:20 4574862061147892267:21 17241709254077376921:22 11162666878533603762:23 17414791962410575054:24 3613283134603402626:25 18333160135461364208:26 +1 1 5841576283076759122:0 6718470718629228516:1 13736117138133016446:2 1529185287032455422:3 10289645275367710598:4 15218982276382079900:5 12219910503415112001:6 476551412373857478:7 16705280652459417397:8 10502870772583566854:9 7709944093920699848:10 6625192222420878491:11 8367636140724141923:12 2576394315108315074:13 14643263989734319679:14 4847192240487161615:15 11752122932856338617:16 304257334858494316:17 15841159443225760662:18 1450301568544842084:19 17448608490400648307:20 3310681076380009974:21 17241709254077376921:22 14895502180141653390:23 16227083810990001366:24 1212354230547063649:25 6046005918922891339:26 +1 0 17241709254077376921:0 6718470718629228516:1 13638147752706036569:2 3074368415590455844:3 8904989556311027751:4 15218982276382079900:5 12219910503415112001:6 14114057567039215395:7 16705280652459417397:8 10502870772583566854:9 16041267730365020418:10 13215171499502271015:11 5461414925766068262:12 16759783342728243176:13 17995078462363758872:14 15896137188699604196:15 1101066663604879927:16 5923634413866883174:17 13293834139238633019:18 17241709254077376921:19 17241709254077376921:20 16228061434981101242:21 17241709254077376921:22 2889020552648910850:23 3767297468498765274:24 +1 0 17241709254077376921:0 132683728328325035:1 13638147752706036569:2 3074368415590455844:3 8904989556311027751:4 14669113407484985090:5 11163313789190369446:6 12591978802007535941:7 16705280652459417397:8 5275575326790214142:9 13771838652852816030:10 8885450730259554296:11 5461414925766068262:12 15118869621319575296:13 10635807090093424908:14 3922542365398847669:15 1101066663604879927:16 304257334858494316:17 523783748084120554:18 17241709254077376921:19 17241709254077376921:20 16228061434981101242:21 14702504267520853429:22 9596905073876765726:23 3767297468498765274:24 +1 0 2489716146917121730:0 132683728328325035:1 12875455536576904474:2 12861242875098225016:3 5455576107295117382:4 15218982276382079900:5 11163313789190369446:6 13498795872817025468:7 16705280652459417397:8 10502870772583566854:9 4416853476367033701:10 17256037306092196196:11 1551193749783651897:12 16821634134493805625:13 14643263989734319679:14 1565199297719275733:15 6489730728852370287:16 304257334858494316:17 6702151720359481043:18 6674055552811657342:19 17448608490400648307:20 5381079020795095159:21 17241709254077376921:22 11162666878533603762:23 2407064251793561829:24 4164242000176313026:25 18352595854979698789:26 +1 0 17241709254077376921:0 132683728328325035:1 13269072425766530826:2 8469104618800065557:3 14648424205675448851:4 14669113407484985090:5 8545055878216481300:6 10446853368944622849:7 16705280652459417397:8 10502870772583566854:9 9116963774439914137:10 14153401105953999066:11 172138924868194437:12 6020000510654702509:13 17995078462363758872:14 9391627788929346347:15 883905295314056489:16 7214965342802508003:17 11487055308647903360:18 6674055552811657342:19 17448608490400648307:20 4574862061147892267:21 17241709254077376921:22 9596905073876765726:23 17414791962410575054:24 3613283134603402626:25 7953251115798210533:26 +1 0 13237225503670494420:0 132683728328325035:1 2302007180625858651:2 12427473243524142178:3 3789112372305922230:4 7239340616520487435:5 11163313789190369446:6 3075631905248506434:7 991491529160202440:8 5275575326790214142:9 2325886750190784890:10 3557854724473529018:11 17920882885284333207:12 10123798490811782077:13 17995078462363758872:14 11153225875822172166:15 4852996870923404678:16 7214965342802508003:17 10783949422666782912:18 17241709254077376921:19 17241709254077376921:20 17321253496113904093:21 17241709254077376921:22 2889020552648910850:23 2078387580204111440:24 +1 0 7674613650421074157:0 132683728328325035:1 15330267725134755020:2 9452782523589518213:3 1725984468018631238:4 15218982276382079900:5 11163313789190369446:6 7207525335161733398:7 11053760986033849339:8 10502870772583566854:9 9579728145720788731:10 9676201557854305978:11 4731896413009015131:12 17905522760209459181:13 17063534181803794493:14 15285744035704368662:15 2265596674932911774:16 304257334858494316:17 1819108601587180398:18 5421479283559898697:19 8243359970626135167:20 13861143137683308479:21 17241709254077376921:22 14895502180141653390:23 5075464188083089464:24 9026989529823845647:25 6420753415704873062:26 +1 0 13237225503670494420:0 132683728328325035:1 7761720401600392176:2 21002485849992795:3 336066712337470945:4 15218982276382079900:5 12219910503415112001:6 11866590129284196737:7 16705280652459417397:8 10502870772583566854:9 15238859373895068969:10 6231104288589860189:11 4018849280330685703:12 7518366351727709627:13 14643263989734319679:14 17417746869860111491:15 11704298043170297190:16 1187841073466173462:17 11710860182646955307:18 15858993896876398499:19 8243359970626135167:20 921766065305888747:21 17241709254077376921:22 9596905073876765726:23 17414791962410575054:24 3613283134603402626:25 6094626736077278091:26 +1 0 13237225503670494420:0 2725392301144350401:1 600209798659007675:2 12315698492775170686:3 15406357556071787535:4 15218982276382079900:5 11163313789190369446:6 16783842240295458777:7 11053760986033849339:8 10502870772583566854:9 14213800323646090430:10 7853636003697589375:11 4009361900010953351:12 11227204779996682625:13 674564578780542685:14 4933751362251299983:15 14454615856887199705:16 12702162550489317753:17 15427010206990513389:18 17241709254077376921:19 17241709254077376921:20 2511008134917666536:21 17241709254077376921:22 9596905073876765726:23 10985039445557659498:24 +1 0 6927017134761466251:0 132683728328325035:1 7761720401600392176:2 15524966656850654451:3 10182599171524437980:4 14669113407484985090:5 17241709254077376921:6 6024319228525808624:7 16705280652459417397:8 10502870772583566854:9 10490984741403024606:10 7686854714387873540:11 6064609207185952215:12 14643529896603192270:13 17063534181803794493:14 2639330246974301517:15 16974669170000599636:16 304257334858494316:17 11710860182646955307:18 6674055552811657342:19 8243359970626135167:20 5135288735729027677:21 17241709254077376921:22 11162666878533603762:23 12286428220600479687:24 3613283134603402626:25 88402684023886513:26 diff --git a/elastic-ctr/client/demo/demo.cpp b/elastic-ctr/client/demo/demo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..59a094ee94839822e918d61c21334415c7cee606 --- /dev/null +++ b/elastic-ctr/client/demo/demo.cpp @@ -0,0 +1,179 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include // NOLINT +#include "elastic-ctr/client/api/elastic_ctr_api.h" + +using baidu::paddle_serving::elastic_ctr::ElasticCTRPredictorApi; +using baidu::paddle_serving::elastic_ctr::Prediction; + +DEFINE_int32(batch_size, 10, "Infernce batch_size"); + +DEFINE_string(test_file, "", "test file"); + +const int VARIABLE_NAME_LEN = 256; +const int CTR_EMBEDDING_TABLE_SIZE = 100000001; + +struct Sample { + std::map> slots; +}; + +std::vector samples; + +int read_samples(const char* file) { + std::ifstream fs(file); + + for (std::string line; std::getline(fs, line);) { + std::vector tokens; + std::stringstream ss(line); + std::string token; + + Sample sample; + + while (std::getline(ss, token, ' ')) { + tokens.push_back(token); + } + + if (tokens.size() <= 3) { + continue; + } + + for (std::size_t i = 2; i < tokens.size(); ++i) { + std::size_t pos = tokens[i].find(':'); + if (pos == std::string::npos) { + continue; + } + + uint64_t x = std::strtoull(tokens[i].substr(0, pos).c_str(), NULL, 10); + std::string slot_name = tokens[i].substr(pos + 1); + + if (sample.slots.find(slot_name) == sample.slots.end()) { + std::vector values; + values.push_back(x % CTR_EMBEDDING_TABLE_SIZE); + sample.slots[slot_name] = values; + } else { + auto it = sample.slots.find(slot_name); + it->second.push_back(x); + } + } + + samples.push_back(sample); + } + + LOG(INFO) << "Samples size = " << samples.size(); + +#if 1 + for (std::size_t i = 0; i < samples.size(); ++i) { + LOG(INFO) << "=============Sample " << i << "========="; + for (auto slot : samples[i].slots) { + LOG(INFO) << "slot_name: " << slot.first.c_str(); + for (auto x : slot.second) { + LOG(INFO) << x; + } + } + LOG(INFO) << "========================================"; + } +#endif + return 0; +} + +int main(int argc, char** argv) { + google::ParseCommandLineFlags(&argc, &argv, true); + + ElasticCTRPredictorApi api; + +#ifdef BCLOUD + logging::LoggingSettings settings; + settings.logging_dest = logging::LOG_TO_FILE; + std::string log_filename(argv[0]); + log_filename = log_filename.substr(log_filename.find_last_of('/') + 1); + settings.log_file = (std::string("./log/") + log_filename + ".log").c_str(); + settings.delete_old = logging::DELETE_OLD_LOG_FILE; + logging::InitLogging(settings); + logging::ComlogSinkOptions cso; + cso.process_name = log_filename; + cso.enable_wf_device = true; + logging::ComlogSink::GetInstance()->Setup(&cso); +#else + struct stat st_buf; + int ret = 0; + if ((ret = stat("./log", &st_buf)) != 0) { + mkdir("./log", 0777); + ret = stat("./log", &st_buf); + if (ret != 0) { + LOG(WARNING) << "Log path ./log not exist, and create fail"; + return -1; + } + } + FLAGS_log_dir = "./log"; + google::InitGoogleLogging(strdup(argv[0])); + FLAGS_logbufsecs = 0; + FLAGS_logbuflevel = -1; +#endif + // predictor conf + if (api.init("./conf", "slot.conf", "predictors.prototxt") != 0) { + LOG(ERROR) << "Failed create predictors api!"; + return -1; + } + + api.thrd_initialize(); + + ret = read_samples(FLAGS_test_file.c_str()); + + std::size_t index = 0; + while (index < samples.size()) { + api.thrd_clear(); + + for (int i = 0; i < FLAGS_batch_size && index < samples.size(); ++i) { + ReqInstance* ins = api.add_instance(); + if (!ins) { + LOG(ERROR) << "Failed create req instance"; + return -1; + } + + for (auto slot : samples[index].slots) { + for (auto x : slot.second) { + api.add_slot(ins, slot.first.c_str(), x); + } + } + + ++index; + } + + std::vector> results_vec; + if (api.inference(results_vec) != 0) { + LOG(ERROR) << "failed call predictor"; + return -1; + } + +#if 1 + for (std::size_t i = 0; i < results_vec.size(); ++i) { + LOG(INFO) << "sample " << i << ": [" << results_vec[i].at(0) << ", " + << results_vec[i].at(1) << "]"; + } +#endif + } // end while + + api.thrd_finalize(); + + api.destroy(); + return 0; +} diff --git a/elastic-ctr/client/demo/elastic_ctr.py b/elastic-ctr/client/demo/elastic_ctr.py new file mode 100644 index 0000000000000000000000000000000000000000..91695fd6656345b26a76807e0d3c258ba3adf81f --- /dev/null +++ b/elastic-ctr/client/demo/elastic_ctr.py @@ -0,0 +1,126 @@ +# 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. + +from __future__ import print_function +import json +import sys +import os + +from elastic_ctr_api import ElasticCTRAPI + +BATCH_SIZE = 3 +SERVING_IP = "127.0.0.1" +SLOT_CONF_FILE = "./conf/slot.conf" +CTR_EMBEDDING_TABLE_SIZE = 100000001 +SLOTS = [] + + +def str2long(str): + if sys.version_info[0] == 2: + return long(str) + elif sys.version_info[0] == 3: + return int(str) + + +def data_reader(data_file, samples, labels): + if not os.path.exists(data_file): + print("Path %s not exist" % data_file) + return -1 + + with open(data_file, "r") as f: + for line in f: + sample = {} + line = line.rstrip('\n') + feature_slots = line.split(' ') + labels.append(int(feature_slots[1])) + feature_slots = feature_slots[2:] + feature_slot_maps = [x.split(':') for x in feature_slots] + + features = [x[0] for x in feature_slot_maps] + slots = [x[1] for x in feature_slot_maps] + + for i in range(0, len(features)): + if slots[i] in sample: + sample[slots[i]] = [ + sample[slots[i]] + str2long(features[i]) % + CTR_EMBEDDING_TABLE_SIZE + ] + else: + sample[slots[i]] = [ + str2long(features[i]) % CTR_EMBEDDING_TABLE_SIZE + ] + + for x in SLOTS: + if not x in sample: + sample[x] = [0] + samples.append(sample) + + +if __name__ == "__main__": + """ main + """ + if len(sys.argv) != 5: + print( + "Usage: python elastic_ctr.py SERVING_IP SERVING_PORT SLOT_CONF_FILE DATA_FILE" + ) + sys.exit(-1) + + samples = [] + labels = [] + + SERVING_IP = sys.argv[1] + SERVING_PORT = sys.argv[2] + SLOT_CONF_FILE = sys.argv[3] + + api = ElasticCTRAPI(SERVING_IP, SERVING_PORT) + ret = api.read_slots_conf(SLOT_CONF_FILE) + if ret != 0: + sys.exit(-1) + + ret = data_reader(sys.argv[4], samples, labels) + + correct = 0 + for i in range(0, len(samples) - BATCH_SIZE, BATCH_SIZE): + api.clear() + batch = samples[i:i + BATCH_SIZE] + instances = [] + for sample in batch: + instance = api.add_instance() + if sys.version_info[0] == 2: + for k, v in sample.iteritems(): + api.add_slot(instance, k, v) + elif sys.version_info[0] == 3: + for k, v in sample.items(): + api.add_slot(instance, k, v) + + ret = api.inference() + ret = json.loads(ret) + predictions = ret["predictions"] + + idx = 0 + for x in predictions: + if x["prob0"] >= x["prob1"]: + pred = 0 + else: + pred = 1 + + if labels[i + idx] == pred: + correct += 1 + else: + print("id=%d predict incorrect: pred=%d label=%d (%f %f)" % + (i + idx, pred, labels[i + idx], x["prob0"], x["prob1"])) + + idx = idx + 1 + + print("Acc=%f" % (float(correct) / len(samples))) diff --git a/elastic-ctr/client/proto/CMakeLists.txt b/elastic-ctr/client/proto/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b384d1d2159a91e9bd29626d2ae2ad13b594330d --- /dev/null +++ b/elastic-ctr/client/proto/CMakeLists.txt @@ -0,0 +1,5 @@ +FILE(GLOB protos ${CMAKE_CURRENT_LIST_DIR}/*.proto) +list(APPEND protos ${CMAKE_SOURCE_DIR}/predictor/proto/pds_option.proto + ${CMAKE_SOURCE_DIR}/predictor/proto/builtin_format.proto) +PROTOBUF_GENERATE_SERVING_CPP(FALSE PROTO_SRCS PROTO_HDRS ${protos}) +LIST(APPEND elastic_ctr_cpp_srcs ${PROTO_SRCS}) diff --git a/elastic-ctr/client/proto/elastic_ctr_prediction.proto b/elastic-ctr/client/proto/elastic_ctr_prediction.proto new file mode 100644 index 0000000000000000000000000000000000000000..8dfdd09835522dcb14e09e21407949caac85533e --- /dev/null +++ b/elastic-ctr/client/proto/elastic_ctr_prediction.proto @@ -0,0 +1,46 @@ +// 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. + +syntax = "proto2"; +import "pds_option.proto"; +import "builtin_format.proto"; +package baidu.paddle_serving.predictor.elastic_ctr; + +option cc_generic_services = true; + +message Slot { + required string slot_name = 1; + repeated int64 feasigns = 2; +}; + +message ReqInstance { repeated Slot slots = 1; }; + +message Request { repeated ReqInstance instances = 1; }; + +message ResInstance { + required float prob0 = 1; + required float prob1 = 2; +}; + +message Response { + repeated ResInstance predictions = 1; + required int64 err_code = 2; + optional string err_msg = 3; +}; + +service ElasticCTRPredictionService { + rpc inference(Request) returns (Response); + rpc debug(Request) returns (Response); + option (pds.options).generate_stub = true; +}; diff --git a/elastic-ctr/serving/CMakeLists.txt b/elastic-ctr/serving/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2ec17c1e6b094ff4d2a4becbb047d29a6e36b509 --- /dev/null +++ b/elastic-ctr/serving/CMakeLists.txt @@ -0,0 +1,59 @@ +if (NOT EXISTS + ${CMAKE_CURRENT_LIST_DIR}/data/model/paddle/fluid/ctr_prediction) + execute_process(COMMAND wget --no-check-certificate + https://paddle-serving.bj.bcebos.com/data/ctr_prediction/elastic_ctr_model.tar.gz + --output-document + ${CMAKE_CURRENT_LIST_DIR}/data/model/paddle/fluid/elastic_ctr_model.tar.gz) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzf + "${CMAKE_CURRENT_LIST_DIR}/data/model/paddle/fluid/elastic_ctr_model.tar.gz" + WORKING_DIRECTORY + ${CMAKE_CURRENT_LIST_DIR}/data/model/paddle/fluid) + execute_process(COMMAND ${CMAKE_COMMAND} -E rename inference_only ctr_prediction + WORKING_DIRECTORY + ${CMAKE_CURRENT_LIST_DIR}/data/model/paddle/fluid) +endif() + +include_directories(SYSTEM ${CMAKE_CURRENT_LIST_DIR}/../kvdb/include) + +include(op/CMakeLists.txt) +include(proto/CMakeLists.txt) +add_executable(elastic_serving ${serving_srcs}) +add_dependencies(elastic_serving pdcodegen fluid_cpu_engine pdserving paddle_fluid cube-api) + +target_include_directories(elastic_serving PUBLIC + ${CMAKE_CURRENT_BINARY_DIR}/../../predictor + ) + +target_link_libraries(elastic_serving -Wl,--whole-archive fluid_cpu_engine + -Wl,--no-whole-archive) + +target_link_libraries(elastic_serving paddle_fluid ${paddle_depend_libs}) + +target_link_libraries(elastic_serving pdserving) +target_link_libraries(elastic_serving cube-api) + +target_link_libraries(elastic_serving kvdb rocksdb) + +target_link_libraries(elastic_serving -liomp5 -lmklml_intel -lmkldnn -lpthread + -lcrypto -lm -lrt -lssl -ldl -lz -lbz2) + +install(TARGETS elastic_serving + RUNTIME DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/serving/bin) +install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/conf DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/serving/) +install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/data DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/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}/elastic_ctr/serving/bin) +endif() diff --git a/elastic-ctr/serving/conf/cube.conf b/elastic-ctr/serving/conf/cube.conf new file mode 100644 index 0000000000000000000000000000000000000000..a462dd23376308a4e3f2f62b4b87d4a1a7acb9e4 --- /dev/null +++ b/elastic-ctr/serving/conf/cube.conf @@ -0,0 +1,15 @@ +[{ + "dict_name": "test_dict", + "shard": 2, + "dup": 1, + "timeout": 200, + "retry": 3, + "backup_request": 100, + "type": "ipport_list", + "load_balancer": "rr", + "nodes": [{ + "ipport_list": "list://xxx.xxx.xxx.xxx:8000" + },{ + "ipport_list": "list://xxx.xxx.xxx.xxx:8000" + }] +}] diff --git a/elastic-ctr/serving/conf/gflags.conf b/elastic-ctr/serving/conf/gflags.conf new file mode 100644 index 0000000000000000000000000000000000000000..b4eedcc8d9d554b4ce159456b0614b139aa979c2 --- /dev/null +++ b/elastic-ctr/serving/conf/gflags.conf @@ -0,0 +1,2 @@ +--enable_model_toolkit +--enable_cube=true diff --git a/elastic-ctr/serving/conf/model_toolkit.prototxt b/elastic-ctr/serving/conf/model_toolkit.prototxt new file mode 100644 index 0000000000000000000000000000000000000000..17ebe03b9e103321fe073fbe04bad12ab946d931 --- /dev/null +++ b/elastic-ctr/serving/conf/model_toolkit.prototxt @@ -0,0 +1,12 @@ +engines { + name: "elastic_ctr_prediction" + type: "FLUID_CPU_ANALYSIS_DIR" + reloadable_meta: "./data/model/paddle/fluid_time_file" + reloadable_type: "timestamp_ne" + model_data_path: "./data/model/paddle/fluid/ctr_prediction" + runtime_thread_num: 0 + batch_infer_size: 0 + enable_batch_align: 0 + sparse_param_service_type: REMOTE + sparse_param_service_table_name: "test_dict" +} diff --git a/elastic-ctr/serving/conf/resource.prototxt b/elastic-ctr/serving/conf/resource.prototxt new file mode 100644 index 0000000000000000000000000000000000000000..0a0d6678fe99a89517ba9855140c0c01f919742e --- /dev/null +++ b/elastic-ctr/serving/conf/resource.prototxt @@ -0,0 +1,3 @@ +model_toolkit_path: "./conf/" +model_toolkit_file: "model_toolkit.prototxt" +cube_config_file: "./conf/cube.conf" diff --git a/elastic-ctr/serving/conf/service.prototxt b/elastic-ctr/serving/conf/service.prototxt new file mode 100644 index 0000000000000000000000000000000000000000..4b9281707b8067dfb59d8e5c3be6cd3240ab0d2c --- /dev/null +++ b/elastic-ctr/serving/conf/service.prototxt @@ -0,0 +1,4 @@ +services { + name: "ElasticCTRPredictionService" + workflows: "workflow1" +} diff --git a/elastic-ctr/serving/conf/workflow.prototxt b/elastic-ctr/serving/conf/workflow.prototxt new file mode 100644 index 0000000000000000000000000000000000000000..fad65dc3cda76924a3cab8b17f79ae08f1131cc8 --- /dev/null +++ b/elastic-ctr/serving/conf/workflow.prototxt @@ -0,0 +1,8 @@ +workflows { + name: "workflow1" + workflow_type: "Sequence" + nodes { + name: "elastic_ctr_prediction_op" + type: "ElasticCTRPredictionOp" + } +} diff --git a/elastic-ctr/serving/data/model/paddle/fluid/.gitignore b/elastic-ctr/serving/data/model/paddle/fluid/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/elastic-ctr/serving/data/model/paddle/fluid_reload_flag b/elastic-ctr/serving/data/model/paddle/fluid_reload_flag new file mode 100644 index 0000000000000000000000000000000000000000..a1866984b04a26a09bbfc4ef4f08dec5e38f818d --- /dev/null +++ b/elastic-ctr/serving/data/model/paddle/fluid_reload_flag @@ -0,0 +1,2 @@ +paddle fluid model +time:20180531 diff --git a/elastic-ctr/serving/data/model/paddle/fluid_time_file b/elastic-ctr/serving/data/model/paddle/fluid_time_file new file mode 100644 index 0000000000000000000000000000000000000000..4d9422cd37f6c51800055f1b1dc625e2c455fc6d --- /dev/null +++ b/elastic-ctr/serving/data/model/paddle/fluid_time_file @@ -0,0 +1,2 @@ +201805311000 +model paddle fluid diff --git a/elastic-ctr/serving/op/CMakeLists.txt b/elastic-ctr/serving/op/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..9287408e5e64fa284acbbdb18563703510114e87 --- /dev/null +++ b/elastic-ctr/serving/op/CMakeLists.txt @@ -0,0 +1,2 @@ +FILE(GLOB op_srcs ${CMAKE_CURRENT_LIST_DIR}/*.cpp) +LIST(APPEND serving_srcs ${op_srcs}) diff --git a/elastic-ctr/serving/op/elastic_ctr_prediction_op.cpp b/elastic-ctr/serving/op/elastic_ctr_prediction_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b94b1f6b1ee12ab8c8b31c24f4e8913836eab316 --- /dev/null +++ b/elastic-ctr/serving/op/elastic_ctr_prediction_op.cpp @@ -0,0 +1,445 @@ +// 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 "elastic-ctr/serving/op/elastic_ctr_prediction_op.h" +#include +#include +#include "cube/cube-api/include/cube_api.h" +#include "predictor/framework/infer.h" +#include "predictor/framework/kv_manager.h" +#include "predictor/framework/memory.h" + +// Flag where enable profiling mode +DECLARE_bool(enable_ctr_profiling); + +namespace baidu { +namespace paddle_serving { +namespace serving { + +using baidu::paddle_serving::predictor::MempoolWrapper; +using baidu::paddle_serving::predictor::elastic_ctr::Slot; +using baidu::paddle_serving::predictor::elastic_ctr::ResInstance; +using baidu::paddle_serving::predictor::elastic_ctr::Response; +using baidu::paddle_serving::predictor::elastic_ctr::ReqInstance; +using baidu::paddle_serving::predictor::elastic_ctr::Request; + +const int VARIABLE_NAME_LEN = 256; + +const int CTR_PREDICTION_DENSE_DIM = 13; +const int CTR_PREDICTION_EMBEDDING_SIZE = 9; + +bthread::Mutex ElasticCTRPredictionOp::mutex_; +int64_t ElasticCTRPredictionOp::cube_time_us_ = 0; +int32_t ElasticCTRPredictionOp::cube_req_num_ = 0; +int32_t ElasticCTRPredictionOp::cube_req_key_num_ = 0; + +void fill_response_with_message(Response *response, + int err_code, + std::string err_msg) { + if (response == NULL) { + LOG(ERROR) << "response is NULL"; + return; + } + + response->set_err_code(err_code); + response->set_err_msg(err_msg); + return; +} + +int ElasticCTRPredictionOp::inference() { + const Request *req = dynamic_cast(get_request_message()); + + TensorVector *in = butil::get_object(); + Response *res = mutable_data(); + + uint32_t sample_size = req->instances_size(); + if (sample_size <= 0) { + LOG(WARNING) << "No instances need to inference!"; + fill_response_with_message(res, -1, "Sample size invalid"); + return 0; + } + + // Verify all request instances have same slots + int slot_num = req->instances(0).slots_size(); +#if 1 + LOG(INFO) << "slot_num =" << slot_num; +#endif + for (int i = 1; i < req->instances_size(); ++i) { + if (req->instances(i).slots_size() != slot_num) { + LOG(WARNING) << "Req " << i + << " has different slot num with that of req 0"; + fill_response_with_message( + res, -1, "Req intance has varying slot numbers"); + } + } + + // Query cube API for sparse embeddings + std::vector keys; + std::vector values; + + // How to organize feasigns in the above `keys` vector: + // + // Assuming N instances, each instance having M feature slots: + // + // ins1: + // slot_1: ins1_slot1_1|ins1_slot1_2 slot2: ins1_slot2_1|ins1_slot2_2 + // + // ins2: + // slot_1: ins2_slot1_1 slot2: ins2_slot2_1|ins2_slot2_2 + // + // ... + // + // insN: + // slot_1: insN_slot1_1|insN_slot1_2 slot2: insN_slot2_1 + // + // We organize the features in such a way that all slot_1 features are before + // slot_2 features: + // + // ins1_slot1_1|ins1_slot1_2|ins2_slot1_1|...|insN_slot1_1|insN_slot1_2 + // ins1_slot2_1|ins1_slot2_2|ins2_slot2_1|ins2_slot2_2|...|insN_slot2_1 + // + // With this placement, after querying KV service, we can retrieve the + // embeddings for each feature slot from the returned `values` vector easily, + // as they are grouped togegher. + + // Level of details of each feature slot + std::vector> feature_slot_lods; + feature_slot_lods.resize(slot_num); + + // Number of feature signs in each slot + std::vector feature_slot_sizes; + feature_slot_sizes.resize(slot_num); + + // Iterate over each feature slot + for (int i = 0; i < slot_num; ++i) { + feature_slot_lods[i].push_back(0); + feature_slot_sizes[i] = 0; + + // Extract feature i values from each instance si + for (int si = 0; si < sample_size; ++si) { +#if 1 + LOG(INFO) << "slot " << i << " sample " << si; +#endif + const ReqInstance &req_instance = req->instances(si); + const Slot &slot = req_instance.slots(i); + feature_slot_lods[i].push_back(feature_slot_lods[i].back() + + slot.feasigns_size()); + feature_slot_sizes[i] += slot.feasigns_size(); + + for (int j = 0; j < slot.feasigns_size(); ++j) { + keys.push_back(slot.feasigns(j)); + } + } + } + +#if 1 + rec::mcube::CubeAPI *cube = rec::mcube::CubeAPI::instance(); + predictor::KVManager &kv_manager = predictor::KVManager::instance(); + const predictor::KVInfo *kvinfo = + kv_manager.get_kv_info(CTR_PREDICTION_MODEL_NAME); + if (kvinfo == NULL) { + LOG(ERROR) << "Sparse param service info not found for model " + << CTR_PREDICTION_MODEL_NAME + << ". Maybe forgot to specify sparse_param_service_type and " + << "sparse_param_service_table_name in " + << "conf/model_toolkit.prototxt"; + fill_response_with_message(res, -1, "Sparse param service info not found"); + return 0; + } + + std::string table_name; + if (kvinfo->sparse_param_service_type != configure::EngineDesc::NONE) { + table_name = kvinfo->sparse_param_service_table_name; + if (table_name.empty()) { + LOG(ERROR) << "sparse_param_service_table_name not specified. " + << "Please specify it in conf/model_toolkit.protxt for model " + << CTR_PREDICTION_MODEL_NAME; + fill_response_with_message( + res, -1, "sparse_param_service_table_name not specified"); + return 0; + } + } + + if (kvinfo->sparse_param_service_type == configure::EngineDesc::LOCAL) { + // Query local KV service + LOG(ERROR) << "Local kv service not supported for model " + << CTR_PREDICTION_MODEL_NAME; + + fill_response_with_message( + res, -1, "Local kv service not supported for this model"); + return 0; + } else if (kvinfo->sparse_param_service_type == + configure::EngineDesc::REMOTE) { + struct timeval start; + struct timeval end; + + int ret; + + gettimeofday(&start, NULL); + ret = cube->seek(table_name, keys, &values); + gettimeofday(&end, NULL); + uint64_t usec = + end.tv_sec * 1e6 + end.tv_usec - start.tv_sec * 1e6 - start.tv_usec; + + // Statistics + mutex_.lock(); + cube_time_us_ += usec; + ++cube_req_num_; + cube_req_key_num_ += keys.size(); + + if (cube_req_num_ >= 1000) { + LOG(INFO) << "Cube request count: " << cube_req_num_; + LOG(INFO) << "Cube request key count: " << cube_req_key_num_; + LOG(INFO) << "Cube request total time: " << cube_time_us_ << "us"; + LOG(INFO) << "Average " + << static_cast(cube_time_us_) / cube_req_num_ + << "us/req"; + LOG(INFO) << "Average " + << static_cast(cube_time_us_) / cube_req_key_num_ + << "us/key"; + + cube_time_us_ = 0; + cube_req_num_ = 0; + cube_req_key_num_ = 0; + } + mutex_.unlock(); + // Statistics end + + if (ret != 0) { + fill_response_with_message(res, -1, "Query cube for embeddings error"); + LOG(ERROR) << "Query cube for embeddings error"; + return 0; + } + } + + if (values.size() != keys.size()) { + LOG(ERROR) << "Sparse embeddings not ready; " + << "maybe forgot to set sparse_param_service_type and " + << "sparse_param_sevice_table_name for " + << CTR_PREDICTION_MODEL_NAME + << " in conf/model_toolkit.prototxt"; + fill_response_with_message( + res, -1, "Sparse param service not configured properly"); + return 0; + } + + for (int i = 0; i < keys.size(); ++i) { + std::ostringstream oss; + oss << keys[i] << ": "; + const char *value = (values[i].buff.data()); + if (values[i].buff.size() != + sizeof(float) * CTR_PREDICTION_EMBEDDING_SIZE) { + LOG(WARNING) << "Key " << keys[i] << " has values less than " + << CTR_PREDICTION_EMBEDDING_SIZE; + } + +#if 0 + for (int j = 0; j < values[i].buff.size(); ++j) { + oss << std::hex << std::uppercase << std::setw(2) << std::setfill('0') + << (static_cast(value[j]) & 0xff); + } + + LOG(INFO) << oss.str().c_str(); +#endif + } + + // Fill feature embedding into feed tensors + std::vector lod_tensors; + lod_tensors.resize(slot_num); + + const ReqInstance &instance = req->instances(0); + for (int i = 0; i < slot_num; ++i) { + paddle::PaddleTensor &lod_tensor = lod_tensors[i]; + + char name[VARIABLE_NAME_LEN]; + snprintf(name, + VARIABLE_NAME_LEN, + "embedding_%s.tmp_0", + instance.slots(i).slot_name().c_str()); + lod_tensor.name = std::string(name); + + lod_tensors[i].dtype = paddle::PaddleDType::FLOAT32; + std::vector> &lod = lod_tensors[i].lod; + lod.resize(1); + lod[0].push_back(0); + } + + int base = 0; + + // Iterate over all slots + for (int i = 0; i < slot_num; ++i) { + paddle::PaddleTensor &lod_tensor = lod_tensors[i]; + std::vector> &lod = lod_tensor.lod; + + lod[0] = feature_slot_lods[i]; + + lod_tensor.shape = {lod[0].back(), CTR_PREDICTION_EMBEDDING_SIZE}; + lod_tensor.data.Resize(lod[0].back() * sizeof(float) * + CTR_PREDICTION_EMBEDDING_SIZE); + + int offset = 0; + // Copy all slot i feature embeddings to lod_tensor[i] + for (uint32_t j = 0; j < feature_slot_sizes[i]; ++j) { + float *data_ptr = static_cast(lod_tensor.data.data()) + offset; + + int idx = base + j; + if (values[idx].buff.size() != + sizeof(float) * CTR_PREDICTION_EMBEDDING_SIZE) { +#if 0 + LOG(ERROR) << "Embedding vector size not expected"; + fill_response_with_message( + res, -1, "Embedding vector size not expected"); + return 0; +#else + // sizeof(float) * CTR_PREDICTION_EMBEDDING_SIZE = 36 + values[idx].buff.append(36, '0'); +#endif + } + + memcpy(data_ptr, values[idx].buff.data(), values[idx].buff.size()); + offset += CTR_PREDICTION_EMBEDDING_SIZE; + } + + in->push_back(lod_tensor); + + // Bump base counter + base += feature_slot_sizes[i]; + } +#else + + // Fill all tensors + std::vector lod_tensors; + lod_tensors.resize(slot_num); + + const ReqInstance &instance = req->instances(0); + for (int i = 0; i < slot_num; ++i) { + paddle::PaddleTensor &lod_tensor = lod_tensors[i]; + + lod_tensor.name = instance.slots(i).slot_name(); + + LOG(INFO) << "slot " << i << "name: " << lod_tensor.name.c_str(); + lod_tensors[i].dtype = paddle::PaddleDType::INT64; + } + + // Iterate over all slots + for (int i = 0; i < slot_num; ++i) { + paddle::PaddleTensor &lod_tensor = lod_tensors[i]; + std::vector> &lod = lod_tensor.lod; + + lod.push_back(feature_slot_lods[i]); + + lod_tensor.shape = {lod[0].back(), 1}; + lod_tensor.data.Resize(lod[0].back() * sizeof(uint64_t)); + + int offset = 0; + // Copy all slot i features to lod_tensor[i] + uint64_t *keys_block = keys.data(); + uint64_t *data_ptr = static_cast(lod_tensor.data.data()); + + memcpy(data_ptr, + keys_block + offset, + feature_slot_sizes[i] * sizeof(uint64_t)); + offset += feature_slot_sizes[i]; + + in->push_back(lod_tensor); + + // Bump base counter + offset += feature_slot_sizes[i]; + } +#endif + TensorVector *out = butil::get_object(); + if (!out) { + LOG(ERROR) << "Failed get tls output object"; + fill_response_with_message(res, -1, "Failed get thread local resource"); + return 0; + } + + // call paddle fluid model for inference + if (predictor::InferManager::instance().infer( + CTR_PREDICTION_MODEL_NAME, in, out, sample_size)) { + LOG(ERROR) << "Failed do infer in fluid model: " + << CTR_PREDICTION_MODEL_NAME; + fill_response_with_message(res, -1, "Failed do infer in fluid model"); + return 0; + } + + if (out->size() != 1) { + LOG(ERROR) << "Model returned number of fetch tensor more than 1"; + fill_response_with_message( + res, -1, "Model returned number of fetch tensor more than 1"); + return 0; + } + + int output_shape_dim = out->at(0).shape.size(); + if (output_shape_dim != 2) { + LOG(ERROR) << "Fetch LoDTensor should be shape of [sample_size, 2]"; + fill_response_with_message( + res, -1, "Fetch LoDTensor should be shape of [sample_size, 2]"); + return 0; + } + + if (out->at(0).dtype != paddle::PaddleDType::FLOAT32) { + LOG(ERROR) << "Fetch LoDTensor data type should be FLOAT32"; + fill_response_with_message( + res, -1, "Fetch LoDTensor data type should be FLOAT32"); + return 0; + } + + int dim1 = out->at(0).shape[0]; + int dim2 = out->at(0).shape[1]; + + if (dim1 != sample_size) { + LOG(ERROR) << "Returned result count not equal to sample_size"; + fill_response_with_message( + res, -1, "Returned result count not equal to sample size"); + return 0; + } + + if (dim2 != 2) { + LOG(ERROR) << "Returned result is not expected, should be 2 floats for " + "each sample"; + fill_response_with_message( + res, -1, "Retunred result is not 2 floats for each sample"); + return 0; + } + + float *data = static_cast(out->at(0).data.data()); + for (int i = 0; i < dim1; ++i) { + ResInstance *res_instance = res->add_predictions(); + res_instance->set_prob0(data[i * dim2]); + res_instance->set_prob1(data[i * dim2 + 1]); + } + + for (size_t i = 0; i < in->size(); ++i) { + (*in)[i].shape.clear(); + } + in->clear(); + butil::return_object(in); + + for (size_t i = 0; i < out->size(); ++i) { + (*out)[i].shape.clear(); + } + out->clear(); + butil::return_object(out); + + res->set_err_code(0); + res->set_err_msg(std::string("")); + return 0; +} + +DEFINE_OP(ElasticCTRPredictionOp); + +} // namespace serving +} // namespace paddle_serving +} // namespace baidu diff --git a/elastic-ctr/serving/op/elastic_ctr_prediction_op.h b/elastic-ctr/serving/op/elastic_ctr_prediction_op.h new file mode 100644 index 0000000000000000000000000000000000000000..34ff1827992464fb169e5e828fb4ba8cfa47f5f4 --- /dev/null +++ b/elastic-ctr/serving/op/elastic_ctr_prediction_op.h @@ -0,0 +1,58 @@ +// 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. + +#pragma once +#include +#ifdef BCLOUD +#ifdef WITH_GPU +#include "paddle/paddle_inference_api.h" +#else +#include "paddle/fluid/inference/api/paddle_inference_api.h" +#endif +#else +#include "paddle_inference_api.h" // NOLINT +#endif +#include "elastic-ctr/serving/elastic_ctr_prediction.pb.h" + +namespace baidu { +namespace paddle_serving { +namespace serving { + +static const char* CTR_PREDICTION_MODEL_NAME = "elastic_ctr_prediction"; + +/** + * ElasticCTRPredictionOp: Serve CTR prediction requests. + * + */ + +class ElasticCTRPredictionOp + : public baidu::paddle_serving::predictor::OpWithChannel< + baidu::paddle_serving::predictor::elastic_ctr::Response> { + public: + typedef std::vector TensorVector; + + DECLARE_OP(ElasticCTRPredictionOp); + + int inference(); + + private: + static bthread::Mutex mutex_; + static int64_t cube_time_us_; + static int32_t cube_req_num_; + static int32_t cube_req_key_num_; +}; + +} // namespace serving +} // namespace paddle_serving +} // namespace baidu diff --git a/elastic-ctr/serving/proto/CMakeLists.txt b/elastic-ctr/serving/proto/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a52340d4dd54e166e1d9c7f8ae988de3f9740a86 --- /dev/null +++ b/elastic-ctr/serving/proto/CMakeLists.txt @@ -0,0 +1,6 @@ +LIST(APPEND protofiles + ${CMAKE_CURRENT_LIST_DIR}/elastic_ctr_prediction.proto +) + +PROTOBUF_GENERATE_SERVING_CPP(TRUE PROTO_SRCS PROTO_HDRS ${protofiles}) +LIST(APPEND serving_srcs ${PROTO_SRCS}) diff --git a/elastic-ctr/serving/proto/elastic_ctr_prediction.proto b/elastic-ctr/serving/proto/elastic_ctr_prediction.proto new file mode 100644 index 0000000000000000000000000000000000000000..b31474bac067e196f153909e046971165b92f110 --- /dev/null +++ b/elastic-ctr/serving/proto/elastic_ctr_prediction.proto @@ -0,0 +1,46 @@ +// 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. + +syntax = "proto2"; +import "pds_option.proto"; +import "builtin_format.proto"; +package baidu.paddle_serving.predictor.elastic_ctr; + +option cc_generic_services = true; + +message Slot { + required string slot_name = 1; + repeated int64 feasigns = 2; +}; + +message ReqInstance { repeated Slot slots = 1; }; + +message Request { repeated ReqInstance instances = 1; }; + +message ResInstance { + required float prob0 = 1; + required float prob1 = 2; +}; + +message Response { + repeated ResInstance predictions = 1; + required int64 err_code = 2; + optional string err_msg = 3; +}; + +service ElasticCTRPredictionService { + rpc inference(Request) returns (Response); + rpc debug(Request) returns (Response); + option (pds.options).generate_impl = true; +}; diff --git a/sdk-cpp/include/common.h b/sdk-cpp/include/common.h index 19a37650c5e037044598da506f2c8576a283b3e1..618b532965707ce18b35a5e44731c95f59e4b671 100644 --- a/sdk-cpp/include/common.h +++ b/sdk-cpp/include/common.h @@ -23,7 +23,6 @@ #include #include -#include "boost/unordered_map.hpp" #include "gflags/gflags.h" #include "google/protobuf/message.h" @@ -35,7 +34,7 @@ #include "base/logging.h" #include "base/object_pool.h" #include "base/time.h" -#include "bthread.h" +#include "bthread.h" // NOLINT #else #include "brpc/channel.h" #include "brpc/parallel_channel.h" @@ -49,7 +48,7 @@ #include "bvar/bvar.h" #ifdef BCLOUD -#include "json_to_pb.h" +#include "json_to_pb.h" // NOLINT #else #include "json2pb/json_to_pb.h" #endif