[runtime.cpp::parsePlan::314] Error Code 1: Serialization (Serialization assertion plan->header.magi

[runtime.cpp::parsePlan::314] Error Code 1: Serialization (Serialization assertion plan->header.magicTag == rt::kPLAN_MAGIC_TAG failed.)

这个错误和yolov8中因为元数据导致的情况不同

主要的原因是导出engine的TensorRT版本和推理的TensorRT版本不一致

提供onnx

要求cudnn是8x

TensorRT 8.6.1.6

#include<iostream>
#include<fstream>
#include<sstream>
#include"logging.h"
#include"NvInfer.h"
#include"NvOnnxParser.h"
#include"NvInferRuntime.h"

using namespace nvonnxparser;
using namespace nvinfer1;

void onnx2engine(const char* onnx_filename, const char* engine_filePath) {
    // 创建日志记录器对象
    sample::Logger logger;
    // 通过 Logger 类创建 builder
    IBuilder* builder = createInferBuilder(logger);

    // 创建 network,kEXPLICIT_BATCH 代表显式 batch(推荐使用),即 tensor 中包含 batch 这个维度。
    uint32_t flag = 1U << static_cast<uint32_t>(NetworkDefinitionCreationFlag::kEXPLICIT_BATCH);
    INetworkDefinition* network = builder->createNetworkV2(flag);

    // 创建 onnx 模型解析器
    IParser* parser = createParser(*network, logger);

    // 解析模型
    parser->parseFromFile(onnx_filename, static_cast<uint32_t>(ILogger::Severity::kWARNING));

    // 设置 config
    IBuilderConfig* config = builder->createBuilderConfig();

    // 设置工作空间大小
    config->setMemoryPoolLimit(MemoryPoolType::kWORKSPACE, 16 * (1 << 20));

    // 设置以半精度构建 engine,我们在 torch 模型中的数据是 32 位浮点数即 fp32,
    // tensorrt 中可以直接将权重量化为 FP16,以提升速度,若要量化为 INT8,则需要设置数据校准。
    // INT8 量化可以参照 YOLO 的代码。
    // 这里不介绍模型量化的原理。
    config->setFlag(BuilderFlag::kFP16);

    // 创建 profile,设置 engine 序列化
    IOptimizationProfile* profile = builder->createOptimizationProfile();

    // 如果在导出 onnx 模型时,设置了动态 batch(可以看我上一篇博客),这里需要设置输入模型的维度范围。
    // 最小维度
    profile->setDimensions("onnx 导出时的输入名字,一定要一样", OptProfileSelector::kMIN, Dims4(1, 1, 256, 256));
    // 最合适的维度
    profile->setDimensions("onnx 导出时的输入名字,一定要一样", OptProfileSelector::kOPT, Dims4(1, 3, 1080, 1920));
    // 最大维度,建议设置多 batch,后续如果要使用多 batch 推理,就不用重新导出 engine。
    profile->setDimensions("onnx 导出时的输入名字,一定要一样", OptProfileSelector::kMAX, Dims4(8, 3, 1080, 1920));

    // 设置 profile,并序列化构建 engine
    config->addOptimizationProfile(profile);
    IHostMemory* serializedModel = builder->buildSerializedNetwork(*network, *config);
    std::ofstream p(engine_filePath, std::ios::binary);
    p.write(reinterpret_cast<const char*>(serializedModel->data()), serializedModel->size());

    // 最后别忘了清理内存空间
    delete parser;
    delete network;
    delete config;
    delete builder;
    delete serializedModel;
}

int main(int argc, char** argv) {
    if (argc!= 3) {
        std::cout << "Usage: " << argv[0] << " <onnx_file_path> <engine_file_path>" << std::endl;
        return -1;
    }
    const char* onnx_filename = argv[1];
    const char* engine_filePath = argv[2];
    onnx2engine(onnx_filename, engine_filePath);
    return 0;
}

### 错误分析 错误代码 `Error Code 1: Serialization` 表明在尝试反序列化 TensorRT 插件时,未能找到对应的插件创建器(IPluginCreator)。这通常发生在加载 `.trt` 文件或执行模型推理的过程中。具体来说,TensorRT 的运行环境无法识别某些自定义插件或未初始化必要的库。 以下是可能的原因及其解决方案: #### 原因一:缺少插件注册 如果使用的模型依赖于特定的 TensorRT 插件,则需要显式调用 `init_libnvinfer_plugins` 函数来初始化这些插件。如果没有完成此操作,可能会触发上述错误[^3]。 #### 原因二:版本不匹配 TensorRT 版本与生成引擎文件的工具链版本不一致也可能引发此类问题。例如,使用较新的 TensorRT 库加载由旧版构建的 `.trt` 文件可能导致兼容性问题[^1]。 --- ### 解决方案 为了修复该问题,可以按照以下方法调整 Python 脚本逻辑: ```python import tensorrt as trt # 初始化 TensorRT 插件库 trt.init_libnvinfer_plugins(None, '') logger = trt.Logger(trt.Logger.WARNING) with open("model.trt", "rb") as f, trt.Runtime(logger) as runtime: engine_data = f.read() engine = runtime.deserialize_cuda_engine(engine_data) ``` 在此脚本中: - **`trt.init_libnvinfer_plugins`**: 此函数用于确保所有必需的插件被正确加载到内存中。 - 如果存在额外的共享对象 (.so),则需将其路径传递给第一个参数;否则传入 None 即可。 另外需要注意的是,当部署不同硬件平台上的应用时,请确认目标设备已安装相同版本的 NVIDIA 驱动程序以及支持相应功能集的 CUDA 工具包[^2]。 最后提醒一点,在实际开发环境中建议捕获异常以便更好地调试潜在问题: ```python try: ... except Exception as e: print(f"Failed to load TRT model due to {e}") ``` 通过这种方式能够更清晰地了解失败的具体原因并采取针对性措施加以修正。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值