您的位置:首页 > 房产 > 建筑 > 最新国际军事动态和军事战争_南京制作网页培训班_巩义网络推广公司_厦门seo外包服务

最新国际军事动态和军事战争_南京制作网页培训班_巩义网络推广公司_厦门seo外包服务

2024/12/23 14:55:42 来源:https://blog.csdn.net/weixin_46319994/article/details/144275249  浏览:    关键词:最新国际军事动态和军事战争_南京制作网页培训班_巩义网络推广公司_厦门seo外包服务
最新国际军事动态和军事战争_南京制作网页培训班_巩义网络推广公司_厦门seo外包服务

十九:Paddle Inference推理 (C++)API详解

4. 使用 GPU 进行预测

注意:

  • Config 默认使用 CPU 进行预测,需要通过EnableUseGpu来启用 GPU 预测
  • 可以尝试启用 CUDNNTensorRT 进行 GPU 预测加速
4.1. GPU 设置
// 启用 GPU 进行预测
// 参数:memory_pool_init_size_mb - 初始化分配的gpu显存,以MB为单位
//      device_id - 设备id
//      precision - 指定推理精度
// 返回:None
void EnableUseGpu(uint64_t memory_pool_init_size_mb, int device_id = 0, Precision precision = Precision::kFloat32);// 禁用 GPU 进行预测
// 参数:None
// 返回:None
void DisableGpu();// 判断是否启用 GPU
// 参数:None
// 返回:bool - 是否启用 GPU
bool use_gpu() const;// 获取 GPU 的device id
// 参数:None
// 返回:int -  GPU 的device id
int gpu_device_id() const;// 获取 GPU 的初始显存大小
// 参数:None
// 返回:int -  GPU 的初始的显存大小
int memory_pool_init_size_mb() const;// 初始化显存占总显存的百分比
// 参数:None
// 返回:float - 初始的显存占总显存的百分比
float fraction_of_gpu_memory_for_pool() const;// 开启线程流,目前的行为是为每一个线程绑定一个流,在将来该行为可能改变
// 参数:None
// 返回:None
void EnableGpuMultiStream();// 判断是否开启线程流
// 参数:None
// 返回:bool - 是否是否开启线程流
bool thread_local_stream_enabled() const;// 低精度模式(float16)下,推理时期望直接 feed/fetch 低精度数据
// 参数:bool - 是否 feed/fetch 低精度数据
// 返回:None
void EnableLowPrecisionIO(bool x = true);

GPU设置代码示例:

// 创建默认 Config 对象
paddle_infer::Config config;// 启用 GPU 进行预测 - 初始化 GPU 显存 100M, Deivce_ID 为 0
config.EnableUseGpu(100, 0);
// 通过 API 获取 GPU 信息
std::cout << "Use GPU is: " << config.use_gpu() << std::endl; // true
std::cout << "Init mem size is: " << config.memory_pool_init_size_mb() << std::endl;
std::cout << "Init mem frac is: " << config.fraction_of_gpu_memory_for_pool() << std::endl;
std::cout << "GPU device id is: " << config.gpu_device_id() << std::endl;// 禁用 GPU 进行预测
config.DisableGpu();
// 通过 API 获取 GPU 信息
std::cout << "Use GPU is: " << config.use_gpu() << std::endl; // false

开启多线程流代码示例:

// 自定义 Barrier 类,用于线程间同步
class Barrier {public:explicit Barrier(std::size_t count) : _count(count) {}void Wait() {std::unique_lock<std::mutex> lock(_mutex);if (--_count) {_cv.wait(lock, [this] { return _count == 0; });} else {_cv.notify_all();}}private:std::mutex _mutex;std::condition_variable _cv;std::size_t _count;
};int test_main(const paddle_infer::Config& config, Barrier* barrier = nullptr) {static std::mutex mutex;// 创建 Predictor 对象std::shared_ptr<paddle_infer::Predictor> predictor;{std::unique_lock<std::mutex> lock(mutex);predictor = std::move(paddle_infer::CreatePredictor(config));}if (barrier) {barrier->Wait();}// 准备输入数据int input_num = shape_production(INPUT_SHAPE);std::vector<float> input_data(input_num, 1);auto input_names = predictor->GetInputNames();auto input_tensor = predictor->GetInputHandle(input_names[0]);input_tensor->Reshape(INPUT_SHAPE);input_tensor->CopyFromCpu(input_data.data());// 执行预测predictor->Run();// 获取预测输出auto output_names = predictor->GetOutputNames();auto output_tensor = predictor->GetOutputHandle(output_names[0]);std::vector<int> output_shape = output_tensor->shape();std::cout << "Output shape is " << shape_to_string(output_shape) << std::endl;
}int main(int argc, char **argv) {const size_t thread_num = 5;std::vector<std::thread> threads(thread_num);Barrier barrier(thread_num);// 创建 5 个线程,并为每个线程开启一个单独的 GPU Streamfor (size_t i = 0; i < threads.size(); ++i) {threads[i] = std::thread([&barrier, i]() {paddle_infer::Config config;config.EnableUseGpu(100, 0);config.SetModel("./model/resnet.pdmodel", "./model/resnet.pdiparams");config.EnableGpuMultiStream();test_main(config, &barrier);});}for (auto& th : threads) {th.join();}
}
4.2. TensorRT 设置

注意:

  • 启用 TensorRT 的前提为已经启用 GPU,否则启用 TensorRT 无法生效
  • 对存在LoD信息的模型,如BERT, ERNIE等NLP模型,必须使用动态 Shape
  • 启用 TensorRT OSS 可以支持更多 plugin,详细参考 TensorRT OSS。当前开始OSS只对ERNIE/BERT模型加速效果(示例代码)。
    更多 TensorRT 详细信息,请参考 使用Paddle-TensorRT库预测。

API定义如下:

// 启用 TensorRT 进行预测加速
// 参数:workspace_size     - 指定 TensorRT 在网络编译阶段进行kernel选择时使用的工作空间大小,不影响运
//                           行时显存占用。该值设置过小可能会导致选不到最佳kernel,设置过大时会增加初始
//                           化阶段的显存使用,请根据实际情况调整,建议值256MB
//      max_batch_size     - 设置最大的 batch 大小,运行时 batch 大小不得超过此限定值
//      min_subgraph_size  - Paddle 内 TensorRT 是以子图的形式运行,为了避免性能损失,当 TensorRT
//                           子图内部节点个数大于 min_subgraph_size 的时候,才会使用 TensorRT 运行
//      precision          - 指定使用 TensorRT 的精度,支持 FP32(kFloat32),FP16(kHalf),
//                           Int8(kInt8)
//      use_static         - 若指定为 true,在初次运行程序退出Predictor析构的时候会将 TensorRT 的优
//                           化信息进行序列化到磁盘上。下次运行时直接加载优化的序列化信息而不需要重新生
//                           成,以加速启动时间(需要在同样的硬件和相同 TensorRT 版本的情况下)
//      use_calib_mode     - 若要运行 TensorRT INT8 离线量化校准,需要将此选项设置为 true
// 返回:None
void EnableTensorRtEngine(int workspace_size = 1 << 20,int max_batch_size = 1, int min_subgraph_size = 3,Precision precision = Precision::kFloat32,bool use_static = false,bool use_calib_mode = true);// 判断是否启用 TensorRT
// 参数:None
// 返回:bool - 是否启用 TensorRT
bool tensorrt_engine_enabled() const;// 启用 TensorRT 显存优化
// 参数:engine_memory_sharing     - 指定是否开启 TensorRT 显存优化,默认为 false,开启后,当一个模型中(predictor)存在
//                                  多个 TensorRT Engine(子图)时,它们的运行时 context memory 会共享
//      sharing_identifier        - 如果有多个可以保证串行执行的模型(多个串行执行的 predictor),可通过此参数控制它们之间的
//                                  子图共享显存。参与显存共享的 predictor 的 config 配置中,指定此参数为相同的大于0的一个值即可
// 返回:None
void EnableTensorRTMemoryOptim(bool engine_memory_sharing = true,int sharing_identifier = 0);// 设置 TensorRT 的动态 Shape
// 参数:min_input_shape          - TensorRT 子图支持动态 shape 的最小 shape,推理时输入 shape 的任何
//                                 维度均不能小于该项配置
//      max_input_shape          - TensorRT 子图支持动态 shape 的最大 shape,推理是输入 shape 的任何
//                                 维度均不能大于该项配置
//      optim_input_shape        - TensorRT 子图支持动态 shape 的最优 shape,TensorRT 在初始化选
//                                 kernel 阶段以此项配置的 shape 下的性能表现作为选择依据
//      disable_trt_plugin_fp16  - 设置 TensorRT 的 plugin 不在 fp16 精度下运行
// 返回:None
void SetTRTDynamicShapeInfo(std::map<std::string, std::vector<int>> min_input_shape,std::map<std::string, std::vector<int>> max_input_shape,std::map<std::string, std::vector<int>> optim_input_shape,bool disable_trt_plugin_fp16 = false);//
// TensorRT 动态 shape 的自动推导,使用示例参考 https://github.com/PaddlePaddle/Paddle-Inference-Demo/blob/d6c1aac35fa8a02271c9433b0565ff0054a5a82b/c++/paddle-trt/tuned_dynamic_shape
// 参数: shape_range_info_path  - 统计生成的 shape 信息存储文件路径,当设置为空时,在运行时收集
//       allow_build_at_runtime - 是否开启运行时重建 TensorRT 引擎功能,当设置为 true 时,输入 shape
//                                超过 tune 范围时会触发 TensorRT 重建。当设置为 false 时,输入 shape
//                                超过 tune 范围时会引起推理出错
// 返回:None
void EnableTunedTensorRtDynamicShape(const std::string& shape_range_info_path = "",bool allow_build_at_runtime = true);// 启用 TensorRT OSS 进行 ERNIE / BERT 预测加速(示例代码 https://github.com/PaddlePaddle/Paddle-Inference-Demo/tree/master/c%2B%2B/ernie-varlen )
// 参数:None
// 返回:None
void EnableTensorRtOSS();// 判断是否启用 TensorRT OSS
// 参数:None
// 返回:bool - 是否启用 TensorRT OSS
bool tensorrt_oss_enabled();/// 启用 TensorRT DLA 进行预测加速
/// 参数:dla_core - DLA 设备的 id,可选 0,1,...,DLA 设备总数 - 1
/// 返回:None
void EnableTensorRtDLA(int dla_core = 0);/// 判断是否已经开启 TensorRT DLA 加速
/// 参数:None
/// 返回:bool - 是否已开启 TensorRT DLA 加速
bool tensorrt_dla_enabled();

代码示例 (1):使用 TensorRT FP32 / FP16 / INT8 进行预测

// 创建 Config 对象
paddle_infer::Config config("./model/mobilenet.pdmodel", "./model/mobilenet.pdiparams");// 启用 GPU 进行预测
config.EnableUseGpu(100, 0);// 启用 TensorRT 进行预测加速 - FP32
config.EnableTensorRtEngine(1 << 28, 1, 3,paddle_infer::PrecisionType::kFloat32, false, false);
// 通过 API 获取 TensorRT 启用结果 - true
std::cout << "Enable TensorRT is: " << config.tensorrt_engine_enabled() << std::endl;// 开启 TensorRT 显存优化
config.EnableTensorRTMemoryOptim();// 启用 TensorRT 进行预测加速 - FP16
config.EnableTensorRtEngine(1 << 28, 1, 3,paddle_infer::PrecisionType::kHalf, false, false);
// 通过 API 获取 TensorRT 启用结果 - true
std::cout << "Enable TensorRT is: " << config.tensorrt_engine_enabled() << std::endl;// 启用 TensorRT 进行预测加速 - Int8
config.EnableTensorRtEngine(1 << 28, 1, 3,paddle_infer::PrecisionType::kInt8, false, true);
// 通过 API 获取 TensorRT 启用结果 - true
std::cout << "Enable TensorRT is: " << config.tensorrt_engine_enabled() << std::endl;

代码示例 (2):使用 TensorRT 动态 Shape 进行预测

// 创建 Config 对象
paddle_infer::Config config("./model/mobilenet.pdmodel", "./model/mobilenet.pdiparams");// 启用 GPU 进行预测
config.EnableUseGpu(100, 0);// 启用 TensorRT 进行预测加速 - Int8
config.EnableTensorRtEngine(1 << 29, 1, 1,paddle_infer::PrecisionType::kInt8, false, true);// 开启 TensorRT 显存优化
config.EnableTensorRTMemoryOptim();// 设置模型输入的动态 Shape 范围
std::map<std::string, std::vector<int>> min_input_shape = {{"image", {1, 1, 3, 3}}};
std::map<std::string, std::vector<int>> max_input_shape = {{"image", {1, 1, 10, 10}}};
std::map<std::string, std::vector<int>> opt_input_shape = {{"image", {1, 1, 3, 3}}};
// 设置 TensorRT 的动态 Shape
config.SetTRTDynamicShapeInfo(min_input_shape, max_input_shape, opt_input_shape);

代码示例 (3):使用 TensorRT OSS 进行预测(示例)

// 创建 Config 对象
paddle_infer::Config config("./model/ernie.pdmodel", "./model/ernie.pdiparams");// 启用 GPU 进行预测
config.EnableUseGpu(100, 0);// 启用 TensorRT 进行预测加速
config.EnableTensorRtEngine();
// 启用 TensorRT OSS 进行预测加速
config.EnableTensorRtOSS();// 通过 API 获取 TensorRT OSS 启用结果 - true
std::cout << "Enable TensorRT is: " << config.tensorrt_oss_enabled() << std::endl;

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com