做工业视觉这几年,我最大的感受是:目标检测模型越来越强,但产线老师傅问你最多的一个问题永远是“这是哪颗料?能不能用?”YOLO系列从v8一路更新到v10、v11、v12,社区里的YOLO26都已经开始被拿来当对比基线时,模型把“框和类别”这件事已经做得相当成熟了。真正缺的,是检测结果到业务决策之间的那段“人话翻译”。
我去年在一条电子元器件分拣线上搭了一套视觉检测系统,思路很直接:YOLO负责又快又准地把电阻、电容、芯片引脚这类目标框出来,DeepSeek和千问大模型负责把框出来的目标“看懂”,再结合业务规则给出可执行的判定建议。这篇文章会把整套系统从版本选型、数据集制作、训练评估、推理部署,到本地接入大模型的完整流程写清楚,给打算做“视觉检测加大模型”这类项目的同学一个可以直接落地的参照。
1. 系统整体设计:为什么是“YOLO加大模型”而不是只用一个模型
1.1 只用YOLO会卡在哪
电子元器件目标检测和通用目标检测不一样,难点非常集中:
- 贴片电阻、电容尺寸很小,0402封装只有1.0毫米乘0.5毫米,在普通工业相机画面里占的像素极少,属于典型的小目标。
- 元件表面反光严重,引脚和焊盘在低角度光源下会拉出高光,边缘轮廓不干净,目标框很容易漂。
- 同一类目下的不同规格外观几乎一致,比如同样是0603封装的10kΩ电阻和1kΩ电阻,丝印只有几个字符的差异,YOLO这类纯视觉检测器实际上学不到这种“阅读理解”级别的特征。
- 极性元件需要区分方向,比如电解电容的正负极标志、二极管的色环方向,这类语义信息靠纯检测模型很难稳定输出。
YOLO擅长的定位和粗分类在这里没有被浪费,但光靠它,系统只能告诉你“这里有一颗电容”,没法告诉你“这颗电容的容值耐压和BOM单是否匹配”。这正是大模型可以发挥作用的地方。
1.2 大模型在这里到底负责什么
我在这套系统里把大模型拆成了两个角色,各管一段:
千问系的多模态模型负责“看图说话”。YOLO把目标框出来后,我把框内图像裁剪下来,喂给Qwen-VL这样的视觉语言模型,让它输出对这颗元器件的自然语言描述,包括丝印内容、引脚数量、极性标志、是否存在缺损。这类描述是YOLO分类头给不出来的细粒度信息。
DeepSeek负责“推理和决策”。它接收Qwen-VL的描述,再结合从知识库里检索出来的规格书片段和产线规则,输出最终判定,比如“该物料与BOM单匹配,可正常使用”或“丝印模糊,建议人工复检”,同时生成JSON结构化数据给下游系统。
检测模型和大模型组合起来以后,整个系统就不只是“找到”元器件,而是“理解”元器件。
1.3 整套系统的工作流程
整个平台的运行链路是:
- 工业相机采图,图传到检测服务。
- YOLO模型对整张图做目标检测,输出目标框、类别、置信度。
- 按目标框裁剪ROI区域,做必要的图像增强。
- Qwen-VL对每个ROI生成文本描述。
- BGE-M3把描述和检索语句向量化,从元器件规格书知识库中召回相关文档片段。
- DeepSeek综合视觉描述和检索结果,依据规则库输出判定结论。
- 系统返回结构化结果,包括目标位置、类别、置信度、判定建议、异常描述。
这个流程的核心思路是“视觉模型出框,多模态模型出描述,推理模型出结论”。三个模型各司其职,任何一环都可以单独替换升级,不会互相影响。
2. YOLO版本选型:v8/v10/v11/v12和YOLO26到底怎么挑
2.1 各版本的实际表现对比
现阶段在Ultralytics生态里能直接上手的主要是YOLOv8、v10、v11、v12,另外还有社区里广泛流传的YOLO26这类实验版本。我把它们在电子元器件数据集上的实际表现整理成了表格,方便快速选型:
| 版本 | 核心特点 | 我实测的感受 | 适合场景 |
|---|---|---|---|
| YOLOv8 | 生态最成熟,Anchor-Free,C2f模块,文档和教程最全 | 最稳的基线,导出ONNX、TensorRT极少出问题,训练收敛稳定 | 主力模型,绝大多数产线场景 |
| YOLOv10 | NMS-free端到端检测,推理时少了NMS后处理环节 | 延迟确实低,但收敛速度比v8稍慢,AP在小目标上略低于v8 | 边缘盒子、低延迟要求高的场景 |
| YOLOv11 | C3k2模块,特征融合做了调整,整体结构更紧凑 | 小目标AP有轻微提升,但推理耗时增加约10% | 追求精度、算力充裕的离线检测 |
| YOLOv12 | 在注意力机制和训练细节上做了大量工程化打磨 | 开箱即用的体验最好,数据增强和EMA策略更稳 | 新项目试水时可以直接从它开始 |
| YOLO26 | 社区实验版本,网络结构改动大,API不稳定 | 我只把它当精度对比基线,没有用到生产环境 | 算法预研、论文对比 |
对电子元器件这种“小目标、高精度、样本可离线采集”的场景,我的最终选择是以YOLOv8s为主力,YOLOv10n做低延迟备份,YOLOv11和v12在相同数据集上做交叉验证。YOLO26这类新版本,等社区稳定下来以后再评估也不迟。
2.2 损失函数在小目标检测中的关键作用
YOLO的损失函数通常包含三部分:分类损失、边界框回归损失和DFL分布损失。很多人训练电子元器件检测模型时只看mAP,一旦效果不好就盲目加数据或换大模型,其实问题往往出在损失函数配置上。
分类损失一般用BCE,适合多标签场景。边界框回归损失最常用的是CIoU,它同时考虑了重叠面积、中心点距离和长宽比。比DIoU多了一项长宽比惩罚项,对小而扁的贴片元器件特别重要,这类目标的长宽比往往极度不对称。
DFL是更关键的一项。它把边界框坐标当成离散分布来做回归,让模型对目标边缘位置更敏感。对于电子元器件的引脚这类精细结构,DFL的权重适当调高一些,定位精度会有明显改善。我实测下来,在训练时把DFL权重从默认的0.5调整到0.7,配合CIoU,小目标的APs指标能提升一到两个百分点。
如果做的是引脚级检测而不是整颗器件检测,可以考虑切换YOLOv8-seg做实例分割。分割掩码对引脚轮廓的表达能力远强于边界框,但训练成本和推理耗时都会上升,需要做取舍。
2.3 评估指标不能只看mAP
小目标检测领域经常提到一组评价参数:mAP@0.5、mAP@0.5:0.95、APs、ARs和F1-score。这些指标在我这套系统里都有对应落地方式。
mAP@0.5表示IoU阈值取0.5时的平均精度,这个值适合评估“有没有检出”这个粗粒度问题。mAP@0.5:0.95则把IoU阈值从0.5逐步提高到0.95,对定位精度要求更严格,对电子元器件的引脚和极小型贴片元件更有参考价值。APs专门统计小目标的平均精度,我一般要求在0.3以上才算达标。
实际产线验收时,我除了看这些模型指标,还会记录更贴近业务的指标:漏检率、误检率、平均响应时间。mAP高不等于产线好用,因为mAP统计的是检测框和真实框的匹配比例,产线关心的是“有没有把A料错判成B料”。这两个维度需要配合着看,缺一不可。
3. 电子元器件数据集制作:从拍照到标注那点事
3.1 先解决图像质量问题
电子元器件检测的数据集,图像质量比数量重要得多。前期拍摄光源没打好,后面再怎么增强都补不回来。
我的经验是,光源方案优先考虑低角度环形光和同轴光。环形光可以从四周均匀打亮元件轮廓,减少暗角;同轴光对高反光的引脚和焊盘更友好,能压住高光。如果条件有限,至少要在元件上方加一块柔光板,直接把硬光打上去会生产大量反光点,检测框边缘特别容易抖动。
相机分辨率建议不低于1200万像素。很多元器件在画面里只占几十个像素,分辨率不够,小目标检测指标再优化也没用。另外,采集时不要只拍一种背景,至少覆盖浅色、深色、纹理背景三种情况,让训练集包含足够的背景多样性。
还有一个容易被忽略的点:负样本一定要单独采一批采集空板、缺件、错件、引脚弯曲的图。大模型和YOLO都需要通过负样本学会“什么不该框、什么算异常”。
3.2 CVAT标注与YOLO格式转换
我标注工具首选CVAT,免费、支持团队协作,导出格式丰富。标注电子元器件时,类别不要分得太细,比如不要直接标注“10k欧姆电阻”,而是标注“电阻Resistor”,具体规格留给大模型去判断。YOLO只负责粗分类,这样训练样本的类内方差更小,模型更容易收敛。
CVAT导出的是COCO格式或者CVAT自有格式,需要转换成YOLO格式。YOLO格式每张图片对应一个txt文件,每行内容是“类别id 中心点x 中心点y 宽度 高度”,全部归一化到0到1之间。
如果数据来源不是CVAT,比如拿到的标注是KITTI格式,转换逻辑也很简单。KITTI标注是“类别 截断 遮挡 左 上 右 下”这种格式,写一个Python脚本转成YOLO格式即可:
import os def kitti_to_yolo(line, img_w, img_h): parts = line.strip().split() cls_name = parts[0] left, top, right, bottom = map(float, parts[4:8]) center_x = ((left + right) / 2) / img_w center_y = ((top + bottom) / 2) / img_h box_w = (right - left) / img_w box_h = (bottom - top) / img_h return f"{cls_name} {center_x:.6f} {center_y:.6f} {box_w:.6f} {box_h:.6f}"转换完以后,务必用可视化工具随机抽检几百张,确认框位置没有偏移。标注错位是训练效果差的头号原因,没有之一。
3.3 数据增强与半合成数据
Ultralytics训练时默认会开启Mosaic、MixUp、随机翻转等增强策略,对通用目标检测效果很好。但用在电子元器件上要小心:水平翻转会把极性元件的方向搞反。比如电解电容的正负极标志,实物里应该从右向左,翻转后变成从左向右,模型学到的是错误方向信息。
我通常会把翻转增强的概率关小,让水平翻转概率保持默认0.5,垂直翻转概率直接设成0。Mosaic增强保留,但开启之后要注意小目标会不会被裁掉。如果发现小目标漏检严重,可以关闭Mosaic的最后10个epoch,让模型在纯真实分布上收尾。
半合成数据是我这段时间用过最有效的手段:从真实图像里切出元件图块,用程序随机贴到空PCB板图上,再给贴图位置施加透视变换、亮度变化和模糊,自动生成几十万张带标签的图片。这种方式补充了大量背景变化,也把本来就稀少的小目标数量拉高了很多。合成数据需要和真实数据按1比5左右混合训练,完全用合成数据训练的效果不太行。
3.4 小目标与密集场景的专项处理
对于尺寸小于32×32像素的目标,我坚持两个处理原则:一是输入分辨率不能低,训练时imgsz至少设置1024,分辨率越高,小目标特征保留越多;二是推理时对稠密区域做SAHI切片推理,把大图切成带重叠区域的小图分别检测,再将结果拼回去。
SAHI的缺点是推理时间变长。一张4000×3000的图切成1024的小图并发推理,耗时大约是整图推理的3到4倍。我的处理策略是先用YOLO整图快速推理一遍,如果检测出某个区域目标特别密集,再只对该区域做二次切片推理。两段式方案既保证了速度,也稳住了小目标召回率。
4. 训练、评估与部署:从实验室到产线的完整链路
4.1 训练环境与超参数配置
训练环境这块,最省心的组合是NVIDIA显卡加Ultralytics。导出到TensorRT也很方便。如果只有AMD显卡,也不是不能跑。在Linux下可以用ROCm版本的PyTorch跑训练,在Windows下可以用DirectML后端做推理,但训练这块AMD确实不如N卡省心,训练速度会有差距。我的建议是主力训练机用N卡,AMD显卡如果只是做离线推理,用ONNX Runtime加DirectML是完全够用的。
训练超参我给出一个可以直接抄作业的配置:
yolo detect train \ data=components.yaml \ model=yolov8s.pt \ epochs=200 \ imgsz=1024 \ batch=16 \ optimizer=AdamW \ lr0=0.001 \ mosaic=1.0 \ close_mosaic=10 \ fliplr=0.5 \ flipud=0.0 \ dfl=0.7对电子元器件这种高分辨率小目标场景,imgsz=1024是底线。batch要结合显存调整,如果16张放不下,就降到8。训练200轮左右基本能看到收敛,如果到150轮时验证集已经过拟合,提前早停就行。
4.2 评估指标怎么读
训练完成后,不要只看训练日志里最后一行mAP。我一般会导出val结果,重点看以下指标:
| 指标 | 我设置的合格线 | 说明 |
|---|---|---|
| Precision | 大于等于0.95 | 检出的目标里真实目标的比例,误检不能多 |
| Recall | 大于等于0.95 | 所有真实目标被找到的比例,漏检不能多 |
| mAP@0.5 | 大于等于0.98 | 粗定位能力,必须拉满 |
| mAP@0.5:0.95 | 大于等于0.75 | 精确定位能力,影响后期ROI裁剪质量 |
| APs | 大于等于0.30 | 小目标检出能力,电子元器件重点看这个 |
| F1-score | 大于等于0.95 | 综合精度和召回率 |
还要把混淆矩阵导出来看。如果发现电容和电感两类互相误检,说明类别外观太像,YOLO分类头已经到瓶颈,这时就该设计上把这两类合并粗类,交给Qwen-VL去做精细区分。
4.3 导出ONNX、TensorRT与OpenVINO
模型训练好之后,部署到不同平台用的格式不一样。通用导出命令如下:
yolo export model=best.pt format=onnx dynamic=True imgsz=1024导出的ONNX可以直接用ONNX Runtime跑,也可以作为中间格式转成TensorRT或OpenVINO。
TensorRT对N卡推理速度的提升非常明显,在1024输入下,YOLOv8s的TensorRT FP16推理速度能到5到8毫秒每帧。OpenVINO在Intel CPU和核显上优化得不错,一些工控机没有独显,用OpenVINO跑ONNX也能拿到实时性。
如果用的是YOLOv10,导出后可以通过配置启用端到端输出,跳过传统NMS后处理。推理链路少一环,在边缘设备上省下来的时间很可观。但要注意,端到端检测在密集小目标场景下的表现会略低于NMS版本,需要实测对比后再决定。
4.4 一键部署脚本的思路
生产环境我一般是写一个一键部署脚本,把从裸机到服务可用的步骤固化下来。脚本核心逻辑包括四步:
- 安装Python环境、CUDA或DirectML运行时。
- 拉取项目代码和模型权重,权重文件放在固定目录。
- 安装依赖包,导出ONNX或TensorRT引擎。
- 启动FastAPI服务,加载模型,监听检测请求。
这样现场装机时只需要执行一条命令,不需要人工逐步配置。我这边的脚本还会在启动时做一次自检,用一张验证图跑一遍推理,确认输出正常后再对外提供服务,避免模型权重放错目录导致运行时报错。
5. 本地接入DeepSeek与千问大模型:从检索到判定
5.1 DeepSeek、千问和BGE-M3怎么分工
这套智能识别平台里,大模型不是随便接一个就行,三个模型有明确分工:
- Qwen-VL(比如Qwen2.5-VL系列)承担视觉语言理解。它接收YOLO裁剪出来的元件ROI图片,输出对元件外观的描述,包括丝印、引脚、极性标志和表面状态。
- DeepSeek承担推理和最终决策。它接收Qwen-VL输出的文本,再结合业务规则和知识库检索结果,生成判定结论和异常说明。
- BGE-M3承担知识检索。元器件规格书、厂家手册、BOM表这些资料先做好向量化,用户查询或系统判定时,用BGE-M3在数据库里检索最相关的片段,让DeepSeek回答时有据可依。
这个分工的核心是让大模型“各干各的擅长的事”。不用一个模型硬扛所有任务,因为多模态模型的纯文本推理能力往往不如专门的推理模型。
5.2 本地部署还是API调用
DeepSeek和千问都提供API调用方式,也可以本地部署开源权重,两种方式各有适用场景。
API调用的优势是接入简单,一行代码就能完成请求。适合开发调试、功能验证、数据量不大的项目。缺点是数据要传到外部服务,而且每次调用都要按token计费,产线高峰期如果每张图片都调用大模型,成本会迅速上升。
本地部署的优势是数据不出厂、时延可控、支持私有化定制。现在用Ollama或vLLM在本地起一个兼容OpenAI接口的服务非常简单。DeepSeek的轻量模型和Qwen2.5系列模型在24GB显存上就能跑得很流畅,如果要做高并发,上A10或4090这类卡就能支撑不少并发。
我的建议是:产线验证阶段用API快速出结果,验证通过以后,值得专门配一台服务器做本地部署。延迟从单次2到3秒降到500毫秒以内,长期算下来也更省钱。
5.3 代码示例:DeepSeek API与本地Qwen-VL
DeepSeek的API调用方式和OpenAI兼容接口写法一致,我在业务代码里直接用客户端请求deepseek-chat模型:
from openai import OpenAI client = OpenAI( base_url="https://api.deepseek.com", api_key="你的APIKey" ) resp = client.chat.completions.create( model="deepseek-chat", messages=[ {"role": "system", "content": "你是电子元器件质量判定助手,请严格根据输入信息输出JSON结果。"}, {"role": "user", "content": "YOLO检测到一颗贴片电阻,丝印内容为330,引脚数量为2,请判定是否与BOM匹配。"} ] ) print(resp.choices[0].message.content)本地跑Qwen-VL我推荐用vLLM起服务,启动之后同样走OpenAI兼容接口,业务代码不用改:
from openai import OpenAI client = OpenAI( base_url="http://localhost:8000/v1", api_key="EMPTY" ) resp = client.chat.completions.create( model="Qwen/Qwen2.5-VL-7B-Instruct", messages=[ {"role": "user", "content": [ {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}}, {"type": "text", "text": "详细描述这张图片中的电子元器件外观特征。"} ]} ] ) print(resp.choices[0].message.content)这样本地和云端的切换只需要改base_url和model两个参数,架构上非常干净。
5.4 提示词模板与结果结构化
大模型接入后,能不能稳定产出业务可用的结果,关键在提示词模板。我在系统里把请求结构化成一个固定模板,每次只替换动态内容:
你是一名电子元器件质检专家。以下是一条检测记录: 检测类别:{class_name} 置信度:{confidence} 位置:{bbox} 视觉描述:{qwen_description} 知识库检索结果:{retrieved_context} 请根据以上信息完成判断: 1. 该元件是否存在异常? 2. 是否与BOM单中的物料编码匹配? 3. 建议操作:放行、复检、报废。 只输出JSON,不要输出解释。提示词里明确写“只输出JSON,不要输出解释”,是防止大模型输出一堆废话导致下游系统解析失败。同时把知识库检索结果放在视觉描述之后,让模型在推理时有充分上下文。
5.5 把DeepSeek接入团队开发工具
这里顺带分享一个很实用的经验。团队在做这套系统时,规则脚本和维护的提示词模板非常多,我直接把DeepSeek接入到了VSCode这类开发工具里,让它当编码助手。写格式转换脚本、调YOLO训练参数、快速生成提示词模板片段,效率比纯手写高很多。Codex这类工具如果支持自定义模型地址,也可以把DeepSeek配置进去,在新项目初始化时生成目录结构和基础代码,省下不少重复工作。
6. 我踩过的坑:常见问题与排查实录
6.1 训练阶段的坑
| 现象 | 原因 | 解决方案 |
|---|---|---|
| 训练时loss不降 | 学习率太高或标注类别id错乱 | 用lr0=0.0005重试,可视化检查标注 |
| mAP很高但漏检严重 | 负样本太少,模型不知道什么不该框 | 增加空板和缺件样本 |
| 小目标AP特别低 | 输入分辨率不够 | imgsz从640提高到1024 |
| 验证集过拟合 | 数据增强太强或训练轮数过多 | 调低增强强度,打开early stopping |
印象最深的一次是训练了100多轮的模型在验证集mAP@0.5超过0.99,但上线第一天就漏检了一批浅色背景下的电容。后来排查发现训练集里浅色背景的图片占比不到5%,模型对浅色背景的适应性极差。后来补拍了一批浅色背景的真实数据,重新训练后漏检立刻降下去了。数据分布决定模型表现上限,这个坑踩一次就够。
6.2 部署阶段的坑
部署时最容易出问题的是TensorRT版本和动态shape不匹配。建议先固定输入分辨率,不要开动态shape,减少不必要的麻烦。如果开了dynamic=True导出ONNX,再用TensorRT转引擎时,记得要指定profile的min、opt、max三种shape,否则推理时会报尺寸不匹配。
YOLOv8和v10处理NMS的方式不同。v8导出后还需要额外处理NMS节点,我一般用ONNX Runtime自带的后处理函数。v10用NMS-free输出,但输出张量的解读方式不同,需要单独写解析逻辑。这两者不要混用。
AMD显卡跑部署的注意点是DirectML的OP支持范围。个别YOLO版本里的自定义算子可能在DirectML上不支持,或者速度异常慢。我的处理方案是多保留一个ONNX模型,遇到算子不兼容时先检查ONNX算子版本,必要时用OpenVINO替代DirectML。
6.3 大模型接入阶段的坑
| 现象 | 原因 | 解决方案 |
|---|---|---|
| Qwen-VL描述和实际不符 | 输入图片被压缩失真 | 提升ROI原图质量,不要直接缩放 |
| DeepSeek输出格式不稳定 | 提示词没有约束输出格式 | 强制要求只输出JSON,并在代码层面做重试解析 |
| 回答结果经常自相矛盾 | 知识库上下文冲突 | 用BGE-M3限定检索范围,只传最相关的2到3段 |
| 大模型判断过于灵敏 | 描述噪声被当成异常 | 让DeepSeek参考置信度阈值,置信度低于0.8时输出“无法判断” |
大模型的幻觉问题要特别重视。我在系统里做了两层保护:第一层是只有YOLO置信度超过0.75的ROI才会送大模型做进一步分析,置信度低的目标一律走“人工复检”通道;第二层是让DeepSeek的输出只作为“判定建议”,实际控制产线分拣动作的还是PLC在收到高置信度一致的信号后才执行。大模型在这个架构里是决策辅助,不是唯一决策源。
7. 写给想复现这套方案的人
如果你准备在类似场景里落地这套系统,我给一个清晰的参考路线:先花两周把YOLO检测模型跑通,再花一周接入大模型做辅助判定,不要同时上手所有东西。YOLO部分用v8s加imgsz=1024,数据量从1000张真实图片起步,优先保证图像质量和标注质量。等YOLO的精度和速度都达标后,再按第5章的流程把Qwen-VL、BGE-M3和DeepSeek串联起来。
整个系统里,大模型和YOLO服务一定要解耦成独立服务。YOLO检测服务用FastAPI单独部署,大模型服务单独占一台机器,两边通过HTTP接口通信。这样升级大模型权重时不需要重启检测服务,检测服务出故障也不会把大模型推理线程拖死。
这套系统跑顺之后,我最大的体会是:模型能力决定上限,工程化和数据质量决定下限。YOLO和大模型都只是工具,真正值钱的是把产线老师傅的经验翻译成规则和提示词的过程。如果预算有限,先别急着堆显卡,把打光方案和数据采集做好,效果比换更大参数模型明显得多。
最后再说一个实际操作中的小技巧:YOLO检测框的裁剪区域不要直接缩放到224×224再送Qwen-VL,那样会丢失丝印细节。建议先按原图比例把ROI扩到640×640左右再进多模态模型,视觉语言模型在分辨率足够时,对丝印和极性的识别准确率会高出一截。检测框的精度,永远是大模型能正确理解的前提。