C++ tensorRT部署real-esrgan onnx
时间: 2023-08-02 07:09:06 浏览: 346
TensorRT是一个高性能的深度学习推理库,可以用来加速模型的推理。如果你想在C++中使用TensorRT部署Real-ESRGAN ONNX模型,你可以按照以下步骤操作:
1. 安装TensorRT和CUDA,并且将ONNX模型转换为TensorRT模型。
2. 在C++代码中导入TensorRT和CUDA的头文件,并且初始化TensorRT引擎。
3. 创建TensorRT的输入和输出Buffer,并设置输入数据。
4. 执行推理,并从输出Buffer中获取输出数据。
这里是一个示例代码,可以帮助你了解如何使用TensorRT部署Real-ESRGAN ONNX模型:
```c++
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <chrono>
#include <NvInfer.h>
#include <NvOnnxParser.h>
using namespace std;
using namespace nvinfer1;
const string ENGINE_NAME = "real_esrgan.engine";
const string ONNX_MODEL_PATH = "real_esrgan.onnx";
// 创建TensorRT引擎
ICudaEngine* createEngine(IBuilder& builder, IBuilderConfig& config, const string& enginePath) {
// 创建ONNX解析器
nvonnxparser::IParser* parser = nvonnxparser::createParser(builder.getFp16Mode() || builder.getInt8Mode());
parser->parseFromFile(ONNX_MODEL_PATH.c_str(), static_cast<int>(ILogger::Severity::kWARNING));
// 构建TensorRT网络
INetworkDefinition* network = builder.createNetwork();
builder.setNetworkExplicitPrecision(network, builder.getFp16Mode() ? DataType::kHALF : DataType::kFLOAT);
builder.allowGPUFallback(true);
// 添加输入
ITensor* input = network->addInput("input", DataType::kFLOAT, Dims3(3, 720, 1280));
assert(input != nullptr);
// 添加输出
ITensor* output = network->addOutput("output");
assert(output != nullptr);
// 将ONNX模型中的层添加到TensorRT网络中
parser->convert(ENGINE_NAME.c_str(), *network, nvinfer1::DataType::kFLOAT);
// 构建TensorRT引擎
ICudaEngine* engine = builder.buildEngineWithConfig(*network, config);
if (engine == nullptr) {
cerr << "Failed to create TensorRT engine!" << endl;
return nullptr;
}
// 保存TensorRT引擎
ofstream engineFile(enginePath, ios::binary);
if (!engineFile) {
cerr << "Failed to open TensorRT engine file!" << endl;
return nullptr;
}
IHostMemory* serializedEngine = engine->serialize();
engineFile.write(reinterpret_cast<const char*>(serializedEngine->data()), serializedEngine->size());
serializedEngine->destroy();
// 释放资源
parser->destroy();
network->destroy();
return engine;
}
// 加载TensorRT引擎
ICudaEngine* loadEngine(const string& enginePath) {
ifstream engineFile(enginePath, ios::binary);
if (!engineFile) {
cerr << "Failed to open TensorRT engine file!" << endl;
return nullptr;
}
// 获取文件大小
engineFile.seekg(0, engineFile.end);
size_t fileSize = engineFile.tellg();
engineFile.seekg(0, engineFile.beg);
// 读取文件内容
vector<char> engineData(fileSize);
engineFile.read(engineData.data(), fileSize);
// 加载TensorRT引擎
IRuntime* runtime = createInferRuntime(gLogger);
ICudaEngine* engine = runtime->deserializeCudaEngine(engineData.data(), fileSize, nullptr);
if (engine == nullptr) {
cerr << "Failed to load TensorRT engine!" << endl;
return nullptr;
}
// 释放资源
runtime->destroy();
return engine;
}
int main() {
// 创建TensorRT引擎
IBuilder* builder = createInferBuilder(gLogger);
IBuilderConfig* config = builder->createBuilderConfig();
ICudaEngine* engine = createEngine(*builder, *config, ENGINE_NAME);
if (engine == nullptr) {
cerr << "Failed to create TensorRT engine!" << endl;
return 1;
}
// 加载TensorRT引擎
ICudaEngine* engine = loadEngine(ENGINE_NAME);
if (engine == nullptr) {
cerr << "Failed to load TensorRT engine!" << endl;
return 1;
}
// 创建TensorRT执行上下文
IExecutionContext* context = engine->createExecutionContext();
if (context == nullptr) {
cerr << "Failed to create TensorRT execution context!" << endl;
return 1;
}
// 创建输入和输出Buffer
const int batchSize = 1;
const int inputSize = 3 * 720 * 1280 * batchSize;
const int outputSize = 3 * 1440 * 2560 * batchSize;
void* inputBuffer;
void* outputBuffer;
cudaMalloc(&inputBuffer, inputSize * sizeof(float));
cudaMalloc(&outputBuffer, outputSize * sizeof(float));
// 设置输入数据
ifstream inputFile("input.bin", ios::binary);
inputFile.read(reinterpret_cast<char*>(inputBuffer), inputSize * sizeof(float));
inputFile.close();
// 执行推理
context->execute(batchSize, {inputBuffer}, {outputBuffer});
// 获取输出数据
ofstream outputFile("output.bin", ios::binary);
outputFile.write(reinterpret_cast<const char*>(outputBuffer), outputSize * sizeof(float));
outputFile.close();
// 释放资源
cudaFree(inputBuffer);
cudaFree(outputBuffer);
context->destroy();
engine->destroy();
builder->destroy();
return 0;
}
```
在这个示例代码中,我们首先使用TensorRT的ONNX解析器将ONNX模型转换为TensorRT网络。然后,我们使用IBuilder和IBuilderConfig来构建TensorRT引擎。在创建引擎后,我们可以将其序列化为文件,以便在未来的部署中使用。在执行推理时,我们需要创建输入和输出Buffer,并将其传递给TensorRT执行上下文。最后,我们从输出Buffer中获取输出数据,并将其保存到文件中。
请注意,在这个示例代码中,我们使用了一个名为“input.bin”的文件来存储输入数据,并将输出数据保存到一个名为“output.bin”的文件中。你需要根据你的实际情况来修改这些文件路径和数据大小。
阅读全文