
简介YOLO-World资源包整合了下一代YOLO检测器的PyTorch源码、预训练权重、预训练与微调代码及配套文档适合目标检测方向的研究者、算法工程师以及具备一定PyTorch基础的进阶学习者。作者采用prompt-then-detect的提示后检测范式让模型通过用户自定义词汇即可完成开放词汇检测与定位在检测、定位和图文数据集上均有良好表现。压缩包共161个文件约2.35MB其中110个Python脚本对应模型结构、训练与推理流程20个Markdown文档提供安装使用及调参说明另有JSON类别文本、Shell一键脚本、Dockerfile等便于快速搭建环境。已有879人学习下载。包内还包含inference.ipynb推理示例、测试图片与LVIS类别文本配置可直观展示从加载权重到输出检测结果的完整链路既可用于论文复现也能作为二次开发和教学演示的参考。1. 开放词表检测怎么落地一个能识别“没训练过”类别的检测器做目标检测最烦的一件事是什么训练集里没见过的类别模型永远检测不出来。你辛辛苦苦标了两千张图训了一个晚上第二天产品经理丢来一张新类别的图模型直接哑火。我拿到这份 yolo-world 源码加文档资料时第一反应是终于有人把开放词表检测从论文拉到了能跑的工程状态。YOLO-World 的核心思路是把目标检测从“固定类别分类”改成“输入文本、输出框”。你在推理时给一句“person.bicycle.car”它就能在这三个类别上出框换个提示词再跑一次又是另一组类别——不需要重新训练。对做巡检、安防、电商素材分类的开发者来说这意味着一个模型覆盖上百种动态变化的检测需求。这份资料里源码、预训练权重、训练推理文档都齐我拆完之后觉得它不光能跑通而且 PyTorch 技术栈的开发者能直接上手改。2. 架构解析把 CLIP 文本编码器塞进 YOLO检测头如何读懂自然语言2.1 从封闭词表到开放词表YOLO-World 改了什么传统检测器的输出头是一个固定维度的分类器比如 COCO 80 类模型最后出来的 logits 就是 80 个分值。你想加一个新类别就得改输出头、重新标注、重新训练——整个过程重得让人想放弃。YOLO-World 的改动发生在两个地方。第一把分类头从固定维度换成文本特征匹配图像侧提取 region embedding文本侧提取类别名的 embedding两者做点积算相似度相似度高于阈值的区域就是目标。第二在 Neck 部分加入了跨模态融合模块让图像特征在还没进检测头之前就先去“看”一眼文本特征相当于给检测器的每一层都配了一张“提示卡”。这样做的直接好处推理时你可以动态替换文本编码器的输入换成新类别就能检测新类别。整个过程中图像侧的权重可以完全不动——这就是 open-vocabulary开放词表检测的核心能力。2.2 三大核心模块Text Encoder、CSPDarknet、RepVL-PAN拆开源码整个模型其实由三段拼起来。Text Encoder。用的是 CLIP 的文本编码器输入是类别名的 token 序列输出是归一化后的文本 embedding。源码里对文本做了模板包装——默认的模板是“a photo of {class}”如果你输入“helmet”实际送进编码器的是“a photo of helmet”。这个细节很关键因为 CLIP 是在图文对上预训练的模板措辞直接影响 embedding 的质量。CSPDarknet 骨架。以 YOLOv8 的 CSPDarknet 为基础输出三层的特征图P3、P4、P5分别对应小目标、中目标、大目标的检测。源码里提供了从 nano 到 xl 的缩放配置宽度和深度因子控制模型大小。如果只是快速验证效果我一般先用 small 或者 medium推理快很多。RepVL-PAN。这是 YOLO-World 最核心的网络结构改动。它在标准 PAN-FPN 的路径里插入了 Text-guided 模块——每一层特征图在上采样或下采样之前会先和文本 embedding 做一次跨模态融合。融合方式是新加的 Cross-Model Fusion 模块对文本 embedding 做线性投影得到 attention 权重再用这个权重去加权图像特征图的通道维。源码里这段逻辑在 yoloworld/yolo_world/vl_pan.py 里。核心代码如下class CrossModelFusion(nn.Module): def __init__(self, in_channels, text_channels, out_channels): super().__init__() self.text_proj nn.Linear(text_channels, in_channels) self.image_proj nn.Linear(in_channels, in_channels) self.gate nn.Sigmoid() def forward(self, image_feat, text_feat): # text_feat 是文本 embedding已被 L2 归一化 text_weight self.text_proj(text_feat) # [B, C] text_weight self.gate(text_weight) # 门控控制文本影响强度 image_feat self.image_proj(image_feat) image_feat image_feat * text_weight.unsqueeze(-1).unsqueeze(-1) return image_feat这段代码的逻辑很直观text embedding 经过一个线性层投影成和图像特征一样的通道数再经过 Sigmoid 变成 0 到 1 之间的门控值。这个门控值直接乘到图像特征的通道上——相当于给每个通道“打分”和当前提示词相关的通道保留无关的通道抑制。参数说明一下in_channels 是特征图的通道数text_channels 是 CLIP 文本编码器的输出维度典型值是 512 或 768out_channels 是融合后的输出通道数通常保持和输入一致。2.3 重参数化推理为什么部署时能保持 YOLO 的速度开放词表听着美好但有个工程痛点如果每次推理都把文本编码器跑一遍再和每个 region embedding 做匹配推理速度会慢到没法用。YOLO-World 的解决办法是重参数化——把文本信息直接融合进卷积权重里。具体做法在训练完成、进入部署阶段时文本 embedding 已经确定了比如你要检测“helmet.vest.shoe”这三类那就把文本 embedding 和 Cross-Model Fusion 模块的线性层全部合成到检测头的卷积核里。这一步是一次性计算跑完以后整个模型就是一个纯视觉的 YOLO速度和原始 YOLOv8 几乎一致。源码里有个 weight_repack 方法核心逻辑是这样def repack(self, text_embeddings): # text_embeddings: [num_classes, text_dim] new_weights [] for conv, proj in zip(self.class_conv_list, self.text_proj_list): # 把文本投影权重乘进卷积权重 merged_weight conv.weight * proj(text_embeddings).unsqueeze(-1).unsqueeze(-1) new_weights.append(merged_weight) return new_weights这个 repack 的本质是把“卷积 文本匹配”两步融合成一步卷积。之后推理时不再需要文本分支模型变成一个纯卷积网络——这也是为什么它能跑出接近原生 YOLO 的速度。我一般在导出 ONNX 或 TensorRT 之前做这个操作导出的模型尺寸更小推理也更稳。2.4 目录结构与关键文件定位拿到压缩包之后先别急着跑花五分钟把目录过一遍。这份资料的结构大致如下├── configs/ # 模型配置yoloworld_s/m/l/xl 等 │ ├── yoloworld_s.py │ ├── yoloworld_m.py │ └── yoloworld_l.py ├── yoloworld/ # 核心源码 │ ├── yolo_world/ │ │ ├── vl_pan.py # 跨模态融合模块 │ │ ├── text_encoder.py # CLIP 文本编码器 │ │ └── head.py # 区域文本对比头 ├── tools/ │ ├── train.py # 训练入口 │ └── test.py # 测试入口 ├── demo.py # 推理演示脚本 ├── assets/ # 示例图片 └── docs/ # 训练和部署文档重点关注三个文件vl_pan.py 是跨模态融合的核心text_encoder.py 处理提示词转 embeddingdemo.py 是跑通流程最快的入口。改模型结构动前两个改推理逻辑动 demo.py训练调参进 tools/train.py。3. 源码级核心逻辑推理、训练、微调三段代码拆解3.1 推理从一句提示词到边界框的完整链路demo.py 是整个项目最快能跑起来的入口。先说流程再说代码。推理分三步第一步把提示词字符串按句点切分成多个类别第二步文本编码器生成所有类别的 embedding第三步图像经过重参数化后的检测头直接输出边界框、类别和置信度。我在本地跑了 demo.py核心调用部分长这样# 提示词用 . 分隔多个类别 text person.bicycle.car # 切分并获得文本 embedding texts text.split(.) embeddings text_encoder(texts) # shape: [num_classes, text_dim] # 构建模型并加载权重 model YOLOWorld(config_path, checkpoint_path) model.set_text_embeddings(embeddings) # 推理 results model.predict(image_path, conf_threshold0.35) for box in results.boxes: print(box.cls, box.conf, box.xyxy)这段代码里有几个参数值得注意。text 用英文句点分隔这是源码里 tokenizer 的分隔符约定改成逗号会直接报错或者产生错误的 embedding我第一次跑就踩了这个坑。conf_threshold 是置信度阈值默认 0.35实际项目里我调到 0.25 能召回更多目标但误检也会变多按落地场景取舍。set_text_embeddings 内部会触发上一节所说的重参数化——所以后续推理速度几乎不受类别数量影响。3.2 训练区域文本对比损失怎么算如果你要基于自己的数据微调 YOLO-World得先理解它的损失函数。传统 YOLO 用分类损失 回归损失而 YOLO-World 多了一个区域文本对比损失——这是它区分于普通 YOLO 的关键。思路是这样训练时每张图配一组文本描述图像侧的特征图被划分成多个 region embedding每个 region 和文本 embedding 做对比学习。正样本是“这个区域确实包含该类别”的配对负样本是“区域里没有该类别”的配对。损失函数用对比损失让正样本的相似度拉近、负样本拉远。源码里的损失计算大体是这个结构def region_text_contrast_loss(region_embeds, text_embeds, targets): # region_embeds: [num_regions, embed_dim] # text_embeds: [num_classes, embed_dim] logits region_embeds text_embeds.T # 相似度矩阵 # 根据 targets 构造正负标签 labels build_contrastive_labels(targets) loss cross_entropy(logits / temperature, labels) return losstemperature 是温度系数源码里默认设了可学习参数初始值通常接近 0.07。这个值越大logits 分布越平缓训练难度越低越小模型越激进地拉大正负样本差距。实践中我一般不动它让模型自己学。训练时完整的 loss 是三项加总区域文本对比损失、边界框回归损失IoU loss、分布聚焦损失DFL。权重比大概是 1:1:0.5具体在配置文件的 loss_weight 里调。3.3 微调在自己的数据集上冻结 backbone 训练大多数开发者的需求不是从零训练而是在自己的数据上微调。YOLO-World 支持两种微调策略差别很大。第一种是冻结 backbone 和文本编码器只训练检测头和融合模块。这种做法适合数据量中等几千张、类别和预训练类别比较接近的场景。优点是小显存也能跑8G 够用速度也快缺点是如果目标域和预训练域差异太大特征提取能力可能不够。第二种是全量微调。所有参数都解冻适合数据量大、且目标域风格明显不同的场景。我遇到过一个巡检测试夜间红外图占了一半冻结训练一直掉点全量微调之后 mAP 涨了 7 个点。代价是显存需求直接翻倍训练时间拉长。微调命令大概长这样python tools/train.py configs/yoloworld/yoloworld_s.py \ --data data/your_dataset.yaml \ --freeze_backbone True \ --batch_size 16 \ --epochs 50 \ --lr 0.0001参数含义freeze_backbone 控制是否冻结骨架batch_size 根据显存调整lr 用 1e-4 起步——因为文本编码器是预训练模型学习率太大会摧毁它的语义能力。验证阶段用 tools/test.py 跑一遍输出 COCO 格式的 mAP对比微调前后的指标差距。4. 本地跑通全流程环境配置、权重下载、推理和评估4.1 环境依赖与版本建议这份资料基于 PyTorch 实现环境配置不算复杂但版本坑不少。我自己的建议组合是 Python 3.9 以上、PyTorch 1.13 或 2.x 都行、CUDA 11.7 以上。注意一点PyTorch 版本别太新2.5 以上某些 API 变更可能导致 mmdetection 版本的兼容报错。还需要安装 mmcv、mmdet 和 mmyolo 这几个仓库的对应版本。如果源码里已经带了 requirements.txt直接 pip install -r 即可如果没有按官方文档装。这块是我觉得最容易劝退新手的地方YOLO-World 的很多实现依赖 mmyolo 的基础模块版本对不上会有一堆莫名其妙的 attribute error。我一般先用 conda 建一个干净环境隔离掉系统里旧版本库的干扰conda create -n yolo_world python3.9 -y conda activate yolo_world pip install torch2.0.1 torchvision0.15.1 pip install -r requirements.txt安装时间取决于网络环境torch 和 mmcv 都是大头建议用国内镜像源加速。装完后先跑 import 检查python -c import torch; import mmcv; import mmyolo; print(torch.__version__, mmcv.__version__)能顺利打印版本号说明基础环境没问题可以进入下一步。4.2 权重文件与配置文件对应关系YOLO-World 的预训练权重文件命名有规律yolo_world_v2_s_ov.pth、yolo_world_v2_m_ov.pth 这种格式其中 s/m/l/xl 对应模型尺寸。下载前先看好配置文件名两者必须匹配——用 small 配置去加载 large 权重十有八九报 shape mismatch 的错误。我在本地用的是一套“small 配置 small 权重”的组合显存占用约 4G单张 1080P 图片推理耗时在 80 毫秒左右。如果换成 xl显存直接上到 14G 以上推理时间翻倍但精度提升有限。实际工程里我一般先用 small 验证流程确认效果后再换更大的模型。加载权重的代码没有额外参数模型类会根据 config 结构自动匹配 state_dict。如果出现 missing key 的告警基本就是模型尺寸不匹配别犹豫去重新下载对应权重。4.3 推理 Demo检测任意提示词指定目标跑 demo.py 是确认整个链路通了的最好方式。假设你有一张示例图片想检测人和自行车python demo.py \ --config configs/yoloworld/yoloworld_s.py \ --checkpoint weights/yolo_world_v2_s_ov.pth \ --image assets/demo.jpg \ --text person.bicycle.car \ --output_dir outputs/参数说明config 指定模型结构的配置文件checkpoint 是下载好的权重路径text 是检测提示词多个类别用英文句点分隔output_dir 是结果输出目录。跑完之后在 outputs/ 下会看到标注了边界框和类别名的结果图。我第一次跑的时候检测结果全是空框检查后发现问题出在提示词上——我用了逗号分隔而源码里只认句点符。这个是开放词表检测最容易翻车的细节提示词格式直接对标文本编码器的 tokenizer 分词规则你用错分隔符整个文本语义就乱了。4.4 批量评估在 COCO 或自建数据集上量化效果跑通单张图片只是开始评估模型性能要上 coco_eval。源码里提供了测试脚本运行方式python tools/test.py \ configs/yoloworld/yoloworld_s.py \ weights/yolo_world_v2_s_ov.pth \ --data data/coco.yaml \ --metrics bbox输出会包含 mAP0.5、mAP0.5:0.95 等一系列指标。不同预训练权重的 baseline 数值不一样small 模型在 COCO val 上大概 40 个点 mAP 左右xl 能到 50 以上。评估的意义在于你后续做任何模型修改都要拿这组 numbers 当参照改完没涨点说明改动无效。如果要用自己标注的数据集评估需要把数据组织成 COCO 格式的 JSON 标注文件然后在 data/coco.yaml 里改数据路径和类别名。这一步纯粹是个体力活标注格式转换不对会直接导致评估结果全为 0。我一般会先用三张图的小样本跑通流程再全量评估。5. 避坑与常见问题权重、显存、提示词和版本冲突5.1 权重加载报 shape mismatch现象运行 demo.py 时抛出 size mismatch for text_encoder... 之类的错误。原因配置文件和你下载的权重不是同一个模型尺寸。写配置文件里模型结构定义和权重文件的训练结构对不上PyTorch 在加载时发现张量维度不一致就会报错。解决确认 configs 下的文件名和权重文件名里的尺度标识一致s 配 s、m 配 m。如果不确定打印模型每个 key 的 shape 和权重的对比不过最快的方式还是按资料里推荐的配对组合重新下载。5.2 检测结果全是空框现象模型跑通了但没有输出任何检测框或者输出的类别明显不对。原因大概率是提示词格式问题。我踩过的是用了中文逗号或者提示词用了句号结尾导致多出一个空类别。另外置信度阈值设太高也会把低分目标都过滤掉。解决提示词严格用英文句点分隔末尾不要带多余符号。conf_threshold 从 0.25 往下调试试。如果还是空框换一张内容简单的图排查逐步排除图像侧的问题。5.3 显存溢出 OOM现象训练或推理时 CUDA out of memory。原因模型配置选太大或者 batch size 设置过高。small 模型的推理显存大约 4G训练显存差不多 8G 起步xl 训练直接需要 24G 以上。解决降级模型尺寸或者减小 batch size。训练场景优先冻结 backbone显存占用能降一半。实在要跑大模型用梯度累积模拟大 batch这也是常见做法。5.4 训练 loss 不下降现象训练十几个 epochloss 纹丝不动或者直接 nan。原因学习率设置太高尤其微调时全局 lr 用了 1e-3 这种默认值把文本编码器的预训练参数冲击坏了也有可能是数据集中类别描述和图像内容不匹配比如标注里有“helmet”提示词里写的却是“hat”。解决微调 lr 降到 1e-4 以下文本编码器部分单独设置更低的学习率。检查数据集类别名是否和提示词严格一致连单复数、大小写都要对上——CLIP 文本编码器对这东西极其敏感也是算得上一种玄学反正对齐就没问题。5.5 mmcv 和 mmyolo 版本兼容性现象import 时报 module has no attribute xxx常见的是 mmcv 的算子加载失败。原因mmcv、mmdet、mmyolo 三者版本之间存在强依赖关系尤其是 mmcv-full 和 PyTorch 的 CUDA 版本必须匹配。不同版本之间 API 有变动混用就会出现属性缺失。解决严格按照资料里的 requirements.txt 安装不要手动升级任何一个包。如果已经装乱了重建 conda 环境按顺序安装是最省心的后悔药。6. 二次开发落地自定义提示词模板与部署加速的实践拿到这份源码资源真正的价值在于按自己的业务场景改造它。我给一个具体的落地思路把 YOLO-World 接成一个动态检测服务。第一步封装提示词模板。实际业务中类别名不是固定写死的可能是后端下发的配置。我在项目里做了个简单的模板映射def build_prompt(category_list): # category_list: [person, bicycle, car] templates [fa photo of {cat} for cat in category_list] return ..join(templates)注意这里每个类别都套了“a photo of”模板这是我在实验中发现比直接送裸类别名更稳的做法召回率有小幅提升。如果类别名里带空格或者连字符比如“fire extinguisher”不需要特殊处理CLIP 的 tokenizer 会自然分词。第二步处理类别动态增减。部署场景里每次请求可能带不同的类别列表。不需要重新加载模型只需要重新调用 repack 方法更新检测头的卷积权重。这个操作在 CPU 上做一次也就几十毫秒完全可以承受。我实际做的服务里把文本编码器和 repack 的结果做了缓存同样的类别组合直接命中缓存响应时间进一步缩短。第三步导出加速。线下验证通过后用 ONNX 导出然后转 TensorRT 部署。关键一点导出前先做 repack导出后的模型就是一个标准 YOLO不包含文本分支TensorRT 优化效果好很多。导出的动态 batch 维度设成 1输入尺寸固定成 640 或 1280这样在推理时能稳定跑到实时。最后说个血泪经验无论改什么改完都要先跑一遍原来的 COCO 评估对比 baseline 指标再决定要不要继续。我有一次为了加速把融合模块里的门控去掉了COCO mAP 直接掉了 6 个点等于白做。从那以后我每次改模型结构都强制走一遍“改代码 → 跑评估 → 对比数据 → 再迭代”的流程不再凭感觉行事。开放词表检测的坑不少但每一步都有迹可循——希望这份源码解析能帮你少踩几个我踩过的坑。本文还有配套的精品资源点击获取