TensorRT学习

TensorRT加速模型推理的原理

  1. 深度学习模型在训练时经常用32位或者16位的数据,然而在推理时并不一定需要这么高的精度,所以TensorRT支持16位或者8位的推理,可以对模型的inference进行加速
  2. TensorRT对于网络结构进行了重构,把一些能够合并的运算合并在了一起,针对GPU的特性做了优化

网络结构垂直整合

将目前主流神经网络的conv、BN、Relu三个层融合为了一个层,所谓CBR

网络水平组合

水平组合是指将输入为相同张量和执行相同操作的层融合一起

TensorRT使用流程

1. 初始化

 Logger:日志记录器,可用于记录模型编译的过程

 创建logger:

class Logger : public ILogger           
{
    void log(Severity severity, const char* msg) noexcept override
    {
        // 抑制信息级别的消息
        if (severity <= Severity::kWARNING)
            cout << msg << endl;
    }
};

Logger logger;

Builder:可用于创建 Network,对模型进行序列化生成engine

Network:由 Builder 的创建,最初只是一个空的容器

创建builder,并用builder创建network:

auto builder = unique_ptr<IBuilder>(createInferBuilder(logger));
// flag为0:同时支持动态和静态输出
// flag为1:仅支持静态输出
auto network = unique_ptr<INetworkDefinition>(builder->createNetworkV2(flag));

 2. 转换模型

Parser:用于解析 Onnx 等模型

ONNX解析器:

auto parser = unique_ptr<nvonnxparser::IParser>(nvonnxparser::createParser(*network, logger));
// IParser 是一个用于解析ONNX(Open Neural Network Exchange)模型文件的类。
// IParser 类的主要功能是将ONNX模型文件解析为TensorRT可以理解的网络定义

解析模型:

parser->parseFromFile(file_path, static_cast<int32_t>(ILogger::Severity::kWARNING));

3. 读取模型並构建推理引擎以及推理上下文 

context:上接 engine,下接 inference,因此解释为上下文

用builder创建config,并用config做一些初始化设置:

// 创建构建配置,用来指定trt如何优化模型
auto config = unique_ptr<IBuilderConfig>(builder->createBuilderConfig());
// 工作空间大小
config->setMemoryPoolLimit(MemoryPoolType::kWORKSPACE, 1U << 20);
// 设置精度
config->setFlag(nvinfer1::BuilderFlag::kFP16);

用buider创建engine(推理引擎):

auto engine = unique_ptr<IHostMemory>(builder->buildSerializedNetwork(*network, *config));

对engine进行序列化与反序列化: 

// engine的序列化
IHostMemory *serializedModel = engine->serialize();
// 保存
std::ofstream p("saved.engine", std::ios::binary);
if (!p) 
{
    std::cerr << "Could not open plan output file" << std::endl;
    assert(false);
}
p.write(reinterpret_cast<const char*>(serialized_engine->data()), serialized_engine->size());
// 安全删除
engine->destroy();
network->destroy();
builder->destroy();
serializedModel->destroy();

// 创建runtime
auto runtime = unique_ptr<IRuntime>(createInferRuntime(logger));
// 读取engine,反序列化
auto plan = load_engine_file(engine_file_path);
auto engine = shared_ptr<ICudaEngine>(runtime->deserializeCudaEngine(plan.data(), plan.size()));

用engine创建context(推理上下文):

auto context = unique_ptr<IExecutionContext>(engine->createExecutionContext());
context->setTensorAddress(INPUT_NAME, inputBuffer);
context->setTensorAddress(OUTPUT_NAME, outputBuffer);

// 如果engine的输入是动态大小,则还需要额外指定input shapes
context->setInputShape(INPUT_NAME, inputDims);

4. 执行推理

// 创建cuda流
cudaStream_t stream;
cudaStreamCreate(&stream);

//执行推理
context->enqueueV3(stream);
cudaStreamSynchronize(stream);
cudaStreamDestroy(stream);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值