产品咨询:18982151213
联系我们
产品咨询

YOLO 系列算法在国产 AI 边缘盒子的完整部署流程

作者:万物纵横
发布时间:2026-02-03 10:28
阅读量:

将YOLO系列(v5/v6/v7/v8/v9等)算法部署到国产AI边缘盒子,核心是适配国产芯片的硬件架构+完成模型格式转换与优化+基于厂商专属框架开发推理工程,国产边缘盒子主流基于昇腾(Ascend)、瑞芯微(RK)、地平线(Horizon)、寒武纪等国产AI芯片,不同芯片有专属的推理框架和模型格式,整体流程可统一分为6个核心步骤,以下是全流程落地指南(含各芯片关键适配点)。


YOLO 系列算法在国产 AI 边缘盒子的完整部署流程(图1)


一、前期准备:明确硬件环境与软件依赖


部署前需先完成环境和工具的准备,核心是匹配边缘盒子的芯片型号、厂商提供的底层驱动/SDK/推理框架,这是后续所有操作的基础。


1. 硬件信息确认:从边缘盒子厂商手册中获取核心信息——芯片型号(如昇腾310B/瑞芯微RK3588/地平线X3/X6/寒武纪MLU220)、算力规格、内存/存储大小、对外接口(网口/USB/HDMI);


2. 软件环境搭建:


开发端:建议使用Ubuntu18.04/20.04(与边缘盒子系统兼容性最好),安装Python3.8+/PyTorch1.13+/TensorFlow2.x(模型导出用)、对应芯片的开发工具包(DK)(如昇腾CANN、瑞芯微RKNN-Toolkit2、地平线Horizon Hobot Toolkit);


设备端(边缘盒子):预装厂商提供的底层驱动、AI框架运行时(Runtime)、依赖库(如昇腾AscendCL运行时、瑞芯微RKNN Runtime),部分盒子支持刷机烧录定制系统;


3. 基础文件准备:训练好的YOLO模型文件(.pt/PyTorch格式为主,主流YOLO均基于PyTorch开发)、数据集样本(用于模型量化校准)、YOLO模型的类别名文件(.names/.txt)。


国产主流芯片对应核心工具


国产芯片

核心推理框架

模型开发工具包

目标模型格式

昇腾Ascend

AscendCLACL

CANN Toolkit

OM(离线模型)

瑞芯微RK

RKNN API

RKNN-Toolkit2

RKNN

地平线Horizon

Hobot Infer

Horizon Hobot Toolkit

BModel(二进制模型)

寒武纪Cambricon

CNML/CNRT

Cambricon PyTorch Extension

BANG


二、模型导出:将YOLO原生模型转为ONNX通用中间格式


国产AI芯片的专属工具几乎不直接支持PyTorch的.pt原生格式,需先将YOLO模型转为ONNX(Open Neural Network Exchange) 格式——这是跨框架、跨平台的通用模型中间件,是连接训练框架(PyTorch)和国产芯片专属工具的核心桥梁,这一步是所有国产边缘盒子部署的通用必做步骤。


核心导出步骤(以YOLOv8为例,v5/v7/v9流程类似)


1. 加载训练好的YOLO模型:使用官方库(如ultralytics for YOLOv8、ultralytics/yolov5 for YOLOv5)加载.pt模型,确保模型为推理模式(model.eval())(关闭Dropout/BatchNorm训练层,避免推理精度损失);


2. 构造虚拟输入张量:ONNX需要固定输入维度,需构造与模型训练时一致的输入(如3×640×640),格式为torch.randn(1, 3, h, w)(batch_size=1,边缘端推理一般为单张图推理);


3. 执行ONNX导出:调用torch.onnx.export()函数,关键参数需注意:


opset_version:建议设为11/12/13(与国产芯片工具兼容性最好,过高易出现算子不支持);


do_constant_folding:设为True(常量折叠,优化模型结构);


input_names/output_names:明确输入(如["images"])和输出节点名(如["output0"]),避免后续解析出错;


禁用动态维度:边缘端推理固定输入尺寸,需关闭dynamic_axes,避免模型格式混乱。


YOLOv8导出ONNX示例代码


from ultralytics import YOLO
import torch

# 1. 加载训练好的YOLOv8模型(推理模式)
model = YOLO("runs/detect/train/weights/best.pt")  # 你的训练模型路径
model.model.eval()

# 2. 构造虚拟输入(与模型输入尺寸一致,如640×640)
input_shape = (1, 3, 640, 640)
dummy_input = torch.randn(input_shape).to("cpu")  # 边缘端多为CPU/NNPU,无需CUDA

# 3. 导出ONNX模型
onnx_save_path = "yolov8_best.onnx"
torch.onnx.export(
    model.model,
    dummy_input,
    onnx_save_path,
    opset_version=12,  # 兼容国产芯片工具的核心版本
    do_constant_folding=True,
    input_names=["images"],  # 输入节点名
    output_names=["output0"],  # 输出节点名
    dynamic_axes=None  # 固定维度,禁用动态
)
print(f"ONNX模型导出成功:{onnx_save_path}")


关键验证:检查ONNX模型有效性


导出后需验证模型是否可用,避免后续步骤报错:


import onnx

# 加载ONNX模型并检查结构
onnx_model = onnx.load(onnx_save_path)
onnx.checker.check_model(onnx_model)  # 检查模型完整性
print("ONNX模型结构无错误,导出有效!")


三、模型转换:ONNX转国产芯片专属的离线推理格式


完成ONNX模型导出后,需通过对应芯片的开发工具包(DK),将ONNX模型转为芯片专属的离线推理格式(如昇腾OM、瑞芯微RKNN、地平线BModel)。这一步是硬件适配的核心,不同国产芯片的转换工具和命令不同,需严格按照厂商手册操作,核心操作包括算子解析、硬件适配优化、离线模型生成。


主流国产芯片转换示例(核心步骤)


1. 昇腾Ascend:ONNX → OM模型(基于CANN Toolkit)


昇腾CANN工具提供atc(Ascend Tensor Compiler)命令行工具,专门用于ONNX/TF/Torch模型转OM离线模型,需指定芯片型号、输入维度:


# 昇腾ATC命令转换ONNX到OM
atc \
--model=yolov8_best.onnx \  # 输入ONNX模型路径
--framework=5 \  # 5=ONNX框架,3=PyTorch,1=TensorFlow
--output=yolov8_best_ascend \  # 输出OM模型名(无需后缀)
--input_shape="images:1,3,640,640" \  # 输入维度,与ONNX一致
--soc_version=Ascend310B \  # 边缘盒子芯片型号(如Ascend310/Ascend310B)
--log=info  # 日志级别


执行成功后生成yolov8_best_ascend.om,即为昇腾边缘盒子的可执行模型。


2. 瑞芯微RK:ONNX → RKNN模型(基于RKNN-Toolkit2)


通过Python脚本调用RKNN-Toolkit2接口,完成模型转换,支持直接加载ONNX模型:


from rknn.api import RKNN

# 初始化RKNN对象
rknn = RKNN()
# 配置模型参数(目标芯片、输入归一化)
rknn.config(
   target_platform="rk3588",  # 边缘盒子芯片型号(如rk3568/rk3588)
   mean=[0, 0, 0],  # 与YOLO训练时的归一化一致
   std=[255, 255, 255],  # YOLO一般为img/255,故std=255
   output_optimize=2  # 优化级别,2为最高
)
# 加载ONNX模型
print("开始加载ONNX模型...")
rknn.load_onnx(model="yolov8_best.onnx", input_size_list=[[3, 640, 640]])
# 构建模型(解析算子+生成RKNN中间结构)
rknn.build(do_quantization=False)  # 先不量化,生成浮点RKNN模型
# 导出RKNN模型
rknn.export_rknn("yolov8_best_rknn.rknn")
rknn.release()
print("RKNN模型转换成功!")


3. 地平线Horizon:ONNX → BModel(基于Hobot Toolkit)


地平线工具需先将ONNX模型转为ONNX精简版(删除无用算子),再通过hb_mapper命令转BModel:


# 1. 精简ONNX模型(地平线专属工具)
hb_mapper checker --model yolov8_best.onnx --input-shape images:1,3,640,640
# 2. 转换为BModel(指定芯片型号)
hb_mapper makertbin \
--model yolov8_best.onnx \
--input-shape images:1,3,640,640 \
--target-arch x3 \  # 地平线边缘盒子芯片(x3/x6/x8)
--output yolov8_best_horizon.bmodel


转换关键注意事项


1. 算子兼容性:若转换时报**“算子不支持”,需通过厂商工具的算子自定义/替换功能**解决,或降低ONNX的opset版本;


2. 输入维度严格一致:ONNX模型的输入维度必须与转换命令中指定的input_shape完全一致,否则转换失败;


3. 输出节点匹配:确保ONNX的输出节点与YOLO的推理输出对应(如检测框、置信度、类别),避免后续后处理解析出错。


四、模型优化:量化(核心)+ 裁剪 + 蒸馏,适配边缘端算力


国产AI边缘盒子的算力(一般为1~20TOPS)远低于服务器GPU,而YOLOv8/v9等模型直接以浮点32位(FP32) 部署时,存在推理速度慢、内存占用高的问题,无法满足边缘端实时检测需求(如视频流30FPS)。因此模型优化是边缘端部署的必做步骤,其中量化是核心优化手段,可在小幅损失精度的前提下,将模型体积缩小4倍,推理速度提升2~5倍。


1. 核心优化:模型量化(主流为INT8量化)


量化的本质是将浮点32位(FP32) 的模型权重/激活值,转换为整数8位(INT8),大幅降低计算量和内存占用,国产芯片均对INT8量化有硬件级加速支持。主流量化方式为训练后量化(PTQ,Post-Training Quantization)——无需重新训练模型,仅通过少量校准数据集(一般100~500张样本,与训练集同分布)即可完成量化,兼顾效率和落地性,是边缘端部署的首选。


量化核心步骤(通用流程,各芯片工具仅接口不同)


1. 准备量化校准集:从训练/测试集中选取100~500张代表性样本,按YOLO的预处理方式处理(缩放、归一化、转张量);


2. 加载浮点离线模型(如FP32的RKNN/OM/BModel);


3. 向量化工具输入校准集,执行量化校准(工具通过校准集统计浮点值的分布,确定量化映射关系);


4. 生成INT8量化模型(如INT8的RKNN/OM/BModel),为边缘端最终部署模型。


瑞芯微RKNN INT8量化示例(核心代码片段)


from rknn.api import RKNN
import cv2
import numpy as np

# 初始化RKNN
rknn = RKNN()
rknn.config(target_platform="rk3588", mean=[0,0,0], std=[255,255,255])
rknn.load_onnx(model="yolov8_best.onnx", input_size_list=[[3,640,640]])

# 1. 准备校准集(100张样本,预处理为模型输入格式)
calib_dataset_path = "calib_images/"  # 校准集文件夹
calib_images = []
for img_name in os.listdir(calib_dataset_path)[:100]:
   img = cv2.imread(os.path.join(calib_dataset_path, img_name))
   img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # YOLO默认RGB
   img = cv2.resize(img, (640, 640))  # 缩放到模型输入尺寸
   img = img.transpose(2, 0, 1)  # HWC→CHW
   img = img / 255.0  # 归一化,与训练一致
   calib_images.append(img)

# 2. 构建并执行INT8量化(do_quantization=True,指定校准集)
rknn.build(
   do_quantization=True,
   dataset=calib_images,  # 量化校准集
   quantization_level=2  # 量化级别,2为全量量化
)

# 3. 导出INT8量化后的RKNN模型(边缘端最终部署模型)
rknn.export_rknn("yolov8_best_rknn_int8.rknn")
rknn.release()
print("INT8量化RKNN模型导出成功!")


2. 辅助优化:模型裁剪+知识蒸馏(低算力盒子必做)


若边缘盒子算力极低(如<5TOPS),可在量化前做辅助优化,进一步降低模型复杂度:


模型裁剪:删除YOLO模型中冗余的卷积层/注意力层,或减小模型宽度/深度(如YOLOv8n/nano版,专为边缘端设计);


知识蒸馏:用大模型(如YOLOv8x)作为教师模型,训练小模型(如YOLOv8n),让小模型学习大模型的检测特征,在保证精度的前提下提升速度。


五、推理工程开发:基于厂商框架编写C/C++/Python推理代码


生成国产芯片专属的量化模型后,需在边缘盒子端基于厂商提供的推理框架API(如昇腾AscendCL、瑞芯微RKNN API、地平线Hobot Infer)编写推理代码,实现图像/视频输入→模型推理→结果后处理→检测输出的完整流程,是算法落地的核心工程步骤。


推理工程核心模块(通用流程)


无论哪种国产芯片,推理代码均包含5个核心模块,仅API调用不同:


1. 初始化推理框架:加载芯片驱动、初始化推理引擎、设置硬件参数(如推理设备为NNPU/CPU);


2. 加载离线量化模型:将INT8的OM/RKNN/BModel模型加载到边缘盒子的内存/NNPU中;


3. 输入预处理:对摄像头/网口/USB传入的图像/视频帧做预处理,必须与YOLO训练/量化时的预处理完全一致(核心:尺寸缩放640×640、色域转换BGR→RGB、归一化img/255、维度转换HWC→CHW),否则会导致检测精度大幅下降;


4. 模型推理:将预处理后的张量传入加载的模型,调用推理API执行前向计算,得到模型原始输出(如YOLO的检测框坐标、置信度、类别概率);


5. 输出后处理:对模型原始输出做解析,执行非极大值抑制(NMS) 去除重复检测框,过滤低置信度框(如conf>0.25、iou>0.5),最终得到清晰的检测结果(框坐标、类别、置信度);


6. 结果输出:将检测结果通过HDMI显示、网口上传、本地保存等方式输出。


瑞芯微RK3588 Python推理示例(核心代码,基于RKNN API)


以瑞芯微RK3588边缘盒子为例,加载INT8量化RKNN模型,实现USB摄像头实时检测:


import rknn.api as rknn
import cv2
import numpy as np

# YOLOv8参数配置
IMG_SIZE = 640
CONF_THRESH = 0.25  # 置信度阈值
IOU_THRESH = 0.5    # NMS IOU阈值
CLASSES = ["person", "car", "bus", ...]  # 你的模型类别名

def preprocess(img):
   """预处理:与训练/量化完全一致"""
   h, w = img.shape[:2]
   # 缩放为640×640
   img_resize = cv2.resize(img, (IMG_SIZE, IMG_SIZE))
   # BGR→RGB(YOLO默认RGB)
   img_rgb = cv2.cvtColor(img_resize, cv2.COLOR_BGR2RGB)
   # HWC→CHW
   img_chw = img_rgb.transpose(2, 0, 1)
   # 归一化:img/255
   img_norm = img_chw / 255.0
   # 增加batch维度:(3,640,640)→(1,3,640,640)
   img_input = np.expand_dims(img_norm, axis=0).astype(np.float32)
   return img_input, h, w

def postprocess(output, h_ori, w_ori):
   """后处理:解析输出+NMS+还原原始图像坐标"""
   output = output[0]  # 去除batch维度,(84,8400) for YOLOv8n (80类+4框)
   # 解析检测框:x,y,w,h → x1,y1,x2,y2
   box_xy = output[:2, :] * np.array([w_ori/IMG_SIZE, h_ori/IMG_SIZE])
   box_wh = output[2:4, :] * np.array([w_ori/IMG_SIZE, h_ori/IMG_SIZE])
   x1 = box_xy[0] - box_wh[0]/2
   y1 = box_xy[1] - box_wh[1]/2
   x2 = box_xy[0] + box_wh[0]/2
   y2 = box_xy[1] + box_wh[1]/2
   boxes = np.stack([x1, y1, x2, y2], axis=1)
   # 解析置信度和类别
   confs = output[4:5, :].squeeze()
   cls_probs = output[5:, :].T
   cls_ids = np.argmax(cls_probs, axis=1)
   scores = confs * cls_probs[np.arange(len(cls_ids)), cls_ids]
   
   # NMS非极大值抑制,去除重复框
   indices = cv2.dnn.NMSBoxes(boxes.tolist(), scores.tolist(), CONF_THRESH, IOU_THRESH)
   if len(indices) == 0:
       return []
   # 筛选最终检测结果
   final_boxes = boxes[indices]
   final_scores = scores[indices]
   final_cls = cls_ids[indices]
   return list(zip(final_boxes, final_scores, final_cls))

def main():
   # 1. 初始化RKNN引擎
   rknn_model = rknn.RKNN()
   # 2. 加载INT8量化RKNN模型
   ret = rknn_model.load_rknn("yolov8_best_rknn_int8.rknn")
   if ret != 0:
       print("模型加载失败!")
       return
   # 初始化推理环境
   ret = rknn_model.init_runtime(target="rk3588")
   if ret != 0:
       print("推理引擎初始化失败!")
       return
   # 打开USB摄像头(设备号0)
   cap = cv2.VideoCapture(0)
   cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
   cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
   
   while cap.isOpened():
       ret, frame = cap.read()
       if not ret:
           break
       # 3. 输入预处理
       img_input, h_ori, w_ori = preprocess(frame)
       # 4. 模型推理
       outputs = rknn_model.inference(inputs=[img_input])
       # 5. 输出后处理
       det_results = postprocess(outputs[0], h_ori, w_ori)
       # 绘制检测结果
       for box, score, cls_id in det_results:
           x1, y1, x2, y2 = box.astype(int)
           cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
           cv2.putText(frame, f"{CLASSES[cls_id]}:{score:.2f}",
                       (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
       # 显示结果
       cv2.imshow("YOLOv8 RK3588 Detection", frame)
       if cv2.waitKey(1) & 0xFF == ord('q'):
           break
   # 释放资源
   cap.release()
   cv2.destroyAllWindows()
   rknn_model.release()

if __name__ == "__main__":
   main()


开发关键注意事项


1. 预处理一致性:这是保证检测精度的核心,尺寸、归一化、色域转换必须与训练/量化阶段完全一致;


2. 后处理适配:不同YOLO版本的输出格式不同(如YOLOv5是(25200,85),YOLOv8是(84,8400)),需针对性解析;


3. 硬件加速:调用芯片的NNPU硬件推理(而非CPU),否则推理速度会大幅下降(国产芯片的API默认优先使用NNPU);


4. 资源管理:推理结束后需释放模型、摄像头、内存等资源,避免边缘盒子内存泄漏。


六、部署与测试:烧录程序到边缘盒子,验证性能与精度


完成推理代码开发后,将量化模型文件+推理代码+依赖库部署到边缘盒子,并进行全面测试,确保满足实际应用需求。


1. 程序部署(主流方式)


1. 本地拷贝:通过U盘/移动硬盘将文件拷贝到边缘盒子的本地存储(如EMMC/SD卡);


2. 网络传输:通过SCP/FTP将开发端的文件上传到边缘盒子(需保证开发端与盒子在同一局域网);


# SCP上传示例:将本地模型和代码传到边缘盒子(用户名:root,IP:192.168.1.100)
scp yolov8_best_rknn_int8.rknn root@192.168.1.100:/home/
scp yolo_detect.py root@192.168.1.100:/home/


3. 刷机烧录:若需批量部署,可将推理程序、模型、系统打包为镜像,通过厂商工具刷机烧录到边缘盒子。


2. 运行推理程序


在边缘盒子的终端中,进入程序目录,执行推理代码:


# 瑞芯微RK3588运行Python推理程序
cd /home/
python3 yolo_detect.py


若为C/C++开发的程序,需先交叉编译(开发端),再在盒子端执行可执行文件:


# 交叉编译(以瑞芯微为例,使用厂商提供的交叉编译工具链)
aarch64-linux-gnu-g++ yolo_detect.cpp -o yolo_detect -lrknn_api -lopencv_core -lopencv_highgui
# 盒子端执行
./yolo_detect


3. 核心测试指标(边缘端部署关键)


需同时验证性能和精度,缺一不可,确保满足实际应用的实时性和检测要求:


(1)性能测试:推理速度(核心指标)


关键指标:单帧推理延迟(ms/帧)、帧率(FPS)(边缘端实时检测一般要求≥15FPS,视频监控要求≥30FPS);


测试方法:在推理代码中添加计时功能,统计1000帧的平均推理时间;


import time
start_time = time.time()
outputs = rknn_model.inference(inputs=[img_input])  # 推理计时
infer_time = (time.time() - start_time) * 1000  # 转换为毫秒
fps = 1 / (infer_time / 1000)
print(f"单帧推理延迟:{infer_time:.2f}ms,帧率:{fps:.2f}FPS")


优化方向:若帧率不足,可降低模型输入尺寸(如416×416)、进一步量化/裁剪模型、关闭不必要的后处理操作。


(2)精度测试:检测准确率


关键指标:mAP@0.5(目标检测通用指标,IOU=0.5时的平均精度),需保证量化后的模型精度与浮点模型相比,精度损失≤5%(可接受范围);


测试方法:用标准测试集(如COCO/自定义测试集)在边缘盒子上推理,统计检测结果的mAP@0.5,与训练时的浮点模型mAP对比;


精度优化:若精度损失过大,可增加量化校准集的样本数量、提高量化校准集的代表性、降低量化级别(如从INT8改为FP16)。


4. 问题排查(常见故障)


1. 模型加载失败:检查模型格式是否与芯片匹配、模型文件是否损坏、推理框架运行时是否安装正确;


2. 推理速度慢:确认使用NNPU推理(而非CPU)、检查模型是否为INT8量化版本、输入尺寸是否过大;


3. 检测精度低:排查预处理是否与训练一致、量化校准集是否代表性不足、置信度/NMS阈值设置是否合理;


4. 程序崩溃:检查边缘盒子的内存/算力是否足够、资源是否释放、代码是否存在语法/逻辑错误。


总结


YOLO系列算法部署到国产AI边缘盒子的核心流程可概括为6步:环境准备→ONNX模型导出→芯片专属模型转换→模型量化优化→推理工程开发→部署测试,其中3个关键核心点决定部署成败:


1. ONNX是通用中间件,所有国产芯片均需先将YOLO原生模型转为ONNX,这是跨框架适配的基础;


2. 量化是边缘端性能的核心保障,INT8训练后量化(PTQ) 是兼顾效率和精度的首选,低算力盒子可叠加模型裁剪/蒸馏;


3. 预处理一致性是精度保障的关键,推理阶段的预处理必须与训练/量化阶段完全一致,否则会导致精度大幅下降。


不同国产AI芯片(昇腾/瑞芯微/地平线)的核心差异在于模型转换工具、推理框架API、专属模型格式,但整体部署流程完全通用,只需针对性替换对应芯片的工具和API即可实现快速落地。

- END -
分享:
留言 留言 试用申请
电话咨询 电话咨询 产品咨询
18982151213
微信在线客服 微信在线客服 在线客服
返回官网顶部 返回官网顶部 回到顶部
关闭窗口
产品订购
  • *

  • *

  • *

  • *

  • *