用视觉 AI 加速图像和视频标注
在 Potato 中配置 YOLO、Ollama、OpenAI 和 Claude 视觉端点,让模型提出边界框和标签,由标注者接受或拒绝。
用检测模型画框,用视觉语言模型做判断,再让标注者接受或拒绝模型提出的结果,而不是手工画出每一个区域。
Potato 2.1 加入了视觉 AI 支持,把模型建议放进图像和视频标注界面。YOLO 这类检测器找出目标并画出候选框供审核。GPT-4o、Claude 或本地 Ollama 模型这类视觉语言模型对整张图像或某个区域分类,并解释分类的依据。模型提出的任何结果,在标注者接受之前都不会成为标注。
本指南介绍四种视觉端点、每种端点支持的辅助模式,以及如何在同一个项目里搭配使用视觉端点和文本端点。完整的 API 参考见视觉 AI 源文档。
需要准备的东西
视觉 AI 需要 Potato 2.1.0 或更高版本:
pip install --upgrade potato-annotation选哪个端点决定了其余的设置:
- YOLO 在本地运行:
pip install ultralytics opencv-python - Ollama 在本地运行:从 ollama.ai 安装并拉取一个视觉模型
- OpenAI 需要一个能访问 GPT-4o 的 API 密钥
- Anthropic 需要一个能访问 Claude 视觉模型的 API 密钥
用 YOLO 做目标检测
任务是给常见物体画边界框、而且图像不该离开本机时,选 YOLO。它每张图只花几毫秒就能检测出人、车、动物和家具,返回的是坐标而不是文字,这正是画框任务需要的。
方案级的 ai_support 块决定标注者看到哪些按钮,项目级的块决定由哪个模型来回应。把两者分开,一个项目才能只在检测方案上启用 AI,其余方案保持不动。
annotation_task_name: "Object Detection with YOLO"
task_dir: "."
data_files:
- data/images.json
item_properties:
id_key: id
text_key: image_url
instance_display:
fields:
- key: image_url
type: image
display_options:
max_width: 800
zoomable: true
annotation_schemes:
- annotation_type: image_annotation
name: objects
description: "Draw a box around every object and label it"
source_field: "image_url"
tools:
- bbox
labels:
- name: "person"
color: "#FF6B6B"
- name: "car"
color: "#4ECDC4"
- name: "dog"
color: "#45B7D1"
- name: "cat"
color: "#96CEB4"
ai_support:
enabled: true
features:
detection: true
pre_annotate: true
hint: true
ai_support:
enabled: true
endpoint_type: "yolo"
ai_config:
model: "yolov8m.pt"
confidence_threshold: 0.5
output_annotation_dir: "annotation_output/"
user_config:
allow_all_users: true数据文件每行一个 JSON 对象,图像路径或 URL 放在 text_key 指定的字段里:
{"id": "img_001", "image_url": "images/street_scene_1.jpg"}
{"id": "img_002", "image_url": "images/park_photo.jpg"}
{"id": "img_003", "image_url": "https://example.com/images/office.jpg"}挑选模型大小
模型大小是在延迟和召回之间取舍,而这个取舍的两头都要花标注者的时间。漏检目标的模型会把预标注重新变回画框任务,每张图要跑几秒的模型则让标注者在条目之间干等。中间几档是通常的选择,不是因为它们在哪一头胜出,而是因为它们把两头的代价都压得比较小。
| 模型 | 大小 | 速度 | 准确度 | 适用场景 |
|---|---|---|---|---|
yolov8n.pt | 6 MB | 最快 | 较低 | 快速试做 |
yolov8s.pt | 22 MB | 快 | 不错 | 均衡的工作量 |
yolov8m.pt | 50 MB | 中等 | 更好 | 通用 |
yolov8l.pt | 84 MB | 较慢 | 高 | 准确度要紧时 |
yolov8x.pt | 131 MB | 最慢 | 最高 | 追求最高精度 |
对于 YOLO 内置类别以外的物体,YOLO-World 做开放词表检测:
ai_config:
model: "yolo-world"
confidence_threshold: 0.3设置置信度阈值
阈值决定你交给标注者的是哪一种活。阈值低,框就多,他们的时间花在拒绝误报上。阈值高,框就少,时间花在补画模型漏掉的目标上。从 0.5 开始,看第一批数据里哪一种修正占多数,再调:
ai_config:
confidence_threshold: 0.3 # more detections, more false positivesai_config:
confidence_threshold: 0.7 # fewer detections, higher precision用 Ollama 视觉模型做本地场景理解
Ollama 在你自己的硬件上跑视觉语言模型。与 YOLO 不同,这些模型读的是整个场景并写出解释,这是分类任务需要、而检测器给不了的。数据不离开本机,所以同一套设置也覆盖那些不能送到托管 API 的数据集。
curl -fsSL https://ollama.ai/install.sh | sh
ollama pull llava下面这个项目用本地模型对场景类型分类。这里没有方案级的 ai_support 块,因为分类功能在这里是项目级的,而不是挂在某个画图工具上:
annotation_task_name: "Image Classification with Ollama Vision"
task_dir: "."
data_files:
- data/images.json
item_properties:
id_key: id
text_key: image_url
instance_display:
fields:
- key: image_url
type: image
display_options:
max_width: 600
zoomable: true
annotation_schemes:
- annotation_type: radio
name: scene_type
description: "What type of scene is shown?"
labels:
- indoor
- outdoor_urban
- outdoor_nature
- aerial
- underwater
ai_support:
enabled: true
endpoint_type: "ollama_vision"
ai_config:
model: "llava:latest"
base_url: "http://localhost:11434"
max_tokens: 500
temperature: 0.1
output_annotation_dir: "annotation_output/"
user_config:
allow_all_users: true低 temperature 在这里比在写作任务里更要紧。同一张图像出现两次,应该得到同一个建议标签,而在高温度下采样的模型有时会自相矛盾,标注者读到的是工具的噪声,而不是模型的不确定。
Potato 支持 LLaVA 的 7B、13B 和 34B 三种规模,还有 LLaVA-LLaMA3、BakLLaVA、11B 和 90B 的 Llama 3.2 Vision、Qwen2.5-VL 以及 Moondream。小模型回答得够快,能让标注者不停下来;标签取决于细节时,大模型值得多等。
OpenAI 视觉
GPT-4o 通过同一个 ai_support 块处理图像,其中 detail 设置控制送出图像的多少:
ai_support:
enabled: true
endpoint_type: "openai_vision"
ai_config:
api_key: "${OPENAI_API_KEY}"
model: "gpt-4o"
max_tokens: 1000
detail: "auto"export OPENAI_API_KEY="sk-..."low 送出缩小过的图像,更便宜,对场景级分类也够快。high 送出完整分辨率,找小物体需要它。auto 交给 API 自己选。这个设置按图像计费,所以值得在跑大批量之前就定好,而不是等账单出来。
Anthropic 视觉
Claude 的视觉模型读取图像上下文,并写出分类背后的推理,所以在标注者需要的是解释而不是一个框的任务里很合适:
ai_support:
enabled: true
endpoint_type: "anthropic_vision"
ai_config:
api_key: "${ANTHROPIC_API_KEY}"
model: "claude-sonnet-4-20250514"
max_tokens: 1024export ANTHROPIC_API_KEY="sk-ant-..."辅助模式
每种模式都会给标注者的工具栏加一个按钮,也改变向模型提出的要求。只打开任务需要的那几个,因为每多一个按钮,标注者在每个条目上就多一个要做的决定。
检测找出与你配置的标签相符的物体,用虚线覆盖层显示出来。标注者逐张处理图像、希望每张图都有个起点时,用这个模式:
ai_support:
enabled: true
features:
detection: true预标注一次性把检测器跑遍所有数据,标注者打开每个条目时建议已经在上面了。这是在大数据集上划算的模式,也是最需要校准好阈值的模式,因为这一遍跑完以后没人会再去看设置:
ai_support:
enabled: true
features:
pre_annotate: true分类给选中的区域或整张图像打标签,返回一个带置信度分数的建议标签。提示给出指引但不给答案,适合用在标注者培训阶段,在那里把标签直接给出去什么也教不会:
ai_support:
enabled: true
features:
classification: true
hint: true接受和拒绝建议
建议以虚线覆盖层出现,在标注者动手之前一直只是建议。双击覆盖层把它变成真正的标注,右键点击把它丢掉,工具栏上还有“全部接受”和“清除”,用在所有建议全对或者全错的条目上。
接受这一步是标注文件保持诚实的原因。导出的是人接受过的东西,而不是模型提出的东西,所以调得不好的阈值只会费掉标注时间,不会悄悄把错标签写进数据集。这也让接受和拒绝的计数在试点期间值得盯着,因为标注者把大多数建议都拒绝掉的一轮,先告诉你的是阈值的事,之后才是模型的事。
视频:场景切分
视频方案有自己的一套功能,涵盖场景边界、帧分类、关键帧和跟踪。max_frames 限制模型从片段里采样多少帧,这是同时影响准确度和等待时间的主要杠杆:
annotation_schemes:
- annotation_type: video_annotation
name: scenes
description: "Segment this video into scenes"
mode: segment
labels:
- name: "intro"
color: "#4ECDC4"
- name: "main_content"
color: "#FF6B6B"
- name: "outro"
color: "#45B7D1"
ai_support:
enabled: true
features:
scene_detection: true
pre_annotate: true
hint: true
ai_support:
enabled: true
endpoint_type: "ollama_vision"
ai_config:
model: "llava:latest"
max_frames: 10文本一个端点,图像另一个
混用文本方案和图像方案的项目通常希望两边用不同的模型,因为画框最好的模型不是写提示最好的那个。visual_endpoint_type 和 visual_ai_config 设置第二个端点。把这个块加到已经有 ai_support 段的配置里:
ai_support:
enabled: true
endpoint_type: "ollama"
ai_config:
model: "llama3.2"
include:
all: true
visual_endpoint_type: "yolo"
visual_ai_config:
model: "yolov8m.pt"
confidence_threshold: 0.5同样的搭配也适用于托管视觉模型配本地文本模型:
ai_support:
enabled: true
endpoint_type: "ollama"
visual_endpoint_type: "openai_vision"
ai_config:
model: "llama3.2"
visual_ai_config:
api_key: "${OPENAI_API_KEY}"
model: "gpt-4o"在 2.9.1 里这一对有一个要注意的地方。AI 缓存会读这两个键,第二个端点也确实能用,但 potato validate --strict 会把它们报成无法识别,所以用了它们的配置过不了严格校验这一关。用 --strict 把关部署的项目,在上游把这件事理顺之前,最好把视觉端点和文本端点放在不同的项目里。
一个完整的例子:产品照片
这个项目让标注者框出产品和瑕疵,判断照片能不能发布,并标出照片哪里有问题。YOLO 提出边界框,两个判断类方案仍然由人来做:
annotation_task_name: "Product Photo Annotation"
task_dir: "."
data_files:
- data/product_photos.json
item_properties:
id_key: sku
text_key: photo_url
instance_display:
layout:
direction: horizontal
gap: 24px
fields:
- key: photo_url
type: image
label: "Product Photo"
display_options:
max_width: 600
zoomable: true
- key: product_description
type: text
label: "Product Details"
annotation_schemes:
- annotation_type: image_annotation
name: product_regions
description: "Draw boxes around products and defects"
source_field: "photo_url"
tools:
- bbox
labels:
- name: "product"
color: "#4ECDC4"
- name: "defect"
color: "#FF6B6B"
- name: "label"
color: "#45B7D1"
- name: "packaging"
color: "#96CEB4"
ai_support:
enabled: true
features:
detection: true
pre_annotate: true
- annotation_type: radio
name: photo_quality
description: "Is this photo suitable for the product listing?"
labels:
- Approved
- Needs editing
- Reshoot required
- annotation_type: multiselect
name: quality_issues
description: "Select any issues present"
labels:
- Blurry
- Poor lighting
- Wrong angle
- Background clutter
- Color inaccurate
ai_support:
enabled: true
endpoint_type: "yolo"
ai_config:
model: "yolov8m.pt"
confidence_threshold: 0.5
output_annotation_dir: "annotation_output/"
export_annotation_format: "jsonl"
user_config:
allow_all_users: true要给这两个判断方案加上文本提示,把上面那对 visual_endpoint_type 配置加进这个配置里,文本模型作 endpoint_type,yolo 作视觉端点。图像方案的框仍旧来自 YOLO,单选和多选方案的提示来自文本模型。
示例数据(data/product_photos.json):
{"sku": "SKU-001", "photo_url": "images/products/laptop_front.jpg", "product_description": "15-inch laptop, silver finish"}
{"sku": "SKU-002", "photo_url": "images/products/headphones_side.jpg", "product_description": "Over-ear wireless headphones, black"}
{"sku": "SKU-003", "photo_url": "images/products/backpack_full.jpg", "product_description": "40L hiking backpack, navy blue"}把设置做对
- 在大数据集上让标注者开工之前,先跑一遍预标注。 按条目算,审核加修正比从头画要快,而且这份好处随数据集规模增长,设置的成本不会。
- 让端点对上问题。 检测器回答“它在哪”,视觉语言模型回答“这是什么、为什么”,让其中一个去干另一个的活,产生的建议标注者很快就学会不看。
- 在试点批次上调阈值。 从 0.5 开始,按标注者更常做哪一种修正来调。
- 培训时用提示模式。 它给新标注者指个方向,但不把标签递过去,记录下来的仍然是他们自己的判断。
- 把结果缓存下来。 磁盘缓存让同一张图像不会被付费分析两遍。
排查问题
“未配置视觉 AI 端点”
检查 ai_support.enabled 是不是 true,以及 endpoint_type 指的是不是一个视觉端点:yolo、ollama_vision、openai_vision 或 anthropic_vision。在图像方案上用文本端点就会出这条消息。
YOLO 检测不到你的目标
YOLO 的内置类别覆盖 80 个常见物体类别,所以这个集合之外的标签,无论阈值怎么设都匹配不上。换成 YOLO-World 拿到开放词表。如果标签确实落在 YOLO 的类别里,只是检测结果偏少,那就调低 confidence_threshold。
Ollama 报错
检查服务是不是在运行,以及你写的那个模型是不是既装好了、又支持视觉:
curl http://localhost:11434/api/tags
ollama list云 API 调用很慢
打开磁盘缓存,同一张图像就不会跨会话被分析两遍。路径相对 task_dir 解析,而且必须待在它里面:
ai_support:
cache_config:
disk_cache:
enabled: true
path: "ai_cache/visual_cache.json"下一步
- 读视觉 AI 支持文档拿到完整的 API 参考
- 设置实例显示,让图像和其他内容并排显示
- 了解基于文本的 AI 支持,用于提示和关键词高亮