
刚做完一个基于YOLOv8的交通标志检测项目从数据准备到模型落地部署走了个完整的流程。这中间踩了不少坑也积累了一些实战经验。很多朋友问我YOLOv8怎么做交通标志检测正好借这个机会把整个项目复盘一遍从环境搭建、数据集处理、模型训练到后面的TensorRT部署、RK3588板端移植整个过程完整记录希望给正在做类似项目或者准备拿YOLOv8做毕业设计的同学一些参考。实际上交通标志检测这个任务看起来简单真正做起来有很多细节。交通标志本身是小目标在画面中占的比例很小再加上户外光照变化、遮挡、运动模糊这些因素模型想要稳定识别并不容易。YOLOv8作为目前主流的检测模型在精度和速度上取得了不错的平衡而且官方提供的接口非常友好不管是训练自己的数据集还是后续部署都有比较成熟的方案。1. 项目整体设计与思路拆解1.1 为什么选YOLOv8做交通标志检测先说结论YOLOv8在交通标志检测这个任务上属于综合性价比最高的方案之一。对比之前的YOLOv5YOLOv8在结构上做了不少调整。最核心的变化是换掉了Anchor-Based的方式改成了Anchor-Free这直接省掉了聚类锚框和调anchor的麻烦。对于交通标志这种尺寸比较固定的目标来说Anchor-Free的解码方式反而让边框预测更稳定。其次是backbone里的C3模块换成了C2f模块梯度流更丰富特征提取能力有提升。Head部分也改成了解耦头分类和回归分成两个分支收敛速度和精度都有改善。从工程角度看YOLOv8官方仓库的文档齐全训练接口经过封装调用起来非常简单。不需要自己写训练循环也不需要手动处理数据增强、学习率调度这些细节对于做应用落地的开发者来说非常友好。交通标志检测的场景有两个显著特点。第一是小目标问题一张1920x1080的路面图像里远处的限速标志可能只有30x30像素对特征提取的要求很高。第二是类别不平衡有些标志比如限速40、限速60出现频率高有些警告标志则很少见。YOLOv8在数据增强和多尺度训练上的支持比较完善这两类问题都有办法缓解。1.2 系统整体架构与工作流程整个系统分成四个层次数据层、训练层、评估层、部署层。数据层主要负责数据集的收集、整理、标注格式转换和数据增强策略。训练层包括模型选型、超参数配置、训练过程监控。评估层是在验证集上计算mAP、Precision、Recall等指标并可视化检测效果。部署层是把训练好的模型导出为不同格式比如ONNX、TensorRT engine或者通过RKNN工具链移植到RK3588等边缘设备上。这四个层次是串行依赖的关系前面环节出了问题后面全白做。我在实际项目里最深的体会是数据准备阶段花的时间往往会超过训练和调参的时间这个环节非常值得投入精力。1.3 硬件选型的现实考量训练阶段的硬件直接决定了迭代速度。我手头有RTX 5060和GTX 1660 Ti两种显卡做了对比测试。RTX 5060的显存和算力都比较充裕用YOLOv8n模型、batch size 32的情况下1920分辨率输入一轮迭代大概1.2秒左右。GTX 1660 Ti显存只有6GBbatch size超过16就会OOM只能降低到8或者16同时输入分辨率要降到1280一轮要跑3秒多。如果预算允许建议至少用12GB显存的显卡训练体验会好很多。不过即便只有GTX 1660 Ti这样的显卡YOLOv8n和YOLOv8s这两个小模型还是可以跑的只是需要把batch size调小。博主“白老师”在视频里也提到了GTX 1660 Ti跑YOLOv8的配置技巧核心思路就是优先保证输入分辨率其次再考虑batch size因为分辨率对检测精度的影响远大于batch size。2. 环境配置与数据准备2.1 环境搭建完整步骤这是整个项目中最容易翻车的地方。YOLOv8的安装虽然官方文档写得很简单但真正跑起来的时候PyTorch版本、CUDA版本、cuDNN版本之间的匹配问题经常让人头大。我这里的推荐配置方案如下组件版本建议说明Python3.8 - 3.103.10以上部分依赖库可能不兼容CUDA11.8 或 12.1根据显卡驱动版本选择cuDNN对应CUDA版本的匹配版本最好用8.6以上PyTorch2.0.0 - 2.1.1实测这两个版本最稳定ultralytics8.0.x 以上版本更新很快锁定大版本即可我先装CUDA和cuDNN然后创建Conda虚拟环境最后装PyTorch和ultralytics包。具体命令如下# 创建虚拟环境 conda create -n yolo python3.9 conda activate yolo # 安装PyTorchCUDA 11.8版本 pip install torch2.0.1 torchvision0.15.2 --index-url https://download.pytorch.org/whl/cu118 # 安装ultralytics pip install ultralytics # 测试安装 python -c from ultralytics import YOLO; print(OK)这里有几个细节要提醒注意PyTorch的安装源不要用默认的PyPI源装PyTorch那样装到的多半是CPU版本训练速度慢到怀疑人生。必须到CUDA对应的index-url安装GPU版本。安装完成之后用nvidia-smi确认显卡能识别再在Python中输入import torch; print(torch.cuda.is_available())确认PyTorch能看到显卡。如果是True说明环境没问题。2.2 交通标志数据集的获取与预处理交通标志检测没有统一的公开数据集标准最常见的选择是TT100K和CCTSDB。TT100K是中国交通标志数据集包含上万张实景图像覆盖了中国路面上绝大多数标志类型。CCTSDB是长沙理工大学开源的交通标志数据集规模相对小一些。如果做国际通用场景GTSRB也可以考虑但它是单帧分类为主检测场景适配度不如前两者。我这次用的是TT100K的子集选了场景覆盖比较全的类别大概50类左右。TT100K原始数据是JSON格式标注COCO风格的框需要转成YOLO格式的txt文件。YOLO格式的中心点坐标和宽高都是相对于图像宽高的归一化浮点数。转换脚本可以直接自己写import json import os def convert_tt100k_to_yolo(json_path, save_dir, img_width, img_height): with open(json_path, r, encodingutf-8) as f: data json.load(f) for annotation in data[annotations]: image_id annotation[image_id] category_id annotation[category_id] bbox annotation[bbox] # [x, y, width, height] x_center (bbox[0] bbox[2] / 2) / img_width y_center (bbox[1] bbox[3] / 2) / img_height width bbox[2] / img_width height bbox[3] / img_height txt_path os.path.join(save_dir, f{image_id}.txt) with open(txt_path, a) as f_txt: f_txt.write(f{category_id} {x_center} {y_center} {width} {height}\n)标注文件格式转换完成之后数据集目录按照YOLO的标准结构组织datasets/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamldata.yaml里要指定路径和类别信息train: datasets/images/train val: datasets/images/val test: datasets/images/test nc: 50 names: [限速40, 限速60, 限速80, 解除限速, 禁止左转, ...]类别名称建议直接用中文可读性更好实际训练时内部用的是索引编号影响不大。2.3 数据增强策略的取舍交通标志数据增强的核心原则是适度增强不要过度。经过实测这里有几个经验Mosaic增强在目标检测中泛化提升明显但交通标志尺寸较小Mosaic把四张图拼接后小目标进一步缩小容易导致训练困难。建议在训练后期关闭Mosaicclose_mosaic参数设为一个较小的值比如5个epoch。hsv_h、hsv_s、hsv_v这三个颜色增强对交通标志比较友好因为实际场景中光照变化大适当调整色相和饱和度可以提升模型在不同光线下的鲁棒性。平移和缩放增强会导致部分标志被裁剪不宜设置过大scale控制在0.3-0.5之间比较合适。翻转增强对交通标志要慎重左转和右转箭头在翻转后会语义反转如果数据集中包含方向性标志不要开左右翻转只开上下翻转如果有倒装标志的话。3. 模型训练与核心参数调优3.1 训练参数配置详解YOLOv8的训练入口非常简单一行命令的事情yolo train modelyolov8n.yaml datadatasets/data.yaml epochs200 imgsz640 batch16 device0但参数设置直接影响训练效果。我把关键参数整理成一张表参数建议值说明modelyolov8n / yolov8s先小模型跑通再根据效果升级epochs150-300数据集小可以多跑一些imgsz640 或 1280显存够用就尽量用1280对小目标友好batch显存允许的最大值16-64之间freeze前10-20个epoch冻结backbone加快收敛防止预训练权重被破坏optimizerAdamW 或 SGD小数据集用AdamW大一点用SGDlr00.01SGD/ 0.001AdamW初始学习率close_mosaic训练最后10个epoch设为0避免小目标丢失patience30-50早停耐心值最容易被忽视的参数是imgsz。YOLOv8默认的640分辨率在COCO上表现不错但交通标志多为小目标640分辨率下远处的标志可能只有几个像素。有条件的情况下把输入分辨率提升到1280对小目标检测效果提升非常明显。代价是显存占用成倍增加、训练时间变长。折中方案是先以640跑通流程后续再用1280微调。freeze参数的应用要灵活。小数据集上预训练权重本身已经在COCO上学到了通用的特征如果一开始就全部解冻微调很容易破坏底层特征。实际操作中我习惯先冻结backbone训练10个epoch等损失稳定后再解冻全部层进行完整微调。如果是只针对自己的场景微调或者数据量非常小可以先用freeze10跑一部分再重新加载权重全量训练。3.2 损失函数曲线观察与分析训练过程中监控loss曲线的走势是判断模型是否正常收敛的关键手段。YOLOv8训练完成后会在runs/detect/train目录下生成results.csv文件里面包含了每一轮的box_loss、cls_loss、dfl_loss以及对应的p、r、mAP50、mAP50-95等指标。我自己写了一个简单的脚本从results.csv里读取数据并绘制多条曲线比直接看训练日志直观得多import pandas as pd import matplotlib.pyplot as plt # 读取训练结果 df pd.read_csv(runs/detect/train/results.csv) # 清理列名中的空格 df.columns df.columns.str.strip() # 创建一个2x3的子图 fig, axes plt.subplots(2, 3, figsize(18, 10)) # 各种损失 loss_metrics [ (train/box_loss, Box Loss), (train/cls_loss, Cls Loss), (train/dfl_loss, DFL Loss), (val/box_loss, Val Box Loss), (val/cls_loss, Val Cls Loss), (val/dfl_loss, Val DFL Loss) ] for idx, (col, title) in enumerate(loss_metrics): ax axes[idx // 3][idx % 3] x df[epoch] y df[col] ax.plot(x, y, linewidth2) ax.set_title(title) ax.set_xlabel(Epoch) ax.grid(True) plt.tight_layout() plt.savefig(loss_curves.png, dpi150)正常训练过程中train loss和val loss应该同步下降并且两条曲线之间的gap不会太大。如果train loss持续下降但val loss在某个epoch后开始回升说明过拟合了可以调大weight_decay或者提前停止。如果两条曲线都下降得很慢可能学习率太低了。如果出现了明显的震荡和脉冲常用手段是降低learning rate或者检查数据标注错误。3.3 不同硬件条件下的训练策略训练免不了等待。GPU越强迭代越快除此之外还有两个策略可以明显提速混合精度训练默认开启能减少约40%的显存占用训练速度提升20-30%。多GPU训练一张卡不够时YOLOv8直接支持多卡并行yolo train modelyolov8n.yaml datadatasets/data.yaml epochs200 imgsz640 batch64 device0,1batch参数会按卡数均分比如指定batch64、device0,1就是每张卡32。多卡训练要注意batch size不要减小到影响BN统计的程度一般单卡batch最好大于8。如果用的是一台苹果电脑MPS加速在YOLOv8里也可以直接用devicemps即可。实测M2 Max跑YOLOv8s大概比CPU快5-8倍但相比NVIDIA GPU还是有差距。4. 模型改进与轻量化实践4.1 针对交通标志的模型改进思路YOLOv8原版模型在通用目标检测上表现均衡在特定场景下仍然有提升空间。交通标志检测最常见的改进方向有三个注意力机制在Head或Backbone中加CBAM、SE或CA模块能让模型更关注标志区域。我试过在C2f中引入CA注意力对小目标召回率的提升大约有1-2个点mAP。特征融合改进YOLOv8的PANet结构虽然已经很好但对小目标仍然不够敏感。引入ASFF自适应空间特征融合可以自动学习不同层级特征的权重对小目标检测有正向效果。不过ASFF实现复杂度高一些需要修改网络结构代码对于常规需求来说不是必需的。Head改进比如把检测头换成DynamicHead或者增加一个小目标检测层P2层。对于交通标志这种密集小目标场景P2层可以在原图分辨率1/4的位置增加一个检测尺度对小目标出框能力提升比较明显代价是计算量增加不少。要注意的是改进网络结构之后需要把改进后的结构写成一个新的yaml文件并且在训练时指定这个yaml作为模型定义。不要直接在别人的代码上乱改否则很难排查问题。4.2 轻量化模型与嵌入式部署场景交通标志检测系统经常要部署在嵌入式设备上比如路侧单元、车载终端、移动设备。这时候模型大小和推理速度比精度更重要。YOLOv8官方提供的n、s、m、l、x五个规模中n和s最适合嵌入式场景。YOLOv8n的参数量只有约300万模型文件大小约6MB在RK3588上推理速度可以做到30ms以内。代价是精度相比YOLOv8s低一些mAP50大概差2-3个点。如果要进一步压缩模型可以选择的技术路线包括通道剪枝对训练好的模型做结构化剪枝删除影响较小的通道压缩率可以达到30%-50%。TensorRT和ONNXRuntime都支持部分剪枝后的加速优化。知识蒸馏用一个大的YOLOv8l模型作为教师网络蒸馏一个YOLOv8n学生网络学生模型的精度可以提升1-2个点。轻量化Backbone替换比如把Backbone换成MobileNetV4或ShuffleNetV2计算量可以再降一个量级但需要自己修改网络定义并适配预训练权重。我在轻量化上的实操经验是优先尝试YOLOv8n原版加TensorRT FP16量化这个组合不需要改任何网络结构精度损失很小推理速度已经足够快。如果还是不够再做剪枝或者Backbone替换逐级往下走。4.3 评估指标的选取与模型选择交通标志检测最终效果到底怎么评价不能只看mAP。我习惯组合看几个指标指标关注点组合使用场景mAP0.5定位宽松场景下的整体精度与mAP0.5:0.95一起评估mAP0.5:0.95定位严格场景下的精度对边框回归更敏感模型间横向对比Precision检测结果中正确比例误检敏感防止路口标志误识别成限速标志Recall漏检比例对漏检敏感小目标场景F1 Score平衡Precision和Recall单模型快速评估对于交通标志检测系统来说Recall和F1往往比mAP更关键。实际路测中错过一个限速标志比多报一个标志后果严重得多。所以如果两个模型mAP相近我会选Recall更高的那个宁可多一些误检也不能漏掉关键标志。5. 模型部署从Python原型到正式落地5.1 ONNX导出与TensorRT 8.6部署训练好的模型要落到实际系统通常不能直接跑Python。典型路径是先转ONNX再转TensorRT engine然后C调用。先用ultralytics的导出接口生成ONNXyolo export modelbest.pt formatonnx opset12 imgsz640 simplifyTrue导出ONNX后会生成一个与模型同名的.onnx文件。这个环节有几点需要注意simplifyTrue会做图优化。opset12在TensorRT 8.6上兼容性最好。imgsz要和训练时保持一致或者至少是倍数关系。接下来用TensorRT生成推理引擎。TensorRT 8.6版本配合对应的CUDA环境trtexec --onnxbest.onnx --saveEnginebest.trt --fp16如果希望动态输入尺寸加--minShapesinput:1x3x640x640 --optShapesinput:1x3x640x640 --maxShapesinput:1x3x640x640参数。固定尺寸的engine在推理时会更快动态尺寸灵活一些可以根据实际场景取舍。C上TensorRT推理的核心步骤包括读取engine文件、创建runtime和context、分配GPU显存、执行推理。一个最简版本的推理代码框架是#include NvInfer.h #include fstream #include vector class TRTInference { public: void loadEngine(const std::string enginePath) { std::ifstream file(enginePath, std::ios::binary); std::vectorchar data(std::istreambuf_iteratorchar(file), {}); runtime nvinfer1::createInferRuntime(logger); engine runtime-deserializeCudaEngine(data.data(), data.size()); context engine-createExecutionContext(); } void infer(float* input, float* output) { // 分配CUDA内存、复制输入数据、执行推理、复制输出结果 // 这里是标准的CUDA流程 } private: nvinfer1::IRuntime* runtime; nvinfer1::ICudaEngine* engine; nvinfer1::IExecutionContext* context; };TensorRT的部署门槛主要在环境配置上。CUDA版本和TensorRT版本必须匹配我踩过的坑包括TensorRT 9.0对opset更高的ONNX模型可能报不支持的错误TensorRT 8.6和8.5的engine文件不兼容需要重新序列化。强烈建议用Docker镜像来固定环境避免部署到客户机器上后环境不一致的问题。5.2 RK3588边缘设备部署全流程RK3588是瑞芯微的一款高性能边缘AI芯片有6 TOPS的NPU算力在嵌入式场景下运行YOLOv8n非常合适。很多同学问怎么在RK3588上跑YOLOv8这里把完整流程梳理一遍。第一步RK3588不支持直接跑TensorRT需要用瑞芯微自带的RKNN-Toolkit2工具链将ONNX模型转换为RKNN格式然后在板端通过RKNN Runtime进行推理。转换流程大致是# 在PC上安装RKNN-Toolkit2 pip install rknn-toolkit2 # 编写转换脚本 from rknn.api import RKNN rknn RKNN() # 配置量化参数 rknn.config(mean_values[[0, 0, 0]], std_values[[255, 255, 255]], target_platformrk3588) # 加载ONNX模型 ret rknn.load_onnx(modelbest.onnx) # 构建RKNN模型 ret rknn.build(do_quantizationTrue, datasetdataset.txt) # 导出RKNN文件 ret rknn.export_rknn(best.rknn)转换过程最关键在于do_quantizationTrue的量化设置。RKNN工具链默认以INT8量化如果校准数据集选取得不好量化后精度损失会很明显。我通常的做法是从训练集里随机抽200-300张有代表性的图片生成一个dataset.txt量化后的mAP下降控制在1-2个点以内。第二步在RK3588板子上部署。板端推理用的是RKNN Runtime的C API或Python API。Python API更适合快速验证from rknnlite.api import RKNNLite # 初始化 rknn_lite RKNNLite() # 加载模型 rknn_lite.load_rknn(best.rknn) rknn_lite.init_runtime(core_maskRKNNLite.NPU_CORE_0_1_2) # 推理 outputs rknn_lite.inference(inputs[img])板端推理的速度受NPU核心分配的影响很大。RK3588有3个NPU核心可以单独使用也可以组合使用。实测YOLOv8n在RK3588上单核推理约30ms三核并行可以到15ms左右。功耗比运行TensorRT的GPU方案低得多非常适合做边缘部署。正点原子有一套完整的RK3588部署YOLOv8的教程核心步骤跟我上面写的类似但在模型预处理和输出后处理上有很多细节需要注意。YOLOv8的输出解码在板端需要自己写包括通过conf阈值过滤、NMS等。如果对C更熟悉可以在板端用C版本的RKNN API做推理性能相对Python版本还会有一点提升。5.3 针对交通标志检测场景的部署优化交通标志检测部署还有一个特殊需求实时视频流里的连续检测。路面上的标志牌是静止的但摄像头在移动同一块标志会出现在连续多帧画面中。如果每一帧都重新检测计算量大且容易出现检测结果跳动。常见的优化方案是加一个跟踪器比如ByteTrack或DeepSORT把连续帧中的检测框关联起来。这样既减少了重复检测的算力浪费又可以通过多帧投票机制过滤掉单帧误检。我在项目中采用的是YOLOv8检测加ByteTrack跟踪的组合在RK3588上整体帧率仍能保持25fps以上检测稳定性明显比逐帧独立检测要好。6. 常见问题与排查技巧实录6.1 训练阶段高频问题速查整个项目做完整理了这份问题速查表覆盖了训练和部署阶段最常见的故障。每一条都是我实际遇到或者给网友排查过的应该能帮大家少走很多弯路。问题现象可能原因解决方案训练时OOM显存不足batch size过大或imgsz过大减小batch或降低imgsz或换更小的模型版本训练一两轮后loss为nan学习率过高或数据里有异常标注降低lr0检查数据集的bbox是否越界、标签是否超出nc范围验证集mAP一直很低0.3数据标注错误、类别不平衡、imgsz过小优先检查标注文件和类别对应关系换大输入分辨率模型预测框位置偏移明显Anchor-Free解码后处理没匹配检查导出的ONNX输出的shape确认用对输出分支导出ONNX到TensorRT报错算子不支持或opset版本不兼容用opset12重新导出检查模型中是否有自定义层RKNN转换后精度骤降量化校准集不具代表性从训练集均匀抽取校准图片增加校准集数量到300张以上这里我要特别展开说一下loss为nan的问题。很多人上来就怀疑是网络结构坏了实际上90%的情况是数据集标注出了问题。YOLO格式的标注里如果出现坐标大于1或者width/height为0的情况训练过程中计算损失就会产生无效值。我自己后来在数据预处理里加了一个校验函数专门检查标注文件的范围def check_labels(label_path): import numpy as np with open(label_path, r) as f: for line in f: parts line.strip().split() if len(parts) ! 5: return False cls_id int(parts[0]) x_center float(parts[1]) y_center float(parts[2]) w float(parts[3]) h float(parts[4]) # 检查坐标范围 if not (0 x_center 1 and 0 y_center 1): return False if not (0 w 1 and 0 h 1): return False return True6.2 训练曲线异常的诊断经验Loss曲线的形态基本能反映训练的健康状况。我在多轮调试中有几个总结性的判断方法如果train loss不断下降但val loss在第30轮左右开始上升这是过拟合的标志。处理方法有三选一调大weight_decay、在数据增强中增加Mosaic的概率、增加训练数据量哪怕只是复制增加样本进行简单重复也能减缓过拟合。如果loss曲线下降非常缓慢甚至持平可能是学习率设置过低可以尝试把初始学习率调大5-10倍也可能是模型规模太小对复杂数据集的拟合能力不足需要换用更大的模型版本。另外需要确认是否启用了预训练权重。YOLOv8的默认行为是在训练前下载COCO预训练权重如果网络受限没有下载成功模型会从零开始训练收敛速度会明显变慢。如果loss在某个epoch突然跳变通常和数据增强的关闭时机有关。YOLOv8默认在最后10个epoch关闭Mosaic增强这个时刻loss会出现一个小幅波动属于正常现象。如果跳变幅度特别大说明Mosaic对模型的分布影响太强可以考虑把关闭Mosaic的时间提前到20-30个epoch。6.3 部署推理速度优化的独门技巧模型部署到边缘设备后推理速度经常不够理想。除了常规的TensorRT FP16量化、RKNN INT8量化之外还有几个容易忽略的优化点预处理优化图像缩放和归一化尽量放在预处理阶段用CUDA实现不要每次推理时在CPU上做。TensorRT的预处理网络preprocessing plugin可以在GPU上直接完成BGR转RGB、resize、归一化操作减少数据搬运时间。输出后处理优化YOLOv8的输出解码包含置信度阈值过滤和NMS这部分在CPU上做非常耗时。如果纯TensorRT部署可以考虑用TensorRT自带的EfficientNMS插件在后处理上可以省掉大量的手动解码时间。或者在C中用多线程并行处理多路输入充分利用CPU多核。内存复用在连续推理场景中避免重复申请和释放显存统一分配到内存池里。Edge设备显存本来就小不合理的分配策略会导致频繁的碎片和copy操作。双路流处理如果是多个摄像头场景优先考虑batch推理而不是多线程推理。把两路或多路图像拼成一个batch输入到模型GPU的利用率会显著高于单路推理。实测在RTX 5060上batch4的推理总耗时只比batch1多不到30%吞吐量提升很明显。我自己在实际部署中感受最深的一点是很多性能瓶颈并不在模型计算本身而是在数据的传输和预处理上。如果把整个pipeline的数据流阶段都优化一遍对比最初的原型代码端到端延迟能下降50%以上这个比例相当可观。7. 项目总结与经验沉淀这套交通标志检测系统做下来我自己对YOLOv8的整个生态有了更深入的理解。模型本身只是一个引擎真正决定项目成败的往往是数据质量、参数配置和部署方案的合理性。几个值得记住的关键结论模型选型上YOLOv8n适合边缘部署YOLOv8s是精度与速度的平衡点追求更高精度可以用YOLOv8m进行蒸馏后压缩。数据集上交通标志检测一定要关注小目标问题高分辨率输入和multi-scale训练几乎是必备手段。训练调优上先跑通再调优小模型验证baseline再逐步升级模型规模和输入尺寸。部署落地时TensorRT和RKNN是两条主流路径量化精度损失的把控是关键。最后再分享一点个人体会。做这种目标检测项目最容易走的弯路就是一上来就追求最强的模型、最炫的网络结构改进结果卡在环境配置和数据准备上出不来。我的经验是先把一个最简单、最可靠的端到端pipeline跑通——哪怕先用YOLOv8n、用默认参数、只用少量数据跑5个epoch只要流程完整了后面再往里面填充优化手段就顺理成章了。每一次改动只变更一个变量记录前后效果差异这样调试起来最有效率。交通标志检测技术本身已经相当成熟但落地过程中有大量非模型类的工程问题需要解决。希望这篇文章能帮正在做类似项目的同学少踩几个坑把精力集中在真正有价值的地方。