RT-DETR Without Ultralytics: v1, v2 and v4 Under Apache-2.0
RT-DETR is a real-time detection transformer from Baidu. It decodes a fixed set of queries instead of a dense grid, so there is no NMS step to tune. Search for it and one of the first implementations you find is the one inside the ultralytics Python package. That raises a license question the model itself never had.
The RT-DETR license depends on the repository
The license belongs to a repository, not to a model. RT-DETR has several, and they do not agree:
| Repository | Covers | License |
|---|---|---|
| lyuwenyu/RT-DETR | RT-DETR and RT-DETRv2, PyTorch and Paddle | Apache-2.0 |
| RT-DETRs/RT-DETRv4 | RT-DETRv4 | Apache-2.0 |
| ultralytics/ultralytics | RT-DETR inside the ultralytics package | AGPL-3.0 or Enterprise License |
| LibreYOLO | RT-DETR, RT-DETRv2 and RT-DETRv4 | MIT code, Apache-2.0 weights |
The Ultralytics implementation is a solid one. Its RT-DETR page lists pretrained rtdetr-l.pt and rtdetr-x.pt with training, validation, inference and export. It ships inside a package licensed AGPL-3.0, and Ultralytics sells an Enterprise License for teams that do not want to open-source their whole project. If neither fits, the architecture is available under Apache-2.0 from its own authors. The YOLO licenses explainer covers the same pattern across the YOLO family, and the commercial license guide explains what AGPL-3.0 means for a closed-source product.
Run RT-DETR with LibreYOLO
pip install libreyolo
from libreyolo import LibreYOLO, SAMPLE_IMAGE
model = LibreYOLO("LibreRTDETRr18.pt") # downloads from Hugging Face on first use
result = model(SAMPLE_IMAGE, save=True)
for box in result.boxes:
print(box.cls, box.conf, box.xyxy)
The same call works from the command line:
libreyolo predict model=LibreRTDETRr18.pt source=image.jpg save=True
conf and max_det filter a top-k decode over queries and classes. iou is accepted but unused, because there is no NMS. The returned Results object is the one every LibreYOLO model returns, so swapping detectors is a one-line change.
RT-DETR, RT-DETRv2 and RT-DETRv4 in one loader
The version is part of the file name, and LibreYOLO() routes on the checkpoint, so all three load the same way:
- RT-DETR:
LibreRTDETRin r18, r34, r50, r50m, r101 (ResNet backbones) and l, x (HGNetv2). - RT-DETRv2:
LibreRTDETRv2in r18, r34, r50, r50m and r101. It keeps version 1's architecture and changes how deformable attention samples. - RT-DETRv4:
LibreRTDETRv4in s, m, l and x. It reuses D-FINE's architecture, and its weights come from distilling a DINOv3 teacher into an HGNetv2 student.
All detection weights are trained on COCO and run at 640 px. For reference, the upstream READMEs report 46.5 AP for RT-DETR-R18 and 53.0 AP for RT-DETR-L on COCO, and 49.8 AP for RT-DETRv4-S up to 57.0 AP for RT-DETRv4-X. The RT-DETR docs page has LibreYOLO's own benchmark table for every checkpoint.
RT-DETRv2 also does oriented boxes. LibreRTDETRv2n-obb.pt through LibreRTDETRv2x-obb.pt are the official DOTA v1.0 checkpoints, 15 aerial classes at 1024 px, converted to LibreYOLO's format:
from libreyolo import LibreYOLO
model = LibreYOLO("LibreRTDETRv2n-obb.pt")
result = model("aerial.png", save=True)
print(result.obb.xywhr) # (N, 5): cx, cy, w, h, radians
Oriented detection covers the label format and metrics.
Fine-tune RT-DETR on your own data
Training starts from a published checkpoint:
from libreyolo import LibreYOLO
model = LibreYOLO("LibreRTDETRr18.pt")
model.train(data="coco128.yaml", epochs=50, batch=4, lr0=1e-4)
Point data at your own dataset YAML for a real run. Each version carries its own learning rate default, and versions 1 and 2 set the backbone rate to a twentieth of lr0, following the original recipe. Multi-GPU is device=0,1 on the CLI, and LoRA adapter fine-tuning is lora=True with the lora extra installed. The oriented models on RT-DETRv2 are inference only. See training for datasets, augmentation and loggers.
Validate and export
metrics = model.val(data="coco128.yaml")
print(metrics["metrics/mAP50-95"])
path = model.export(format="onnx") # needs: pip install "libreyolo[onnx]"
val() returns a plain dictionary. Export targets include ONNX, TorchScript, ExecuTorch, TensorRT and OpenVINO; the export matrix on the model page shows which are validated for each task. An exported .onnx or .engine file loads back through LibreYOLO() and returns the same Results. See export for the per-format guides.
Where the original repos are still the right choice
If you need to reproduce a paper result with the authors' exact configs, want the Paddle version, or want to run RT-DETRv4's DINOv3 teacher distillation yourself, use the upstream repositories. LibreYOLO fine-tunes the released v4 student; it does not run the teacher. And if your project is already AGPL-3.0 or covered by an Ultralytics Enterprise License, there is no license reason to move.
A note on the license
LibreYOLO's code is MIT. Every RT-DETR weight file is Apache-2.0, and each Hugging Face weight repo ships the upstream LICENSE and NOTICE, which Apache-2.0 asks you to keep when you redistribute the weights. Weights you train on your own data are yours. RT-DETRv4 uses DINOv3 only as a training-time teacher, and the released students hold no DINOv3 parameters. This is general information, not legal advice. Check the current LICENSE files before you ship.
Try it
pip install libreyolo
from libreyolo import LibreYOLO
model = LibreYOLO("LibreRTDETRv4s.pt")
result = model("image.jpg", save=True)
print(result.boxes.xyxy)
LibreYOLO is MIT-licensed, runs on Linux, Mac and Windows, and works on GPU, Apple Silicon and plain CPU with no code change.