From 22aafcb5b37311bb121e20417fc4ae1a9c52af67 Mon Sep 17 00:00:00 2001 From: Superjomn Date: Fri, 15 Jun 2018 06:34:58 +0000 Subject: [PATCH 01/16] Init --- paddle/contrib/inference/demo/CMakeLists.txt | 2 + paddle/contrib/inference/demo/README.md | 19 +++ paddle/contrib/inference/demo/mobilenet.cc | 117 ++++++++++++++++++ .../inference/demo/simple_on_word2vec.cc | 1 + 4 files changed, 139 insertions(+) create mode 100644 paddle/contrib/inference/demo/README.md create mode 100644 paddle/contrib/inference/demo/mobilenet.cc diff --git a/paddle/contrib/inference/demo/CMakeLists.txt b/paddle/contrib/inference/demo/CMakeLists.txt index 7b0fa77ad13c1..4041190bb8e78 100644 --- a/paddle/contrib/inference/demo/CMakeLists.txt +++ b/paddle/contrib/inference/demo/CMakeLists.txt @@ -14,3 +14,5 @@ # inference_api_test(simple_on_word2vec ARGS test_word2vec) +cc_test(mobilenet_infernce_demo SRCS mobilenet.cc DEPS + paddle_inference_api paddle_fluid) diff --git a/paddle/contrib/inference/demo/README.md b/paddle/contrib/inference/demo/README.md new file mode 100644 index 0000000000000..5002b652136fa --- /dev/null +++ b/paddle/contrib/inference/demo/README.md @@ -0,0 +1,19 @@ +# Infernce Demos + +## MobileNet +Input data format: + +- Each line contains a single record +- Each record's format is + +``` +\t +``` + +Follow the C++ codes in `mobilenet.cc`. + +To execute the demo, simply run + +```sh +./mobilenet_inference_demo --modeldir --data +``` diff --git a/paddle/contrib/inference/demo/mobilenet.cc b/paddle/contrib/inference/demo/mobilenet.cc new file mode 100644 index 0000000000000..686958eb222af --- /dev/null +++ b/paddle/contrib/inference/demo/mobilenet.cc @@ -0,0 +1,117 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +/* + * This file contains a demo for mobilenet. + * TODO(Superjomn) add some links of the actual models. + */ + +#include +#include // use glog instead of PADDLE_ENFORCE to avoid importing other paddle header files. +#include +#include +#include "paddle/contrib/inference/paddle_inference_api.h" +#include "paddle/utils/StringUtil.h" + +namespace paddle { +namespace demo { + +DEFINE_string(modeldir, "", "Directory of the inference model."); +DEFINE_string( + data, + "", + "path of data; each line is a record, format is " + "'\t data; + std::vector shape; +}; + +void split(const std::string& str, char sep, std::vector* pieces); + +Record ProcessALine(const std::string& line) { + std::vector columns; + split(line, '\t', &columns); + CHECK_EQ(columns.size(), 2UL) + << "data format error, should be \t"; + + Record record; + + std::vector data_strs; + split(line, ' ', &data_strs); + for (auto& d : data_strs) { + record.data.push_back(std::stof(d)); + } + + std::vector shape_strs; + split(line, ' ', &shape_strs); + for (auto& s : shape_strs) { + record.shape.push_back(std::stoi(s)); + } + return record; +} + + +/* + * Use the native fluid engine to inference the mobilenet. + */ +void Main(bool use_gpu) { + NativeConfig config; + config.model_dir = FLAGS_modeldir; + config.use_gpu = use_gpu; + config.fraction_of_gpu_memory = 0.15; + config.device = 0; + + auto predictor = + CreatePaddlePredictor(config); + + // Just a single batch of data. + std::string line; + std::getline(std::cin, line); + auto record = ProcessALine(line); + + // Inference. + PaddleBuf buf{.data = record.data.data(), + .length = record.data.size() * sizeof(float)}; + PaddleTensor input{.name = "xx", + .shape = record.shape, + .data = buf, + .dtype = PaddleDType::FLOAT32}; + + std::vector output; + predictor->Run({input}, &output); +} + +TEST(demo, mobilenet) { Main(false /*use_gpu*/); } + +void split(const std::string& str, char sep, std::vector* pieces) { + pieces->clear(); + if (str.empty()) { + return; + } + size_t pos = 0; + size_t next = str.find(sep, pos); + while (next != std::string::npos) { + pieces->push_back(str.substr(pos, next - pos)); + pos = next + 1; + next = str.find(sep, pos); + } + if (!str.substr(pos).empty()) { + pieces->push_back(str.substr(pos)); + } +} + +} // namespace demo +} // namespace paddle diff --git a/paddle/contrib/inference/demo/simple_on_word2vec.cc b/paddle/contrib/inference/demo/simple_on_word2vec.cc index 192a6414260ce..2076b68d594cc 100644 --- a/paddle/contrib/inference/demo/simple_on_word2vec.cc +++ b/paddle/contrib/inference/demo/simple_on_word2vec.cc @@ -21,6 +21,7 @@ limitations under the License. */ #include #include #include "paddle/contrib/inference/paddle_inference_api.h" + namespace paddle { namespace demo { From f5d07830fe05560641e1445dd107edbdacd3565e Mon Sep 17 00:00:00 2001 From: Superjomn Date: Sun, 24 Jun 2018 04:08:58 +0000 Subject: [PATCH 02/16] init --- paddle/contrib/inference/demo/CMakeLists.txt | 1 + paddle/contrib/inference/demo/mobilenet.cc | 44 +++++++-------- paddle/contrib/inference/demo/utils.h | 54 +++++++++++++++++++ .../contrib/inference/paddle_inference_api.cc | 17 ++++++ .../contrib/inference/paddle_inference_api.h | 7 ++- 5 files changed, 98 insertions(+), 25 deletions(-) create mode 100644 paddle/contrib/inference/demo/utils.h diff --git a/paddle/contrib/inference/demo/CMakeLists.txt b/paddle/contrib/inference/demo/CMakeLists.txt index 4041190bb8e78..f49e5d10c3088 100644 --- a/paddle/contrib/inference/demo/CMakeLists.txt +++ b/paddle/contrib/inference/demo/CMakeLists.txt @@ -14,5 +14,6 @@ # inference_api_test(simple_on_word2vec ARGS test_word2vec) + cc_test(mobilenet_infernce_demo SRCS mobilenet.cc DEPS paddle_inference_api paddle_fluid) diff --git a/paddle/contrib/inference/demo/mobilenet.cc b/paddle/contrib/inference/demo/mobilenet.cc index 686958eb222af..987becf022898 100644 --- a/paddle/contrib/inference/demo/mobilenet.cc +++ b/paddle/contrib/inference/demo/mobilenet.cc @@ -20,9 +20,10 @@ limitations under the License. */ #include #include // use glog instead of PADDLE_ENFORCE to avoid importing other paddle header files. #include +#include #include +#include "paddle/contrib/inference/demo/utils.h" #include "paddle/contrib/inference/paddle_inference_api.h" -#include "paddle/utils/StringUtil.h" namespace paddle { namespace demo { @@ -42,45 +43,52 @@ struct Record { void split(const std::string& str, char sep, std::vector* pieces); Record ProcessALine(const std::string& line) { + LOG(INFO) << "process a line"; std::vector columns; split(line, '\t', &columns); CHECK_EQ(columns.size(), 2UL) << "data format error, should be \t"; Record record; - std::vector data_strs; - split(line, ' ', &data_strs); + split(columns[0], ' ', &data_strs); for (auto& d : data_strs) { record.data.push_back(std::stof(d)); } std::vector shape_strs; - split(line, ' ', &shape_strs); + split(columns[1], ' ', &shape_strs); for (auto& s : shape_strs) { record.shape.push_back(std::stoi(s)); } + LOG(INFO) << "data size " << record.data.size(); + LOG(INFO) << "data shape " << record.shape.size(); return record; } - /* * Use the native fluid engine to inference the mobilenet. */ void Main(bool use_gpu) { NativeConfig config; - config.model_dir = FLAGS_modeldir; + // config.model_dir = FLAGS_modeldir; + config.param_file = FLAGS_modeldir + "/__params__"; + config.prog_file = FLAGS_modeldir + "/__model__"; config.use_gpu = use_gpu; config.fraction_of_gpu_memory = 0.15; config.device = 0; + LOG(INFO) << "init predictor"; auto predictor = CreatePaddlePredictor(config); + LOG(INFO) << "begin to process data"; // Just a single batch of data. std::string line; - std::getline(std::cin, line); + std::ifstream file(FLAGS_data); + std::getline(file, line); auto record = ProcessALine(line); + file.close(); // Inference. PaddleBuf buf{.data = record.data.data(), @@ -90,28 +98,16 @@ void Main(bool use_gpu) { .data = buf, .dtype = PaddleDType::FLOAT32}; + LOG(INFO) << "run executor"; std::vector output; predictor->Run({input}, &output); + + LOG(INFO) << "output.size " << output.size(); + auto& tensor = output.front(); + LOG(INFO) << "output: " << SummaryTensor(tensor); } TEST(demo, mobilenet) { Main(false /*use_gpu*/); } -void split(const std::string& str, char sep, std::vector* pieces) { - pieces->clear(); - if (str.empty()) { - return; - } - size_t pos = 0; - size_t next = str.find(sep, pos); - while (next != std::string::npos) { - pieces->push_back(str.substr(pos, next - pos)); - pos = next + 1; - next = str.find(sep, pos); - } - if (!str.substr(pos).empty()) { - pieces->push_back(str.substr(pos)); - } -} - } // namespace demo } // namespace paddle diff --git a/paddle/contrib/inference/demo/utils.h b/paddle/contrib/inference/demo/utils.h new file mode 100644 index 0000000000000..383616720ba26 --- /dev/null +++ b/paddle/contrib/inference/demo/utils.h @@ -0,0 +1,54 @@ +#pragma once +#include +#include + +#include "paddle/contrib/inference/paddle_inference_api.h" + +namespace paddle { +namespace demo { + +static void split(const std::string& str, + char sep, + std::vector* pieces) { + pieces->clear(); + if (str.empty()) { + return; + } + size_t pos = 0; + size_t next = str.find(sep, pos); + while (next != std::string::npos) { + pieces->push_back(str.substr(pos, next - pos)); + pos = next + 1; + next = str.find(sep, pos); + } + if (!str.substr(pos).empty()) { + pieces->push_back(str.substr(pos)); + } +} + +/* + * Get a summary of a PaddleTensor content. + */ +static std::string SummaryTensor(const PaddleTensor& tensor) { + std::stringstream ss; + int num_elems = tensor.data.length / PaddleDtypeSize(tensor.dtype); + + ss << "data[:10]\t"; + switch (tensor.dtype) { + case PaddleDType::INT64: { + for (int i = 0; i < std::min(num_elems, 10); i++) { + ss << static_cast(tensor.data.data)[i] << " "; + } + break; + } + case PaddleDType::FLOAT32: + for (int i = 0; i < std::min(num_elems, 10); i++) { + ss << static_cast(tensor.data.data)[i] << " "; + } + break; + } + return ss.str(); +} + +} // namespace demo +} // namespace paddle diff --git a/paddle/contrib/inference/paddle_inference_api.cc b/paddle/contrib/inference/paddle_inference_api.cc index d67e1e7667800..b8de9bc1f0a22 100644 --- a/paddle/contrib/inference/paddle_inference_api.cc +++ b/paddle/contrib/inference/paddle_inference_api.cc @@ -13,3 +13,20 @@ See the License for the specific language governing permissions and limitations under the License. */ #include "paddle/contrib/inference/paddle_inference_api.h" + +namespace paddle { + +int PaddleDtypeSize(PaddleDType dtype) { + switch (dtype) { + case PaddleDType::FLOAT32: + return sizeof(float); + case PaddleDType::INT64: + return sizeof(int64_t); + default: + // + assert(false); + return -1; + } +} + +} // namespace paddle diff --git a/paddle/contrib/inference/paddle_inference_api.h b/paddle/contrib/inference/paddle_inference_api.h index 77e2d77b6b7fe..6f21a2970a631 100644 --- a/paddle/contrib/inference/paddle_inference_api.h +++ b/paddle/contrib/inference/paddle_inference_api.h @@ -15,12 +15,13 @@ limitations under the License. */ /* * This file contains the definition of a simple Inference API for Paddle. * - * ATTENTION: It requires some C++ features, for lower version C++ or C, we + * ATTENTION: It requires some C++11 features, for lower version C++ or C, we * might release another API. */ #pragma once +#include #include #include #include @@ -32,6 +33,9 @@ enum PaddleDType { INT64, }; +// Get number of bytes of a data type. +int PaddleDtypeSize(PaddleDType dtype); + struct PaddleBuf { void* data; // pointer to the data memory. size_t length; // number of memory bytes. @@ -113,4 +117,5 @@ struct AnakinConfig : public PaddlePredictor::Config { // Similarly, each engine kind should map to a unique predictor implementation. template std::unique_ptr CreatePaddlePredictor(const ConfigT& config); + } // namespace paddle From 2e739cf395591dd24b22eb1ecea45a4d11561b50 Mon Sep 17 00:00:00 2001 From: Superjomn Date: Mon, 25 Jun 2018 08:50:30 +0000 Subject: [PATCH 03/16] add automatic model deploy --- paddle/contrib/inference/demo/CMakeLists.txt | 36 ++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/paddle/contrib/inference/demo/CMakeLists.txt b/paddle/contrib/inference/demo/CMakeLists.txt index f49e5d10c3088..18a0d018c6e32 100644 --- a/paddle/contrib/inference/demo/CMakeLists.txt +++ b/paddle/contrib/inference/demo/CMakeLists.txt @@ -15,5 +15,37 @@ inference_api_test(simple_on_word2vec ARGS test_word2vec) -cc_test(mobilenet_infernce_demo SRCS mobilenet.cc DEPS - paddle_inference_api paddle_fluid) +set(mobilenet_url "xxx") +set(DEMO_INSTALL_DIR "${THIRD_PARTY_PATH}/inference_demo") + + +function(inference_download_test_demo TARGET) + if (NOT WITH_TESTING) + return() + endif() + set(options "") + set(oneValueArgs URL) + set(multiValueArgs SRCS) + cmake_parse_arguments(tests "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(test_dir "${DEMO_INSTALL_DIR}/${TARGET}") + message(STATUS "inference demo ${test_dir}") + + if(NOT EXISTS "${test_dir}") + message(STATUS "Download ${TARGET} model from ${tests_URL}") + execute_process(COMMAND bash -c "mkdir -p ${test_dir}") + execute_process(COMMAND bash -c "cd ${test_dir}; wget -q ${tests_URL}") + execute_process(COMMAND bash -c "cd ${test_dir}; tar xzf *.tar.gz") + endif() + + cc_test(${TARGET} SRCS "${tests_SRCS}" + DEPS paddle_inference_api paddle_fluid + ARGS --data="${test_dir}/data.txt" + --modeldir="${test_dir}/model" + --fraction_of_gpu_memory_to_use=0.5) +endfunction() + + +inference_download_test_demo (mobilenet_inference_demo + SRCS mobilenet.cc + URL http://paddlemodels.bj.bcebos.com/inference-vis-demos%2Fmobilenet.tar.gz) From 904297e419baa632ffbf7c5932aba310ae189f62 Mon Sep 17 00:00:00 2001 From: Superjomn Date: Mon, 25 Jun 2018 10:55:27 +0000 Subject: [PATCH 04/16] upadte --- paddle/contrib/inference/demo/mobilenet.cc | 11 +++++------ paddle/contrib/inference/demo/utils.h | 4 ++-- paddle/contrib/inference/paddle_inference_api.h | 2 ++ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/paddle/contrib/inference/demo/mobilenet.cc b/paddle/contrib/inference/demo/mobilenet.cc index 987becf022898..536a2aa3edd31 100644 --- a/paddle/contrib/inference/demo/mobilenet.cc +++ b/paddle/contrib/inference/demo/mobilenet.cc @@ -91,12 +91,11 @@ void Main(bool use_gpu) { file.close(); // Inference. - PaddleBuf buf{.data = record.data.data(), - .length = record.data.size() * sizeof(float)}; - PaddleTensor input{.name = "xx", - .shape = record.shape, - .data = buf, - .dtype = PaddleDType::FLOAT32}; + PaddleTensor input{ + .name = "xx", + .shape = record.shape, + .data = PaddleBuf(record.data.data(), record.data.size() * sizeof(float)), + .dtype = PaddleDType::FLOAT32}; LOG(INFO) << "run executor"; std::vector output; diff --git a/paddle/contrib/inference/demo/utils.h b/paddle/contrib/inference/demo/utils.h index 383616720ba26..931ab31f65884 100644 --- a/paddle/contrib/inference/demo/utils.h +++ b/paddle/contrib/inference/demo/utils.h @@ -37,13 +37,13 @@ static std::string SummaryTensor(const PaddleTensor& tensor) { switch (tensor.dtype) { case PaddleDType::INT64: { for (int i = 0; i < std::min(num_elems, 10); i++) { - ss << static_cast(tensor.data.data)[i] << " "; + ss << static_cast(tensor.data.data())[i] << " "; } break; } case PaddleDType::FLOAT32: for (int i = 0; i < std::min(num_elems, 10); i++) { - ss << static_cast(tensor.data.data)[i] << " "; + ss << static_cast(tensor.data.data())[i] << " "; } break; } diff --git a/paddle/contrib/inference/paddle_inference_api.h b/paddle/contrib/inference/paddle_inference_api.h index 65d931a382127..238d8c772ec87 100644 --- a/paddle/contrib/inference/paddle_inference_api.h +++ b/paddle/contrib/inference/paddle_inference_api.h @@ -141,4 +141,6 @@ struct AnakinConfig : public PaddlePredictor::Config { template std::unique_ptr CreatePaddlePredictor(const ConfigT& config); +int PaddleDtypeSize(PaddleDType dtype); + } // namespace paddle From 1c0bbfdaa5d40fbcd8b3c03959bb6fa5006aa198 Mon Sep 17 00:00:00 2001 From: Superjomn Date: Mon, 25 Jun 2018 12:08:19 +0000 Subject: [PATCH 05/16] update --- paddle/contrib/inference/demo/utils.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/paddle/contrib/inference/demo/utils.h b/paddle/contrib/inference/demo/utils.h index 931ab31f65884..b5330d8d9d892 100644 --- a/paddle/contrib/inference/demo/utils.h +++ b/paddle/contrib/inference/demo/utils.h @@ -1,3 +1,17 @@ +// Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once #include #include @@ -31,7 +45,7 @@ static void split(const std::string& str, */ static std::string SummaryTensor(const PaddleTensor& tensor) { std::stringstream ss; - int num_elems = tensor.data.length / PaddleDtypeSize(tensor.dtype); + int num_elems = tensor.data.length() / PaddleDtypeSize(tensor.dtype); ss << "data[:10]\t"; switch (tensor.dtype) { From c34da73049411a26821b5e169a1033635191c29b Mon Sep 17 00:00:00 2001 From: Superjomn Date: Mon, 25 Jun 2018 12:44:56 +0000 Subject: [PATCH 06/16] update --- paddle/contrib/inference/demo/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/paddle/contrib/inference/demo/CMakeLists.txt b/paddle/contrib/inference/demo/CMakeLists.txt index 18a0d018c6e32..bd30004f5a6e0 100644 --- a/paddle/contrib/inference/demo/CMakeLists.txt +++ b/paddle/contrib/inference/demo/CMakeLists.txt @@ -40,8 +40,8 @@ function(inference_download_test_demo TARGET) cc_test(${TARGET} SRCS "${tests_SRCS}" DEPS paddle_inference_api paddle_fluid - ARGS --data="${test_dir}/data.txt" - --modeldir="${test_dir}/model" + ARGS --data=${test_dir}/data.txt + --modeldir=${test_dir}/model --fraction_of_gpu_memory_to_use=0.5) endfunction() From 8b827d0d2d094ad745faa78f1b5e4e0f6a4c53c9 Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Mon, 25 Jun 2018 22:42:23 +0800 Subject: [PATCH 07/16] refine --- paddle/contrib/inference/demo/CMakeLists.txt | 11 ++++------- paddle/contrib/inference/demo/mobilenet.cc | 9 ++++++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/paddle/contrib/inference/demo/CMakeLists.txt b/paddle/contrib/inference/demo/CMakeLists.txt index bd30004f5a6e0..be3f38938f266 100644 --- a/paddle/contrib/inference/demo/CMakeLists.txt +++ b/paddle/contrib/inference/demo/CMakeLists.txt @@ -15,9 +15,8 @@ inference_api_test(simple_on_word2vec ARGS test_word2vec) -set(mobilenet_url "xxx") set(DEMO_INSTALL_DIR "${THIRD_PARTY_PATH}/inference_demo") - +set(mobilenet_url http://paddlemodels.bj.bcebos.com/inference-vis-demos%2Fmobilenet.tar.gz) function(inference_download_test_demo TARGET) if (NOT WITH_TESTING) @@ -41,11 +40,9 @@ function(inference_download_test_demo TARGET) cc_test(${TARGET} SRCS "${tests_SRCS}" DEPS paddle_inference_api paddle_fluid ARGS --data=${test_dir}/data.txt - --modeldir=${test_dir}/model - --fraction_of_gpu_memory_to_use=0.5) + --modeldir=${test_dir}/model) endfunction() - -inference_download_test_demo (mobilenet_inference_demo +inference_download_test_demo(mobilenet_inference_demo SRCS mobilenet.cc - URL http://paddlemodels.bj.bcebos.com/inference-vis-demos%2Fmobilenet.tar.gz) + URL ${mobilenet_url}) diff --git a/paddle/contrib/inference/demo/mobilenet.cc b/paddle/contrib/inference/demo/mobilenet.cc index 536a2aa3edd31..846859b6e7f30 100644 --- a/paddle/contrib/inference/demo/mobilenet.cc +++ b/paddle/contrib/inference/demo/mobilenet.cc @@ -34,6 +34,9 @@ DEFINE_string( "", "path of data; each line is a record, format is " "'\t data; @@ -75,7 +78,11 @@ void Main(bool use_gpu) { config.param_file = FLAGS_modeldir + "/__params__"; config.prog_file = FLAGS_modeldir + "/__model__"; config.use_gpu = use_gpu; - config.fraction_of_gpu_memory = 0.15; +#ifdef PADDLE_WITH_CUDA + config.fraction_of_gpu_memory = FLAGS_fraction_of_gpu_memory_to_use; +#else + config.fraction_of_gpu_memory = 0.1; +#endif config.device = 0; LOG(INFO) << "init predictor"; From c583513ca213399f6dd2e81aca61659af760cf19 Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Mon, 25 Jun 2018 23:26:05 +0800 Subject: [PATCH 08/16] add se-renext50 infer demo --- paddle/contrib/inference/demo/CMakeLists.txt | 4 + paddle/contrib/inference/demo/se_renext50.cc | 119 +++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 paddle/contrib/inference/demo/se_renext50.cc diff --git a/paddle/contrib/inference/demo/CMakeLists.txt b/paddle/contrib/inference/demo/CMakeLists.txt index be3f38938f266..1fc7128ba64fd 100644 --- a/paddle/contrib/inference/demo/CMakeLists.txt +++ b/paddle/contrib/inference/demo/CMakeLists.txt @@ -17,6 +17,7 @@ inference_api_test(simple_on_word2vec ARGS test_word2vec) set(DEMO_INSTALL_DIR "${THIRD_PARTY_PATH}/inference_demo") set(mobilenet_url http://paddlemodels.bj.bcebos.com/inference-vis-demos%2Fmobilenet.tar.gz) +set(se_renext50_url http://paddlemodels.bj.bcebos.com/inference-vis-demos%2Fse-renext50.tar.gz) function(inference_download_test_demo TARGET) if (NOT WITH_TESTING) @@ -46,3 +47,6 @@ endfunction() inference_download_test_demo(mobilenet_inference_demo SRCS mobilenet.cc URL ${mobilenet_url}) +inference_download_test_demo(se_renext50_inference_demo + SRCS se_renext50.cc + URL ${se_renext50_url}) diff --git a/paddle/contrib/inference/demo/se_renext50.cc b/paddle/contrib/inference/demo/se_renext50.cc new file mode 100644 index 0000000000000..e6729e1478439 --- /dev/null +++ b/paddle/contrib/inference/demo/se_renext50.cc @@ -0,0 +1,119 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +/* + * This file contains a demo for se-renext50. + * TODO(Superjomn) add some links of the actual models. + */ + +#include +#include // use glog instead of PADDLE_ENFORCE to avoid importing other paddle header files. +#include +#include +#include +#include "paddle/contrib/inference/demo/utils.h" +#include "paddle/contrib/inference/paddle_inference_api.h" + +namespace paddle { +namespace demo { + +DEFINE_string(modeldir, "", "Directory of the inference model."); +DEFINE_string( + data, + "", + "path of data; each line is a record, format is " + "'\t data; + std::vector shape; +}; + +void split(const std::string& str, char sep, std::vector* pieces); + +Record ProcessALine(const std::string& line) { + LOG(INFO) << "process a line"; + std::vector columns; + split(line, '\t', &columns); + CHECK_EQ(columns.size(), 2UL) + << "data format error, should be \t"; + + Record record; + std::vector data_strs; + split(columns[0], ' ', &data_strs); + for (auto& d : data_strs) { + record.data.push_back(std::stof(d)); + } + + std::vector shape_strs; + split(columns[1], ' ', &shape_strs); + for (auto& s : shape_strs) { + record.shape.push_back(std::stoi(s)); + } + LOG(INFO) << "data size " << record.data.size(); + LOG(INFO) << "data shape " << record.shape.size(); + return record; +} + +/* + * Use the native fluid engine to inference the se-renext50. + */ +void Main(bool use_gpu) { + NativeConfig config; + // config.model_dir = FLAGS_modeldir; + config.param_file = FLAGS_modeldir + "/__params__"; + config.prog_file = FLAGS_modeldir + "/__model__"; + config.use_gpu = use_gpu; +#ifdef PADDLE_WITH_CUDA + config.fraction_of_gpu_memory = FLAGS_fraction_of_gpu_memory_to_use; +#else + config.fraction_of_gpu_memory = 0.1; +#endif + config.device = 0; + + LOG(INFO) << "init predictor"; + auto predictor = + CreatePaddlePredictor(config); + + LOG(INFO) << "begin to process data"; + // Just a single batch of data. + std::string line; + std::ifstream file(FLAGS_data); + std::getline(file, line); + auto record = ProcessALine(line); + file.close(); + + // Inference. + PaddleTensor input{ + .name = "xx", + .shape = record.shape, + .data = PaddleBuf(record.data.data(), record.data.size() * sizeof(float)), + .dtype = PaddleDType::FLOAT32}; + + LOG(INFO) << "run executor"; + std::vector output; + predictor->Run({input}, &output); + + LOG(INFO) << "output.size " << output.size(); + auto& tensor = output.front(); + LOG(INFO) << "output: " << SummaryTensor(tensor); +} + +TEST(demo, se_renext50) { Main(false /*use_gpu*/); } + +} // namespace demo +} // namespace paddle From c94cacc8c5d22643e5c316ec208431dd13e8748d Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Tue, 26 Jun 2018 11:43:07 +0800 Subject: [PATCH 09/16] update url --- paddle/contrib/inference/demo/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/paddle/contrib/inference/demo/CMakeLists.txt b/paddle/contrib/inference/demo/CMakeLists.txt index 1fc7128ba64fd..a56fb9c72bdcc 100644 --- a/paddle/contrib/inference/demo/CMakeLists.txt +++ b/paddle/contrib/inference/demo/CMakeLists.txt @@ -17,7 +17,8 @@ inference_api_test(simple_on_word2vec ARGS test_word2vec) set(DEMO_INSTALL_DIR "${THIRD_PARTY_PATH}/inference_demo") set(mobilenet_url http://paddlemodels.bj.bcebos.com/inference-vis-demos%2Fmobilenet.tar.gz) -set(se_renext50_url http://paddlemodels.bj.bcebos.com/inference-vis-demos%2Fse-renext50.tar.gz) +set(se_renext50_url + http://paddlemodels.bj.bcebos.com/inference-vis-demos%2Fse-renext50.tar-0.gz) function(inference_download_test_demo TARGET) if (NOT WITH_TESTING) From fc568f470982ddf61b8ed1ac1c0bcbbe938870f8 Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Tue, 26 Jun 2018 14:18:40 +0800 Subject: [PATCH 10/16] refine and add ocr --- paddle/contrib/inference/demo/CMakeLists.txt | 20 +-- paddle/contrib/inference/demo/se_renext50.cc | 119 ------------------ .../demo/{mobilenet.cc => vis_demo.cc} | 12 +- 3 files changed, 17 insertions(+), 134 deletions(-) delete mode 100644 paddle/contrib/inference/demo/se_renext50.cc rename paddle/contrib/inference/demo/{mobilenet.cc => vis_demo.cc} (93%) diff --git a/paddle/contrib/inference/demo/CMakeLists.txt b/paddle/contrib/inference/demo/CMakeLists.txt index a56fb9c72bdcc..488aed2bc6d3a 100644 --- a/paddle/contrib/inference/demo/CMakeLists.txt +++ b/paddle/contrib/inference/demo/CMakeLists.txt @@ -16,9 +16,7 @@ inference_api_test(simple_on_word2vec ARGS test_word2vec) set(DEMO_INSTALL_DIR "${THIRD_PARTY_PATH}/inference_demo") -set(mobilenet_url http://paddlemodels.bj.bcebos.com/inference-vis-demos%2Fmobilenet.tar.gz) -set(se_renext50_url - http://paddlemodels.bj.bcebos.com/inference-vis-demos%2Fse-renext50.tar-0.gz) +set(URL_ROOT http://paddlemodels.bj.bcebos.com/inference-vis-demos%2F) function(inference_download_test_demo TARGET) if (NOT WITH_TESTING) @@ -42,12 +40,16 @@ function(inference_download_test_demo TARGET) cc_test(${TARGET} SRCS "${tests_SRCS}" DEPS paddle_inference_api paddle_fluid ARGS --data=${test_dir}/data.txt - --modeldir=${test_dir}/model) + --modeldir=${test_dir}/model + --refer=${test_dir}/result.txt) endfunction() inference_download_test_demo(mobilenet_inference_demo - SRCS mobilenet.cc - URL ${mobilenet_url}) -inference_download_test_demo(se_renext50_inference_demo - SRCS se_renext50.cc - URL ${se_renext50_url}) + SRCS vis_demo.cc + URL ${URL_ROOT}mobilenet.tar.gz) +inference_download_test_demo(se_resnext50_inference_demo + SRCS vis_demo.cc + URL ${URL_ROOT}se_resnext50.tar.gz) +inference_download_test_demo(ocr_inference_demo + SRCS vis_demo.cc + URL ${URL_ROOT}ocr.tar.gz) diff --git a/paddle/contrib/inference/demo/se_renext50.cc b/paddle/contrib/inference/demo/se_renext50.cc deleted file mode 100644 index e6729e1478439..0000000000000 --- a/paddle/contrib/inference/demo/se_renext50.cc +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. */ - -/* - * This file contains a demo for se-renext50. - * TODO(Superjomn) add some links of the actual models. - */ - -#include -#include // use glog instead of PADDLE_ENFORCE to avoid importing other paddle header files. -#include -#include -#include -#include "paddle/contrib/inference/demo/utils.h" -#include "paddle/contrib/inference/paddle_inference_api.h" - -namespace paddle { -namespace demo { - -DEFINE_string(modeldir, "", "Directory of the inference model."); -DEFINE_string( - data, - "", - "path of data; each line is a record, format is " - "'\t data; - std::vector shape; -}; - -void split(const std::string& str, char sep, std::vector* pieces); - -Record ProcessALine(const std::string& line) { - LOG(INFO) << "process a line"; - std::vector columns; - split(line, '\t', &columns); - CHECK_EQ(columns.size(), 2UL) - << "data format error, should be \t"; - - Record record; - std::vector data_strs; - split(columns[0], ' ', &data_strs); - for (auto& d : data_strs) { - record.data.push_back(std::stof(d)); - } - - std::vector shape_strs; - split(columns[1], ' ', &shape_strs); - for (auto& s : shape_strs) { - record.shape.push_back(std::stoi(s)); - } - LOG(INFO) << "data size " << record.data.size(); - LOG(INFO) << "data shape " << record.shape.size(); - return record; -} - -/* - * Use the native fluid engine to inference the se-renext50. - */ -void Main(bool use_gpu) { - NativeConfig config; - // config.model_dir = FLAGS_modeldir; - config.param_file = FLAGS_modeldir + "/__params__"; - config.prog_file = FLAGS_modeldir + "/__model__"; - config.use_gpu = use_gpu; -#ifdef PADDLE_WITH_CUDA - config.fraction_of_gpu_memory = FLAGS_fraction_of_gpu_memory_to_use; -#else - config.fraction_of_gpu_memory = 0.1; -#endif - config.device = 0; - - LOG(INFO) << "init predictor"; - auto predictor = - CreatePaddlePredictor(config); - - LOG(INFO) << "begin to process data"; - // Just a single batch of data. - std::string line; - std::ifstream file(FLAGS_data); - std::getline(file, line); - auto record = ProcessALine(line); - file.close(); - - // Inference. - PaddleTensor input{ - .name = "xx", - .shape = record.shape, - .data = PaddleBuf(record.data.data(), record.data.size() * sizeof(float)), - .dtype = PaddleDType::FLOAT32}; - - LOG(INFO) << "run executor"; - std::vector output; - predictor->Run({input}, &output); - - LOG(INFO) << "output.size " << output.size(); - auto& tensor = output.front(); - LOG(INFO) << "output: " << SummaryTensor(tensor); -} - -TEST(demo, se_renext50) { Main(false /*use_gpu*/); } - -} // namespace demo -} // namespace paddle diff --git a/paddle/contrib/inference/demo/mobilenet.cc b/paddle/contrib/inference/demo/vis_demo.cc similarity index 93% rename from paddle/contrib/inference/demo/mobilenet.cc rename to paddle/contrib/inference/demo/vis_demo.cc index 846859b6e7f30..43f413dadc358 100644 --- a/paddle/contrib/inference/demo/mobilenet.cc +++ b/paddle/contrib/inference/demo/vis_demo.cc @@ -13,8 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ /* - * This file contains a demo for mobilenet. - * TODO(Superjomn) add some links of the actual models. + * This file contains demo for mobilenet, se-resnext50 and ocr. */ #include @@ -29,11 +28,13 @@ namespace paddle { namespace demo { DEFINE_string(modeldir, "", "Directory of the inference model."); +DEFINE_string(refer, "", "path to reference result for comparison."); DEFINE_string( data, "", "path of data; each line is a record, format is " "'\t Date: Tue, 26 Jun 2018 14:30:21 +0800 Subject: [PATCH 11/16] update readme --- paddle/contrib/inference/demo/README.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/paddle/contrib/inference/demo/README.md b/paddle/contrib/inference/demo/README.md index 5002b652136fa..f1d256660299a 100644 --- a/paddle/contrib/inference/demo/README.md +++ b/paddle/contrib/inference/demo/README.md @@ -1,6 +1,5 @@ # Infernce Demos -## MobileNet Input data format: - Each line contains a single record @@ -10,10 +9,28 @@ Input data format: \t ``` -Follow the C++ codes in `mobilenet.cc`. +Follow the C++ codes in `vis_demo.cc`. + +## MobileNet To execute the demo, simply run ```sh ./mobilenet_inference_demo --modeldir --data ``` + +## SE-ResNeXt-50 + +To execute the demo, simply run + +```sh +./se_resnext50_inference_demo --modeldir --data +``` + +## OCR + +To execute the demo, simply run + +```sh +./ocr_inference_demo --modeldir --data +``` From d509021df350a664ea3691e9f53f72d65a3181c4 Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Tue, 26 Jun 2018 15:09:01 +0800 Subject: [PATCH 12/16] add check refer --- paddle/contrib/inference/demo/vis_demo.cc | 32 ++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/paddle/contrib/inference/demo/vis_demo.cc b/paddle/contrib/inference/demo/vis_demo.cc index 43f413dadc358..f9c52b789f785 100644 --- a/paddle/contrib/inference/demo/vis_demo.cc +++ b/paddle/contrib/inference/demo/vis_demo.cc @@ -66,10 +66,37 @@ Record ProcessALine(const std::string& line) { record.shape.push_back(std::stoi(s)); } LOG(INFO) << "data size " << record.data.size(); - LOG(INFO) << "data shape " << record.shape.size(); + LOG(INFO) << "data shape size " << record.shape.size(); return record; } +void CheckOutput(const std::string& referfile, const PaddleTensor& output) { + std::string line; + std::ifstream file(referfile); + std::getline(file, line); + auto refer = ProcessALine(line); + file.close(); + + size_t numel = output.data.length() / PaddleDtypeSize(output.dtype); + LOG(INFO) << "predictor output numel " << numel; + LOG(INFO) << "reference output numel " << refer.data.size(); + EXPECT_EQ(numel, refer.data.size()); + switch (output.dtype) { + case PaddleDType::INT64: { + for (size_t i = 0; i < numel; ++i) { + EXPECT_EQ(static_cast(output.data.data())[i], refer.data[i]); + } + break; + } + case PaddleDType::FLOAT32: + for (size_t i = 0; i < numel; ++i) { + EXPECT_NEAR( + static_cast(output.data.data())[i], refer.data[i], 1e-3); + } + break; + } +} + /* * Use the native fluid engine to inference the demo. */ @@ -111,6 +138,9 @@ void Main(bool use_gpu) { LOG(INFO) << "output.size " << output.size(); auto& tensor = output.front(); LOG(INFO) << "output: " << SummaryTensor(tensor); + + // compare with reference result + CheckOutput(FLAGS_refer, tensor); } TEST(demo, vis_demo) { Main(false /*use_gpu*/); } From 7449fe7b1038a4930542bd355450c55ce9dd5707 Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Tue, 26 Jun 2018 15:33:53 +0800 Subject: [PATCH 13/16] update and enable gpu test --- paddle/contrib/inference/demo/CMakeLists.txt | 2 +- paddle/contrib/inference/demo/vis_demo.cc | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/paddle/contrib/inference/demo/CMakeLists.txt b/paddle/contrib/inference/demo/CMakeLists.txt index 488aed2bc6d3a..5764f054d6206 100644 --- a/paddle/contrib/inference/demo/CMakeLists.txt +++ b/paddle/contrib/inference/demo/CMakeLists.txt @@ -15,7 +15,7 @@ inference_api_test(simple_on_word2vec ARGS test_word2vec) -set(DEMO_INSTALL_DIR "${THIRD_PARTY_PATH}/inference_demo") +set(DEMO_INSTALL_DIR "${PADDLE_BINARY_DIR}/inference_demo") set(URL_ROOT http://paddlemodels.bj.bcebos.com/inference-vis-demos%2F) function(inference_download_test_demo TARGET) diff --git a/paddle/contrib/inference/demo/vis_demo.cc b/paddle/contrib/inference/demo/vis_demo.cc index f9c52b789f785..c7d695fde2fad 100644 --- a/paddle/contrib/inference/demo/vis_demo.cc +++ b/paddle/contrib/inference/demo/vis_demo.cc @@ -102,15 +102,13 @@ void CheckOutput(const std::string& referfile, const PaddleTensor& output) { */ void Main(bool use_gpu) { NativeConfig config; - // config.model_dir = FLAGS_modeldir; config.param_file = FLAGS_modeldir + "/__params__"; config.prog_file = FLAGS_modeldir + "/__model__"; config.use_gpu = use_gpu; - config.fraction_of_gpu_memory = 0.1; + config.device = 0; #ifdef PADDLE_WITH_CUDA config.fraction_of_gpu_memory = FLAGS_fraction_of_gpu_memory_to_use; #endif - config.device = 0; LOG(INFO) << "init predictor"; auto predictor = @@ -143,7 +141,9 @@ void Main(bool use_gpu) { CheckOutput(FLAGS_refer, tensor); } -TEST(demo, vis_demo) { Main(false /*use_gpu*/); } - +TEST(demo, vis_demo_cpu) { Main(false /*use_gpu*/); } +#ifdef PADDLE_WITH_CUDA +TEST(demo, vis_demo_gpu) { Main(true /*use_gpu*/); } +#endif } // namespace demo } // namespace paddle From 5c8e323d1c8971ebc4a48e3c79b72bd408ef57b6 Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Tue, 26 Jun 2018 16:18:40 +0800 Subject: [PATCH 14/16] fix issue on gpu --- paddle/contrib/inference/demo/vis_demo.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/paddle/contrib/inference/demo/vis_demo.cc b/paddle/contrib/inference/demo/vis_demo.cc index c7d695fde2fad..c177639d3768c 100644 --- a/paddle/contrib/inference/demo/vis_demo.cc +++ b/paddle/contrib/inference/demo/vis_demo.cc @@ -24,6 +24,10 @@ limitations under the License. */ #include "paddle/contrib/inference/demo/utils.h" #include "paddle/contrib/inference/paddle_inference_api.h" +#ifdef PADDLE_WITH_CUDA +DECLARE_double(fraction_of_gpu_memory_to_use); +#endif + namespace paddle { namespace demo { @@ -35,10 +39,6 @@ DEFINE_string( "path of data; each line is a record, format is " "'\t data; std::vector shape; From 33b8ea8302ac2a132123228972fab4355fa0f38f Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Tue, 26 Jun 2018 16:41:24 +0800 Subject: [PATCH 15/16] update threshold --- paddle/contrib/inference/demo/vis_demo.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paddle/contrib/inference/demo/vis_demo.cc b/paddle/contrib/inference/demo/vis_demo.cc index c177639d3768c..45575f9a862de 100644 --- a/paddle/contrib/inference/demo/vis_demo.cc +++ b/paddle/contrib/inference/demo/vis_demo.cc @@ -91,7 +91,7 @@ void CheckOutput(const std::string& referfile, const PaddleTensor& output) { case PaddleDType::FLOAT32: for (size_t i = 0; i < numel; ++i) { EXPECT_NEAR( - static_cast(output.data.data())[i], refer.data[i], 1e-3); + static_cast(output.data.data())[i], refer.data[i], 1e-5); } break; } From ba0401a318c0481dd1ed7e417ec4e18fca4f5da9 Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Wed, 27 Jun 2018 10:13:50 +0800 Subject: [PATCH 16/16] disable inference mobilenet test --- paddle/contrib/inference/demo/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/paddle/contrib/inference/demo/CMakeLists.txt b/paddle/contrib/inference/demo/CMakeLists.txt index 5764f054d6206..566c7d1a0784f 100644 --- a/paddle/contrib/inference/demo/CMakeLists.txt +++ b/paddle/contrib/inference/demo/CMakeLists.txt @@ -44,9 +44,10 @@ function(inference_download_test_demo TARGET) --refer=${test_dir}/result.txt) endfunction() -inference_download_test_demo(mobilenet_inference_demo - SRCS vis_demo.cc - URL ${URL_ROOT}mobilenet.tar.gz) +# disable mobilenet test +#inference_download_test_demo(mobilenet_inference_demo +# SRCS vis_demo.cc +# URL ${URL_ROOT}mobilenet.tar.gz) inference_download_test_demo(se_resnext50_inference_demo SRCS vis_demo.cc URL ${URL_ROOT}se_resnext50.tar.gz)