paddle_engine.h 6.9 KB
Newer Older
Z
update  
zhangjun 已提交
1
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
Z
zhangjun 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
//
// 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 <pthread.h>
#include <fstream>
#include <map>
Z
zhangjun 已提交
20
#include <memory>
Z
zhangjun 已提交
21 22 23 24
#include <string>
#include <vector>
#include "core/configure/include/configure_parser.h"
#include "core/configure/inferencer_configure.pb.h"
Z
zhangjun 已提交
25
#include "core/predictor/common/utils.h"
Z
zhangjun 已提交
26
#include "core/predictor/framework/infer.h"
Z
zhangjun 已提交
27 28 29 30 31 32 33
#include "paddle_inference_api.h"  // NOLINT

namespace baidu {
namespace paddle_serving {
namespace inference {

using paddle_infer::Config;
Z
zhangjun 已提交
34
using paddle_infer::PrecisionType;
Z
zhangjun 已提交
35 36 37 38
using paddle_infer::Predictor;
using paddle_infer::Tensor;
using paddle_infer::CreatePredictor;

Z
zhangjun 已提交
39
DECLARE_int32(gpuid);
Z
fix  
zhangjun 已提交
40 41
DECLARE_string(precision);
DECLARE_bool(use_calib);
Z
zhangjun 已提交
42

Z
zhangjun 已提交
43 44
static const int max_batch = 32;
static const int min_subgraph_size = 3;
Z
fix  
zhangjun 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57
static PrecisionType precision_type;

PrecisionType GetPrecision(const std::string& precision_data) {
  std::string precision_type = predictor::ToLower(precision_data);
  if (precision_type == "fp32") {
    return PrecisionType::kFloat32;
  } else if (precision_type == "int8") {
    return PrecisionType::kInt8;
  } else if (precision_type == "fp16") {
    return PrecisionType::kHalf;
  }
  return PrecisionType::kFloat32;
}
Z
zhangjun 已提交
58

Z
update  
zhangjun 已提交
59
// Engine Base
H
HexToString 已提交
60
class EngineCore {
Z
zhangjun 已提交
61
 public:
H
HexToString 已提交
62
  virtual ~EngineCore() {}
Z
zhangjun 已提交
63
  virtual std::vector<std::string> GetInputNames() {
Z
zhangjun 已提交
64
    return _predictor->GetInputNames();
Z
zhangjun 已提交
65 66 67
  }

  virtual std::unique_ptr<Tensor> GetInputHandle(const std::string& name) {
Z
zhangjun 已提交
68
    return _predictor->GetInputHandle(name);
Z
zhangjun 已提交
69 70 71
  }

  virtual std::vector<std::string> GetOutputNames() {
Z
zhangjun 已提交
72
    return _predictor->GetOutputNames();
Z
zhangjun 已提交
73 74 75
  }

  virtual std::unique_ptr<Tensor> GetOutputHandle(const std::string& name) {
Z
zhangjun 已提交
76
    return _predictor->GetOutputHandle(name);
Z
zhangjun 已提交
77 78 79
  }

  virtual bool Run() {
Z
zhangjun 已提交
80
    if (!_predictor->Run()) {
Z
zhangjun 已提交
81 82 83 84 85 86
      LOG(ERROR) << "Failed call Run with paddle predictor";
      return false;
    }
    return true;
  }

Z
update  
zhangjun 已提交
87
  virtual int create(const configure::EngineDesc& conf) = 0;
Z
zhangjun 已提交
88

Z
update  
zhangjun 已提交
89 90
  virtual int clone(void* predictor) {
    if (predictor == NULL) {
Z
zhangjun 已提交
91 92 93
      LOG(ERROR) << "origin paddle Predictor is null.";
      return -1;
    }
Z
zhangjun 已提交
94 95
    Predictor* prep = static_cast<Predictor*>(predictor);
    _predictor = prep->Clone();
Z
update  
zhangjun 已提交
96 97
    if (_predictor.get() == NULL) {
      LOG(ERROR) << "fail to clone paddle predictor: " << predictor;
Z
zhangjun 已提交
98 99 100 101 102
      return -1;
    }
    return 0;
  }

Z
update  
zhangjun 已提交
103
  virtual void* get() { return _predictor.get(); }
Z
zhangjun 已提交
104 105

 protected:
Z
update  
zhangjun 已提交
106
  std::shared_ptr<Predictor> _predictor;
Z
zhangjun 已提交
107 108
};

Z
update  
zhangjun 已提交
109
// Paddle Inference Engine
H
HexToString 已提交
110
class PaddleInferenceEngine : public EngineCore {
Z
zhangjun 已提交
111
 public:
Z
update  
zhangjun 已提交
112 113 114
  int create(const configure::EngineDesc& engine_conf) {
    std::string model_path = engine_conf.model_dir();
    if (access(model_path.c_str(), F_OK) == -1) {
Z
zhangjun 已提交
115
      LOG(ERROR) << "create paddle predictor failed, path not exits: "
Z
update  
zhangjun 已提交
116
                 << model_path;
Z
zhangjun 已提交
117 118 119 120
      return -1;
    }

    Config config;
Z
update  
zhangjun 已提交
121
    // todo, auto config(zhangjun)
Z
zhangjun 已提交
122 123 124
    if (engine_conf.has_encrypted_model() && engine_conf.encrypted_model()) {
      // decrypt model
      std::string model_buffer, params_buffer, key_buffer;
H
HexToString 已提交
125 126 127
      predictor::ReadBinaryFile(model_path + "/encrypt_model", &model_buffer);
      predictor::ReadBinaryFile(model_path + "/encrypt_params", &params_buffer);
      predictor::ReadBinaryFile(model_path + "/key", &key_buffer);
Z
zhangjun 已提交
128 129 130 131 132 133 134 135 136 137

      auto cipher = paddle::MakeCipher("");
      std::string real_model_buffer = cipher->Decrypt(model_buffer, key_buffer);
      std::string real_params_buffer =
          cipher->Decrypt(params_buffer, key_buffer);
      config.SetModelBuffer(&real_model_buffer[0],
                            real_model_buffer.size(),
                            &real_params_buffer[0],
                            real_params_buffer.size());
    } else if (engine_conf.has_combined_model()) {
Z
zhangjun 已提交
138
      if (!engine_conf.combined_model()) {
Z
zhangjun 已提交
139
        config.SetModel(model_path);
Z
update  
zhangjun 已提交
140 141 142 143 144 145 146
      } else {
        config.SetParamsFile(model_path + "/__params__");
        config.SetProgFile(model_path + "/__model__");
      }
    } else {
      config.SetParamsFile(model_path + "/__params__");
      config.SetProgFile(model_path + "/__model__");
Z
zhangjun 已提交
147
    }
Z
zhangjun 已提交
148

Z
zhangjun 已提交
149
    config.SwitchSpecifyInputNames(true);
Z
update  
zhangjun 已提交
150 151 152 153
    config.SetCpuMathLibraryNumThreads(1);
    if (engine_conf.has_use_gpu() && engine_conf.use_gpu()) {
      // 2000MB GPU memory
      config.EnableUseGpu(2000, FLAGS_gpuid);
Z
zhangjun 已提交
154
    }
Z
fix  
zhangjun 已提交
155
    precision_type = GetPrecision(FLAGS_precision);
Z
zhangjun 已提交
156

Z
update  
zhangjun 已提交
157
    if (engine_conf.has_use_trt() && engine_conf.use_trt()) {
Z
zhangjun 已提交
158 159 160
      if (!engine_conf.has_use_gpu() || !engine_conf.use_gpu()) {
        config.EnableUseGpu(2000, FLAGS_gpuid);
      }
Z
update  
zhangjun 已提交
161 162 163
      config.EnableTensorRtEngine(1 << 20,
                                  max_batch,
                                  min_subgraph_size,
164
                                  precision_type,
Z
update  
zhangjun 已提交
165
                                  false,
Z
fix  
zhangjun 已提交
166
                                  FLAGS_use_calib);
Z
update  
zhangjun 已提交
167
      LOG(INFO) << "create TensorRT predictor";
Z
zhangjun 已提交
168 169
    }

Z
zhangjun 已提交
170
    if (engine_conf.has_use_lite() && engine_conf.use_lite()) {
171 172 173 174 175 176
      config.EnableLiteEngine(precision_type, true);
    }

    if ((!engine_conf.has_use_lite() && !engine_conf.has_use_gpu()) ||
        (engine_conf.has_use_lite() && !engine_conf.use_lite() &&
         engine_conf.has_use_gpu() && !engine_conf.use_gpu())) {
Z
zhangjun 已提交
177
#ifdef WITH_MKLML
Z
fix  
zhangjun 已提交
178
      if (precision_type == PrecisionType::kInt8) {
179
        config.EnableMkldnnQuantizer();
Z
fix  
zhangjun 已提交
180
      } else if (precision_type == PrecisionType::kHalf) {
181
        config.EnableMkldnnBfloat16();
Z
zhangjun 已提交
182 183 184 185 186
      } else {
#ifdef WITH_MKLDNN
        config.EnableMKLDNN();
        config.SwitchIrOptim(true);
#endif
187
      }
Z
zhangjun 已提交
188
#endif
Z
zhangjun 已提交
189 190
    }

Z
zhangjun 已提交
191
    if (engine_conf.has_use_xpu() && engine_conf.use_xpu()) {
Z
update  
zhangjun 已提交
192 193 194
      // 2 MB l3 cache
      config.EnableXpu(2 * 1024 * 1024);
    }
Z
zhangjun 已提交
195 196
    if (engine_conf.has_enable_ir_optimization() &&
        !engine_conf.enable_ir_optimization()) {
Z
zhangjun 已提交
197
      config.SwitchIrOptim(false);
Z
update  
zhangjun 已提交
198 199
    } else {
      config.SwitchIrOptim(true);
Z
zhangjun 已提交
200 201
    }

Z
zhangjun 已提交
202 203
    if (engine_conf.has_enable_memory_optimization() &&
        engine_conf.enable_memory_optimization()) {
Z
update  
zhangjun 已提交
204
      config.EnableMemoryOptim();
Z
zhangjun 已提交
205
    }
Z
zhangjun 已提交
206

Z
zhangjun 已提交
207
    predictor::AutoLock lock(predictor::GlobalCreateMutex::instance());
Z
update  
zhangjun 已提交
208 209
    _predictor = CreatePredictor(config);
    if (NULL == _predictor.get()) {
Z
zhangjun 已提交
210
      LOG(ERROR) << "create paddle predictor failed, path: " << model_path;
Z
zhangjun 已提交
211 212
      return -1;
    }
Z
update  
zhangjun 已提交
213

Z
zhangjun 已提交
214
    VLOG(2) << "create paddle predictor sucess, path: " << model_path;
Z
zhangjun 已提交
215 216 217 218
    return 0;
  }
};

Z
update  
zhangjun 已提交
219
}  // namespace inference
Z
zhangjun 已提交
220 221
}  // namespace paddle_serving
}  // namespace baidu