☰
自动标注实战:X-AnyLabeling、Grounded-SAM与autodistill高效协同指南
2026/10/2 13:36:11 网站建设 项目流程

做视觉模型的人大概都经历过这种绝望:模型推理只要几毫秒,标注一箱图却要熬好几个通宵。我接手的第一个数据项目是两千张工业零件图,做实例分割标注,第一周只完成了三百多张,剩下的硬是被客户催着赶工。后来我开始研究自动标注,把 X-AnyLabeling、autodistill、Grounded-SAM 组合起来用,硬是把标注周期从三周压到了四天左右。这篇文章就是我完整跑通这套流程之后的一次复盘,包括每款工具怎么打开、参数怎么调、输出怎么衔接,以及我在生产环境里踩过的坑。如果你正在为检测或分割项目造数据集,或者想用基础模型给人工标注打底,这篇应该能在你开工之前就帮你避掉大部分问题。

1. 先看清三个工具在标注链条上分别扮演什么角色

1.1 手工标注的真实痛点和"自动标注"到底能帮多少忙

很多人一听到自动标注,第一反应是"机器能标谁还用人",但实际做过项目的人都知道,自动标注解决的核心不是"无人化",而是"把人的劳动从重复画框里解放出来"。手工标注的隐性成本不只是时间,还有一致性:一个人连续标了四个小时之后,框的边距会不自觉变大,凹进去的轮廓会偷懒少点几个点,这还只是一天之内的漂移。如果换成多人协作,标注风格差异更明显,后期清洗数据比标注本身还痛苦。

自动标注的价值在于,它可以提供一个几乎零成本的初稿,让人工从空白画布上画画,变成在已有结果上做增删改。我的实际经验是:在一张图上从零画一个分割掩码需要 30 到 60 秒,但校对一张自动生成的结果只需要 5 到 15 秒,前提是预标注质量不低于 60% 的可用率。所以整套流程的思路并不复杂——让大模型先干粗活,人工专心做精修,再让小模型接力,形成一条可持续产出的标注链路。

1.2 三款工具的能力边界与配合关系

先说结论:这三个工具不是竞争关系,而是链条上的不同环节。

  • X-AnyLabeling:这是一个带完整图形界面的本地标注工具,支持矩形、多边形、关键点、线段、掩码等常见标注形式。它最大的特点是把一批深度模型直接集成到了界面上,包括 SAM、Grounding DINO、YOLO 系列等,可以边标注边调用模型做辅助。它的角色是"人工校验出口和格式转换中枢",最后进训练集的数据基本都要在这里过一遍。
  • Grounded-SAM:这是由 Grounding DINO 与 SAM 串起来的自动标注管线。Grounding DINO 负责根据文本提示检测出目标框,SAM 负责在框内生成高精度的分割掩码。它的角色是"批量初稿生成器",适合在没有标注数据的冷启动阶段快速造一批预标注结果。
  • autodistill:这是 Roboflow 推出的自动标注与模型蒸馏框架。它让你先定义好类别,然后调用一个大型基础模型去自动标注你的数据,再用这些自动标注数据训练一个小模型。它的角色是"持续生产力",当目标小模型训练到一定效果后,可以替代大模型继续标注新增数据。

三个工具放在同一张表里看会更清楚:

工具核心能力操作方式主要输出适合阶段
X-AnyLabeling交互式标注、模型辅助精修、格式转换图形界面COCO / VOC / YOLO 等人工校对与数据交付
Grounded-SAM文本提示驱动的批量检测与分割命令行 / Python掩码 + JSON冷启动预标注
autodistill基础模型自动标注 + 目标模型训练Python API数据集 + 训练权重数据循环迭代

明白分工之后,整套流程的轮廓就出来了:先让 Grounded-SAM 或 autodistill 批量产预标注,再用 X-AnyLabeling 做人工修正,导出 COCO 或 YOLO 格式训练小模型,最后小模型再配合人工抽检继续扩数据。下面我从 X-AnyLabeling 开始,把每个环节的细节展开讲。

2. X-AnyLabeling 上手:核心用法与打开方式

2.1 安装与启动:Windows 和 Linux 两条路线

热词里全是"x-anylabeling 使用说明""x-anylabeling 怎么打开",可见大部分人卡在了第一步。其实这个工具的使用门槛很低,但打开方式确实有好几种,我分别说。

Windows 路线:最省事的办法是直接下载编译好的安装包,解压后双击X-AnyLabeling.exe就能打开。如果你想跑最新源码、调用更多模型,就克隆源码:

git clone https://github.com/CVHub520/X-AnyLabeling.git cd X-AnyLabeling pip install -r requirements.txt python main.py

这里有个细节:源码方式启动前,建议把依赖装到一个干净的 Python 虚拟环境里,因为它依赖 PyQt5、onnxruntime、opencv-python 等一堆包,和已有环境里的 torch 版本如果冲突了,界面会启动失败或者模型加载时直接闪退。

Linux 路线:我主力环境是 Ubuntu 20.04,安装依赖后直接用python main.py启动。如果你运行后提示窗口无法显示,很大概率是缺少系统级的图形库,常见的是libxcb-cursor0。这一步别急着查 Python 环境,先跑一下:

sudo apt-get install libxcb-cursor0

另外要注意的是,Linux 下如果要用 GPU 跑模型,onnxruntime 的版本不能装错。我踩过最尴尬的坑是装成了普通的onnxruntime,界面也能跑,但模型推理全部走 CPU,一张千元级显卡在旁边闲着,自动标注慢得让人怀疑人生。正确做法是根据自己的 CUDA 版本安装onnxruntime-gpu,具体版本号建议去官方发布页对照一下,不要盲装最新版。

打开之后的界面,左侧是文件树和当前图片列表,中间是画布,右侧是标注属性和模型控制面板。第一次打开可能没有模型可用,需要先去模型管理里下载权重,这里会受网络环境影响,比较大的 SAM 权重建议用带断点续传的工具拉下来,再手动放到对应目录。

2.2 界面布局、快捷键与模型调用逻辑

X-AnyLabeling 的交互习惯继承了 LabelImg/AnyLabeling 那一套,常用快捷键如下:

快捷键功能
W新建矩形框
E新建多边形
D删除当前选中标注
Ctrl + Z撤销上一步
Ctrl + S保存当前标注
A/D切换上一张 / 下一张图片

模型调用逻辑是它和普通标注工具最大的差异:你不需要事先用一批数据训练完再标注,而是可以随时加载一个辅助模型,让它针对当前图片输出建议。我常用的组合是,加载 Grounding DINO 做检测建议,再加载 SAM 做掩码精修。操作流程是这样的:

  1. 在右侧模型列表中选择 Grounding DINO 对应的模型配置,加载权重。
  2. 在提示词输入框里输入类别,比如cat . dog .,点预测。
  3. 界面会在图上画出一批候选框,置信度高的直接生成标注。
  4. 对不满意的框,用 SAM 的"点选提示"模式点击目标中心和边界,让模型重新生成掩码。

这一步最关键的不是怎么点选,而是理解"人工在这里的真正职责是判断,不是绘制"。我习惯把模型建议当成一个具备一定可信度的同事,它标出来的框我会快速检查边界贴合度,明显离谱的删掉,轻微偏移的用Ctrl + Z回退后在局部加点微调,效率会比从零画高很多。

2.3 基于内置 Grounding DINO 的提示标注实操

很多人不知道 X-AnyLabeling 里已经内置了 Grounding DINO,不用单独拉一个命令行环境。实际使用中,提示词的写法会直接影响召回率和准确率。

我的经验是三个原则。第一,类别之间用英文句号隔开,比如car . pedestrian . bicycle .,不要用 and 连接,逗号也尽量少用。第二,类别词尽量用你观察到的外观词汇,而不是功能词汇。比如"resistor"和"axial lead resistor"在特定数据集里,前者更容易漏检,后者虽然长一点但召回率明显高。第三,如果图片背景复杂,提示词里不要加入对背景的描述词,比如不要写"car on road",这会让模型去搜索整个语义场景而不是目标本身。

生成候选框之后,X-AnyLabeling 允许你对结果做批量接受或逐条修正。我常用的策略是先把小阈值的结果全部展示出来,用快捷键快速浏览一遍,把明显误检的全选删除,然后再放大检查真正感兴趣的目标是否都被召回。这一步肉眼过的速度非常快,比一张张从零画快得多。

2.4 标注数据导入导出格式转换

X-AnyLabeling 支持导入和导出的格式比较全,我实际主要用的是 COCO 和 YOLO 两种。这里有个非常容易踩的坑:导出 YOLO 格式时,类别顺序取决于项目里的类别列表顺序,而不是你在标注框里写的文字标签。如果你在不同工具之间来回导了几次,类别顺序很容易错位,最后训练时模型会在类别上鬼打墙。

我的习惯是,在一开始就固定一个classes.txt,所有工具都用这个文件来约定类别顺序。Grounded-SAM 生成的标注、X-AnyLabeling 导出的 YOLO、autodistill 生成的文件夹,全部严格对齐这个顺序。宁可多花十分钟做一次格式校验,也不要等到损失曲线异常时再回来怀疑数据,因为数据问题永远是训练里最难排查的。

3. Grounded-SAM:用一句话给整批图片做预标注

3.1 检测器与分割器是怎么协作的

Grounded-SAM 的完整项目一般是指 IDEA-Research 开源的 Grounded-Segment-Anything,它把两个模型的优势接了起来:Grounding DINO 负责把文本提示转成目标框,SAM 负责把目标框转成精细的像素级掩码。

用一个类比来解释:Grounding DINO 是一个视力很好但手指很粗的寻物助手,它能在图片里快速指出"你要的东西大概在这个位置";SAM 是一个对边界非常敏感的雕刻师,只要给它一个框或一个点,它就能把目标边缘切得很干净。前者擅长理解和搜索,后者擅长细节和轮廓,二者串起来就是一条完整的"语言到掩码"生产线。

这里要注意一个容易误判的点:Grounded-SAM 的输出质量上限由 Grounding DINO 的检测质量决定。如果 Grounding DINO 根本没检测到目标,SAM 再强也没有用;如果检测框偏了,SAM 则可能把框内的干扰背景也一起分割进来。所以预标注调优的重点放在检测环节,而不是分割环节。

3.2 批处理命令与关键参数

官方仓库里的演示脚本默认针对单张图片,实际做项目时显然不可能一张张跑。我对这些脚本做了一层薄封装,把它们包成了一个按目录批量处理的循环,核心参数如下(版本不同字段可能有差异,但思路通用):

python grounded_sam_demo.py \ --config GroundingDINO/groundingdino/config/GroundingDINO_SwinT_OGC.py \ --grounded_checkpoint groundingdino_swint_ogc.pth \ --sam_checkpoint sam_vit_h_4b8939.pth \ --input_dir ./images \ --output_dir ./auto_labels \ --text_prompt "valve . pipe . flange ." \ --box_threshold 0.35 \ --text_threshold 0.25 \ --nms_threshold 0.8

三个阈值参数是最值得花时间调的:

  • box_threshold:目标框置信度阈值,默认 0.35 左右。调低会让更多候选框被保留,召回率上升但误检变多;调高则相反。冷启动阶段我建议先设低一点,宁可多产出误检,也不要漏检,因为漏检在人工校对阶段需要重新绘制,成本远高于删除一个错误框。
  • text_threshold:文本匹配阈值,也就是模型对"这个目标确实属于文字描述的类别"的置信度。如果类别长得像,比如"左法兰"和"右法兰",这个阈值需要适度提高,否则两个类别会互相污染。
  • nms_threshold:非极大值抑制阈值,主要用来消除同一目标的重叠框。阈值越高,保留的重复框越多;太低又可能把紧密相邻的真实多个目标误杀成一个。一般保持 0.8 左右不用大动。

权重方面,GroundingDINO-SwinT 大概 700MB,SAM ViT-H 接近 2.4GB,如果你显存有限,可以把 SAM 换成 ViT-B,分割精度牺牲不大,推理速度和显存占用会友好很多。实在没 GPU 也能跑,但那种慢的程度,个人建议直接放弃自动标注,老老实实手工画可能更快。

3.3 输出结果怎么落盘、怎么转成可训练格式

批量跑完之后,输出目录里会有一堆 JSON 文件,每个 JSON 记录了一张图片的检测框、掩码的 RLE 编码、置信度和类别信息。这里提醒一句:不同版本和不同封装脚本输出的 JSON 结构不一定一致,我踩过一次把 RLE 当成普通数组去解析的坑,转换脚本跑了一半才报警。

所以拿到一个不熟悉的输出格式,第一件事不是写转换函数,而是打印一条记录看看结构。这一步看起来慢,实际上能省掉后面最痛苦的排错时间。我自己一般会写一个很小的转换脚本,把它转成 X-AnyLabeling 能识别的格式,或者直接转成 COCO 格式:

import json with open("annotations.json") as f: data = json.load(f) # 这里按实际字段结构调整 for image_id, image_name in enumerate(data["images"]): print(image_id, image_name) for ann in data["annotations"]: print(ann["category_name"], ann["bbox"], ann["segmentation"])

转换完成后,我建议先把它放进 X-AnyLabeling 打开一遍,千万不要直接拿去训练。即使 Grounded-SAM 在测试集上看着效果不错,真实业务数据里总会在某个角落出现类别混淆。在标注工具里过一遍,相当于给数据集上了第一道保险。

4. autodistill:让基础模型替你打工,再蒸馏出小模型

4.1 "蒸馏"思路为什么适合数据标注

autodistill 的核心思路是:先用一个能力很强但昂贵的基础模型去自动标注你的数据,然后用这些数据训练一个能力足够但便宜的小模型。这个思路听起来像知识蒸馏,但在数据标注场景下,它的价值更直接——你要的不只是一个小模型,而是一条可以持续产出标注数据的生产链路。

我理解它的收益其实来自两头。一头是基础模型不需要训练,开箱即用,省去了前期整理人工标注数据的过程;另一头是目标小模型训练完之后,推理成本可能降低一个数量级,之后处理新增数据就可以脱离大模型,在小模型基础上配合人工抽检继续迭代。等到业务场景变化,或者类别列表调整,再回到基础模型重新生成一轮数据,形成一个闭环。

4.2 ontology 定义与基础模型选择

autodistill 的使用习惯是从定义一个 ontology(本体/类别描述)开始的。我用过的一个版本是这样写的:

pip install autodistill autodistill-grounded-sam
from autodistill_grounded_sam import GroundedSAM from autodistill.detection import CaptionOntology ontology = CaptionOntology({ "person": "person", "hard hat": "hard-hat", })

左边的字符串是基础模型理解用的自然语言提示,右边是最终数据集里的类别名。这一步要特别注意:左边的提示词不要偷懒直接复制类别名,一定要写成基础模型更容易理解的自然语言描述,必要时可以给同一类别配多个提示词,比如"car"和"sedan car"同时映射到"car",能明显提升召回率。

基础模型的选择也不是越多越好。我实际横向测过几类,简单来说:如果你只做目标检测,且类别是常见物体,GroundedSAM 组合是好选择;如果你的类别非常小众或者描述困难,建议换用 DETIC 这类更强调零样本分类的模型。不要一上来就堆一个大模型,先拿一个 100 张的小批次跑通流程,再决定是否换更强的底座。

4.3 从自动标注到目标模型训练的完整代码流程

下面是我跑通的一个最小流程,数据文件夹里放着未经标注的图片,autodistill 会直接在图片旁边生成对应的标注文件:

from autodistill_grounded_sam import GroundedSAM from autodistill.detection import CaptionOntology from autodistill_yolov8 import YOLOv8 ontology = CaptionOntology({ "pill bottle": "bottle", "medicine box": "box", }) base_model = GroundedSAM(ontology=ontology) dataset = base_model.label( input_folder="./raw_images", output_folder="./labeled_dataset", )

执行完之后,./labeled_dataset里会有一个自动标注好的数据集,图片和标注文件已经排好目录结构。接着直接训练目标模型:

target_model = YOLOv8("yolov8n.pt") target_model.train("./labeled_dataset", epochs=50)

训练完成后,这个目标模型就可以接手下一批数据的预标注。autodistill 框架的好处在于,它把"用大模型标注"和"用小模型训练"两件事的接口统一了,如果你后续想换目标检测器或者换基础模型,代码结构几乎不用大改。不过有一点必须提醒:框架的版本迭代很快,API 字段在不同版本之间可能变化,比如CaptionOntology和新的Ontology写法,我现在写的代码到了你本地上可能微调一两个参数,这是正常现象,不要慌,看两眼官方示例就能对上。

5. 把它们串起来:一个 2000 张图片的实际标注流程复盘

5.1 流程设计:预标注、人工修正、二次挖掘

说完了每个工具,我把它们串成一个完整流程,以我实际做过的两千张药品包装图片项目为蓝本。

第一步,用 Grounded-SAM 跑第一轮预标注。这个阶段不追求完美,目的是把图片里的主要目标先捞出来,阈值我故意调得偏低,接受一部分误检。跑完之后人工在 X-AnyLabeling 里抽检 10% 的数据,看看漏检严重还是误检严重,做一次阈值小调整。

第二步,把 Grounded-SAM 的输出转成 X-AnyLabeling 项目能识别的格式,人工逐张校对。这一步是整套流程里耗时最长的,但因为你是在改别人的结果而不是从零画,速度会快很多。我当时的统计是,第一阶段自动标注用了一个多小时,人工校对花了差不多两天,但最后的标注质量反而比纯手工更稳定,因为每张图的标准都是对着同一套模型输出校正出来的,风格偏差小。

第三步,把校对完的标注结果导出成 COCO 格式,先在 X-AnyLabeling 里用脚本做一次完整性校验,比如检查是否有空类别、类别顺序是否和约定一致、是否有超出图片边界的框。校验通过后,丢到训练脚本里训一版 YOLOv8n。

第四步,用训练好的小模型去推断那些不在第一批里的图片,生成第二轮预标注。这一轮同样进 X-AnyLabeling 校对,但人工工作量明显比第一轮少,因为小模型在一个场景里的表现只会越来越稳。后续有新增数据就继续走这个循环。

5.2 效果实测:三个环节的时间分布与收益

我整理了当时的粗略时间统计:

环节耗时说明
Grounded-SAM 批量预标注约 1.5 小时2000 张图,GPU 单卡,含初期权重下载
X-AnyLabeling 人工校对约 2 天两人轮流,人均每天 500 张左右
autodistill 目标模型训练与二次标注约 1 天包含训练、推理、抽检
纯手工标注对照组(估)约 3 周按一张实例分割图 40 秒估算

只看数字,自动加人工的方案不一定比纯人工快出一个数量级,但真正拉开差距的是后续:纯手工标注到第 500 张的时候,已经积累了一套完整的标注习惯,可以随时用来训练一个不错的模型;而纯手工方案要全部标完才有数据可用。这种"提前收敛"的现金流价值,在项目时间表上是致命的。

5.3 这类流程适合哪些业务,不适合哪些业务

我用了好几轮之后,对这套流程的适用边界有一个很明确的判断。

适合的场景包括:目标类别是有限集合且外观可描述的;图片背景相对可控的;对分割边界精度要求不是病理级严苛的;数据量大但人工标注资源紧张的。

不适合的场景我也踩过:类别之间差异极其细微、需要领域专家才能区分的;目标边缘和背景颜色完全相同、SAM 无法从框内区分出边界的;以及"每个目标都要标到像素级无瑕疵"的高精度业务。这些场景下,自动标注产出的初稿要么太脏,要么需要长时间精修,省下来的时间又赔回去了。

所以我在设计流程时,从来不自欺欺人地说"全自动标注完成"。真正的表述是"自动生成初稿 + 人工校对终稿",这个定位让团队里的每个人都没有幻觉,也知道人工校对环节不可删除。

6. 生产环境里的坑和我的取舍建议

6.1 阈值、提示词和类别平衡:最容易翻车的地方

自动标注翻车通常不是模型跑崩了,而是指标选择错误。我把最常见的几类问题列出来:

一是低阈值导致的背景误检。尤其在做分割标注时,低阈值会把"像是目标的背景纹理"也圈进来。这时候不要只盯着少数误检案例调参数,而是应该抽一批人眼扫一遍,统计误检率占比,再决定是不是阈值开太低。

二是提示词过泛导致的类别污染。比如你想标"black cable",提示词写cable,模型会连白色线缆也画出来;但写black cable .又可能在暗色背景下漏检。我一般会在本体定义里同时保留 2 个变体提示词,然后在验证集上对比召回,选胜出的那组。

三是类别不均衡。自动标注模型天然偏向易检测的类别,数据里 80% 是"A 类大目标",可能最后生成 90% 的 A 类标注。这不是 bug,是真实分布。对策是在第二轮训练时手动做采样平衡,别等到训练时才发现类别全崩了。

6.2 GPU 资源、权重管理与多目标场景

显存是另一个现实问题。Grounded-SAM 要同时加载 Grounding DINO 和 SAM,两个模型加起来对显存的胃口不小。我的解决方案是:分割模型优先用轻量版本,检测模型不动;图片长边统一缩放到 1024 像素左右;batch size 固定为 1。在 8GB 显存的卡上,这种方法虽然慢一点但能稳定跑完。

权重管理也要养成习惯。所有模型权重统一放一个目录,命名带版本号,不要散落在各个项目里。我见过同事为了节省磁盘空间,把 SAM 权重删了,结果下次跑流程又花了半天重新下载,这种时间成本完全是不必要的。

多目标并存的场景要格外注意 NMS 阈值。有一次我处理货架上的商品,商品挨得极近,NMS 阈值设高了之后,相邻的两个商品被并成了一个框,分割掩码直接横跨两个物体,人工修正比重新标注还费劲。后来把 NMS 阈值降下来,再配合小目标专用策略,才把这个问题压住。

6.3 我的原则:自动标注是"预标注",不是"免标注"

整个流程跑下来,我最想分享的体会不是哪个工具好用,而是一个工作原则:自动标注系统永远只能做初稿,人工抽检和终审不可删除。

原因很朴素:基础模型的能力上限不是你的业务上限。你的数据里总有一些目标,是公开模型没有充分训练过的;你的业务方对于"边界多贴一个像素"是有验收标准的;你最终要交付的训练集必须达到某种一致性。这些都不能靠一个通用模型自动保证。

所以我建议每个项目阶段都定一个人工抽检的比例。冷启动阶段,人工逐张校对,比例 100%;第一轮小模型出来后,新数据校对比例降到 50%;等到模型在同类场景稳定跑赢基础模型,再逐步降到 30%。这个比例不是拍脑袋定的,而是我拿误检漏检率倒推出来的安全线。低于 30% 的时候,数据里的噪声就开始在训练指标上露面了。

最后再分享一个小技巧:我会在每轮自动标注开始前,固定抽 50 张图作为"质检基准集",人工完成一次精标,之后每轮自动标注结果都拿这 50 张图做对比。哪个模型版本效果变差了、哪个提示词调整让召回上升了,一目了然。数据标注工作看起来是体力活,但它其实是整个模型项目里最值得投入的复利环节,前期每一分对流程的打磨,都会在后期的每一轮训练里还回来。

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

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

立即咨询