【零基础入门】Python机器视觉第七阶段:AI模型部署与性能优化(ONNX/TensorRT/OpenVINO/服务化)

在第六阶段,我们成功构建了一个工业缺陷检测原型系统,用C# WPF调用了Python YOLOv8模型。但那个方案每次检测都要启动Python进程,性能有限。在真实的工业场景中,我们需要将模型部署为高性能、低延迟、高吞吐的推理服务。本阶段将带你系统学习AI模型部署的完整知识体系。

本文所有代码均可直接复制运行,建议按照步骤逐步实践。


一、本阶段学习目标

  • 理解AI模型部署的核心概念与挑战
  • 掌握ONNX作为模型交换格式的使用方法
  • 学会使用TensorRT在NVIDIA GPU上加速模型
  • 学会使用OpenVINO在Intel CPU/GPU上优化模型
  • 了解Triton Inference Server实现模型服务化
  • 掌握边缘设备部署的基本流程
  • 能够将YOLOv8模型部署到不同硬件平台并测试性能

二、AI部署核心概念速览

2.1 为什么需要模型部署优化?

指标 训练阶段 部署阶段 优化目标
延迟 不敏感 实时性要求高(<50ms) 降低推理时间
吞吐量 批处理大 单帧/小批量 提高每秒处理帧数
硬件 GPU集群 工控机/边缘设备 适配目标硬件
精度 FP32 FP16/INT8可能 平衡速度与精度
依赖 完整框架 轻量运行时 减小体积

2.2 部署工具链全景图

服务化

部署平台

模型优化

训练框架

PyTorch模型

ONNX

TensorFlow模型

TensorRT

OpenVINO

ONNX Runtime

NVIDIA GPU

Intel CPU/GPU/VPU

跨平台CPU/GPU

Triton Inference Server

gRPC/HTTP API

2.3 核心工具简介

工具 适用硬件 核心优势 学习难度
ONNX 所有平台 模型交换标准,跨框架兼容 ⭐⭐
TensorRT NVIDIA GPU 极致性能,层融合/量化/内核调优 ⭐⭐⭐
OpenVINO Intel CPU/GPU/VPU 异构计算,支持边缘设备 ⭐⭐
ONNX Runtime 跨平台 通用推理引擎,易于集成
Triton 服务器 多模型管理,并发调度,服务化 ⭐⭐⭐

三、ONNX:模型交换的标准格式

ONNX(Open Neural Network Exchange)是连接训练框架和部署引擎的桥梁。无论你用PyTorch还是TensorFlow训练模型,都可以导出为ONNX格式,然后在不同平台上运行。

3.1 PyTorch模型导出为ONNX

import torch
import torchvision

# 1. 加载模型(以ResNet50为例)
model = torchvision.models.resnet50(pretrained=True)
model.eval()

# 2. 创建示例输入
dummy_input = torch.randn(1, 3, 224, 224)

# 3. 导出ONNX
torch.onnx.export(
    model,                       # 模型
    dummy_input,                 # 示例输入
    "resnet50.onnx",             # 输出路径
    export_params=True,          # 导出参数
    opset_version=12,            # ONNX算子集版本
    do_constant_folding=True,    # 常量折叠优化
    input_names=['input'],       # 输入名称
    output_names=['output'],     # 输出名称
    dynamic_axes={                # 动态轴(支持可变batch)
        'input': {0: 'batch_size'},
        'output': {0: 'batch_size'}
    }
)
print("ONNX导出成功!")

3.2 YOLOv8导出为ONNX

from ultralytics import YOLO

# 加载训练好的模型
model = YOLO('runs/train/defect_detection/weights/best.pt')

# 导出ONNX
model.export(format='onnx', imgsz=640, opset=12)
# 会在同目录生成 best.onnx

3.3 ONNX模型验证与简化

import onnx
import onnxruntime as ort
import numpy as np

# 1. 验证ONNX模型结构
onnx_model = onnx.load("best.onnx")
onnx.checker.check_model(onnx_model)
print("ONNX模型验证通过")

# 2. ONNX Runtime推理测试
ort_session = ort.InferenceSession("best.onnx")

# 准备输入数据
input_name = ort_session.get_inputs()[0].name
input_shape = ort_session.get_inputs()[0].shape
print(f"输入名称: {input_name}, 形状: {input_shape}")

# 生成随机输入
dummy_input = np.random.randn(1, 3, 640, 640).astype(np.float32)

# 推理
outputs = ort_session.run(None, {input_name: dummy_input})
print(f"输出形状: {outputs[0].shape}")

# 3. ONNX简化(去除冗余算子)
import onnxsim
model_simp, check = onnxsim.simplify("best.onnx")
if check:
    onnx.save(model_simp, "best_simplified.onnx")
    print("ONNX简化成功")

3.4 常见问题解决

问题 解决方案
算子不支持 降低opset_version或升级框架版本
动态形状问题 在dynamic_axes中正确配置
精度损失 启用do_constant_folding=True
模型过大 使用onnx-simplifier简化

四、TensorRT:NVIDIA GPU的终极优化器

TensorRT是NVIDIA推出的深度学习推理优化器,通过层融合、精度校准、内核自动调优等技术,可以显著提升GPU上的推理性能。

4.1 TensorRT核心优化原理

优化技术 作用 效果
层融合 合并相邻操作(如Conv+ReLU→ConvReLU) 减少内核启动开销
精度校准 FP16/INT8量化 降低计算量,提升吞吐
内核自动调优 选择最佳CUDA内核 适配不同GPU架构
内存优化 复用内存,减少拷贝 降低延迟

4.2 从ONNX构建TensorRT引擎

4.2.1 安装TensorRT
# 方式1:通过pip安装(推荐)
pip install tensorrt

# 方式2:从NVIDIA官网下载tar包并配置环境变量
# 需根据CUDA版本选择对应TensorRT版本
4.2.2 Python API构建引擎
import tensorrt as trt
import numpy as np

# 创建logger
logger = trt.Logger(trt.Logger.INFO)

# 创建builder
builder = trt.Builder(logger)

# 创建network(显式batch模式)
network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))

# 创建parser解析ONNX
parser = trt.OnnxParser(network, logger)

# 读取并解析ONNX模型
with open("best.onnx", "rb") as f:
    if not parser.parse(f.read()):
        for error in range(parser.num_errors):
            print(parser.get_error(error))
        raise RuntimeError("ONNX解析失败")

# 创建config
config = builder.create_builder_config()

# 设置工作空间大小(1GB)
config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30)

# 启用FP16(如果GPU支持)
if builder.platform_has_fast_fp16:
    config.set_flag(trt.BuilderFlag.FP16)
    print("启用FP16加速")

# 优化配置(支持动态batch)
profile = builder.create_optimization_profile()
input_tensor = network.get_input(0)
# 设置最小/最优/最大batch
profile.set_shape(input_tensor.name, 
                  min_shape=(1, 3, 640, 640),
                  opt_shape=(4, 3, 640, 640),
                  max_shape=(8, 3, 640, 640))
config.add_optimization_profile(profile)

# 构建引擎
serialized_engine = builder.build_serialized_network(network, config)

# 保存引擎
with open("best.engine", "wb") as f:
    f.write(serialized_engine)
print("TensorRT引擎构建成功!")
4.2.3 C++ API构建引擎(生产环境常用)
#include <NvInfer.h>
#include <NvOnnxParser.h>
#include <fstream>

using namespace nvinfer1;
using namespace nvonnxparser;

// 创建logger
class Logger : public ILogger {
    void log(Severity severity, const char* msg) noexcept override {
        if (severity <= Severity::kWARNING)
            std::cout << msg << std::endl;
    }
} logger;

int main() {
    // 创建builder
    IBuilder* builder = createInferBuilder(logger);
    const auto explicitBatch = 1U << static_cast<uint32_t>(NetworkDefinitionCreationFlag::kEXPLICIT_BATCH);
    INetworkDefinition* network = builder->createNetworkV2(explicitBatch);
    
    // 创建parser
    IParser* parser = createParser(*network, logger);
    
    // 解析ONNX
    std::ifstream onnxFile("best.onnx", std::ios::binary);
    std::string onnxContent((std::istreambuf_iterator<char>(onnxFile)),
                             std::istreambuf_iterator<char>());
    if (!parser->parse(onnxContent.data(), onnxContent.size()))
        return -1;
    
    // 创建config
    IBuilderConfig* config = builder->createBuilderConfig();
    config->setMemoryPoolLimit(MemoryPoolType::kWORKSPACE, 1 << 30);
    config->setFlag(BuilderFlag::kFP16);
    
    // 构建引擎
    IHostMemory* serializedModel = builder->buildSerializedNetwork(*network, *config);
    
    // 保存引擎
    std::ofstream engineFile("best.engine", std::ios::binary);
    engineFile.write(static_cast<char*>(serializedModel->data()), serializedModel->size());
    
    return 0;
}

4.3 使用TensorRT引擎推理

import tensorrt as trt
import pycuda.driver as cuda
import pycuda.autoinit
import numpy as np
import cv2

class TensorRTInfer:
    def __init__(self, engine_path):
        # 加载引擎
        self.logger = trt.Logger(trt.Logger.INFO)
        with open(engine_path, 'rb') as f:
            self.engine = trt.Runtime(self.logger).deserialize_cuda_engine(f.read())
        
        # 创建上下文
        self.context = self.engine.create_execution_context()
        
        # 分配内存
        self.inputs = []
        self.outputs = []
        self.bindings = []
        
        for i in range(self.engine.num_bindings):
            name = self.engine.get_binding_name(i)
            dtype = trt.nptype(self.engine.get_binding_dtype(i))
            shape = self.engine.get_binding_shape(i)
            
            if shape[0] == -1:  # 动态batch
                shape[0] = 1
                
            size = np.prod(shape)
            host_mem = cuda.pagelocked_empty(size, dtype)
            device_mem = cuda.mem_alloc(host_mem.nbytes)
            
            self.bindings.append(int(device_mem))
            
            if self.engine.binding_is_input(i):
                self.inputs.append({
                    'name': name,
                    'dtype': dtype,
                    'shape': shape,
                    'host': host_mem,
                    'device': device_mem
                })
            else:
                self.outputs.append({
                    'name': name,
                    'dtype': dtype,
                    'shape': shape,
                    'host': host_mem,
                    'device': device_mem
                })
    
    def infer(self, image):
        # 预处理
        input_data = self.preprocess(image)
        
        # 复制输入到GPU
        np.copyto(self.inputs[0]['host'], input_data.ravel())
        cuda.memcpy_htod(self.inputs[0]['device'], self.inputs[0]['host'])
        
        # 执行推理
        self.context.execute_v2(self.bindings)
        
        # 复制输出回CPU
        outputs = []
        for out in self.outputs:
            cuda.memcpy_dtoh(out['host'], out['device'])
            outputs.append(out['host'].copy().reshape(out['shape']))
        
        return self.postprocess(outputs)
    
    def preprocess(self, image):
        # 调整大小
        img = cv2.resize(image, (640, 640))
        # BGR转RGB
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # 归一化
        img = img.astype(np.float32) / 255.0
        # 转CHW
        img = img.transpose(2, 0, 1)
        # 添加batch维度
        img = np.expand_dims(img, axis=0)
        return img
    
    def postprocess(self, outputs):
        # 解析YOLO输出(具体取决于模型结构)
        detections = outputs[0]
        # 后处理代码...
        return detections

# 使用示例
engine = TensorRTInfer("best.engine")
img = cv2.imread("test.jpg")
results = engine.infer(img)

4.4 性能对比数据

在NVIDIA A100上测试ResNet50:

框架 延迟(ms) 吞吐量(img/s)
PyTorch FP32 2.1 476
TensorRT FP16 0.85 1176
TensorRT INT8 0.42 2381

五、OpenVINO:Intel平台的异构计算专家

OpenVINO是Intel推出的开源工具套件,用于在Intel硬件(CPU、集成GPU、VPU、FPGA)上优化和部署深度学习模型。

5.1 OpenVINO核心架构

组件 功能
模型优化器(MO) 将ONNX/TF模型转换为IR格式(.xml + .bin)
推理引擎 加载IR模型并在目标硬件上执行
预处理API 集成OpenCV的图像预处理功能

5.2 安装OpenVINO

# 通过pip安装
pip install openvino-dev

# 验证安装
ovc --help

5.3 YOLOv8导出为OpenVINO IR格式

from ultralytics import YOLO

# 加载模型
model = YOLO('best.pt')

# 导出OpenVINO格式
model.export(format='openvino', imgsz=640)
# 生成 best.xml 和 best.bin

5.4 命令行转换方式

# 先将PyTorch导出为ONNX
yolo export model=best.pt format=onnx imgsz=640

# 使用OpenVINO模型优化器转换
ovc best.onnx --output_dir openvino_model

5.5 OpenVINO推理代码

from openvino.runtime import Core
import cv2
import numpy as np

# 1. 创建Core对象
core = Core()

# 2. 加载模型
model = core.read_model("best.xml")
compiled_model = core.compile_model(model, "CPU")  # 可选CPU, GPU, AUTO

# 3. 获取输入输出信息
input_layer = compiled_model.input(0)
output_layer = compiled_model.output(0)

# 4. 预处理图像
def preprocess(image):
    img = cv2.resize(image, (640, 640))
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = img.astype(np.float32) / 255.0
    img = img.transpose(2, 0, 1)  # HWC -> CHW
    img = np.expand_dims(img, axis=0)  # 添加batch维度
    return img

# 5. 推理
img = cv2.imread("test.jpg")
input_tensor = preprocess(img)
result = compiled_model([input_tensor])[output_layer]

# 6. 后处理(根据YOLO输出格式解析)
print(f"输出形状: {result.shape}")

5.6 性能优化技巧

技巧 说明
FP16精度 使用–data_type FP16减少计算量
异步推理 使用start_async/wait实现流水线
吞吐模式 设置PERFORMANCE_HINT为THROUGHPUT
CPU扩展 对于自定义算子,使用CPU扩展库

5.7 实际部署案例

在LattePanda Mu(Intel N100处理器)上测试YOLOv8n:

部署方式 FPS
原生PyTorch CPU 4-7
OpenVINO优化 15-20

六、Triton Inference Server:模型服务化

当需要将模型部署为可扩展的在线服务时,Triton Inference Server是工业界的最佳选择。它支持多模型管理、并发调度、动态批处理、模型版本控制等功能。

6.1 Triton核心特性

特性 说明
多后端支持 TensorRT、ONNX Runtime、PyTorch、Python等
并发模型服务 单个实例服务多个模型
动态批处理 自动合并请求提高吞吐
模型版本控制 支持A/B测试、回滚
指标监控 Prometheus集成

6.2 模型仓库结构

Triton要求模型按特定目录结构组织:

models/
└── defect_detector/           # 模型名
    ├── 1/                      # 版本号(数字)
    │   └── model.plan           # TensorRT引擎文件
    └── config.pbtxt             # 模型配置

6.3 模型配置文件 config.pbtxt

name: "defect_detector"
platform: "tensorrt_plan"
max_batch_size: 8

input [
  {
    name: "input"
    data_type: TYPE_FP32
    dims: [3, 640, 640]
  }
]

output [
  {
    name: "output"
    data_type: TYPE_FP32
    dims: [84, 8400]  # YOLOv8输出格式示例
  }
]

# 动态批处理配置
dynamic_batching {
  preferred_batch_size: [4, 8]
  max_queue_delay_microseconds: 100
}

# 实例组配置(使用GPU)
instance_group [
  {
    count: 1
    kind: KIND_GPU
    gpus: [0]
  }
]

6.4 启动Triton服务器

# 使用Docker启动
docker run --gpus all --rm -p 8000:8000 -p 8001:8001 -p 8002:8002 \
  -v $(pwd)/models:/models \
  nvcr.io/nvidia/tritonserver:23.10-py3 \
  tritonserver --model-repository=/models

# 检查服务状态
curl -v localhost:8000/v2/health/ready

6.5 Python客户端调用

import tritonclient.http as httpclient
import numpy as np
import cv2

# 1. 创建客户端
client = httpclient.InferenceServerClient(url="localhost:8000")

# 2. 准备输入数据
img = cv2.imread("test.jpg")
img = cv2.resize(img, (640, 640))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img.astype(np.float32) / 255.0
img = img.transpose(2, 0, 1)
img = np.expand_dims(img, axis=0)

# 3. 创建输入/输出对象
inputs = []
outputs = []

inputs.append(httpclient.InferInput("input", img.shape, "FP32"))
inputs[0].set_data_from_numpy(img)

outputs.append(httpclient.InferRequestedOutput("output"))

# 4. 执行推理
results = client.infer(
    model_name="defect_detector",
    inputs=inputs,
    outputs=outputs
)

# 5. 获取结果
output_data = results.as_numpy("output")
print(f"输出形状: {output_data.shape}")

6.6 C# gRPC客户端调用

using Grpc.Net.Client;
using Triton.Inference.Client;

// 创建gRPC通道
var channel = GrpcChannel.ForAddress("http://localhost:8001");
var client = new GRPCInferenceService.GRPCInferenceServiceClient(channel);

// 准备请求
var request = new ModelInferRequest
{
    ModelName = "defect_detector"
};

// 添加输入数据
var input = new ModelInferRequest.Types.InferInputTensor
{
    Name = "input",
    Datatype = "FP32",
    Shape = { 1, 3, 640, 640 }
};
input.Contents.Fp32Contents.AddRange(imageData); // imageData为float数组
request.Inputs.Add(input);

// 添加输出
var output = new ModelInferRequest.Types.InferRequestedOutputTensor
{
    Name = "output"
};
request.Outputs.Add(output);

// 执行推理
var response = client.ModelInfer(request);

七、边缘设备部署实战

7.1 部署流程概览

准备硬件环境

选择/训练模型

导出ONNX

优化转换

开发边缘应用

部署到设备

验证性能

7.2 Jetson平台部署

NVIDIA Jetson系列是边缘部署的首选平台,内置GPU和TensorRT支持。

# 在Jetson上安装依赖
sudo apt-get update
sudo apt-get install python3-pip libopenblas-dev

# 安装PyTorch(Jetson专用版本)
wget https://developer.download.nvidia.com/compute/redist/jp/v512/pytorch/torch-2.1.0-cp38-cp38-linux_aarch64.whl
pip install torch-2.1.0-cp38-cp38-linux_aarch64.whl

# 安装TensorRT(已预装)
dpkg -l | grep tensorrt

# 部署流程同前,构建TensorRT引擎后在Jetson上运行

7.3 Intel x86边缘设备部署

对于Intel NUC、LattePanda等设备,OpenVINO是最佳选择。

# 边缘设备推理示例
import cv2
from openvino.runtime import Core

core = Core()
model = core.read_model("best.xml")
compiled_model = core.compile_model(model, "CPU")

cap = cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    # 预处理
    input_tensor = preprocess(frame)
    
    # 推理
    result = compiled_model([input_tensor])
    
    # 后处理和显示
    frame = draw_detections(frame, result)
    cv2.imshow("Edge Detection", frame)
    
    if cv2.waitKey(1) == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

7.4 嵌入式NPU部署

对于瑞萨、恩智浦等带NPU的芯片,需使用厂商提供的工具链:

厂商 工具链 支持模型格式
瑞萨 RUHMI ONNX, TensorFlow Lite
恩智浦 eIQ Auto ONNX, TensorFlow Lite
高通 SNPE ONNX, TensorFlow Lite

八、部署策略选择指南

8.1 硬件平台决策树

目标硬件

是否有NVIDIA GPU?

使用TensorRT

是否需要服务化?

Triton + TensorRT

直接TensorRT引擎

是否为Intel平台?

使用OpenVINO

使用ONNX Runtime

8.2 精度与速度权衡

精度选项 速度提升 精度损失 适用场景
FP32 1x 0% 精度优先,离线处理
FP16 2-3x <0.5% 实时检测,通用场景
INT8 3-5x 1-2% 边缘设备,带宽受限

8.3 性能调优三板斧

  1. 层融合:利用TensorRT/OpenVINO自动融合相邻操作
  2. 内存复用:重用输入/输出缓冲区减少拷贝
  3. 异步执行:采用流水线模式重叠预处理与推理

九、完整项目:将YOLOv8缺陷检测模型部署到TensorRT

9.1 部署脚本(完整版)

# deploy_tensorrt.py
import os
import sys
import tensorrt as trt
import pycuda.driver as cuda
import pycuda.autoinit
import numpy as np
import cv2
from pathlib import Path

class YOLOv8TensorRTDeploy:
    def __init__(self, onnx_path, engine_path, imgsz=640):
        self.onnx_path = onnx_path
        self.engine_path = engine_path
        self.imgsz = imgsz
        self.logger = trt.Logger(trt.Logger.INFO)
        
    def build_engine(self, fp16=True):
        """构建TensorRT引擎"""
        print(f"构建TensorRT引擎: {self.engine_path}")
        
        builder = trt.Builder(self.logger)
        network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))
        parser = trt.OnnxParser(network, self.logger)
        
        # 解析ONNX
        with open(self.onnx_path, 'rb') as f:
            if not parser.parse(f.read()):
                for error in range(parser.num_errors):
                    print(parser.get_error(error))
                return False
        
        # 创建配置
        config = builder.create_builder_config()
        config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30)  # 1GB
        
        if fp16 and builder.platform_has_fast_fp16:
            config.set_flag(trt.BuilderFlag.FP16)
            print("启用FP16加速")
        
        # 动态batch配置
        profile = builder.create_optimization_profile()
        input_tensor = network.get_input(0)
        profile.set_shape(input_tensor.name,
                         min_shape=(1, 3, self.imgsz, self.imgsz),
                         opt_shape=(4, 3, self.imgsz, self.imgsz),
                         max_shape=(8, 3, self.imgsz, self.imgsz))
        config.add_optimization_profile(profile)
        
        # 构建引擎
        serialized_engine = builder.build_serialized_network(network, config)
        if serialized_engine is None:
            print("构建引擎失败")
            return False
        
        # 保存引擎
        with open(self.engine_path, 'wb') as f:
            f.write(serialized_engine)
        
        print(f"引擎保存成功: {self.engine_path}")
        return True
    
    def load_engine(self):
        """加载引擎"""
        with open(self.engine_path, 'rb') as f:
            serialized_engine = f.read()
        self.engine = trt.Runtime(self.logger).deserialize_cuda_engine(serialized_engine)
        self.context = self.engine.create_execution_context()
        print("引擎加载成功")
        
        # 分配内存
        self._allocate_memory()
    
    def _allocate_memory(self):
        """分配GPU内存"""
        self.inputs = []
        self.outputs = []
        self.bindings = []
        
        for i in range(self.engine.num_bindings):
            name = self.engine.get_binding_name(i)
            dtype = trt.nptype(self.engine.get_binding_dtype(i))
            shape = self.engine.get_binding_shape(i)
            
            if shape[0] == -1:  # 动态batch
                shape[0] = 1
            
            size = np.prod(shape)
            host_mem = cuda.pagelocked_empty(size, dtype)
            device_mem = cuda.mem_alloc(host_mem.nbytes)
            
            self.bindings.append(int(device_mem))
            
            if self.engine.binding_is_input(i):
                self.inputs.append({
                    'name': name,
                    'dtype': dtype,
                    'shape': shape,
                    'host': host_mem,
                    'device': device_mem
                })
            else:
                self.outputs.append({
                    'name': name,
                    'dtype': dtype,
                    'shape': shape,
                    'host': host_mem,
                    'device': device_mem
                })
    
    def preprocess(self, image):
        """预处理"""
        img = cv2.resize(image, (self.imgsz, self.imgsz))
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img = img.astype(np.float32) / 255.0
        img = img.transpose(2, 0, 1)
        img = np.expand_dims(img, axis=0)
        return img
    
    def infer(self, image):
        """推理"""
        # 预处理
        input_data = self.preprocess(image)
        
        # 复制输入
        np.copyto(self.inputs[0]['host'], input_data.ravel())
        cuda.memcpy_htod(self.inputs[0]['device'], self.inputs[0]['host'])
        
        # 执行推理
        self.context.execute_v2(self.bindings)
        
        # 复制输出
        outputs = []
        for out in self.outputs:
            cuda.memcpy_dtoh(out['host'], out['device'])
            outputs.append(out['host'].copy().reshape(out['shape']))
        
        return outputs

# 使用示例
if __name__ == "__main__":
    deploy = YOLOv8TensorRTDeploy("best.onnx", "best.engine")
    
    # 构建引擎
    if not os.path.exists("best.engine"):
        deploy.build_engine(fp16=True)
    
    # 加载引擎
    deploy.load_engine()
    
    # 测试推理
    img = cv2.imread("test.jpg")
    import time
    start = time.time()
    for _ in range(100):
        outputs = deploy.infer(img)
    end = time.time()
    print(f"平均推理时间: {(end-start)/100*1000:.2f} ms")

十、总结与下一步

通过本阶段的学习,你已经掌握了:

  • ✅ ONNX模型导出与优化
  • ✅ TensorRT引擎构建与推理
  • ✅ OpenVINO模型转换与部署
  • ✅ Triton服务化部署
  • ✅ 边缘设备部署流程

至此,你已经完成了从零基础到工业级AI系统部署的全流程学习。

📚 参考文档链接

ONNX相关

TensorRT相关

OpenVINO相关

Triton Inference Server

边缘部署

综合教程


如果在实践中遇到任何问题,欢迎随时交流!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐