general_model.cpp 15.8 KB
Newer Older
G
guru4elephant 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// 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.

G
guru4elephant 已提交
15
#include "core/general-client/include/general_model.h"
M
MRXLT 已提交
16
#include <fstream>
G
guru4elephant 已提交
17 18 19
#include "core/sdk-cpp/builtin_format.pb.h"
#include "core/sdk-cpp/include/common.h"
#include "core/sdk-cpp/include/predictor_sdk.h"
G
guru4elephant 已提交
20
#include "core/util/include/timer.h"
G
guru4elephant 已提交
21

22 23 24
DEFINE_bool(profile_client, false, "");
DEFINE_bool(profile_server, false, "");

G
guru4elephant 已提交
25
using baidu::paddle_serving::Timer;
G
guru4elephant 已提交
26 27 28 29 30 31
using baidu::paddle_serving::predictor::general_model::Request;
using baidu::paddle_serving::predictor::general_model::Response;
using baidu::paddle_serving::predictor::general_model::Tensor;
using baidu::paddle_serving::predictor::general_model::FeedInst;
using baidu::paddle_serving::predictor::general_model::FetchInst;

32
std::once_flag gflags_init_flag;
M
MRXLT 已提交
33
namespace py = pybind11;
34

G
guru4elephant 已提交
35 36 37
namespace baidu {
namespace paddle_serving {
namespace general_model {
38
using configure::GeneralModelConfig;
G
guru4elephant 已提交
39

40 41
void PredictorClient::init_gflags(std::vector<std::string> argv) {
  std::call_once(gflags_init_flag, [&]() {
42
#ifndef BCLOUD
M
MRXLT 已提交
43
    FLAGS_logtostderr = true;
44
#endif
M
MRXLT 已提交
45 46 47 48 49 50 51 52 53 54 55 56
    argv.insert(argv.begin(), "dummy");
    int argc = argv.size();
    char **arr = new char *[argv.size()];
    std::string line;
    for (size_t i = 0; i < argv.size(); i++) {
      arr[i] = &argv[i][0];
      line += argv[i];
      line += ' ';
    }
    google::ParseCommandLineFlags(&argc, &arr, true);
    VLOG(2) << "Init commandline: " << line;
  });
57 58
}

59 60 61
int PredictorClient::init(const std::string &conf_file) {
  try {
    GeneralModelConfig model_config;
M
MRXLT 已提交
62
    if (configure::read_proto_conf(conf_file.c_str(), &model_config) != 0) {
63 64 65 66
      LOG(ERROR) << "Failed to load general model config"
                 << ", file path: " << conf_file;
      return -1;
    }
67

68 69 70 71 72
    _feed_name_to_idx.clear();
    _fetch_name_to_idx.clear();
    _shape.clear();
    int feed_var_num = model_config.feed_var_size();
    int fetch_var_num = model_config.fetch_var_size();
73 74
    VLOG(2) << "feed var num: " << feed_var_num
            << "fetch_var_num: " << fetch_var_num;
75 76
    for (int i = 0; i < feed_var_num; ++i) {
      _feed_name_to_idx[model_config.feed_var(i).alias_name()] = i;
77 78
      VLOG(2) << "feed alias name: " << model_config.feed_var(i).alias_name()
              << " index: " << i;
79
      std::vector<int> tmp_feed_shape;
M
MRXLT 已提交
80 81
      VLOG(2) << "feed"
              << "[" << i << "] shape:";
82 83
      for (int j = 0; j < model_config.feed_var(i).shape_size(); ++j) {
        tmp_feed_shape.push_back(model_config.feed_var(i).shape(j));
M
MRXLT 已提交
84
        VLOG(2) << "shape[" << j << "]: " << model_config.feed_var(i).shape(j);
85 86
      }
      _type.push_back(model_config.feed_var(i).feed_type());
M
MRXLT 已提交
87 88 89
      VLOG(2) << "feed"
              << "[" << i
              << "] feed type: " << model_config.feed_var(i).feed_type();
90
      _shape.push_back(tmp_feed_shape);
G
guru4elephant 已提交
91 92
    }

93 94
    for (int i = 0; i < fetch_var_num; ++i) {
      _fetch_name_to_idx[model_config.fetch_var(i).alias_name()] = i;
M
MRXLT 已提交
95 96
      VLOG(2) << "fetch [" << i << "]"
              << " alias name: " << model_config.fetch_var(i).alias_name();
97 98
      _fetch_name_to_var_name[model_config.fetch_var(i).alias_name()] =
          model_config.fetch_var(i).name();
99 100
      _fetch_name_to_type[model_config.fetch_var(i).alias_name()] =
          model_config.fetch_var(i).fetch_type();
101
    }
M
MRXLT 已提交
102
  } catch (std::exception &e) {
103 104
    LOG(ERROR) << "Failed load general model config" << e.what();
    return -1;
G
guru4elephant 已提交
105
  }
106
  return 0;
G
guru4elephant 已提交
107 108
}

M
MRXLT 已提交
109 110
void PredictorClient::set_predictor_conf(const std::string &conf_path,
                                         const std::string &conf_file) {
G
guru4elephant 已提交
111 112 113
  _predictor_path = conf_path;
  _predictor_conf = conf_file;
}
114 115 116
int PredictorClient::destroy_predictor() {
  _api.thrd_finalize();
  _api.destroy();
B
barrierye 已提交
117
  return 0;
118 119
}

M
MRXLT 已提交
120
int PredictorClient::create_predictor_by_desc(const std::string &sdk_desc) {
G
guru4elephant 已提交
121 122 123 124
  if (_api.create(sdk_desc) != 0) {
    LOG(ERROR) << "Predictor Creation Failed";
    return -1;
  }
D
dongdaxiang 已提交
125
  // _api.thrd_initialize();
B
barrierye 已提交
126
  return 0;
G
guru4elephant 已提交
127 128
}

G
guru4elephant 已提交
129
int PredictorClient::create_predictor() {
G
guru4elephant 已提交
130 131
  VLOG(2) << "Predictor path: " << _predictor_path
          << " predictor file: " << _predictor_conf;
G
guru4elephant 已提交
132 133 134 135
  if (_api.create(_predictor_path.c_str(), _predictor_conf.c_str()) != 0) {
    LOG(ERROR) << "Predictor Creation Failed";
    return -1;
  }
D
dongdaxiang 已提交
136
  // _api.thrd_initialize();
B
barrierye 已提交
137
  return 0;
G
guru4elephant 已提交
138 139
}

M
MRXLT 已提交
140 141 142 143
int PredictorClient::numpy_predict(
    const std::vector<std::vector<py::array_t<float>>> &float_feed_batch,
    const std::vector<std::string> &float_feed_name,
    const std::vector<std::vector<int>> &float_shape,
W
wangjiawei04 已提交
144
    const std::vector<std::vector<int>> &float_lod_slot_batch,
M
MRXLT 已提交
145 146 147
    const std::vector<std::vector<py::array_t<int64_t>>> &int_feed_batch,
    const std::vector<std::string> &int_feed_name,
    const std::vector<std::vector<int>> &int_shape,
W
wangjiawei04 已提交
148
    const std::vector<std::vector<int>> &int_lod_slot_batch,
M
MRXLT 已提交
149 150
    const std::vector<std::string> &fetch_name,
    PredictorRes &predict_res_batch,
151 152
    const int &pid,
    const uint64_t log_id) {
M
MRXLT 已提交
153
  int batch_size = std::max(float_feed_batch.size(), int_feed_batch.size());
D
dongdaxiang 已提交
154
  VLOG(2) << "batch size: " << batch_size;
M
MRXLT 已提交
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
  predict_res_batch.clear();
  Timer timeline;
  int64_t preprocess_start = timeline.TimeStampUS();

  int fetch_name_num = fetch_name.size();

  _api.thrd_initialize();
  std::string variant_tag;
  _predictor = _api.fetch_predictor("general_model", &variant_tag);
  predict_res_batch.set_variant_tag(variant_tag);
  VLOG(2) << "fetch general model predictor done.";
  VLOG(2) << "float feed name size: " << float_feed_name.size();
  VLOG(2) << "int feed name size: " << int_feed_name.size();
  VLOG(2) << "max body size : " << brpc::fLU64::FLAGS_max_body_size;
  Request req;
170
  req.set_log_id(log_id);
M
MRXLT 已提交
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
  for (auto &name : fetch_name) {
    req.add_fetch_var_names(name);
  }

  for (int bi = 0; bi < batch_size; bi++) {
    VLOG(2) << "prepare batch " << bi;
    std::vector<Tensor *> tensor_vec;
    FeedInst *inst = req.add_insts();
    std::vector<py::array_t<float>> float_feed = float_feed_batch[bi];
    std::vector<py::array_t<int64_t>> int_feed = int_feed_batch[bi];
    for (auto &name : float_feed_name) {
      tensor_vec.push_back(inst->add_tensor_array());
    }

    for (auto &name : int_feed_name) {
      tensor_vec.push_back(inst->add_tensor_array());
    }

    VLOG(2) << "batch [" << bi << "] int_feed_name and float_feed_name "
            << "prepared";

    int vec_idx = 0;
    VLOG(2) << "tensor_vec size " << tensor_vec.size() << " float shape "
            << float_shape.size();
    for (auto &name : float_feed_name) {
      int idx = _feed_name_to_idx[name];
      Tensor *tensor = tensor_vec[idx];
      VLOG(2) << "prepare float feed " << name << " shape size "
              << float_shape[vec_idx].size();
      for (uint32_t j = 0; j < float_shape[vec_idx].size(); ++j) {
        tensor->add_shape(float_shape[vec_idx][j]);
      }
W
wangjiawei04 已提交
203 204 205
      for (uint32_t j = 0; j < float_lod_slot_batch[vec_idx].size(); ++j) {
        tensor->add_lod(float_lod_slot_batch[vec_idx][j]);
      }
M
MRXLT 已提交
206 207 208
      tensor->set_elem_type(1);
      const int float_shape_size = float_shape[vec_idx].size();
      switch (float_shape_size) {
M
bug fix  
MRXLT 已提交
209 210 211 212 213 214 215 216 217 218 219 220 221
        case 4: {
          auto float_array = float_feed[vec_idx].unchecked<4>();
          for (ssize_t i = 0; i < float_array.shape(0); i++) {
            for (ssize_t j = 0; j < float_array.shape(1); j++) {
              for (ssize_t k = 0; k < float_array.shape(2); k++) {
                for (ssize_t l = 0; l < float_array.shape(3); l++) {
                  tensor->add_float_data(float_array(i, j, k, l));
                }
              }
            }
          }
          break;
        }
M
MRXLT 已提交
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
        case 3: {
          auto float_array = float_feed[vec_idx].unchecked<3>();
          for (ssize_t i = 0; i < float_array.shape(0); i++) {
            for (ssize_t j = 0; j < float_array.shape(1); j++) {
              for (ssize_t k = 0; k < float_array.shape(2); k++) {
                tensor->add_float_data(float_array(i, j, k));
              }
            }
          }
          break;
        }
        case 2: {
          auto float_array = float_feed[vec_idx].unchecked<2>();
          for (ssize_t i = 0; i < float_array.shape(0); i++) {
            for (ssize_t j = 0; j < float_array.shape(1); j++) {
              tensor->add_float_data(float_array(i, j));
            }
          }
          break;
        }
M
bug fix  
MRXLT 已提交
242 243 244 245 246 247 248
        case 1: {
          auto float_array = float_feed[vec_idx].unchecked<1>();
          for (ssize_t i = 0; i < float_array.shape(0); i++) {
            tensor->add_float_data(float_array(i));
          }
          break;
        }
M
MRXLT 已提交
249 250 251 252 253 254 255 256 257 258 259
      }
      vec_idx++;
    }

    VLOG(2) << "batch [" << bi << "] "
            << "float feed value prepared";

    vec_idx = 0;
    for (auto &name : int_feed_name) {
      int idx = _feed_name_to_idx[name];
      Tensor *tensor = tensor_vec[idx];
M
MRXLT 已提交
260

M
MRXLT 已提交
261 262 263
      for (uint32_t j = 0; j < int_shape[vec_idx].size(); ++j) {
        tensor->add_shape(int_shape[vec_idx][j]);
      }
W
wangjiawei04 已提交
264 265 266
      for (uint32_t j = 0; j < int_lod_slot_batch[vec_idx].size(); ++j) {
        tensor->add_lod(int_lod_slot_batch[vec_idx][j]);
      }
M
MRXLT 已提交
267 268 269 270 271 272 273 274 275
      tensor->set_elem_type(_type[idx]);

      if (_type[idx] == 0) {
        VLOG(2) << "prepare int feed " << name << " shape size "
                << int_shape[vec_idx].size();
      } else {
        VLOG(2) << "prepare int32 feed " << name << " shape size "
                << int_shape[vec_idx].size();
      }
M
MRXLT 已提交
276 277 278 279

      const int int_shape_size = int_shape[vec_idx].size();
      switch (int_shape_size) {
        case 4: {
M
bug fix  
MRXLT 已提交
280
          auto int_array = int_feed[vec_idx].unchecked<4>();
M
MRXLT 已提交
281 282 283 284
          for (ssize_t i = 0; i < int_array.shape(0); i++) {
            for (ssize_t j = 0; j < int_array.shape(1); j++) {
              for (ssize_t k = 0; k < int_array.shape(2); k++) {
                for (ssize_t l = 0; k < int_array.shape(3); l++) {
M
MRXLT 已提交
285 286 287 288 289
                  if (_type[idx] == 0) {
                    tensor->add_int64_data(int_array(i, j, k, l));
                  } else {
                    tensor->add_int_data(int_array(i, j, k, l));
                  }
M
MRXLT 已提交
290 291 292 293 294 295 296 297 298 299 300
                }
              }
            }
          }
          break;
        }
        case 3: {
          auto int_array = int_feed[vec_idx].unchecked<3>();
          for (ssize_t i = 0; i < int_array.shape(0); i++) {
            for (ssize_t j = 0; j < int_array.shape(1); j++) {
              for (ssize_t k = 0; k < int_array.shape(2); k++) {
M
MRXLT 已提交
301 302 303 304 305
                if (_type[idx] == 0) {
                  tensor->add_int64_data(int_array(i, j, k));
                } else {
                  tensor->add_int_data(int_array(i, j, k));
                }
M
MRXLT 已提交
306 307 308 309 310 311 312 313 314
              }
            }
          }
          break;
        }
        case 2: {
          auto int_array = int_feed[vec_idx].unchecked<2>();
          for (ssize_t i = 0; i < int_array.shape(0); i++) {
            for (ssize_t j = 0; j < int_array.shape(1); j++) {
M
MRXLT 已提交
315 316 317 318 319
              if (_type[idx] == 0) {
                tensor->add_int64_data(int_array(i, j));
              } else {
                tensor->add_int_data(int_array(i, j));
              }
M
MRXLT 已提交
320 321 322 323 324
            }
          }
          break;
        }
        case 1: {
M
bug fix  
MRXLT 已提交
325
          auto int_array = int_feed[vec_idx].unchecked<1>();
M
MRXLT 已提交
326
          for (ssize_t i = 0; i < int_array.shape(0); i++) {
M
MRXLT 已提交
327 328 329 330 331
            if (_type[idx] == 0) {
              tensor->add_int64_data(int_array(i));
            } else {
              tensor->add_int_data(int_array(i));
            }
M
MRXLT 已提交
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
          }
          break;
        }
      }
      vec_idx++;
    }

    VLOG(2) << "batch [" << bi << "] "
            << "int feed value prepared";
  }

  int64_t preprocess_end = timeline.TimeStampUS();

  int64_t client_infer_start = timeline.TimeStampUS();

  Response res;

  int64_t client_infer_end = 0;
  int64_t postprocess_start = 0;
  int64_t postprocess_end = 0;

  if (FLAGS_profile_client) {
    if (FLAGS_profile_server) {
      req.set_profile_server(true);
    }
  }

  res.Clear();
  if (_predictor->inference(&req, &res) != 0) {
    LOG(ERROR) << "failed call predictor with req: " << req.ShortDebugString();
    return -1;
  } else {
    client_infer_end = timeline.TimeStampUS();
    postprocess_start = client_infer_end;
    VLOG(2) << "get model output num";
    uint32_t model_num = res.outputs_size();
    VLOG(2) << "model num: " << model_num;
B
barrierye 已提交
369 370 371
    for (uint32_t m_idx = 0; m_idx < model_num; ++m_idx) {
      VLOG(2) << "process model output index: " << m_idx;
      auto output = res.outputs(m_idx);
B
barrierye 已提交
372 373
      ModelRes model;
      model.set_engine_name(output.engine_name());
B
barrierye 已提交
374

M
MRXLT 已提交
375
      int idx = 0;
M
MRXLT 已提交
376
      for (auto &name : fetch_name) {
B
barrierye 已提交
377
        // int idx = _fetch_name_to_idx[name];
B
barrierye 已提交
378
        int shape_size = output.insts(0).tensor_array(idx).shape_size();
B
barrierye 已提交
379 380
        VLOG(2) << "fetch var " << name << " index " << idx << " shape size "
                << shape_size;
B
barrierye 已提交
381 382 383 384 385 386 387 388 389 390 391
        model._shape_map[name].resize(shape_size);
        for (int i = 0; i < shape_size; ++i) {
          model._shape_map[name][i] =
              output.insts(0).tensor_array(idx).shape(i);
        }
        int lod_size = output.insts(0).tensor_array(idx).lod_size();
        if (lod_size > 0) {
          model._lod_map[name].resize(lod_size);
          for (int i = 0; i < lod_size; ++i) {
            model._lod_map[name][i] = output.insts(0).tensor_array(idx).lod(i);
          }
392
        }
B
barrierye 已提交
393
        idx += 1;
B
barrierye 已提交
394
      }
395

M
MRXLT 已提交
396 397
      idx = 0;

B
barrierye 已提交
398
      for (auto &name : fetch_name) {
B
barrierye 已提交
399
        // int idx = _fetch_name_to_idx[name];
B
barrierye 已提交
400
        if (_fetch_name_to_type[name] == 0) {
M
MRXLT 已提交
401
          VLOG(2) << "ferch var " << name << "type int64";
B
barrierye 已提交
402
          int size = output.insts(0).tensor_array(idx).int64_data_size();
W
WangXi 已提交
403 404 405
          model._int64_value_map[name] = std::vector<int64_t>(
              output.insts(0).tensor_array(idx).int64_data().begin(),
              output.insts(0).tensor_array(idx).int64_data().begin() + size);
M
MRXLT 已提交
406
        } else if (_fetch_name_to_type[name] == 1) {
B
barrierye 已提交
407
          VLOG(2) << "fetch var " << name << "type float";
B
barrierye 已提交
408
          int size = output.insts(0).tensor_array(idx).float_data_size();
W
WangXi 已提交
409 410 411
          model._float_value_map[name] = std::vector<float>(
              output.insts(0).tensor_array(idx).float_data().begin(),
              output.insts(0).tensor_array(idx).float_data().begin() + size);
M
MRXLT 已提交
412 413 414
        } else if (_fetch_name_to_type[name] == 2) {
          VLOG(2) << "fetch var " << name << "type int32";
          int size = output.insts(0).tensor_array(idx).int_data_size();
M
MRXLT 已提交
415 416 417
          model._int32_value_map[name] = std::vector<int32_t>(
              output.insts(0).tensor_array(idx).int_data().begin(),
              output.insts(0).tensor_array(idx).int_data().begin() + size);
M
MRXLT 已提交
418
        }
B
barrierye 已提交
419
        idx += 1;
M
MRXLT 已提交
420
      }
B
barrierye 已提交
421
      predict_res_batch.add_model_res(std::move(model));
M
MRXLT 已提交
422
    }
423
    postprocess_end = timeline.TimeStampUS();
M
MRXLT 已提交
424 425
  }

M
MRXLT 已提交
426 427 428
  if (FLAGS_profile_client) {
    std::ostringstream oss;
    oss << "PROFILE\t"
M
MRXLT 已提交
429
        << "pid:" << pid << "\t"
M
MRXLT 已提交
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
        << "prepro_0:" << preprocess_start << " "
        << "prepro_1:" << preprocess_end << " "
        << "client_infer_0:" << client_infer_start << " "
        << "client_infer_1:" << client_infer_end << " ";
    if (FLAGS_profile_server) {
      int op_num = res.profile_time_size() / 2;
      for (int i = 0; i < op_num; ++i) {
        oss << "op" << i << "_0:" << res.profile_time(i * 2) << " ";
        oss << "op" << i << "_1:" << res.profile_time(i * 2 + 1) << " ";
      }
    }

    oss << "postpro_0:" << postprocess_start << " ";
    oss << "postpro_1:" << postprocess_end;

    fprintf(stderr, "%s\n", oss.str().c_str());
  }
D
dongdaxiang 已提交
447 448

  _api.thrd_clear();
M
MRXLT 已提交
449
  return 0;
M
MRXLT 已提交
450
}
G
guru4elephant 已提交
451 452 453
}  // namespace general_model
}  // namespace paddle_serving
}  // namespace baidu