4、推理引擎与SDK:TensorRT部署流程、OpenVINO部署流程、NCNN/TNN/MNN等国产推理引擎对比、各引擎的API调用示例。

说到推理引擎,我脑子里第一个蹦出来的词就是「八仙过海」。你想想看,模型训练出来只是第一步,真正要跑到边缘设备上,还得靠这些引擎来「翻译」和「加速」。今天我就把几个主流引擎的部署流程和API调用,掰开了揉碎了讲给你听。

4.1 TensorRT部署流程:NVIDIA的看家本领

TensorRT,说白了就是NVIDIA给自家GPU量身定做的推理优化器。我在项目中遇到过最头疼的事,就是模型在GPU上跑得慢,后来发现是没做TensorRT优化。嗯,这里要注意,TensorRT不是万能的,但它对NVIDIA GPU的加速效果,确实没话说。

部署流程大致分三步:

  1. 模型转换:把训练好的模型(比如ONNX格式)转成TensorRT的engine文件。
  2. 精度校准:如果你用INT8量化,需要准备校准数据集。
  3. 推理执行:加载engine,跑推理。

来看一个简单的API调用示例:

// C++示例:TensorRT推理
#include <NvInfer.h>
#include <cuda_runtime_api.h>

// 创建推理引擎
nvinfer1::IRuntime* runtime = nvinfer1::createInferRuntime(logger);
nvinfer1::ICudaEngine* engine = runtime->deserializeCudaEngine(modelData, modelSize);

// 创建执行上下文
nvinfer1::IExecutionContext* context = engine->createExecutionContext();

// 分配GPU内存
void* buffers[2];
cudaMalloc(&buffers[0], inputSize);
cudaMalloc(&buffers[1], outputSize);

// 执行推理
context->enqueueV2(buffers, stream, nullptr);
cudaStreamSynchronize(stream);
我的小技巧: 做INT8量化时,校准数据集最好选100-500张有代表性的图片。我曾经偷懒只用了50张,结果精度掉了3个点,后来老老实实补到200张才稳住。

4.2 OpenVINO部署流程:Intel生态的利器

OpenVINO是Intel推出的推理引擎,专门优化自家CPU、集成显卡和VPU。我个人习惯在x86平台上优先考虑它,因为不用额外买显卡,省成本。

部署流程:

  1. 模型优化器:用mo.py把模型转成IR格式(.xml + .bin)。
  2. 推理引擎:加载IR文件,选择设备(CPU/GPU/VPU)。
  3. 异步推理:OpenVINO支持异步,能提高吞吐量。

API调用示例:

# Python示例:OpenVINO推理
from openvino.inference_engine import IECore

# 加载模型
ie = IECore()
net = ie.read_network(model='model.xml', weights='model.bin')

# 配置输入输出
input_blob = next(iter(net.input_info))
output_blob = next(iter(net.outputs))

# 加载到CPU
exec_net = ie.load_network(network=net, device_name='CPU')

# 推理
result = exec_net.infer(inputs={input_blob: input_data})
避坑指南: 我曾经在树莓派上试OpenVINO,结果发现它只支持x86和部分ARM。如果你用ARM架构,建议先查一下硬件兼容列表,不然白折腾。

4.3 国产推理引擎对比:NCNN / TNN / MNN

这几年国产引擎发展很快,我挨个说说我的使用感受。

引擎 开发者 主打场景 优点 缺点
NCNN 腾讯 移动端/ARM 轻量、兼容性好、社区活跃 GPU支持弱
TNN 腾讯 移动端/服务端 支持多后端、性能优化好 文档稍乱
MNN 阿里巴巴 移动端/IoT 内存占用低、跨平台 部分算子不全

我的选择建议:

  • 如果你做手机App推理,NCNN是首选,我用了三年没出过大问题。
  • 如果需要在服务端和移动端统一部署,TNN的多后端支持很香。
  • 如果内存紧张(比如IoT设备),MNN的轻量化设计值得一试。

4.4 各引擎API调用示例对比

光说不练假把式,咱们直接看代码。下面是一个分类模型在三个引擎上的推理对比:

// NCNN示例
ncnn::Net net;
net.load_param("model.param");
net.load_model("model.bin");
ncnn::Mat in = ncnn::Mat::from_pixels(image_data, ncnn::Mat::PIXEL_BGR, 224, 224);
ncnn::Extractor ex = net.create_extractor();
ex.input("data", in);
ncnn::Mat out;
ex.extract("prob", out);

// TNN示例
tnn::Net net;
tnn::ModelConfig config;
config.model_type = "ONNX";
net.Init("model.onnx", config);
tnn::InputShapeMap input_shape;
tnn::Mat input_mat = tnn::Mat(1, 3, 224, 224, data);
net.Forward(input_mat, output_mat);

// MNN示例
mnn::Interpreter* interpreter = mnn::Interpreter::createFromFile("model.mnn");
mnn::Session* session = interpreter->createSession();
mnn::Tensor* input = interpreter->getSessionInput(session, "input");
input->copyFromHostImage(image_data);
interpreter->runSession(session);
mnn::Tensor* output = interpreter->getSessionOutput(session, "output");
核心要点: 三个引擎的API设计思路其实很像——加载模型、准备输入、执行推理、取输出。但细节上各有千秋:NCNN的Extractor模式最直观,TNN的配置项最丰富,MNN的内存管理最精细。

4.5 知识体系总览

为了让你更直观地理解本章内容,我画了一张流程图,把推理引擎的部署逻辑串起来:

推理引擎部署全流程 训练好的模型 模型转换(ONNX / IR / 自定义格式) 推理引擎选择:TensorRT / OpenVINO / NCNN / TNN / MNN GPU加速(TensorRT) CPU/集成显卡(OpenVINO) 移动端/IoT(NCNN/TNN/MNN)

这张图把整个流程串起来了:从训练好的模型出发,经过格式转换,再根据你的硬件平台选择合适的引擎。我个人觉得,选引擎就像选工具——没有最好的,只有最合适的。

我的经验之谈: 如果你刚开始接触,建议从NCNN入手。它文档全、社区活跃,踩坑了也容易找到答案。等熟悉了基本流程,再尝试TensorRT或OpenVINO,你会发现一通百通。

公众号:蓝海资料掘金营,微信deep3321