RT-DETR
一个为实时推理而生的检测 transformer:它解码的是一组固定的 query,而不是一张稠密网格,所以不跑 NMS。LibreYOLO 收录了它的三个版本,靠你加载的检查点(checkpoint)来区分,版本 2 还提供旋转框。
- 任务
- detection, oriented boxes
- 尺寸
- rtdetr: r18, r34, r50, r50m, r101, l, x at 640 px; rtdetrv2: r18, r34, r50, r50m, r101 for detection at 640 px, n, s, m, l, x for oriented boxes at 1024 px; rtdetrv4: s, m, l, x at 640 px
- 安装
pip install "libreyolo[rtdetr]"- 支持层级
- 核心,自 v1.1.0 起。核心的可训练检测器:功能在同一个发布波次里紧跟旗舰。
- 上游
- RT-DETR, RT-DETRv2 and RT-DETRv4,由 Baidu (versions 1 and 2), Peking University and Tsinghua University (version 4) 发布,采用 Apache-2.0 许可。论文、源码
- 许可
- 代码采用 Apache-2.0,权重采用 Apache-2.0。商用
安装
RT-DETR 不需要任何可选 extra。它导入的一切都在基础安装里,而 rtdetr 这个 extra
只是一个稳定的名字,并不会在此之上添加任何东西。
pip install libreyolo用 lora=True 做适配器(adapter)微调是个例外,它需要 lora extra。
pip install "libreyolo[lora]"预测
权重在首次使用时从 Hugging Face 下载,并缓存在本地。
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreRTDETRr18.pt")result = model(SAMPLE_IMAGE, save=True) for box in result.boxes: print(box.cls, box.conf, box.xyxy)libreyolo predict model=LibreRTDETRr18.pt save=True \ source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpgfrom libreyolo import LibreYOLO # 版本是文件名的一部分,工厂按检查点分发,所以三个版本的加载# 方式完全一样model = LibreYOLO("LibreRTDETRv4s.pt") # 库接受的任何数据源:文件、文件夹、URL、摄像头索引、RTSP 流,# 或者一个 .streams 列表for result in model.predict("clip.mp4", stream=True, save=True): print(len(result.boxes))from libreyolo import LibreYOLO # 仅限版本 2。-obb 后缀选中任务,而检查点是从它自己的张量里被# 认出为旋转的,所以不需要传 task 参数。这些权重是 DOTA v1.0,# 15 个航拍类别,1024 pxmodel = LibreYOLO("LibreRTDETRv2n-obb.pt")result = model("aerial.png", save=True) obb = result.obbprint(obb.xywhr) # (N, 5):cx, cy, w, h, 弧度print(obb.xyxyxyxy) # 同样这些行,表示成四个角点print(result.boxes.xyxy) # 外接的轴对齐检测框libreyolo predict model=LibreRTDETRv2n-obb.pt source=aerial.png save=True返回的 Results 对象和每个家族返回的都是同一个,所以换成另一个检测器只是一行的
改动。conf 和 max_det 过滤的是在 query 和类别上做的 top-k 解码;这里没有 NMS
步骤需要调,iou 会被接受但不起作用。旋转检查点原生地填充 result.obb,同时也用
外接的轴对齐矩形填充 result.boxes。数据源、流式处理和结果处理见预测。
变体
三个版本,它们之间一共两个任务,而且尺寸代号不在同一条序列上。版本 1 按骨干给尺寸 命名,ResNet 或 HGNetv2。版本 2 只复用 ResNet 那套名字:两个 HGNetv2 尺寸版本 1 已经提供,而版本 2 在那里的结果足够接近,LibreYOLO 就不再为它们发布重复的权重。 版本 4 用的是一套纯字母序列,和版本 1 的 HGNetv2 名字撞了,所以单看一个尺寸代号 并不能确定是哪个模型。版本写在检查点的文件名里。
| 检查点 | 输入(px) | mAP 50-95 | 参数量(M) |
|---|---|---|---|
| LibreRTDETRl | 640 | 55.8 | 32.93 |
| LibreRTDETRr101 | 640 | 56.8 | 76.56 |
| LibreRTDETRr18 | 640 | 49.7 | 20.18 |
| LibreRTDETRr34 | 640 | 52.2 | 31.44 |
| LibreRTDETRr50 | 640 | 55.9 | 42.89 |
| LibreRTDETRr50m | 640 | 53.8 | 36.59 |
| LibreRTDETRx | 640 | 57.9 | 67.37 |
| LibreRTDETRv2r101 | 640 | 56.8 | 76.56 |
| LibreRTDETRv2r18 | 640 | 50.8 | 20.18 |
| LibreRTDETRv2r34 | 640 | 53.2 | 31.44 |
| LibreRTDETRv2r50 | 640 | 55.7 | 42.89 |
| LibreRTDETRv2r50m | 640 | 54.8 | 36.59 |
| LibreRTDETRv4l | 640 | 57.8 | 31.24 |
| LibreRTDETRv4m | 640 | 56.5 | 19.59 |
| LibreRTDETRv4s | 640 | 52.8 | 10.32 |
| LibreRTDETRv4x | 640 | 60.0 | 62.62 |
COCO val2017, 500 images。数据由 LibreYOLO 基准测试工具测得,并发布在 Vision Analysis 上,可在此比较不同硬件和运行时的延迟,并查看完整的运行记录。
版本 2 保留了版本 1 的架构和 state dict 布局,改的是可变形注意力的采样方式,这也
是为什么区分两者靠的是检查点里的元数据,而不是形状。版本 4 是另一条谱系:它复用了
D-FINE 的架构和训练器,它的权重来自把一个 DINOv3 视觉基础模型教师蒸馏进 HGNetv2
学生。在 LibreYOLO 里,LibreRTDETRv4 是 LibreDFINE 的子类,mask head 被钉死为
关闭,所以它只做检测。
版本 2 上的旋转框
版本 2 是唯一一个带第二个任务的版本。它支持的任务是 detect 和 obb,两者既不
共享计算图,也不共享一条尺寸序列。检测用 ResNet 那几档尺寸,在 640 px 下;旋转
检测用一套 HGNetv2 序列,n、s、m、l 和 x,在 1024 px 下,而且输入尺寸是按任务解析
的,不是按家族。一个检查点是不是旋转的,是从它自己的张量里认出来的,靠的是五坐标的
检测框 head 和版本 2 的采样参数,所以 -obb 权重不需要 task 参数就能加载进旋转
计算图,两者不匹配会直接报硬错误,而不是被悄悄按另一种方式重新解释。
已发布的文件是从 LibreRTDETRv2n-obb.pt 到 LibreRTDETRv2x-obb.pt。它们是官方的
DOTA v1.0 单尺度检查点转换成 LibreYOLO 格式的产物,15 个航拍类别,从飞机和船只
到港口和直升机,类别名已经写进检查点里。和检测那边不同,旋转任务只做推理:预测、
验证和导出都能用,而对一个旋转模型调用 train() 会抛异常。跟踪和测试时增强同样
不支持旋转框。旋转框检测讲了这个任务、标注格式
和指标。
训练
训练从一个已发布的检查点开始。三个版本都接受 pretrained,然后把它丢掉,所以
pretrained=False 并不会给你一个随机初始化的模型。本节讲的全是检测:版本 2 的旋转
任务只做推理,而且从检测权重到它没有迁移路径,因为两者用的骨干不同。
from libreyolo import LibreYOLO model = LibreYOLO("LibreRTDETRr18.pt") # coco128.yaml 会在首次使用时下载一份 128 张图片的样本;真正要# 跑的时候,把 `data` 指向你自己的数据集 YAMLmodel.train(data="coco128.yaml", epochs=50, batch=4, lr0=1e-4)libreyolo train model=LibreRTDETRr18.pt data=coco128.yaml \ epochs=50 batch=4 lr0=1e-4# 需要 lora extra:pip install "libreyolo[lora]"from libreyolo import LibreYOLO model = LibreYOLO("LibreRTDETRr18.pt")model.train(data="coco128.yaml", epochs=50, lora=True)libreyolo train model=LibreRTDETRr18.pt data=coco128.yaml \ epochs=50 device=0,1学习率是那个必须调对的参数,而且每个版本带的是自己的默认值,不是库级别的那个。
Python 的 train() 签名从该版本的训练配置里读它,不传 lr0 时 CLI 解析出来的
也是同一个值。版本 1 和版本 2 还接受 lr_backbone,并按原始配方把它默认设为
lr0 的二十分之一;版本 4 走的是 D-FINE 的训练器,它改用 backbone_lr_mult 来
缩放骨干的参数组。
除非你有理由改,否则把 imgsz 保持在检查点的原生尺寸上。在其他尺寸下验证和预测
都能工作,但残留一个问题:一个 token 数和原生尺寸相同的矩形尺寸,仍然会复用一个
按错误宽高比构建的嵌入向量。
数据集、数据增强、多卡训练和日志记录器见训练。
验证
val() 返回一个由 metrics/ 键组成的字典,涵盖查准率、查全率、mAP 50 和
mAP 50-95,在任何采用你训练时那种格式的数据集上测量。
from libreyolo import LibreYOLO model = LibreYOLO("LibreRTDETRr18.pt") # val() 返回的是普通 dict,不是对象metrics = model.val(data="coco128.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])print(metrics["metrics/precision"], metrics["metrics/recall"])libreyolo val model=LibreRTDETRr18.pt data=coco128.yaml# coco-val-only.yaml 会取回 5000 张 val2017 图片并跳过训练集;# 它带着一个内嵌的下载脚本,所以除非数据集已经在本地,否则# 需要显式放行libreyolo val model=LibreRTDETRr18.pt data=coco-val-only.yaml \ allow_download_scripts=Truefrom libreyolo import LibreYOLO # 旋转验证用旋转 IoU 来匹配,所以一个位置对、角度错的预测算# 漏检model = LibreYOLO("LibreRTDETRv2n-obb.pt")metrics = model.val(data="my-obb-dataset.yaml") print(metrics["metrics/mAP50-95(OBB)"])print(metrics["metrics/mAP50(OBB)"])上面基准测试表格里的那些行来自 LibreYOLO 的基准测试框架;表格下方的说明记录了 它们出自哪个数据集,并链接到运行记录。
旋转验证走的是同一个调用,报告的键也一样,另外还有四个带 (OBB) 后缀的重复项。
匹配用的是旋转 IoU,而不是外接矩形的 IoU,所以角度错了就算漏检。这个任务上
augment=True 会被拒绝。
导出
| 任务 | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Detection | Detection to ONNX:支持 | Detection to TorchScript:支持 | Detection to ExecuTorch:支持 | Detection to TensorRT:支持 | Detection to OpenVINO:支持 | Detection to Paddle:不支持 | Detection to MNN:支持 | Detection to RKNN:不支持 | Detection to ncnn:不支持 | Detection to TFLite:不支持 | Detection to CoreML:不支持 | Detection to Core AI:支持 |
| Oriented boxes | Oriented boxes to ONNX:支持 | Oriented boxes to TorchScript:支持 | Oriented boxes to ExecuTorch:支持 | Oriented boxes to TensorRT:支持 | Oriented boxes to OpenVINO:支持 | Oriented boxes to Paddle:不支持 | Oriented boxes to MNN:不支持 | Oriented boxes to RKNN:不支持 | Oriented boxes to ncnn:不支持 | Oriented boxes to TFLite:不支持 | Oriented boxes to CoreML:不支持 | Oriented boxes to Core AI:不支持 |
这张矩阵把整条谱系当成一页来覆盖:三个版本对某种格式意见不一致时,单元格显示的是 三者中最弱的那个,所以不管你加载的是哪个版本,这里都没有把话说满。旋转那一行只 属于版本 2。ONNX 和 TorchScript 在那里通过了验证,FP32、批大小 1、固定的 1024 乘 1024 画布;OpenVINO、TensorRT 和 ExecuTorch 能转换也能重新加载,但还没有在整个 query 集合上达到原始输出的一致,所以靠前的检测框能对到不到一个像素,尾部则会漂移。
导出的产物按文件后缀经由 LibreYOLO() 重新加载,所以一个 .onnx 或 .engine
文件的表现和检查点一样,返回同样的 Results。
# 需要 onnx extra:pip install "libreyolo[onnx]"from libreyolo import LibreYOLO model = LibreYOLO("LibreRTDETRr18.pt")path = model.export(format="onnx")print(path)libreyolo export model=LibreRTDETRr18.pt format=onnx# ONNX 和 TorchScript 是旋转任务上已验证的导出目标,FP32、# 批大小 1、固定的 1024 乘 1024 画布libreyolo export model=LibreRTDETRv2n-obb.pt format=onnx imgsz=1024libreyolo export model=LibreRTDETRv2n-obb.pt format=torchscript imgsz=1024from libreyolo import LibreYOLO, SAMPLE_IMAGE # 工厂按文件后缀分发,所以导出的产物加载方式和任何检查点一样,# 返回的也是同一个 Results 对象model = LibreYOLO("LibreRTDETRr18.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)检查点
这个家族已发布的全部权重文件。
| 文件 | 输入(px) | 权重许可 |
|---|---|---|
| Detection | ||
| LibreRTDETRr34.pt | 640 | apache-2.0 |
| LibreRTDETRr18.pt | 640 | apache-2.0 |
| LibreRTDETRr50.pt | 640 | apache-2.0 |
| LibreRTDETRr50m.pt | 640 | apache-2.0 |
| LibreRTDETRr101.pt | 640 | apache-2.0 |
| LibreRTDETRl.pt | 640 | apache-2.0 |
| LibreRTDETRx.pt | 640 | apache-2.0 |
| LibreRTDETRv2r18.pt | 640 | apache-2.0 |
| LibreRTDETRv2r34.pt | 640 | apache-2.0 |
| LibreRTDETRv2r50m.pt | 640 | apache-2.0 |
| LibreRTDETRv2r50.pt | 640 | apache-2.0 |
| LibreRTDETRv2r101.pt | 640 | apache-2.0 |
| LibreRTDETRv4s.pt | 640 | apache-2.0 |
| LibreRTDETRv4m.pt | 640 | apache-2.0 |
| LibreRTDETRv4l.pt | 640 | apache-2.0 |
| LibreRTDETRv4x.pt | 640 | apache-2.0 |
| Oriented boxes | ||
| LibreRTDETRv2n-obb.pt | 1024 | apache-2.0 |
| LibreRTDETRv2s-obb.pt | 1024 | apache-2.0 |
| LibreRTDETRv2m-obb.pt | 1024 | apache-2.0 |
| LibreRTDETRv2l-obb.pt | 1024 | apache-2.0 |
| LibreRTDETRv2x-obb.pt | 1024 | apache-2.0 |
上面的每个文件目前都在 LibreYOLO 组织中,并会在首次使用时下载。
文件名里先是版本,然后是尺寸,再是任务。检测权重是 LibreRTDETR<size>.pt、
LibreRTDETRv2<size>.pt 和 LibreRTDETRv4<size>.pt,全都在 640 px 下。旋转权重
只有版本 2 才有,并加上任务后缀,从 LibreRTDETRv2n-obb.pt 到
LibreRTDETRv2x-obb.pt,全都在 1024 px 下,训练用的是 DOTA v1.0 而不是 COCO。
许可证
请检查你所下载的具体权重在 Hugging Face 仓库中的许可。LibreYOLO 组织里的每个检查点都附有许可,同一家族内也不一定相同。该仓库是权威来源;以下摘要说明本页上次验证时适用的情况。
这里只说明涉及的许可证,不构成法律意见。如果答案对商用很重要,请自行阅读许可证并咨询法律顾问。
- 原始工作
- RT-DETR, RT-DETRv2 and RT-DETRv4, Baidu (versions 1 and 2), Peking University and Tsinghua University (version 4)
- 上游许可
- Apache-2.0
- LibreYOLO 代码
- MIT
- 权重
- 采用 Apache-2.0 许可,重新发布在 huggingface.co/LibreYOLO
- 解读
- Apache-2.0 is a permissive license, so these weights can be used in commercial and closed-source products. It asks you to keep its license text and attribution notices with any copy of the weights you redistribute, and it grants a patent license. It places no obligation on your own application code, and weights you train yourself on your own data are yours. All three versions carry it, across two repositories and three papers: RT-DETR and RT-DETRv2 at github.com/lyuwenyu/RT-DETR, and RT-DETRv4 at github.com/RT-DETRs/RT-DETRv4, which is cited separately (arXiv 2510.25257). RT-DETRv4 distills from a DINOv3 teacher while training only; the released student weights hold no DINOv3 parameters, and the tensors that fed the teacher are dropped when a checkpoint is converted, so Meta's DINOv3 license does not reach them.
引用
@misc{lv2023detrs,
title={DETRs Beat YOLOs on Real-time Object Detection},
author={Yian Zhao and Wenyu Lv and Shangliang Xu and Jinman Wei and Guanzhong Wang and Qingqing Dang and Yi Liu and Jie Chen},
year={2023},
eprint={2304.08069},
archivePrefix={arXiv},
primaryClass={cs.CV}
}
@misc{lv2024rtdetrv2improvedbaselinebagoffreebies,
title={RT-DETRv2: Improved Baseline with Bag-of-Freebies for Real-Time Detection Transformer},
author={Wenyu Lv and Yian Zhao and Qinyao Chang and Kui Huang and Guanzhong Wang and Yi Liu},
year={2024},
eprint={2407.17140},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2407.17140},
}复制自作者在 github.com/lyuwenyu/RT-DETR#citation 上提供的引用块。
上面这段是作者为版本 1 和版本 2 的检测发布的内容。版本 2 的旋转权重还有第三个 上游,即采用 Apache-2.0 许可的 RiO-DETR 仓库 github.com/RicePasteM/RiO-DETR,DOTA 检查点就来自那里;如果你用了其中之一,请引用那个项目。版本 4 是 另一组人写的另一篇论文,有自己的引用区块,见 github.com/RT-DETRs/RT-DETRv4; 如果你用的是版本 4 的检查点,请引用那一个。