2026/10/21 4:46:48

YOLOv12工业缺陷检测实战:太阳能电池板视觉系统与PySide6界面开发

YOLOv12工业缺陷检测实战:太阳能电池板视觉系统与PySide6界面开发 1. 项目概述与系统定位做工业视觉检测这几年我一直有个感受很多缺陷检测项目卡在算法能跑通和产线能用起来之间。算法工程师交付一个脚本、一组权重现场人员面对黑乎乎的终端窗口根本无从下手反过来懂界面开发的人又不一定懂模型训练。这个太阳能电池板缺陷识别系统正好把两端补齐了——底层用YOLOv12做缺陷推理上层用图形界面做交互中间还塞了用户登录注册来区分操作权限。整套东西跑起来就是一个能交付给工厂车间的完整Demo而不是一个孤零零的Python脚本。这个项目的检测目标很明确太阳能电池板表面的隐裂、碎片、断栅、脏污、划痕这几类常见缺陷。这些都是电池板生产质检环节的高频问题尤其是隐裂肉眼很难发现但会直接影响组件转换效率。用目标检测模型来做本质上就是让模型学会在图像里框出缺陷的位置和类别相当于给质检员配了一个不知疲倦的AI助手。它的价值主要体现在三个层面对开发者来说这是一条完整的数据集—训练—部署—界面项目链路可以一次性打通从算法到产品的所有环节对生产方来说图形界面大幅降低了操作门槛普通产线工人经过几分钟培训就能上手对管理者来说登录注册功能让不同角色各归其位检测记录也能溯源到具体账号这在实际车间管理里是刚需。阅读这篇内容不需要你已经是深度学习专家但要有一点Python基础知道什么是训练集验证集粗浅了解卷积神经网络就够。完整跟着走一遍你能得到一个带登录界面、检测界面和可运行模型权重的桌面级应用而且每一步涉及的关键原理我都会用大白话讲明白。2. 项目整体架构与实现思路我习惯在动手写代码前先把整个系统的数据流画清楚。这个系统的数据流其实非常规整登录验证通过后进入主界面加载模型权重用户选择图片或者调用摄像头模型推理出缺陷框和类别结果渲染到界面上同时记录到日志。搞清楚这条链路后面写代码就是填格子的事。2.1 为什么选择YOLOv12作为核心检测算法当前工业缺陷检测领域能用的目标检测算法其实不少两阶段的Faster R-CNN、单阶段的SSD、老牌YOLOv5还有更新的YOLOv8、YOLOv9、YOLOv10甚至RT-DETR这些Transformer架构也在被讨论。我最终选定YOLOv12是从项目实际需求反推的不是图新潮。首先说速度。太阳能电池板产线的节拍很快一条线每分钟要过几十片板子每片可能拍多张图。就算离线抽检一张图的推理时间也不能拖到几百毫秒。YOLOv12继承了YOLO系列单阶段检测器的优势推理速度快在一般显卡上可以达到毫秒级响应。这点跟两阶段检测器相比是降维打击Faster R-CNN一张图动辄上百毫秒在实时性上根本没得比。再说精度。YOLOv12引入了注意力机制改进官方说法叫Area Attention它能更高效地建模全局上下文信息。用大白话解释传统卷积核看到的范围是局部的就像人眼聚焦在一个小方块上注意力机制则能让模型学会哪里值得多看两眼。电池板缺陷有个特点——目标小、对比度低、背景纹理复杂比如隐裂就是发丝一样的细线混在电池片栅线纹理里非常考验模型的特征提取能力。YOLOv12的注意力机制对这类小目标、弱纹理目标有更好的特征表达能力这也是我选它的核心原因。还有一个现实层面的考量生态成熟度。YOLOv12是基于Ultralytics框架开发的训练、验证、导出、部署的接口跟YOLOv5、v8一脉相承网上资料多遇到问题容易找到解决方案。在工业项目里生态成熟意味着风险可控。2.2 系统技术栈与分层思路整个系统我分了四层每层职责单一方便后续独立升级数据层负责缺陷图像的收集、标注、预处理和数据增强。这一层决定了模型能力的上限算法只是逼近这个上限的工具。模型层基于YOLOv12进行训练、验证、测试产出最佳权重。这一层是整个系统的算法心脏但普通用户不需要感知它的存在。应用层封装推理逻辑接收前端传来的图像调用模型推理返回检测结果。这层要处理好GPU/CPU设备的切换、模型的生命周期管理、推理耗时控制。界面层用户登录注册、主界面布局、检测交互、结果展示和历史记录。这层是用户唯一看得到、摸得着的部分体验是否顺畅全靠它。界面层我用了PySide6也就是Qt for Python。选择它而不是Tkinter或者PyQt5因为PySide6是Qt官方支持的Python绑定许可证友好控件风格现代做出来的界面不至于像上世纪的老软件。虽然打包体积大一点但在工业场景下界面美观度和交互流畅度的优先级更高。登录注册模块独立放在应用层和界面层之间用户输入账号密码后端校验用户表。数据库用了轻量级的SQLitePython标准库自带支持不需要额外安装数据库服务对桌面应用来说是性价比最高的方案。用户密码我做了哈希处理而不是明文存储这一点在后面的实现章节会详细展开。2.3 界面设计如何兼顾操作效率与功能完整性工业检测软件有个通病功能全堆在界面上按钮密密麻麻现场工人看着就头疼。我在设计这个系统界面时定了一个原则——主界面只放最核心的检测功能把用户管理和记录管理收进二级菜单或独立窗口。主界面布局是这样规划的左侧是操作区包含图片选择按钮、摄像头采集按钮、开始检测按钮和检测结果参数显示中间大面积区域用来展示当前检测的图片和推理结果画框底部状态栏显示当前模型文件、推理耗时、当前登录用户。这种左控右显的布局符合操作人员从左到右的操作习惯逻辑上也是先选择后查看的自然流程。登录注册界面单独做一个窗口程序启动时先加载登录页验证通过才进入主窗口。这既保证了安全性也是整个项目完整性的一个体现。注册的时候要求用户名和密码都有长度限制密码需要二次确认这些基础校验逻辑虽然简单但恰恰是很多Demo项目忽略的细节。3. 太阳能电池板缺陷数据集的构建与预处理在缺陷检测项目里算法和数据集的关系我常跟人打比方模型就像一个学生数据集就是教材。你给人家一本错漏百出的教材再厉害的学霸也考不了高分。这个项目里数据集的质量直接决定检测效果的上限所以这块我花的时间和精力最多。3.1 数据集来源与类别体系项目所用的数据集综合了几个渠道一部分来自公开的太阳能电池板电致发光EL图像数据集一部分是通过数据增强模拟的扩充样本还有一部分是实验室环境采集的实物照片。混合数据集的思路是尽可能还原产线真实情况避免模型只在某一种图像风格上表现好。缺陷类别我定义了五种全部是光伏质检中的常见问题隐裂Crack电池片内部的细微裂纹EL图像中表现为暗色线条是最难检测的类型之一碎片Fragment电池片断裂成多块边缘有明显破损断栅Busbar_break主栅线或细栅线断开在EL图像中表现为连续的亮线变暗脏污Stain表面污染或工艺残留呈现不规则暗区划痕Scratch机械损伤造成的线状痕迹类别体系不是越多越好要跟产线实际需求对齐。设计这五类时我咨询了从事光伏质检的朋友他说产线抽检主要关注的就是这几类分太细会导致标注成本暴涨、类别间特征混淆分太粗又达不到质检追溯要求五类是一个比较合适的粒度。3.2 标注格式与标注工作流标注格式我选用了YOLO的txt格式这是YOLO系列最原生、训练最简单的方式。每张图片对应一个同名txt文件每一行格式是类别ID、归一化中心点x坐标、归一化中心点y坐标、归一化宽度、归一化高度。这里提一个新手容易踩的坑归一化坐标是相对于图片宽高的比例值取值范围在0到1之间不是像素坐标。很多人拿像素坐标直接写进txt训练的时候loss直接爆炸。我当时用标注工具导出时特意核对了几个数据确保数值范围正确。标注工具我用的是LabelImg和X-AnyLabeling结合着用。LabelImg老牌稳定支持YOLO格式导出X-AnyLabeling支持交互式标注和自动分割辅助对细长的隐裂标注效率更高。标注工作流是先用X-AnyLabeling做初标再用LabelImg做复核修正两道工序下来标注质量有明显保障。标注过程中最需要耐心的是隐裂。EL图像里电池片本身有栅线纹理隐裂线条跟栅线走向容易混淆我要求标注团队遵循一个铁律凡是连续、独立、与栅线走向不一致的暗线才标记为隐裂如果只是栅线本身的明暗变化不标。这个规则听起来简单实际执行中能大幅度减少误标。3.3 数据增强策略与样本均衡处理数据增强在工业缺陷检测里是刚需因为产线上的缺陷样本天然稀少。我用了三组增强策略第一组是几何变换包括随机旋转、水平翻转、垂直翻转。电池板图像没有固定方向性这几类变换不会破坏语义信息。但要注意旋转角度不要超过15度旋转过大可能让细长缺陷的形状严重变形反而干扰训练。第二组是色彩与光照变换包括亮度调整、对比度调整、高斯噪声。产线拍摄环境的光照不可能完全一致模型需要对这些变化有鲁棒性。这里的颜色扰动是针对RGB图像的EL图像本身是灰度风格色彩扰动幅度要更克制一些。第三组是Mosaic拼接增强这是YOLO系列训练的标准做法把四张图随机裁剪拼接成一张图相当于一次让模型看到更多变体。Mosaic对小目标检测特别友好因为拼接后目标在画面中的相对尺寸会变化模型能学到不同尺度的特征。样本不均衡也是要处理的硬骨头。脏污类缺陷样本多隐裂类样本少如果直接训练模型会偏向多数类隐裂漏检率飙升。我的处理方案是对少数类使用过采样复制对多数类使用欠采样剔除部分冗余样本再结合在线增强让少数类每个epoch都能以不同变体出现。经过均衡后训练集各类样本数基本维持在相近水平。3.4 数据集划分与目录结构数据集按7:2:1划分为训练集、验证集、测试集。这个比例不是我拍脑袋定的是经过交叉验证后确定的训练集比例太高容易过拟合太低模型学不到位测试集独立于训练和验证过程用来模拟真实场景下的检测效果。划分时我用了随机种子固定保证每次划分结果一致方便复现实验。项目目录组织成这样datasets/ solar_defect/ images/ train/ val/ test/ labels/ train/ val/ test/ data.yamldata.yaml是Ultralytics框架要求的配置文件里面用绝对路径或者相对路径指向训练和验证图片目录列出类别名称和数量。这个文件写错会导致框架启动即报错尤其是路径分隔符和目录名拼写我建议写完先打印出来检查一遍。4. YOLOv12模型训练全流程与调参实践模型训练是整个项目里玄学成分最多的环节同一个数据集、同一个网络结构不同人调参出来的效果可能天差地别。这一章我把自己训练YOLOv12的全过程、参数设置的逻辑和踩过的坑都摊开来讲给后来人做参考。4.1 环境搭建与版本搭配环境版本匹配是第一个大坑。YOLOv12基于PyTorch实现PyTorch版本、CUDA版本、显卡驱动版本三者要互相匹配否则会出现莫名其妙的报错。我这边实际可用的搭配是Python 3.10、PyTorch 2.1.0、CUDA 11.8、Ultralytics 8.2.x。搭建虚拟环境是必须的我强烈推荐用conda创建独立环境不要让项目依赖污染系统Python。命令很简单conda create -n yolov12 python3.10 conda activate yolov12 pip install torch2.1.0 torchvision0.16.0 --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics安装完成后用一行代码验证CUDA是否可用import torch print(torch.cuda.is_available())如果输出False八成是CUDA版本或驱动问题不要急着上网搜答案先运行nvidia-smi确认驱动支持的CUDA版本再倒推该装哪个PyTorch版本。我遇到过有人装了半天PyTorch CPU版怎么都调用不了显卡排查一圈才发现是下载源没指定cu118。4.2 训练参数配置的详细拆解我用的训练命令基于Ultralytics的YOLO接口参数配置包含大量细节from ultralytics import YOLO model YOLO(yolo12n.yaml) # 从配置文件构建模型 results model.train( datadatasets/solar_defect/data.yaml, epochs200, batch16, imgsz640, device0, workers4, optimizerSGD, lr00.01, lrf0.01, momentum0.937, weight_decay0.0005, patience30, seed42, augmentTrue, mosaic1.0, )一个个说参数的选择逻辑。imgsz选择640是精度和速度的均衡点。分辨率越高小缺陷越清晰但显存占用和推理时间同步上升。在电池板缺陷这种小目标场景我试过768和1024精度提升有限训练时间却长了快一倍性价比不高。如果你用的是高端显卡并且对精度要求极端可以试1024但显存低于16G不建议碰。batch16是综合考虑显存和BN效果的选择。批量太小BatchNorm统计不稳定模型难以收敛批量太大显卡直接OOM。8G显存跑YOLOv12nbatch16基本是上限。如果你显存吃紧把imgsz降到512或者换更小的网络体量。优化器我选了SGD而不是AdamW这是很多人不理解的地方。Adam系优化器收敛快、调参省心但最终精度往往不如精心调过的SGD。YOLO系列的默认配置就是SGDmomentum这也是大量实验验证的组合。在学习率策略上lr00.01配合余弦退火前几个epoch做warmup后期学习率平滑下降。如果你用AdamW初始学习率应降到0.001附近直接沿用0.01会发散。patience30是早停策略的耐心值连续30个epoch验证集指标没有提升就停止训练。这个参数对于保护时间非常关键我见过不设早停跑200个epoch的项目实际到120个epoch就开始严重过拟合后面的训练时间纯属浪费。4.3 训练过程监控与结果解读训练启动后Ultralytics会实时输出每个epoch的loss、精度、召回率和mAP指标。我看训练过程的核心指标是val/box_loss和val/cls_loss这两个验证损失它们不降反升就是过拟合的预警信号这时候训练集loss再低也没意义。训练结束后重点看三个东西首先是result图这是训练过程的完整曲线记录包括训练/验证损失、精度、召回率、mAP0.5和mAP0.5:0.95。mAP0.5是IoU阈值在0.5时的平均精度实际工程中更关注这个值mAP0.5:0.95是多个IoU阈值的平均值学术味道更重。其次是混淆矩阵这是判断类别间是否混淆的最直接工具。我第一版训练结果里碎片和断栅之间存在明显混淆因为两者都表现为亮线断裂特征边界模糊。后来我重新审视了标注规则在标注规范里补充了断栅必须严格对齐栅线走向碎片不受走向限制的判定条件重新标注后混淆明显减少。最后是验证集上的预测样本图可视化缺陷框是否准确贴合真实缺陷。这一步跟指标同样重要有时候指标看起来不错实际框的位置偏移很严重这类问题光看数字发现不了。4.4 模型评估与最佳权重选择评估阶段用测试集来做最终验证测试集不参与训练和验证是唯一能代表真实场景表现的数据。我关注的核心指标有Precision精确率预测为缺陷的框中真正是缺陷的比例。精确率低意味着误检多产线会把好板当坏板造成浪费。Recall召回率真实缺陷中被成功检出的比例。召回率低意味着漏检多缺陷板流到下道工序这是质检事故。mAP0.5综合评估指标兼顾精确率和召回率。在产线场景下我的经验是召回率优先级高于精确率。理由是漏检一块缺陷板可能导致整批组件被退货而误检只是多一次人工复核。所以我在最终选择权重时综合权衡各项指标优先保障召回率达到90%以上。最佳权重不是最后一个epoch的权重Ultralytics会自动保存best.pt这个文件对应的就是验证集上mAP最高的权重。我测试下来best.pt通常比last.pt高出2-3个百分点的mAP直接无脑用best。如果你自己要从多个权重中选别只盯着精度把每个权重在测试集上跑一遍比较直观的检测效果再决定。5. 登录注册模块与系统界面实现模型训练得再好最后还是要落地成产线工人能直接操作的工具。这一步我实现了完整的登录注册功能并把模型推理集成到图形界面让整个系统具备桌面级应用的样子。5.1 用户系统的数据库设计与安全实践用户表设计没有走复杂的权限模型就用一张user表存储用户基本信息CREATE TABLE IF NOT EXISTS user ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, role TEXT NOT NULL DEFAULT operator, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )密码存储是安全实践的重头戏绝不能明文保存。我用的是hashlib加盐哈希每次注册时生成随机盐值把盐和密码拼接后做SHA-256哈希数据库同时存储盐值和哈希值。登录校验时取出该用户对应的盐值对输入的密码做同样哈希对比数据库中的哈希值。import hashlib import os def hash_password(password: str, salt: str None) - tuple: salt salt or os.urandom(16).hex() hashed hashlib.sha256((salt password).encode()).hexdigest() return hashed, salt def verify_password(password: str, salt: str, hashed: str) - bool: return hash_password(password, salt)[0] hashed这个方案虽然不是BCrypt那种重量级的做法但在桌面应用场景下已经能挡住绝大多数风险。毕竟这个系统的威胁模型是防止无关人员误操作不是对抗专业黑客攻击。登录逻辑还有一层细节连续多次输错密码要暂时锁定账号我设置了5次错误后锁定5分钟。这个功能不复杂但能有效防止暴力破解也让系统显得更完整。5.2 主界面功能区划分与交互逻辑主界面的整体设计我在第一章已经说了大概这里把实现细节展开。左侧操作区btn_open_image QPushButton(选择图片) btn_open_camera QPushButton(开启摄像头) btn_detect QPushButton(开始检测) btn_save_result QPushButton(保存检测结果)选择图片按钮会弹出文件对话框支持jpg、png、bmp格式选定后图片缩放到界面中间的显示区域。此时只是加载预览不执行推理。点击开始检测后才调用模型这样设计避免用户误触按钮导致意外推理。检测结果显示分两部分画框后的图片展示在中间缺陷类别、置信度、数量统计展示在右下角的表格中。表格每行对应一个检测框列包含缺陷类别、置信度、位置坐标、尺寸。生产人员可以一眼看到当前图片里总共发现几处缺陷、分别是什么类型。摄像头采集用了OpenCV的VideoCapture接口支持USB摄像头和RTSP网络摄像头。帧率控制在10到15FPS做实时抽检够用。这里要注意摄像头分辨率太高的分辨率推理耗时明显上升我建议采集分辨率控制在1280x720以下推理端再缩放到640x640。5.3 模型推理模块与界面集成的关键实现模型推理不能直接在界面线程里跑否则图像会卡住、窗口无响应。我的做法是用QThread把推理放到后台线程界面线程只负责显示结果。这在PySide6里是标准做法但很多第一次做界面集成的开发者容易忽略。class DetectThread(QThread): result_ready Signal(object) def __init__(self, model_path, image): super().__init__() self.model YOLO(model_path) self.image image def run(self): results self.model.predict( sourceself.image, conf0.25, iou0.45, imgsz640, device0 if torch.cuda.is_available() else cpu, verboseFalse ) self.result_ready.emit(results[0])conf0.25是置信度阈值低于这个值的结果会被过滤掉。这个阈值不是越高越好阈值高会漏检低置信度的真实缺陷阈值低会引入大量误检。0.25是我在验证集上尝试多组值后确定的你可以根据自己的误检和漏检倾向适当调整。iou0.45是NMS的IoU阈值用于消除同一目标的重复框一般保持默认即可。推理结果通过Signal传递到主线程主线程负责把检测框和标签绘制到图片上。绘制时保留了置信度文本Crack 0.87这样的格式方便操作人员判断模型对每个检测结果的把握程度。5.4 界面打包发布的关键配置开发调试完成后要交付给现场使用不能要求每台电脑都装Python环境。PyInstaller打包是桌面Python应用的常规方案但坑也不少。最需要注意的是把模型权重文件和UI资源文件都加进打包配置否则程序启动时找不到模型直接闪退。我用的打包配置核心部分pyinstaller --windowed --onefile --name SolarDefectDetector \ --add-data models/best.pt:models \ --add-data ui/*.qss:ui \ --hidden-importultralytics \ --hidden-importcv2 \ main.py--windowed参数不显示控制台窗口--onefile把所有内容合成一个exe。但onefile模式启动时会先解压临时目录大型模型文件会让启动变慢如果你的模型超过200MB建议用onedir模式启动速度会明显改善。打包后的exe在不同电脑上运行最常出问题的是缺失Visual C运行库。可以用Microsoft提供的VC_redist安装包预先装在目标机器上或者把自己项目里的相关DLL一并打包进去。第一次部署时我在现场踩过这个坑最后是装了一遍运行库解决的。6. 常见问题与实战排查技巧任何一个真实项目都会遇到各种问题走过这些弯路才算真正掌握这个系统。我把项目开发过程中遇到的最典型问题和排查思路整理出来这部分内容花了我大量时间验证是常规文档里不会写的。6.1 训练阶段问题汇总模型不收敛是我遇到最多的训练问题具体表现是loss长期在高位震荡或直接nan。我总结了三个原因第一个是学习率过大初始学习率0.01对于SGD是标准值但如果用了AdamW还沿用0.01基本必炸第二个是数据集标签格式错误常见是归一化坐标超出0-1范围或者类别ID不在配置范围内第三个是BatchNorm的batch size太小导致统计量不稳定。另有一个非常容易被忽视的问题是CUDA内存不足。这个报错表面是显存不够实际可能是批次大小、输入分辨率、模型体量三个因素共同作用。我的排查顺序是先降batch再降分辨率最后换小模型而不是一上来就换显卡。另外Ultralytics会自动开启梯度累积吗并没有需要手动控制。如果显存紧张把batch设为8甚至4配合梯度累积参数也能稳定训练。验证集表现良好但测试集崩掉基本可以确定是过拟合。这时候去检查训练集中有没有测试集的图片有时候网上找的数据集会混在一起。数据泄露是个默默毁掉整个模型的问题我见过一个项目验证集精度95%、测试集只有60%查到最后就是数据划分时没有做随机种子隔离。6.2 界面与应用问题汇总摄像头打开失败这个问题的出现频率非常高。我排查的经验是先看摄像头索引电脑可能有多个摄像头cv2.VideoCapture(0)不一定是对的索引可以循环尝试0到2。再看权限——Windows下有些软件会占用摄像头微信、钉钉后台挂着摄像头就会被锁。最后看RTSP地址格式有些网络摄像头的RTSP地址包含特殊字符需要用URL编码处理。界面在推理时卡死的问题本质上是没有用多线程。这个我在前面强调过界面线程里的任何耗时操作都会阻塞窗口消息循环。除了推理放到工作线程外图片加载也要注意大图直接加载会卡界面应该先缩略显示推理后再用完整分辨率。登录后进入主界面报模型加载失败一般是权重路径写死了开发机的绝对路径到了新电脑上路径变了找不到文件。我的建议是代码里用相对路径把权重文件放在exe同级的models目录下或者用打包工具的资源路径API来定位文件。6.3 检测效果优化进阶建议当我完成第一轮训练后模型对常见的碎片、脏污已经能稳定检出但隐裂这种细小缺陷的召回率还是不够。针对这个问题我实验了几个优化方向第一个是图像增强的前置处理。在推理前对输入图像做CLAHE自适应直方图均衡化增强局部对比度让隐裂的暗线更明显。实验对比后发现隐裂召回率能提升约5个百分点但对脏污检测有轻微负面影响。我的处理方式是只在置信度低于阈值时做二次增强推理相当于多一次复核。第二个是模型集成。用不同seed训练两个模型推理时取两个模型的并集检测框置信度取最大值。这个方法能同时提升精度和召回率但推理时间翻倍只适合离线抽检场景不适合产线实时检测。第三个是重训练时的anchor调优。YOLO系列的anchor是自适应学习的但如果你的缺陷目标尺寸分布跟默认anchor差异很大可以先用k-means聚类重新计算anchor再迁移学习训练。这种方法对细长形目标隐裂、划痕尤其有效因为宽高比极端的anchor能更精确匹配目标形状。6.4 从模型到产品化的几个经验小结最后分享几条散装经验都是项目实践打磨出来的。测试集和验证集一定要分开不要图省事混在一起。很多项目指标好看实际一上线就现原形就是数据划分不规范。好的数据集划分是整个项目可信度的基石。UI界面不是锦上添花是产品能否被接受的关键。一个遮遮掩掩的终端工具和一个人人能看懂结果的图形界面在车间里的接受度天差地别。我见过算法很优秀的系统因为界面难用被产线弃用也见过算法一般但界面清晰的系统被工人主动接受。这个项目把UI当成核心模块来做一点都不多余。模型部署到现场之前务必在目标机器上做一次完整流程测试包括登录、检测、保存结果全链路。开发机上跑得顺不代表现场跑得顺CPU推理和GPU推理的差异、操作系统环境差异都可能让模型加载方式和检测速度发生巨大变化。我不建议第一次就追求极限精度。先让整套系统完整跑通再回来优化指标这样每一步都有明确的调试边界。我开发这个系统时第一版模型mAP只有70出头但整条链路是通的后续调参、换增强策略、优化预处理一个个改下来才到了可用的85以上。工业项目落地稳定可用永远比指标好看更重要。