多模态视觉流水线
十件生产级资产,给真正要把视觉应用上线的开发者:增强、预训练 backbone、实时检测、开放集检测、分割、自然场景和文档 OCR、给 agent 用的截图理解、后处理、数据集与模型评测。你真正会拼起来的栈。
这个 pack 包含什么
这是当通用视觉语言 API 不够用时你会自己搭的那一套 —— 你需要分类自己的图像、检测领域里特殊的物体、OCR 自己的文档版式、给 agent 解析截图,或者按帧分析视频还要满足生产延迟。每个资产都是生产级、活跃维护,代表视觉开发者必须从头到尾负责的某一层。
这个 pack 刻意区别于那种通用的「计算机视觉工具大全」横评。它按你上线时实际取用工具的顺序组织:你不是从 model.predict() 开始的 —— 你是从数据开始、训练或微调 backbone、把检测或分割接到热路径、把检测结果后处理成业务逻辑,然后每次改动都跑一遍评测集。
所有这些资产串起来回答同一个问题,也是大多数视觉团队在上线第 3 周才痛苦意识到的:demo 图能跑通是因为你挑过;唯一重要的数字是在真实留出评测集上的表现,每次改动前后都跑一遍。 这里一半的资产存在的意义就是让这个 loop 跑得快。
推荐安装顺序(增强 → backbone → 检测 → 分割 → OCR → 截图 → 后处理 → 评测)
- Albumentations —— 图像增强。从这里开始,因为再大的模型也救不了瘦弱的训练集。Albumentations 快(NumPy + OpenCV)、可组合、bbox / mask / keypoint 都跟图像同步变换。它是大多数 Kaggle 夺冠和大多数生产训练流水线背后的标准预处理层。
- timm(PyTorch Image Models) —— 预训练 backbone。需要 ResNet / ConvNeXt / EfficientNet / ViT / DINOv2 做分类或特征提取时,timm 都有,统一 API,两行代码切换权重。别自己手写 ResNet 定义,也别从来路不明的随机 checkpoint 起步微调。
- Ultralytics YOLO —— 实时目标检测。YOLO11 是检测、实例分割、分类、姿态估计、旋转框的速度-精度默认选项。一个 Python API + CLI 覆盖训练、验证、预测、导出到 ONNX / TensorRT / CoreML / TFLite。这是大多数生产检测流水线的推理主力。
- Grounding DINO —— 用文本提示的开放集检测。当你要检测的类别不在任何预训练标签集里时,Grounding DINO 接受文本提示(「红色急停按钮」「序列号贴纸」)返回检测框 —— 无需微调。配 SAM 2 一次性做带语义的分割。
- SAM 2(Segment Anything 2) —— 图像与视频通用的可提示分割。点一个点或画一个框,SAM 2 返回 mask;视频上原生跨帧跟踪 segment。「随处提示、随物分割」+ 视频跟踪这个组合让它成为大多数现代标注与分析流水线里的后处理步骤。
- PaddleOCR —— 100+ 语言的生产级 OCR。轻量(边端能跑)、自然场景文本上准确,在截图、招牌、包装、UI 上经过反复实战。输入是自然场景上的散文式文字时用它。
- Surya —— 90+ 语言的文档 OCR。PaddleOCR 是全能选手,Surya 是为扫描件和 PDF 文档专门做的:文本识别、行级检测、阅读顺序、版式分析(标题、表格、插图)。输入是文档而不是照片时用它。
- OmniParser —— 给 AI agent 用的屏幕解析。把截图转成结构化数据(可交互图标、语义区域、标签),下游 LLM 可以直接拿去动作。这是「视觉模型能描述截图」和「agent 能点对按钮」之间缺的那一层。要做截图驱动的 agent,这层必装。
- Supervision —— Roboflow 的后处理工具箱。你之前在每个项目里反复 inline 写的那些东西的可组合版本:检测标注器、多边形区域、过线计数、ByteTrack、数据集格式转换、几十个把原始模型输出转成业务逻辑的小工具。原生配 YOLO 和 Grounding DINO。
- FiftyOne —— 数据集策展与模型评测。评测闭环。把预测和 ground truth 并排可视化、找标注错误、按元数据切 mAP、做 embedding 聚类、在同一个评测集上对比两个模型。生产团队把可衡量的精度提升归功最多的单一工具 —— 因为它让 loop 跑得够快,团队才真的会跑。
它们怎么协同(生产级视觉流水线)
┌─────────────────────────────────────────────────────────────┐
│ 训练 / 微调 │
│ Albumentations ──► 增强后的 batch │
│ │ │
│ ▼ │
│ timm backbone ──► features / head │
│ │ │
│ ▼ │
│ Ultralytics YOLO ──► 训练好的 checkpoint(.pt → .onnx) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 推理(热路径) │
│ │
│ 图像 / 帧 │
│ │ │
│ ├──► YOLO(闭集、实时) │
│ ├──► Grounding DINO(开放集、文本提示) │
│ ├──► SAM 2(分割、图像 + 视频跟踪) │
│ ├──► PaddleOCR(散文 / 场景文字) │
│ ├──► Surya(文档、PDF) │
│ └──► OmniParser(截图 → 结构化 UI 树) │
│ │ │
│ ▼ │
│ Supervision ──► 标注、跟踪、计数、过线、格式转换 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 评测 │
│ FiftyOne ◄── ground truth + 预测 │
│ 按元数据切片 · 找标注错误 · 模型对比 │
└─────────────────────────────────────────────────────────────┘
切分是故意的。训练是批处理,产出一个 checkpoint。推理是热路径,按输入挑专家(物体用检测器、文字用 OCR 引擎、UI 用 OmniParser)。评测把整个东西裹起来 —— 没 FiftyOne 或等价工具,你根本看不出上周改的增强是帮了你还是悄悄把你最在意切片的 mAP 拉低了。
你会遇到的取舍
- 闭集检测 vs 开放集检测 —— YOLO 在你训练过的类别上又快又准。Grounding DINO 更慢,但接受任意文本提示,对没见过的类别 zero-shot 工作。标签集固定且有数据时默认 YOLO。标签集一直在变或者你没法给每个新类标几千个例子时(产品团队每个 sprint 都要一个新属性),上 Grounding DINO。
- PaddleOCR vs Surya vs 视觉语言模型 OCR —— PaddleOCR 赢在自然场景文字和边端部署。Surya 赢在文档、阅读顺序、版式分析。通用视觉语言模型(GPT-4o / Claude / Qwen-VL)赢在「描述你看到的、抽出相关内容」—— 但每页成本高得多,且输出结构一致性没保证。大多数生产栈用专家(PaddleOCR / Surya),只在低置信页面回退到视觉语言模型。
- SAM 2 vs YOLO 分割 —— YOLO-seg 更快,在固定标签集上用 mask 监督训练。SAM 2 可提示(点一个点、画一个框)且跨视频帧跟踪,但本身不知道类别标签。组合用:Grounding DINO 用文本提示出一个框,SAM 2 在框里分割,YOLO-seg 用于你有自己的标注 mask 数据且要实时吞吐量的场景。
- OmniParser vs 纯视觉语言模型解截图 —— 视觉语言模型能描述截图,但很难稳定输出
{button: "Submit", coords: [x,y,w,h]}到能驱动点击的程度。OmniParser 就是为这种结构化输出做的。要做截图驱动的 agent,解析器进流水线,视觉语言模型放在 OmniParser 输出之后做推理。
常见踩坑
- 破坏标签的增强 —— 随机裁切把 bbox 切掉一半、color jitter 把你正要检测的贴纸颜色盖掉、10 类不均衡数据上还用 mosaic + mixup。训练前先把增强后的 batch 可视化。Albumentations 一行搞定可视化,问题是你不跑这行。
- 用预训练 backbone 不查输入归一化 —— timm 模型对归一化(mean / std)有要求,不同 checkpoint 家族不同。把 ImageNet 归一化后的 tensor 喂给 DINOv2 backbone 会悄悄掉精度。用
timm.data.resolve_data_config,别猜。 - 没评测集 = 没进步 —— 视觉团队最常见的死法。没有几百张手工标注的图像作为 ground truth,每次改动都是凭感觉。第一周就把评测集建起来。每次用户反馈坏 case 就加一条。FiftyOne 就是为了让这个 loop 跑得快而存在。
- 全类一刀切阈值 —— 一个全局置信度阈值按整体 mAP 调到最优,然后部署给只关心稀有类(只有 12 个样本)的客户。按类别在你最在意的切片上调阈值,几乎总值得多写那几行代码。
- OCR 不设置信度地板 —— PaddleOCR 和 Surya 都返回 token 级置信度。生产里把每个 OCR 字符串无脑下游的流水线,迟早会被收据总额上一个字符翻转的 case 打脸。设个阈值地板,低置信页面走人工或视觉语言模型回退。
- 忘了截图不是自然图像 —— COCO / ImageNet 训出来的模型不会泛化到 UI 截图。UI 结构用 OmniParser;要闭集检测图标就在真截图上微调 YOLO;不要假设 Grounding DINO 默认 prompt 就能稳定找到「关闭按钮」。
- 后处理写成一次性脚本 —— 每个团队都会在标准化之前 inline 写三遍「画框、过线计数、导出 CSV」。一次接上 Supervision,给团队省下一个季度重复造的工具代码。
10 个资产打包就绪
常见问题
为什么这个 pack 同时收了 PaddleOCR 和 Surya —— 它们不是重复了吗?
覆盖的场景不一样,大多数生产栈两个都跑。PaddleOCR 是自然场景文字的默认选项:截图、招牌、包装、带文字的照片。Surya 是为文档专门做的:扫描 PDF、多栏版式、阅读顺序、表格检测、表单字段。pack 同时列两个,是因为问题不是「选哪一个 OCR」而是「输入是哪种 surface」—— 一旦你产品里同时有发票和商品图,你两个都会用上。
GPT-4o / Claude / Qwen-VL 这类通用视觉语言模型在哪一层?
在 agent 上游、专家下游,不是任何一层的替代。视觉语言模型擅长「描述这张图里有什么」「回答这张图表的一个问题」,以及作为低置信 OCR 页面的回退。它不适合 30 FPS 的实时目标检测、不适合把截图解析成结构化坐标、也不适合高吞吐量文档 OCR —— 每次调用的成本以及保证结构化输出一致性的开销,让专家在这几层更便宜更稳。把视觉语言模型放在 OmniParser / PaddleOCR / YOLO 输出之上做推理层,而不是替代它们。
我真的需要同时上 YOLO 和 Grounding DINO 吗?
不一定 —— 按用例选。如果你的标签集固定、有数据、关心延迟(安防摄像头、瑕疵检测、体育分析),YOLO 就是正确答案,Grounding DINO 是过度配置。如果标签集一直变、或者你没法给每个新类标几千张(产品团队每个 sprint 要找一个新属性),Grounding DINO 值得加上 —— 它接受文本提示且 zero-shot 工作。很多真实栈是 YOLO 跑核心类别、Grounding DINO 当新类别的逃生通道。
已经在用 Weights & Biases 或 MLflow 记指标,还需要装 FiftyOne 吗?
需要,目的不同。W&B 和 MLflow 擅长指标和实验记录;FiftyOne 是让你实际看数据和预测的工具:并排可视化、按元数据切 mAP、找标注错误、在同一批样本上对比两个模型。能拿到最大精度提升的团队是把时间花在 FiftyOne 里的,不是盯着标量曲线看的。两个都用:W&B / MLflow 管 run 历史,FiftyOne 管样本级别的迭代 loop。
最小可用的视觉评测集要多大?
200–500 张带 ground truth 的图,切成至少 3 个对你产品重要的元数据 bucket(比如光照条件、相机角度、客户等级)。在调任何东西之前的第一周就建起来。每次有真实用户反馈的失败 case 就加一条。三个月之后你会有 1000–3000 张,FiftyOne 查询就变成你在上线前发现回归的方式。难点不是数量,是按元数据切片的纪律 —— 这样你才能看出一次改动在某个 bucket 上是帮了还是害了。