☰
自动标注流水线实战:Grounded-SAM + autodistill + X-AnyLabeling 搭建数据飞轮
2026/10/1 12:46:59 网站建设 项目流程

1. 自动标注这件事,为什么值得从头搭一遍

做视觉项目的人都有一个共同的痛:模型结构调得再花哨,最后卡住进度的往往不是网络本身,而是数据。尤其是目标检测、实例分割这类任务,标注成本高得离谱。我手上一个工业质检的小项目,两千张图,三个人标了整整一周,最后还因为标准不统一返工了三分之一。那段时间我就在想,能不能让模型先帮我把框画个八九不离十,人只做修正?这就是自动标注的出发点。

自动标注不是新概念,但真正把它跑通、跑稳、跑成一条可持续的流水线,中间要踩的坑比想象中多。标题里提到的三个东西——X-AnyLabeling、autodistill、Grounded-SAM——恰好代表了自动标注的三个关键环节:交互式标注工具、知识蒸馏式自动打标框架、开放词汇检测分割模型。把它们串起来,就能搭出一条从"零标注"到"可用数据集"的完整链路,而且这条链路是可以滚起来的,也就是大家常说的数据飞轮。

这篇文章面向的是已经有一点深度学习基础、手上有实际标注需求的人。你可能是在做缺陷检测、遥感识别、零售货架分析,或者只是想让自己的数据集扩充得快一点。不管哪种,只要你能跑通 Python 环境、能看懂 YOLO 的标注格式,这篇内容就能直接抄作业。我会把每个环节为什么这么选、参数怎么定、坑在哪里,都掰开讲清楚。

先说结论性的判断:Grounded-SAM 负责"从文字到框和掩码"的冷启动,autodistill 负责"把大模型能力蒸馏到小模型"的批量生产,X-AnyLabeling 负责"人机协同的精细修正与格式落地"。三者不是替代关系,而是流水线上的三道工序。理解了这个分工,后面的操作就顺了。

2. 三个核心组件到底各自解决什么问题

2.1 Grounded-SAM:用一句话把目标框出来

Grounded-SAM 这个名字其实是两个模型的组合:Grounded-DINO 负责开放词汇检测,SAM 负责精细分割。Grounded-DINO 的特点是你可以用自然语言描述你要找的东西,比如"生锈的螺栓""破损的包装袋",它就能把对应的区域框出来,不需要你事先定义类别、不需要训练。SAM 则接过这些框,把框内的物体轮廓精确地抠出来,得到像素级的掩码。

这个组合的威力在于零样本。你不需要准备任何标注数据,只要能用文字描述清楚目标,它就能给你初步结果。对于冷启动阶段,这意味着你可以用几分钟时间,把一批完全没标过的图变成有框有掩码的候选标注。当然,它的短板也很明显:文字描述模糊时召回不稳定,密集小目标容易漏,类别多了之后 prompt 工程本身就成了体力活。

2.2 autodistill:把大模型的知识"蒸馏"成小模型

autodistill 的思路很聪明。它不指望 Grounded-SAM 直接产出最终标注,而是把它当成"老师"。流程是:老师模型在一批无标注图片上生成伪标签,然后用这些伪标签去训练一个"学生"模型,比如 YOLOv8 或者 RT-DETR。学生模型训练好之后,再拿它去批量推理剩下的图片,速度快、成本低,而且随着你不断修正和补充数据,学生模型会越来越准。

这就是数据飞轮的核心机制:老师生成 → 学生训练 → 学生推理 → 人工修正 → 数据回流 → 学生再训练。每一轮循环,学生模型都在变强,人工介入的比例在下降。autodistill 把这条链路的代码封装得很轻,基本上几十行就能跑通一个完整的蒸馏流程,这也是我推荐它的主要原因——它不重,不绑架你的技术栈。

2.3 X-AnyLabeling:人机协同的最后一公里

模型给出的标注永远不可能 100% 正确,尤其是边界、遮挡、小目标这些场景。X-AnyLabeling 的价值就在这里:它是一个带 AI 辅助的标注工具,支持 SAM、YOLO 等多种模型在线推理,你点一下就能自动生成候选框或掩码,然后手动微调。它还支持自动标注模式,可以批量跑模型、批量保存结果,再人工过一遍。

更关键的是格式兼容。X-AnyLabeling 原生支持 COCO、YOLO、VOC、MOT 等主流格式的导入导出,这意味着你从 Grounded-SAM 或 autodistill 拿到的结果,可以无缝进到工具里修正,修完再导出成训练框架认识的格式。这条链路打通之后,标注这件事就从"纯手工"变成了"审核 + 微调",效率提升是数量级的。

组件核心能力在流水线中的角色典型输入典型输出
Grounded-SAM开放词汇检测 + 分割冷启动生成伪标签图片 + 文字 prompt框 + 掩码
autodistill知识蒸馏训练批量生产与模型迭代无标注图片集训练好的学生模型
X-AnyLabeling交互式标注 + AI 辅助人工修正与格式落地模型预测结果标准格式数据集

3. 环境搭建:别在第一步就劝退

3.1 硬件与基础环境的最低要求

自动标注这条链路对硬件的要求分两段。Grounded-SAM 推理阶段吃显存,SAM 的 ViT-H 版本大概需要 8GB 以上显存才能跑得舒服,ViT-B 版本 4GB 也能凑合。autodistill 训练学生模型时,YOLOv8n 这种小模型 6GB 显存足够,如果要上 YOLOv8l 或者 RT-DETR,建议 12GB 起步。X-AnyLabeling 本身很轻,但如果你要在里面挂 SAM 做在线推理,显存需求跟单独跑 SAM 差不多。

我的建议是:如果只有一张消费级显卡,优先用 SAM ViT-B 或者 MobileSAM 做交互,用 YOLOv8s 做学生模型。精度损失在可接受范围内,但速度和显存占用友好太多。别一上来就追求最大模型,跑通链路比堆参数重要。

基础环境我习惯用 conda 隔离,Python 版本锁在 3.10,这个版本对 PyTorch、CUDA 以及几个标注库的兼容性最稳。CUDA 版本跟着 PyTorch 官方推荐走,目前 11.8 和 12.1 都比较成熟。

conda create -n autolabel python=3.10 -y conda activate autolabel pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118

3.2 三个组件的安装顺序与依赖冲突处理

这三个组件的依赖有重叠也有冲突,安装顺序很关键。我的经验是先装 Grounded-SAM,再装 autodistill,最后装 X-AnyLabeling。原因是 Grounded-SAM 对 transformers、segment-anything 这些库的版本比较敏感,先把它钉死,后面两个相对宽容。

Grounded-SAM 的安装核心是拉官方仓库、装依赖、下权重。权重文件比较大,SAM 的 ViT-H 有 2.4GB,Grounded-DINO 的权重也有几百 MB,提前下好放到指定目录,别等到跑的时候再下,容易超时。

git clone https://github.com/IDEA-Research/Grounded-Segment-Anything.git cd Grounded-Segment-Anything pip install -r requirements.txt

autodistill 的安装就简单多了,它本身是个框架,具体用哪个老师模型、哪个学生模型,再单独装对应的子包。比如用 Grounded-SAM 当老师、YOLOv8 当学生:

pip install autodistill autodistill-grounded-sam autodistill-yolov8

X-AnyLabeling 我推荐直接下预编译版本,省去 GUI 依赖的折腾。如果你非要跑源码,注意它依赖 PyQt5,在某些 Linux 发行版上需要额外装系统库。源码运行的话,PyCharm 里配置好解释器,直接跑anylabeling/app.py就行,但记得把工作目录设对,否则资源文件路径会出问题。

注意:三个组件都依赖 opencv-python,但版本要求可能不同。如果出现cv2相关报错,先检查是不是装了多个版本,统一到一个较新的版本通常能解决大部分问题。

3.3 权重下载与目录规划

权重管理是个容易被忽视但很影响效率的事。我习惯在项目根目录建一个weights/文件夹,把所有模型权重集中放,然后在代码里用相对路径引用。这样换机器、备份、迁移都不会乱。

需要准备的权重包括:SAM 的 checkpoint(vit_b、vit_h 按需)、Grounded-DINO 的 checkpoint、以及学生模型 YOLOv8 的预训练权重。SAM 和 Grounded-DINO 的权重在官方仓库的 README 里都有下载链接,YOLOv8 的权重 autodistill 会自动下,但手动下好放到缓存目录能避免重复下载。

目录结构我一般这样组织:

project/ ├── weights/ │ ├── sam_vit_b.pth │ ├── groundingdino_swint.pth │ └── yolov8s.pt ├── data/ │ ├── raw/ # 原始无标注图片 │ ├── pseudo/ # 伪标签结果 │ └── dataset/ # 最终数据集 ├── configs/ └── scripts/

这个结构不是强制的,但清晰的目录规划能让你在调试时少花很多时间找文件。

4. 用 Grounded-SAM 做冷启动:从文字到第一批伪标签

4.1 Prompt 设计的门道

Grounded-SAM 的效果,七成取决于 prompt 怎么写。这里有个反直觉的点:不要用太泛的词,也不要用太细的词。比如你要检测"安全帽",写"helmet"比写"hat"好,因为 hat 会召回一堆无关的帽子;但如果你写"yellow safety helmet with logo",又太细,模型可能因为颜色或 logo 缺失而漏检。

我的经验是采用"类别名 + 关键属性"的组合,用句点分隔多个 prompt。Grounded-DINO 支持这种格式,比如:

person . helmet . safety vest . machinery .

注意每个 prompt 后面加空格和句点,这是 Grounded-DINO 的格式要求,不加的话召回会明显下降。另外,box_threshold 和 text_threshold 这两个参数要调。box_threshold 控制框的置信度门槛,默认 0.3 左右;text_threshold 控制文字匹配的严格程度,默认 0.25。密集小目标场景把 box_threshold 降到 0.2,召回会好很多,但误检也会增加,需要人工修正来兜底。

4.2 批量推理脚本的写法

单张图跑通之后,下一步是批量。我写了一个循环脚本,遍历data/raw/下的所有图片,对每张图跑 Grounded-SAM,把结果保存成 COCO 格式的 JSON。这里有个细节:不要每张图都重新加载模型,模型加载一次要好几秒,批量跑的时候必须把模型初始化放在循环外面。

import os import cv2 import json from groundingdino.util.inference import load_model, load_image, predict from segment_anything import sam_model_registry, SamPredictor # 模型初始化放循环外 grounding_model = load_model("configs/GroundingDINO_SwinT_OGC.py", "weights/groundingdino_swint.pth") sam = sam_model_registry["vit_b"](checkpoint="weights/sam_vit_b.pth") sam.to(device="cuda") predictor = SamPredictor(sam) TEXT_PROMPT = "person . helmet . safety vest ." BOX_THRESHOLD = 0.25 TEXT_THRESHOLD = 0.25 results = [] for img_name in os.listdir("data/raw"): img_path = os.path.join("data/raw", img_name) image_source, image = load_image(img_path) boxes, logits, phrases = predict( model=grounding_model, image=image, caption=TEXT_PROMPT, box_threshold=BOX_THRESHOLD, text_threshold=TEXT_THRESHOLD ) # 用 SAM 生成掩码 predictor.set_image(image_source) # ... 后续处理

这段代码的关键在于把模型加载和推理分离。实测下来,批量处理一千张图,模型加载只花一次时间,整体速度能快 30% 以上。

4.3 结果过滤与初步清洗

Grounded-SAM 的原始输出会有一些明显不合理的框,比如面积过小的、长宽比异常的、重叠度极高的。这些如果直接拿去训练,会污染学生模型。我一般会做几层过滤:

  • 面积过滤:去掉面积小于图像面积 0.1% 的框,这些基本是噪声。
  • 长宽比过滤:去掉长宽比超过 10:1 的框,除非你的目标本身就是细长条。
  • NMS 去重:对同类别的框做非极大值抑制,IoU 阈值设 0.5 左右。

过滤完之后,把结果转成 COCO 格式的 JSON,方便后续导入 X-AnyLabeling 修正。这一步的代码不复杂,但能显著提升伪标签的可用率。我实测过,不做过滤直接训练,学生模型的 mAP 会比过滤后低 5 到 8 个点,这个差距在后期很难补回来。

5. autodistill 蒸馏:让模型自己学会标注

5.1 蒸馏流程的整体设计

autodistill 的蒸馏流程可以概括为四步:老师推理 → 伪标签生成 → 学生训练 → 学生推理。它的 API 设计得很简洁,基本上定义一个老师、一个学生、一个数据集路径,然后调train就行。但简洁不代表没有坑,关键参数的选择直接决定蒸馏效果。

老师模型我选 Grounded-SAM,因为它在开放词汇场景下召回最好。学生模型我选 YOLOv8,因为生态成熟、部署方便、推理速度快。这个组合适合大多数目标检测场景。如果你是做分割,学生模型可以换成 YOLOv8-seg,但要注意分割的蒸馏效果通常比检测差一些,因为掩码的误差累积更明显。

5.2 关键参数:置信度阈值与训练轮次

autodistill 里有两个参数最影响结果:老师模型的置信度阈值和学生模型的训练轮次。

置信度阈值决定了伪标签的质量和数量。阈值高,伪标签少但准;阈值低,伪标签多但脏。我的经验是先用 0.3 左右跑一轮,看看伪标签的数量和可视化效果,再决定调高还是调低。如果目标是密集小目标,可以降到 0.2;如果误检明显,提到 0.4。

训练轮次方面,学生模型不需要训太久,因为伪标签本身有噪声,训太久会过拟合到噪声上。YOLOv8s 在几千张伪标签上,50 到 100 个 epoch 通常就够了。我一般设 80 个 epoch,配合早停,验证集 mAP 连续 10 轮不涨就停。

from autodistill_grounded_sam import GroundedSAM from autodistill_yolov8 import YOLOv8 base_model = GroundedSAM(ontology=CaptionOntology({ "person": "person", "helmet": "helmet", "safety vest": "safety vest" })) target_model = YOLOv8("yolov8s.pt") target_model.train("data/raw", epochs=80, imgsz=640)

这段代码看起来简单,但ontology的定义很关键。左边是 Grounded-SAM 认识的文字 prompt,右边是你想要的类别名。这个映射关系要提前想清楚,因为一旦学生模型训练完,类别就固定了,后面改类别要重新蒸馏。

5.3 学生模型推理与数据回流

学生模型训练好之后,用它去推理剩下的无标注图片,生成第二批伪标签。这批伪标签的质量通常比老师模型直接生成的要好,因为学生模型已经学到了你数据集的分布特点。然后把这批伪标签导入 X-AnyLabeling,人工过一遍,修正错误,导出成标准格式,再回流到训练集里。

这就是数据飞轮的完整闭环。每一轮循环,学生模型都在变强,人工修正的比例在下降。我做过一个对比:第一轮蒸馏后,人工修正率大概 40%;第二轮降到 25%;第三轮降到 15% 左右。到后面,大部分图片只需要扫一眼确认,不需要逐框调整。

提示:数据回流时要注意类别平衡。如果某一类在伪标签里特别少,学生模型会偏向其他类。可以在回流时对稀有类做 oversampling,或者在损失函数里加类别权重。

6. X-AnyLabeling 实操:人机协同的精细修正

6.1 导入伪标签与界面配置

X-AnyLabeling 支持直接导入 COCO JSON 或者 YOLO txt 格式的标注。导入之后,所有框和掩码会显示在图上,你可以逐个检查。界面左侧是文件列表,右侧是标注列表,中间是画布。快捷键方面,A和D切换上一张/下一张,W和S切换上一个/下一个标注,Delete删除选中的标注,这些高频操作建议早点形成肌肉记忆。

如果你要在工具里挂 SAM 做在线推理,需要在设置里配置模型路径。X-AnyLabeling 支持 SAM、SAM-HQ、YOLO 等多种模型,配置好之后,点一下目标就能自动生成掩码,比手动画多边形快得多。这个功能对分割任务尤其有用,我标一个复杂轮廓,手动要一两分钟,用 SAM 辅助只要几秒。

6.2 修正策略:哪些该改,哪些可以放过

人工修正不是要把每个框都调到完美,那样效率就没了。我的策略是抓大放小:明显漏检的补上,明显误检的删掉,边界偏差在 10% 以内的放过。因为训练时数据增强本身会引入扰动,过于精细的标注对最终精度提升有限,反而拖慢进度。

具体来说,我会优先处理这几类问题:漏检的目标(尤其是小目标和遮挡目标)、类别标错的(比如把"安全帽"标成"头")、严重重叠的框(两个框几乎重合,需要合并或删除)。至于边界差几个像素、框稍微大一点小一点,这些不影响训练,直接过。

6.3 导出格式与训练框架对接

修正完之后,导出格式要根据你的训练框架来定。YOLOv8 用 YOLO txt 格式,每行是class_id x_center y_center width height,坐标是归一化的。MMDetection 用 COCO JSON 或者 VOC XML。X-AnyLabeling 都支持,导出时选对应的格式就行。

这里有个容易踩的坑:类别 ID 的映射关系。X-AnyLabeling 里的类别顺序可能跟你的训练配置不一致,导出后要检查一下classes.txt或者 JSON 里的categories字段,确保 ID 对得上。我遇到过好几次训练时类别全错位的情况,排查半天才发现是导出时类别顺序变了。

导出格式适用框架关键检查点
YOLO txtYOLOv5/v8/v11classes.txt 顺序、坐标归一化
COCO JSONMMDetection、Detectron2categories 的 id 与 name 映射
VOC XML老版本框架filename 与图片实际路径一致
MOT多目标跟踪帧号连续性、ID 唯一性

7. 常见问题与排查技巧实录

7.1 Grounded-SAM 召回不稳定怎么办

召回不稳定通常有三个原因:prompt 不合适、阈值设置不当、图片本身质量差。排查顺序是先看可视化结果,再调 prompt,最后调阈值。如果模型完全没框到目标,多半是 prompt 用词跟模型训练分布不匹配,换个更常见的英文词试试。如果框到了但漏了一部分,降低 box_threshold。如果误检太多,提高 text_threshold。

还有一个容易被忽视的点:图片分辨率。Grounded-DINO 对输入尺寸有要求,太小的图会被放大,太大的图会被缩小,缩放过程中小目标可能就丢了。如果目标普遍很小,建议先把图片切块,分块推理再合并结果。

7.2 autodistill 训练不收敛的排查思路

学生模型训练不收敛,先检查伪标签的质量。把伪标签可视化出来看,如果框乱七八糟,那问题在老师模型,不在学生。如果伪标签看着还行但 loss 不降,检查学习率、batch size 这些基础参数。YOLOv8 的默认学习率通常没问题,但如果你的数据集特别小(几百张),学习率要调低,否则容易震荡。

另一个常见原因是类别不平衡。如果某一类的样本数只有其他类的十分之一,模型会忽略这个类。解决办法是在伪标签生成阶段对稀有类降低阈值,多召回一些,或者在训练时用cls权重参数加大稀有类的损失权重。

7.3 X-AnyLabeling 卡顿与崩溃的处理

X-AnyLabeling 卡顿通常是两个原因:图片太大、模型推理占显存。图片超过 4K 建议先缩放再标注,或者用工具的切片功能。模型推理卡顿的话,检查是不是同时挂了多个模型,或者显存不够导致频繁换页。关掉不必要的模型,或者换更小的模型版本。

崩溃的话,先看日志。X-AnyLabeling 的日志一般在用户目录下的.anylabeling文件夹里。常见崩溃原因包括:标注文件格式错误、图片路径含中文或特殊字符、PyQt 版本不兼容。图片路径尽量用英文和数字,别用中文和空格,这个坑我踩过不止一次。

7.4 数据飞轮转不起来的典型症状

数据飞轮转不起来,表现为每一轮人工修正量都很大,学生模型精度上不去。这通常是因为回流数据没有经过清洗,脏数据反复训练,模型学到的都是错的。解决办法是每轮回流前做一次质量检查,把明显错误的标注剔除,别让它们进入训练集。

另一个原因是类别定义不稳定。今天标"安全帽",明天标"头盔",模型就懵了。类别体系一旦定下来,就不要轻易改。如果确实要加类,重新蒸馏一轮,别在旧模型上打补丁。

问题现象可能原因排查动作解决方向
召回低prompt 不匹配可视化检查换词、降阈值
误检多阈值过低统计误检类别提阈值、加负样本
训练不收敛伪标签脏可视化伪标签清洗数据、调学习率
飞轮不转回流数据差抽查回流样本加质检环节
工具卡顿图片过大看显存占用缩放、切片、换小模型

8. 把这套流程跑成习惯之后的一些体会

这套流程我前后在三个项目里跑过,从工业质检到遥感识别,场景不同但骨架是一样的。最大的感受是:自动标注的价值不在于完全替代人工,而在于把人工从"画框"变成"审核"。画框是体力活,审核是判断活,后者对标注员的要求更低,速度也更快。一个熟练的标注员,纯手工一天标 300 张顶天了;用这套流程,一天过 1000 张不是问题。

另一个体会是别追求一步到位。第一轮蒸馏出来的学生模型肯定不完美,但只要它能帮你省掉 50% 的工作量,这轮就值了。后面每一轮都在这个基础上改进,边际成本越来越低。我见过有人非要等模型精度到 90% 才肯用,结果白白多标了几周。

最后分享一个小技巧:在 X-AnyLabeling 里给不同来源的标注设不同颜色。老师模型生成的用灰色,学生模型生成的用蓝色,人工修正过的用绿色。这样你一眼就能看出哪些是可信的、哪些需要重点检查,审核效率能再提一截。这个功能在设置里的"标注颜色"选项里配,花五分钟配好,后面省的时间是几十倍。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询