
最近在尝试将 YOLO-World 应用到具体的业务场景中比如智能零售的商品检测或工业质检的缺陷识别发现最大的挑战往往不是模型本身而是如何准备一份高质量、格式正确的训练数据。网上关于 YOLO-World 模型架构和推理的教程很多但一涉及到“如何训练自己的数据集”资料就变得零散且不成体系特别是其独特的 Grounding 数据标注格式让不少开发者望而却步。本文将为你彻底梳理 YOLO-World 训练数据集的完整准备流程重点拆解 Grounding 数据集的标注格式要求并基于 Ultralytics 框架提供一套从零开始、可复现的实战方案。无论你是想用自定义数据训练一个全新的 YOLO-World 模型还是对现有的预训练模型进行微调这篇文章都能提供清晰的指引和可运行的代码示例。1. YOLO-World 与数据标注的核心概念在深入实操之前我们有必要理解几个核心概念这能帮助你明白为什么 YOLO-World 的数据标注如此特殊以及它如何实现“开放词汇”检测。1.1 什么是 YOLO-WorldYOLO-World 是 Ultralytics 团队推出的一种创新的实时开放词汇目标检测模型。它与传统的 YOLO 系列如 YOLOv5, YOLOv8有本质区别传统 YOLO属于闭集检测。模型在训练时见过哪些类别的物体在推理时就只能检测这些类别。例如你用“猫”、“狗”、“人”的数据集训练了一个 YOLOv8 模型那么它就无法识别“长颈鹿”或“咖啡杯”。YOLO-World属于开放词汇检测。它通过将视觉特征与文本嵌入来自 CLIP 等大型语言模型进行关联实现了“以文搜图”式的检测。你可以在推理时动态地输入任何文本提示如“a red sports car”, “a cracked ceramic tile”模型就能尝试在图像中定位出对应的物体而无需在训练数据中见过这些特定类别。1.2 为什么需要 Grounding 标注格式为了实现开放词汇的能力YOLO-World 的训练方式也必须革新。它不再学习固定的类别 ID如0cat, 1dog而是学习视觉区域与文本描述之间的对齐关系。这就是Grounding 数据的用武之地。Grounding意为“接地”或“关联”在这里特指将图像中的区域Bounding Box与一段自由形式的文本描述Text Description关联起来。一份 Grounding 标注数据会明确告诉模型“图像中的这个框对应着‘一只在沙发上睡觉的橘猫’这段文字描述”。因此YOLO-World 的训练数据集其核心是(图像, 文本提示列表, 边界框列表)的三元组而不是传统的(图像, 类别ID, 边界框)。1.3 与常见数据格式的对比为了更直观地理解我们将其与两种最流行的标注格式进行对比特性YOLO 格式 (.txt)COCO 格式 (.json)YOLO-World Grounding 格式核心思想每张图一个txt每行class_id x_center y_center width height(归一化)一个JSON文件包含所有图像的images,annotations(含category_id),categories信息。一个文本文件如.txt, .jsonl每行对应一张图包含图像路径、文本提示列表、边界框列表。类别表示数字ID (整数)数字ID通过categories列表映射到类别名。自由文本字符串(如 “a person riding a bicycle”)。关联方式通过固定的class_id关联预定义的类别列表。通过category_id关联categories列表。通过列表索引顺序关联第 i 个边界框对应第 i 个文本提示。开放性闭集无法检测新类别。闭集无法检测新类别。开放集文本提示可任意定义。适用场景训练传统 YOLO 模型。训练 COCO 格式的检测模型如 Detectron2, MMDetection。专门用于训练 YOLO-World 或类似开放词汇检测模型。简单来说Grounding 格式用自然语言描述取代了固定的类别ID这是解锁模型开放词汇能力的钥匙。2. 环境准备与项目结构在开始准备数据之前我们需要搭建好实验环境。本文将基于 Ultralytics 框架进行演示。2.1 环境配置建议使用 Python 3.8 或更高版本并使用 Conda 或 Venv 创建独立的虚拟环境。# 1. 创建并激活虚拟环境 (以conda为例) conda create -n yolo-world-train python3.9 conda activate yolo-world-train # 2. 安装 PyTorch (请根据你的CUDA版本选择以CUDA 11.8为例) pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 3. 安装 Ultralytics pip install ultralytics # 4. 安装其他可能用到的工具 pip install opencv-python pillow matplotlib pandas版本说明Ultralytics 版本迭代较快本文示例基于ultralytics8.1.0。核心的 Grounding 数据格式要求在不同小版本间是稳定的但训练命令或部分API可能有细微调整请以官方文档为准。2.2 项目目录结构一个清晰的项目结构有助于管理数据、代码和实验结果。建议按如下方式组织yolo_world_custom_train/ ├── datasets/ │ └── my_custom_dataset/ # 你的自定义数据集根目录 │ ├── images/ # 存放所有训练和验证图片 │ │ ├── train/ │ │ └── val/ │ └── labels/ # 存放 Grounding 格式的标注文件 │ ├── train/ │ └── val/ ├── scripts/ # 存放数据转换、训练脚本 │ ├── convert_to_grounding.py │ └── train_yolo_world.py ├── runs/ # Ultralytics 训练生成的目录自动创建 ├── pretrained_weights/ # 存放预训练模型 └── README.md我们的核心工作将集中在datasets/my_custom_dataset/目录下的数据准备。3. Grounding 数据标注格式详解这是本文最核心的部分。YOLO-World 接受的 Grounding 数据格式主要有两种TXT 格式和JSONL 格式。Ultralytics 官方示例和代码中更常见的是 TXT 格式我们重点讲解它。3.1 TXT 标注格式推荐每个图像对应一个同名的.txt文件放在labels/train/或labels/val/目录下。TXT 文件的内容有严格的格式要求。文件内容格式每一行代表一个标注对象一个边界框及其对应的文本描述。每行包含9 个字段用空格分隔text_prompt_index x_center y_center width height confidence text_prompt image_width image_height字段说明text_prompt_index(int)该边界框对应的文本提示在本张图片的文本提示列表中的索引从0开始。这是关联边界框和文本的关键。x_center,y_center(float)边界框中心点的 x 和 y 坐标归一化到图像尺寸即除以image_width和image_height后的值范围 0~1。width,height(float)边界框的宽度和高度归一化到图像尺寸范围 0~1。confidence(float)标注的置信度通常设置为1.0。text_prompt(string)该边界框对应的文本描述。如果描述中包含空格需要用双引号将整个描述括起来。image_width,image_height(int)图像的原始宽度和高度像素单位。一个具体的例子假设有一张图片001.jpg尺寸为640x480。图中有两个物体一只狗边界框为[100, 120, 200, 180](x_min, y_min, x_max, y_max)一个飞盘边界框为[300, 200, 380, 250]我们为其定义文本提示列表[a dog, a flying disc]。 那么对应的001.txt文件内容应为# 注释text_prompt_index 对应提示列表的索引 # 第一行索引0 - “a dog” 框归一化计算中心(150,150)-(0.234,0.3125), 宽高(100,60)-(0.156,0.125) 0 0.234375 0.3125 0.15625 0.125 1.0 a dog 640 480 # 第二行索引1 - “a flying disc” 框归一化计算中心(340,225)-(0.531,0.469), 宽高(80,50)-(0.125,0.104) 1 0.53125 0.46875 0.125 0.10416666666666667 1.0 a flying disc 640 480重要规则索引唯一性一张图片内同一个text_prompt字符串可能出现多次多个同类物体它们共享同一个text_prompt_index。例如图中有三只“a dog”那么这三行标注的text_prompt_index都应该是0。文本提示列表虽然 TXT 文件中每一行都写入了text_prompt但在训练时模型会为每张图片提取一个去重后的文本提示列表。text_prompt_index就是指向这个去重列表的索引。归一化计算x_center (x_min x_max) / 2.0 / image_width y_center (y_min y_max) / 2.0 / image_width width (x_max - x_min) / image_width height (y_max - y_min) / image_height3.2 JSONL 标注格式JSON Lines 格式每行是一个独立的 JSON 对象代表一张图片的所有标注。这种格式将所有信息打包在一起可能更适合某些流水线处理。每行 JSON 对象结构{ “image”: “path/to/image.jpg”, // 图像路径相对于数据集根目录 “instances”: { “bboxes”: [[x_min1, y_min1, x_max1, y_max1], ...], // 非归一化坐标列表 “labels”: [“text_prompt1”, “text_prompt2”, ...] // 与bboxes一一对应的文本列表 } }注意JSONL 格式中使用的是非归一化的绝对坐标[x_min, y_min, x_max, y_max]这与 TXT 格式不同。Ultralytics 在加载数据时会根据image_width和image_height将其归一化。3.3 数据集配置文件 (dataset.yaml)准备好 images 和 labels 后还需要一个 YAML 文件来告诉 Ultralytics 数据集的结构。这个文件是训练命令model.train(data‘path/to/dataset.yaml’)的关键输入。# dataset.yaml path: /home/user/projects/yolo_world_custom_train/datasets/my_custom_dataset # 数据集根目录的绝对路径 train: images/train # 训练图像路径相对于 path val: images/val # 验证图像路径相对于 path # 以下是 Grounding 数据集特有的关键配置 grounding: train: labels/train # 训练标注路径相对于 path val: labels/val # 验证标注路径相对于 path # 文本提示的配置可选但推荐 text: prompts: - “a dog” - “a flying disc” - “a person” # ... 可以列出数据集中所有出现过的文本提示 # 或者你也可以指定一个包含所有提示的文本文件 # prompts_file: ‘prompts.txt’grounding.text.prompts的作用这个列表定义了模型在训练过程中会“见到”的所有文本概念。虽然理论上 YOLO-World 是开放词汇的但在微调或从头训练时提供一个覆盖训练集的提示列表有助于模型更稳定地学习视觉-文本关联。如果省略模型会从每张图片的标注中动态收集所有文本提示。4. 完整实战从自定义数据到训练现在我们假设你已经有了一批标注好的图片但格式是常见的 COCO JSON 或 YOLO TXT。我们将演示如何将其转换为 Grounding 格式并启动训练。4.1 场景与数据准备假设我们有一个简单的“室内物品”数据集原始标注是 COCO 格式 (annotations.json)包含三类物体cup,keyboard,mouse。我们的目标是为 YOLO-World 训练准备数据并且我们希望模型能理解更丰富的描述比如“a white ceramic cup”而不仅仅是“cup”。4.2 编写格式转换脚本我们需要一个脚本将 COCO 格式转换为 YOLO-World 的 Grounding TXT 格式。创建scripts/convert_coco_to_grounding.pyimport json import os from pathlib import Path import cv2 def convert_coco_to_grounding(coco_json_path, images_dir, output_labels_dir, text_prompt_mappingNone): 将 COCO 格式的标注转换为 YOLO-World Grounding TXT 格式。 Args: coco_json_path (str): COCO annotations.json 文件路径。 images_dir (str): 图片存放的目录。 output_labels_dir (str): 输出 Grounding TXT 文件的目录。 text_prompt_mapping (dict, optional): 将 COCO category_id 映射到更丰富的文本提示。 例如 {1: “a ceramic cup”, 2: “a computer keyboard”, 3: “a wireless mouse”} 如果为 None则使用 COCO 中的 category_name。 # 1. 加载 COCO 标注 with open(coco_json_path, ‘r’) as f: coco_data json.load(f) # 创建类别ID到名称的映射 cat_id_to_name {cat[‘id’]: cat[‘name’] for cat in coco_data[‘categories’]} # 创建图像ID到文件名的映射 image_id_to_info {img[‘id’]: img for img in coco_data[‘images’]} # 2. 按图像分组标注 from collections import defaultdict annotations_by_image defaultdict(list) for ann in coco_data[‘annotations’]: image_id ann[‘image_id’] annotations_by_image[image_id].append(ann) # 3. 确保输出目录存在 Path(output_labels_dir).mkdir(parentsTrue, exist_okTrue) # 4. 处理每一张图片 for image_id, anns in annotations_by_image.items(): img_info image_id_to_info[image_id] img_file_name img_info[‘file_name’] img_width img_info[‘width’] img_height img_info[‘height’] # 构建本张图片的文本提示列表去重 text_prompts_for_this_image [] # 记录每个标注对象对应的提示索引 annotation_data [] # 存储 (bbox, text_prompt) for ann in anns: category_id ann[‘category_id’] # 决定使用哪个文本提示 if text_prompt_mapping and category_id in text_prompt_mapping: text_prompt text_prompt_mapping[category_id] else: text_prompt cat_id_to_name[category_id] # 默认使用类别名 # COCO bbox 格式是 [x_min, y_min, width, height] x_min, y_min, bbox_w, bbox_h ann[‘bbox’] x_max x_min bbox_w y_max y_min bbox_h # 转换为归一化坐标 (YOLO格式) x_center (x_min x_max) / 2.0 / img_width y_center (y_min y_max) / 2.0 / img_height width bbox_w / img_width height bbox_h / img_height annotation_data.append(([x_center, y_center, width, height], text_prompt)) # 收集文本提示用于构建索引 if text_prompt not in text_prompts_for_this_image: text_prompts_for_this_image.append(text_prompt) # 5. 生成该图片的 TXT 文件内容 txt_lines [] for bbox_norm, text_prompt in annotation_data: # 找到该 text_prompt 在去重列表中的索引 text_prompt_index text_prompts_for_this_image.index(text_prompt) x_center, y_center, width, height bbox_norm # 格式化一行数据 # 注意如果 text_prompt 包含空格需要加引号 formatted_prompt f‘“{text_prompt}”’ if ‘ ‘ in text_prompt else text_prompt line f‘{text_prompt_index} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f} 1.0 {formatted_prompt} {img_width} {img_height}’ txt_lines.append(line) # 6. 写入 TXT 文件 txt_file_name Path(img_file_name).stem ‘.txt’ txt_file_path Path(output_labels_dir) / txt_file_name with open(txt_file_path, ‘w’) as f: f.write(‘\n’.join(txt_lines)) print(f‘Converted {img_file_name} - {txt_file_name}’) print(f‘Conversion complete! TXT files saved to {output_labels_dir}’) if __name__ ‘__main__’: # 配置你的路径 COCO_JSON_PATH ‘datasets/my_custom_dataset/annotations/instances_train2017.json‘ IMAGES_DIR ‘datasets/my_custom_dataset/images/train/’ OUTPUT_LABELS_DIR ‘datasets/my_custom_dataset/labels/train/’ # 可选定义更丰富的文本提示映射 # 这可以显著提升模型对细粒度属性的理解能力 CUSTOM_PROMPT_MAPPING { 1: “a ceramic cup”, # 假设 category_id 1 是 ‘cup’ 2: “a computer keyboard”, # 假设 category_id 2 是 ‘keyboard’ 3: “a wireless mouse”, # 假设 category_id 3 是 ‘mouse’ # ... 添加更多映射 } convert_coco_to_grounding( coco_json_pathCOCO_JSON_PATH, images_dirIMAGES_DIR, output_labels_dirOUTPUT_LABELS_DIR, text_prompt_mappingCUSTOM_PROMPT_MAPPING # 传入 None 则使用原始类别名 )运行转换脚本cd yolo_world_custom_train python scripts/convert_coco_to_grounding.py转换完成后检查datasets/my_custom_dataset/labels/train/目录下是否生成了与图片同名的.txt文件并确认其格式符合 3.1 节的要求。4.3 创建数据集配置文件在datasets/my_custom_dataset/目录下创建dataset.yaml# datasets/my_custom_dataset/dataset.yaml path: /绝对路径/yolo_world_custom_train/datasets/my_custom_dataset train: images/train val: images/val grounding: train: labels/train val: labels/val text: prompts: - “a ceramic cup” - “a computer keyboard” - “a wireless mouse” # 如果你的提示很多也可以写到一个文件里 # prompts_file: ‘all_prompts.txt’4.4 编写训练脚本并启动训练创建scripts/train_yolo_world.pyfrom ultralytics import YOLOWorld def main(): # 1. 加载预训练模型 # 可以选择不同规模的模型’yolov8s-world‘, ‘yolov8m-world’, ‘yolov8l-world’, ‘yolov8x-world’ model YOLOWorld(‘yolov8s-world.pt’) # 会自动下载模型 # 2. 准备训练参数 # 关键通过 data 参数指定我们的 dataset.yaml # 通过 project 和 name 指定输出目录 train_args { ‘data’: ‘datasets/my_custom_dataset/dataset.yaml’, ‘epochs’: 50, # 训练轮数根据数据集大小调整 ‘imgsz’: 640, # 输入图像尺寸 ‘batch’: 8, # 批次大小根据GPU内存调整 ‘workers’: 4, # 数据加载线程数 ‘patience’: 10, # 早停耐心值 ‘project’: ‘runs/train’, # 输出主目录 ‘name’: ‘my_custom_dataset_exp1’, # 实验名称 ‘exist_ok’: True, # 允许覆盖同名实验 ‘verbose’: True, # 打印详细信息 # ‘device’: ‘0’, # 指定GPU例如 ‘0’ 或 ‘0,1’ # ‘resume’: True, # 从上次检查点恢复训练 } # 3. 开始训练 results model.train(**train_args) print(“Training completed!”) print(f“Best model saved at: {results.best}”) if __name__ ‘__main__’: main()启动训练cd yolo_world_custom_train python scripts/train_yolo_world.py训练开始后Ultralytics 会在runs/train/my_custom_dataset_exp1/目录下生成所有日志、权重和评估结果。你可以使用 TensorBoard 或直接查看生成的图片来监控训练过程。4.5 使用训练好的模型进行推理训练完成后你可以加载最佳模型进行推理测试其开放词汇能力。from ultralytics import YOLOWorld import cv2 # 1. 加载我们刚刚训练好的模型 model YOLOWorld(‘runs/train/my_custom_dataset_exp1/weights/best.pt’) # 2. 设置自定义的文本提示可以包含训练时未见过的组合或描述 # 注意模型从训练数据中学习了“陶瓷杯”、“键盘”、“无线鼠标”的概念 # 现在我们可以用这些概念进行查询 custom_prompts [“a white ceramic cup on a table”, “a black keyboard”, “a small mouse”] model.set_classes(custom_prompts) # 这是关键步骤设置当前推理的查询文本 # 3. 对一张新图片进行预测 image_path “path/to/your/test_image.jpg” results model.predict(image_path, conf0.25) # 设置置信度阈值 # 4. 可视化结果 plotted_img results[0].plot() # 绘制边界框和标签 cv2.imwrite(‘prediction.jpg’, plotted_img) print(“Prediction saved to prediction.jpg”) # 5. 打印检测到的信息 for result in results: boxes result.boxes if boxes is not None: for box, cls in zip(boxes.xyxy, boxes.cls): x1, y1, x2, y2 box.int().tolist() class_name custom_prompts[int(cls)] conf boxes.conf[0].item() print(f“Detected ‘{class_name}’ at [{x1}, {y1}, {x2}, {y2}] with confidence {conf:.2f}”)通过model.set_classes()你可以动态地指定任何文本提示进行检测这正是 YOLO-World 开放词汇能力的体现。即使你训练时只用了“a ceramic cup”推理时也可以查询“a white ceramic cup on a table”模型会利用其视觉-语言对齐能力尝试定位。5. 常见问题与排查思路在准备数据和训练过程中你可能会遇到以下典型问题。问题现象可能原因排查与解决思路训练时报错IndexError: list index out of range或KeyError1.text_prompt_index索引超出范围。2. TXT 文件格式错误字段数量不对。3. 图像路径不存在或dataset.yaml配置错误。1.检查索引确保每行的text_prompt_index是从0开始的连续整数且小于该图片去重后的文本提示总数。2.检查格式用文本编辑器打开一个生成的.txt文件确认每行恰好有9个字段用空格分隔。3.检查路径确认dataset.yaml中的path是绝对路径且images/和labels/子目录结构正确。Loss 不下降或训练效果极差1. 数据量太少。2. 文本提示过于模糊或不一致。3. 学习率等超参数不合适。4. 预训练模型与任务差异太大。1.增加数据开放词汇检测需要一定的数据量来学习稳健的视觉-文本对齐。2.优化提示确保同一物体的文本描述在整个数据集中保持一致且具有区分性如用“a ceramic cup”而非模糊的“object”。3.调整超参尝试减小学习率 (lr0)增加训练轮数 (epochs)。4.考虑微调如果从头训练困难尝试在更大的 Grounding 数据集如 Flickr30k上预训练过的模型上进行微调。模型推理时检测不到目标1. 训练不充分。2. 推理时设置的文本提示与训练时学习的语义不匹配。3. 置信度阈值 (conf) 设置过高。1.检查训练曲线确认训练loss已收敛mAP等指标在验证集上表现良好。2.对齐语义推理时set_classes的提示词应尽量使用训练时出现过的词汇或其近义词组合。例如训练时用了“dog”推理时用“puppy”可能效果不佳。3.降低阈值尝试将predict的conf参数调低如从0.25调到0.1。标注转换后坐标错误转换脚本中的坐标计算逻辑有误。单元测试写一个简单的测试脚本用 OpenCV 在一个示例图片上根据生成的TXT文件中的归一化坐标反向计算出像素坐标并画框目视检查框是否与物体对齐。‘YOLOWorld’ object has no attribute ‘set_classes’Ultralytics 版本过旧。升级库运行pip install -U ultralytics升级到最新版本。set_classes是 YOLO-World 模型特有的方法。6. 最佳实践与工程建议基于项目经验遵循以下实践能显著提升数据准备效率和模型性能。文本提示工程是成功的关键具体化优于泛化使用“a red sports car”而不是“a car”。更具体的描述能为模型提供更强的学习信号。保持一致性数据集中同一个物体类别应使用相同或高度相似的文本描述。混合使用“dog”、“a dog”、“the dog”会增加模型学习难度。利用属性在标注时尽可能加入颜色、材质、状态等属性如“a broken window”, “a smiling person”。这能极大增强模型对细粒度视觉概念的理解。数据质量与数量质量优先边界框标注务必精确。不准确的框会教给模型错误的位置-文本关联。负样本可选但有益YOLO-World 官方实现支持在dataset.yaml的grounding.text.prompts列表中加入一些负样本提示即数据集中不存在的物体描述。这有助于模型学习区分相关与不相关概念。在列表中加入一些随机物体名如“zebra“, “airplane”试试看。数据量对于自定义场景建议至少有数百张带标注的图像才能获得较好的微调效果。从头开始训练则需要规模大得多的数据集。高效的标注流程使用支持开放词汇的标注工具如Label Studio、CVAT等它们可以直接导出图像区域与文本的关联减少格式转换的麻烦。先粗后精可以先使用一个基础的检测模型如 YOLOv8进行自动预标注然后人工修正和添加文本描述能大幅提升标注效率。训练策略从预训练模型开始除非你有海量数据否则强烈建议使用yolov8s-world.pt等预训练权重进行微调而不是从头训练。冻结骨干网络在数据量较少时可以尝试冻结模型的主干特征提取网络只训练检测头部分以防止过拟合。这可以通过在model.train()的参数中设置freeze10冻结前10层等方式实现具体参数需参考官方文档。监控验证集指标密切关注验证集上的metrics/mAP50-95(B)等指标它是衡量检测性能的核心。版本管理与可复现性固定环境使用pip freeze requirements.txt保存完整的包版本。保存配置将最终的dataset.yaml和训练脚本的参数字典保存下来方便复现和调试。日志完整Ultralytics 的训练日志非常详细妥善保存runs/目录下的所有输出。准备一份合格的 Grounding 格式数据集是解锁 YOLO-World 强大能力的第一步也是最需要耐心和细心的一步。本文详细拆解了数据格式的每一个细节并提供了从格式转换到训练推理的完整代码闭环。核心在于理解“视觉-文本对齐”这一思想并在标注时贯彻“用精准的自然语言描述物体”的原则。当你成功训练出自己的 YOLO-World 模型后可以进一步探索更高级的应用例如提示词集成将用户查询、场景上下文动态生成更优的检测提示词。模型集成将 YOLO-World 与 SAMSegment Anything Model结合实现开放词汇的实例分割。部署优化使用 ONNX、TensorRT 等工具对模型进行加速满足实时性要求。希望这篇教程能帮你扫清 YOLO-World 训练数据准备上的障碍。如果在实践过程中遇到新的问题欢迎在评论区交流讨论。