YOLOE
1. 摘要
-
身份编号:fwb0042
-
类型与序号:YOLOE 方案1
-
进展:
item status detail 方案选择与硬件资源划分 1 模型导出 1 ~导出模型精度一致,提供python验证脚本 1 cpu处理部分c++工程移植 0 ~c++工程精度一致,提供验证脚本 0 ~c++工程性能优化 0 icraft编译通过 0 算子不支持 ~存在量化精度调优工作 0 ~完成基本pyrtcrt搭建与结果验证 0 ~完成pyrtcrt精度测试与对齐 0 完成上板耗时测试 0 ~使用运行时提供的api进行基本性能优化 0 ~存在整体方案各环节优化或优化方案的设计 0 提出bug数 0
2. 方案简介
2.1 算法流程介绍
模型或算法背景:
- YOLOE (You Only Look Once with open prompts, effectively) 是一个高效、统一的开放世界目标检测与分割框架,旨在实现“实时看见任何事物”。
- 源仓库链接:https://github.com/THU-MIG/yoloe
- 开发团队:清华大学智能产业研究院(MIG) (Ao Wang, Lihao Liu 等人主导开发)
- 发布时间:2025年3月 (根据论文arXiv v1版本日期)
- 性能水平:YOLOE 创新地将多种开放提示机制(文本、视觉、无提示)集成到一个高效模型中。它基于成熟的YOLOv8等架构,通过引入创新的模块,在几乎不增加推理开销的情况下,实现了强大的零样本(zero-shot)检测和分割能力,且训练成本远低于同类方法。
在LVIS数据集上与YOLO-Worldv2的性能对比:
| Model | 提示类型 | Params | 训练数据 | 训练时间 | FPS (T4 / iPhone12) | AP | APr (rare) | APc (common) | APf (frequent) |
|---|---|---|---|---|---|---|---|---|---|
| YWorldv2-S | T | 13M | OG | 41.7h | 216.4 / 48.9 | 24.4 | 17.1 | 22.5 | 27.3 |
| YOLOE-v8-S | T / V | 12M / 13M | OG | 12.0h | 305.8 / 64.3 | 27.9 / 26.2 | 22.3 / 21.3 | 27.8 / 27.7 | 29.0 / 25.7 |
| YWorldv2-M | T | 29M | OG | 60.0h | 117.9 / 34.2 | 32.4 | 28.4 | 29.6 | 35.5 |
| YOLOE-v8-M | T / V | 27M / 30M | OG | 17.0h | 156.7 / 41.7 | 32.6 / 31.0 | 26.9 / 27.0 | 31.9 / 31.7 | 34.4 / 31.1 |
| YWorldv2-L | T | 48M | OG | 80.0h | 80.0 / 22.1 | 35.5 | 25.6 | 34.6 | 38.1 |
| YOLOE-v8-L | T / V | 45M / 50M | OG | 22.5h | 102.5 / 27.2 | 35.9 / 34.2 | 33.2 / 33.2 | 34.8 / 34.6 | 37.3 / 34.1 |
注:T/V表示文本/视觉提示。OG表示Objects365和GoldG数据集。
算法流程梳理
YOLOE 的整体架构继承了YOLO系列的高效设计,但在其上融入了针对开放世界场景的核心模块,使其能够理解并响应不同形式的提示。
数据输入(图像/提示) ——> 主干网络(Backbone)——> 颈部网络(Neck)——> 头部网络(Head) ——> 开放提示处理 ——> 输出结果
YOLOE在标准的YOLOv8等模型(包含Backbone, PAN, 回归/分割头)的基础上,针对三种开放提示场景,引入了三大核心组件:
1. 文本提示 (Text Prompts): RepRTA (Re-parameterizable Region-Text Alignment)
- 目的:在不增加推理成本的前提下,提升视觉特征与文本嵌入的对齐质量。
- 方法:在训练时,使用一个轻量级的辅助网络来优化预先提取好的文本特征(如CLIP embedding)。训练完成后,这个辅助网络的权重可以被无缝地“重参数化”合并到检测头的分类卷积层中。
- 优势:推理时架构与原始YOLO完全相同,实现了“零开销”的性能提升。
2. 视觉提示 (Visual Prompts): SAVPE (Semantic-Activated Visual Prompt Encoder)
- 目的:高效地编码视觉提示(如框、点、掩码),并将其转化为与文本提示兼容的嵌入向量。
- 方法:设计了一个解耦的双分支结构。语义分支提取提示无关的通用语义特征;激活分支则将视觉提示与图像特征进行低成本交互,生成一个“注意力权重”,用以加权聚合语义特征。
- 优势:避免了复杂的Transformer或额外的视觉编码器,复杂度极低,部署友好。
3. 无提示 (Prompt-Free): LRPC (Lazy Region-Prompt Contrast)
- 目的:在没有明确指令时,自动检测并识别图像中的所有物体。
- 方法:将该问题重新定义为一个高效的“检索”任务。首先,使用一个专门训练的、用于“寻找所有物体”的嵌入向量,找出图中所有可能的目标。然后,仅对这些找到的目标,在内置的大型词汇库中进行“懒惰”的对比匹配,从而检索出类别名称。
- 优势:无需依赖昂贵的大型语言模型进行实时生成,速度极快,实现了高效的“看到一切”。
基本组件: RepRTA:一个可重参数化的文本嵌入优化模块,训练时增强对齐,推理时零成本。 SAVPE:一个解耦的、轻量级的视觉提示编码器,高效且易于部署。 LRPC:一种懒惰对比策略,通过“先找到,后识别”的两阶段方法,高效实现无提示下的全目标检测。
数据集
- YOLOE的训练主要依赖于大规模的检测和视觉定位数据集,如 Objects365 和 GoldG(包含GQA, Flickr30k等)。
- 分割数据:利用先进的分割模型(如SAM-2.1)为检测框生成高质量的伪标签(pseudo masks),用于联合训练分割任务。
- 数据多样性:训练数据覆盖了海量类别,这为模型的强大零样本泛化能力奠定了基础。
- 提示数据:文本提示直接使用数据集中的类别名;视觉提示使用标注框;无提示场景则将所有物体标注为同一个“物体”类别进行学习。
模型选择
- YOLOE提供了基于YOLOv8和YOLO11架构的S/M/L多种尺寸模型,用户可根据速度和精度的需求灵活选择。
- 起点:模型从标准的YOLOv8/v11权重开始,加载其主干和颈部,然后在其上进行开放词汇能力的训练。
- 适用场景:YOLOE尤其适用于类别多变、需求不固定、需要与用户交互的场景。
前后处理
前处理:
- 图像处理:与标准YOLO一致,包括读取图像、缩放到模型输入尺寸(如640x640)、归一化、通道转换(HWC to NCHW)等。
- 提示处理:
- 文本提示:使用预训练的文本编码器(如MobileCLIP-B)将输入文本转换为嵌入向量。这些向量在训练前可以被缓存,以加速训练。
from ultralytics import YOLOE # Initialize a YOLOE model model = YOLOE("yoloe-11l-seg.pt") # or select yoloe-11s/m-seg.pt for different sizes # Set text prompt to detect person and bus. You only need to do this once after you load the model. names = ["person", "bus"] model.set_classes(names, model.get_text_pe(names)) # Run detection on the given image results = model.predict("path/to/image.jpg") # Show results results[0].show()
- 视觉提示:将用户输入的框、点等转换为掩码(Mask)格式,送入SAVPE。
import numpy as np from ultralytics import YOLOE from ultralytics.models.yolo.yoloe import YOLOEVPSegPredictor # Initialize a YOLOE model model = YOLOE("yoloe-11l-seg.pt") # Define visual prompts using bounding boxes and their corresponding class IDs. # Each box highlights an example of the object you want the model to detect. visual_prompts = dict( bboxes=np.array( [ [221.52, 405.8, 344.98, 857.54], # Box enclosing person [120, 425, 160, 445], # Box enclosing glasses ], ), cls=np.array( [ 0, # ID to be assigned for person 1, # ID to be assigned for glassses ] ), ) # Run inference on an image, using the provided visual prompts as guidance results = model.predict( "ultralytics/assets/bus.jpg", visual_prompts=visual_prompts, predictor=YOLOEVPSegPredictor, ) # Show results results[0].show()
- 无提示:提前将编码器等信息嵌入到模型中,无需在进行
from ultralytics import YOLOE # Initialize a YOLOE model model = YOLOE("yoloe-11l-seg-pf.pt") # Run prediction. No prompts required. results = model.predict("path/to/image.jpg") # Show results results[0].show()
- 文本提示:使用预训练的文本编码器(如MobileCLIP-B)将输入文本转换为嵌入向量。这些向量在训练前可以被缓存,以加速训练。
后处理:
- 阈值筛选与NMS:
- 根据分类得分和置信度筛选高质量的检测框。
- 应用标准的非极大值抑制(NMS)来消除冗余框。
- 无提示检索 (LRPC):
- 在无提示模式下,后处理分为两步:首先用专用提示
Ps找出所有得分超过阈值δ的物体,然后仅对这些物体进行类别词汇库的匹配,极大地降低了计算量。
- 在无提示模式下,后处理分为两步:首先用专用提示
2.2 硬件资源分配
yolo plin模式:摄像头输入数据直接传给pl部分
前处理:fpga,做在数据流上
网络主体:npu
后处理阈值筛选:fpga
后处理nms:fpga
后处理计算框数值等:cpu
可视化:cpu
4. 模型导出说明
与YOLOV8-SEG类似,在导出的时候,导出到最后一步卷积,将后处理部分去除掉交给更适合的FPGA或者CPU处理进行处理。
def lrpc_head_forward(self, cls_feat, loc_feat, conf):
if self.enabled:
pf_score = self.pf(cls_feat)[0, 0].flatten(0)
mask = pf_score.sigmoid() > conf
cls_feat = cls_feat.flatten(2).transpose(-1, -2)
cls_feat = self.vocab(cls_feat[:,mask] if conf else cls_feat * mask.unsqueeze(-1).int())
return self.loc(loc_feat), cls_feat.transpose(-1, -2), mask
else:
cls_feat = self.vocab(cls_feat)
loc_feat = self.loc(loc_feat)
return loc_feat, cls_feat.flatten(2), torch.ones(
cls_feat.shape[2] * cls_feat.shape[3], device=cls_feat.device, dtype=torch.bool
)
LRPCHead.__call__ = lrpc_head_forward
def yoloe_seg_forward(self, x, cls_pe=None):
"""修改后的前向传播,仅输出卷积层结果(不包含后处理).
输入:
x (List[Tensor]): 多尺度特征图 [P3, P4, P5]
cls_pe (Optional[Tensor]): 文本/视觉提示嵌入 (B, N, D)
返回:
Tuple: 所有中间卷积输出(用于 TorchScript 导出)
"""
# 1. 原型掩码分支
p = self.proto(x[0]) # shape=(B, nm, H, W)
masks = []
# 2. 掩码系数分支(cv5层输出)
seg_outputs = []
for i in range(self.nl):
seg_outputs.append(self.cv5[i](x[i])) # shape=(B, nm, H, W)
# 3. 检测分支(cv2/cv3/cv4层输出)
cls_dfl_outputs = []
for i in range(self.nl):
cls_feat = self.cv3[i](x[i]) # 区域特征 (B, embed, H, W)
loc_feat = self.cv2[i](x[i]) # 定位特征 (B, reg_max*4, H, W)
assert isinstance(self.lrpc[i], LRPCHead)
loc_output,cls_output, mask = self.lrpc[i](
cls_feat, loc_feat, 0 if self.export and not self.dynamic else getattr(self, "conf", 0.001)
)
masks.append(mask)
cls_dfl_outputs.extend([loc_output,cls_output])
# 合并所有输出(顺序:loc_feat, cls_feat, mask, seg_feat , proto)
mask = torch.cat(masks)
outputs = []
for i in range(self.nl):
outputs.extend([
cls_dfl_outputs[2 * i], # loc_feat (P3)
cls_dfl_outputs[2 * i + 1], # cls_feat (P3)
seg_outputs[i] # seg_feat (P3)
])
outputs.append(mask) # 最后追加原型
outputs.append(p) # 最后追加原型
# 最后追加原型
return tuple(outputs)
YOLOESegment.__call__ = yoloe_seg_forward
5. cpu处理部分c++工程移植说明
暂无实现
6. ICRAFT编译
编译未通过

不支持点:
-
算子不支持
在icraft logs中找到不支持的算子序列、在源码中定位对应的源码、实现的功能
算子序列 对应源码 实现的功能 NonZero,Gather 
mask_select函数
7. 上板测试与优化
-
优化前各环节耗时统计(表格)
-
优化后耗时统计(表格)
-
优化项与效果
分条描述做了哪些性能优化,提升了多少
-
运行时工程的整体介绍(最好带流程图)