RF-DETR
Трансформер для детекции, который предсказывает фиксированный набор объектов вместо плотной сетки, поэтому на инференсе ему не нужен NMS. LibreYOLO поддерживает его для четырёх задач.
- Задачи
- detection, instance segmentation, pose, oriented boxes
- Размеры
- n, s, m, l for detection and oriented boxes; n through xx for segmentation; x for pose
- Установка
pip install "libreyolo[rfdetr]"- Уровень поддержки
- Флагманский, начиная с v1.0.0. Здесь функции проектируются и первыми проходят полную проверку на GPU.
- Исходный проект
- RF-DETR от Roboflow, Apache-2.0. Статья, исходный код
- Лицензии
- Код: MIT, веса: Apache-2.0. Коммерческое использование
Установка
RF-DETR требует собственного extra, который подтягивает transformers для бэкбона.
pip install "libreyolo[rfdetr]"Без неё загрузка чекпойнта или имени модели RF-DETR, из Python или CLI, останавливается с ошибкой, в которой указана эта строка установки.
Предсказание
Веса скачиваются с Hugging Face при первом запуске и кэшируются локально.
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreRFDETRs.pt")result = model(SAMPLE_IMAGE, save=True) for box in result.boxes: print(box.cls, box.conf, box.xyxy)libreyolo predict model=LibreRFDETRs.pt source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg save=Truefrom libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs.pt") # Любой источник, который принимает библиотека: файл, папка, URL,# индекс веб-камеры, RTSP-поток или список .streamsfor result in model.predict("clip.mp4", stream=True, save=True): print(len(result.boxes))Возвращаемый объект Results — тот же, что возвращает любое семейство, поэтому
замена на другой детектор занимает одну строку. conf и max_det фильтруют
отбор запросов; шага NMS, который надо было бы настраивать, здесь нет. Про
источники, стриминг и обработку результатов см. предсказание.
Для детекции, сегментации и повёрнутых рамок используется билинейное изменение размера OpenCV с плавающей точкой без сглаживания; оценка позы сохраняет сглаживание. Прямоугольный imgsz=(height, width) должен соответствовать сетке патчей/окон задачи. В список чекпойнтов входит детектор элементов интерфейса. Гистограммы событий используют записанный профиль входа.
Варианты
Четыре размера для детекции, от n до l, и четыре задачи на одной архитектуре:
сегментация, оценка позы и повёрнутые рамки переиспользуют декодер детекции с
другой головой, поэтому принимают те же аргументы. Сегментация добавляет x и
xx, а оценка позы есть только в размере x. По числу параметров размеры близки и различаются в
основном входным разрешением.
| Чекпойнт | Вход (пикс.) | mAP 50-95 | Параметры (млн) |
|---|---|---|---|
| LibreRFDETRn | 384 | 51.4 | 30.47 |
| LibreRFDETRs | 512 | 55.2 | 32.11 |
| LibreRFDETRm | 576 | 57.4 | 33.69 |
| LibreRFDETRl | 704 | 58.6 | 33.93 |
COCO val2017, 500 images. Измерено системой бенчмарков LibreYOLO и опубликовано на Vision Analysis, где сравниваются задержки на разном оборудовании и в разных средах выполнения и хранятся полные записи запусков.
Обучение
Обучение начинается с опубликованного чекпойнта — для всех четырёх задач.
pretrained=False вместо этого заново инициализирует всю сеть, включая бэкбон,
и обучает её с нуля.
from libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs.pt")model.train(data="my-dataset.yaml", epochs=50, imgsz=512, batch=8, lr0=1e-4)libreyolo train model=LibreRFDETRs.pt data=my-dataset.yaml \ epochs=50 imgsz=512 batch=8 lr0=1e-4from libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs.pt")model.train(data="my-dataset.yaml", epochs=50, lora=True)libreyolo train model=LibreRFDETRs.pt data=my-dataset.yaml \ epochs=50 device=0,1 batch=-1Здесь два аргумента важнее, чем в CNN-детекторе. Держите lr0 на 1e-4 или
ниже: трансформерные детекторы расходятся при той скорости обучения, которую
модель YOLO переносит спокойно. Оставьте imgsz на родном разрешении
чекпойнта, если нет причины его менять. Вход должен нацело делиться на размер
патча бэкбона, умноженный на число окон; LibreYOLO проверяет это до старта
запуска и называет ближайшие допустимые размеры.
Дообучение сегментации стартует с чекпойнта сегментации, потому что у RF-DETR
нет переноса с детекции на сегментацию. libreyolo train model=LibreRFDETRn-seg.pt task=segment
загружает этот чекпойнт, а чекпойнт детекции с task=segment останавливается
с ошибкой.
Про датасеты, аугментацию, multi-GPU и логгеры см. обучение.
Новые запуски по умолчанию используют output_dir=None, который разрешается в runs/train/rfdetr_exp с увеличиваемым номером и exist_ok=False. Возобновлённый запуск продолжает писать в каталог запуска своего чекпойнта. Датасеты позы с несколькими классами используют kpt_names с индексом или именем класса в ключах; пустой список обозначает класс только с рамками. Предсказания дополняют ключевые точки до kpt_shape; fitness по mAP ключевых точек не оценивает классы только с рамками.
Валидация
val() возвращает словарь с ключами metrics/, покрывающими mAP 50, mAP 50-95,
mAP 75 и среднюю полноту COCO, измеренные на любом датасете в том формате, на котором вы
обучались.
from libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs.pt") # val() возвращает обычный dict, а не объектmetrics = model.val(data="my-dataset.yaml", imgsz=512) print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])print(metrics["metrics/mAP75"], metrics["metrics/AR100"])libreyolo val model=LibreRFDETRs.pt data=my-dataset.yaml imgsz=512# Во встроенный yaml для COCO зашит скрипт скачивания, поэтому нужно# явное разрешение, если датасет ещё не лежит локально.libreyolo val model=LibreRFDETRn.pt data=coco.yaml imgsz=384 \ allow_download_scripts=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: поддерживается. Runtime parity coverage lives in tests/e2e/test_tensorrt.py. | Detection to OpenVINO: поддерживается. Runtime parity coverage lives in tests/e2e/test_openvino.py. | Detection to Paddle: не поддерживается | Detection to MNN: поддерживается | Detection to RKNN: не поддерживается | Detection to ncnn: не поддерживается | Detection to TFLite: не поддерживается | Detection to CoreML: поддерживается. Conversion is available, but runtime parity requires a macOS runner. | Detection to Core AI: поддерживается |
| Instance segmentation | Instance segmentation to ONNX: поддерживается | Instance segmentation to TorchScript: поддерживается | Instance segmentation to ExecuTorch: поддерживается | Instance segmentation to TensorRT: поддерживается. A published Apache-2.0 trained segmentation checkpoint exports and reloads, but public top-k class membership changes. | Instance segmentation to OpenVINO: поддерживается. After Hungarian query alignment, the converted-runtime element match rate is 69.0%, below the validation bar. | Instance segmentation to Paddle: не поддерживается | Instance segmentation to MNN: не поддерживается | Instance segmentation to RKNN: не поддерживается | Instance segmentation to ncnn: не поддерживается | Instance segmentation to TFLite: не поддерживается | Instance segmentation to CoreML: не поддерживается | Instance segmentation to Core AI: не поддерживается |
| Pose | Pose to ONNX: поддерживается | Pose to TorchScript: поддерживается | Pose to ExecuTorch: поддерживается | Pose to TensorRT: поддерживается. A published Apache-2.0 trained pose checkpoint exports and reloads, but matched public boxes fall to 0.704 IoU with 41.4-pixel coordinate drift. | Pose to OpenVINO: поддерживается. After Hungarian query alignment, the converted-runtime element match rate is 72.75%, below the validation bar. | Pose to Paddle: не поддерживается | Pose to MNN: не поддерживается | Pose to RKNN: не поддерживается | Pose to ncnn: не поддерживается | Pose to TFLite: не поддерживается | Pose to CoreML: не поддерживается | Pose to Core AI: не поддерживается |
| Oriented boxes | Oriented boxes to ONNX: поддерживается | Oriented boxes to TorchScript: поддерживается | Oriented boxes to ExecuTorch: поддерживается | Oriented boxes to TensorRT: поддерживается. A deterministic synthetic OBB fixture exports and reloads, but public top-k class membership changes. | Oriented boxes to OpenVINO: поддерживается. After Hungarian query alignment, the converted-runtime element match rate is 91.25%, below the validation bar. | 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: не поддерживается |
Экспортированный артефакт загружается обратно через LibreYOLO() по расширению
файла, поэтому файл .onnx или .engine ведёт себя как чекпойнт и возвращает
тот же Results. Запуск графа в голой среде выполнения, без установленного
LibreYOLO, тоже поддерживается, но тогда предобработку и постобработку придётся
писать самостоятельно.
from libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs.pt")model.export(format="onnx", imgsz=512)model.export(format="tensorrt", imgsz=512, half=True) # Аргументы, которые принимает любой формат:## format "onnx" | "torchscript" | "executorch" | "tensorrt"# | "openvino" | "paddle" | "mnn" | "rknn" | "ncnn"# | "tflite" | "coreml" | "coreai".# "engine" — псевдоним tensorrt, "litert" — tflite.# imgsz int или (высота, ширина). По умолчанию — родное# разрешение чекпойнта.# batch int, по умолчанию 1.# half bool, экспорт в FP16. По умолчанию False.# int8 bool, экспорт в INT8. По умолчанию False. Нужен `data`.# data путь к YAML датасета, по нему калибруется int8.# fraction float, доля этого калибровочного набора. По умолчанию 1.0.# dynamic bool, динамические оси. По умолчанию True.# simplify bool, упрощение графа ONNX. По умолчанию True.# opset int, opset ONNX. Если не задан, выбирается по семейству.# device str, устройство для трассировки. По умолчанию — устройство# модели.# output_path str, по умолчанию имя, производное от чекпойнта.# verbose bool, по умолчанию False.# allow_download_scripts bool, по умолчанию False. Разрешает# встроенный Python в YAML датасета, который нужно скачать.## Некоторые форматы принимают собственные дополнительные аргументы,# например целевую платформу RKNN. Они описаны на странице каждого# формата.libreyolo export model=LibreRFDETRs.pt format=onnx imgsz=512libreyolo export model=LibreRFDETRs.pt format=tensorrt imgsz=512 half=Truefrom libreyolo import LibreYOLO, SAMPLE_IMAGE # Фабрика выбирает загрузчик по расширению файла, поэтому# экспортированный артефакт загружается как любой чекпойнт и# возвращает тот же объект Results.model = LibreYOLO("LibreRFDETRs.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)import numpy as npimport onnxruntime as ort # Запуск графа напрямую означает, что предобработку и постобработку# придётся писать самому. Прежде чем что-то подключать, посмотрите# на сигнатуру.session = ort.InferenceSession("weights/LibreRFDETRs.onnx")name = session.get_inputs()[0].nameoutputs = session.run(None, {name: np.zeros((1, 3, 512, 512), dtype=np.float32)}) for meta, array in zip(session.get_outputs(), outputs): print(meta.name, array.shape)Входы и выходы ONNX
| Тензор | input float32 [batch, 3, height, width] |
|---|---|
| Цвет | RGB |
| Масштабирование | пиксель / 255 |
| Нормализация | среднее [0.485,0.456,0.406], стандартное отклонение [0.229,0.224,0.225] |
| Изменение размера | custom, bilinear |
The input tensor is named input, not images.
Square input only. Export rejects a non-square imgsz. The default size comes from the checkpoint and is stored in the imgsz metadata key: 384 for LibreRFDETRn, 312 for LibreRFDETRn-seg, 576 for LibreRFDETRx-pose.
A custom imgsz must be a multiple of patch size x windows: 32 for detection and OBB, 12 for segmentation n, 24 for the other segmentation sizes and for pose.
Stretch the whole image to width x height. There is no letterbox and no padding, so the aspect ratio is not kept.
Detection, segmentation and OBB: convert the 8-bit RGB image to float32 and divide by 255 first, then resize the float image with cv2.resize INTER_LINEAR (half-pixel centers, no antialiasing). Resizing the 8-bit image before dividing is close but moves scores by up to about 0.01.
Pose resizes differently: divide by 255 the same way, then resize the float image with antialiased bilinear, as torch.nn.functional.interpolate does with mode bilinear, align_corners False and antialias True. This is the filter of Pillow's BILINEAR, which widens by the shrink factor, but in float with no rounding to 8 bits. Per axis, let s = in_size / out_size and f = max(s, 1). Output pixel i has center c = (i + 0.5) * s. It reads source pixels j from int(c - f + 0.5) to int(c + f + 0.5) - 1, clipped to the image, each with weight max(0, 1 - |j + 0.5 - c| / f). Divide the weights by their sum.
The pose model is sensitive to this. On the test image, cv2.resize INTER_LINEAR or INTER_AREA adds 3 to 9 detections, and Pillow on the 8-bit image adds one and moves keypoints by more than 4 px.
Then subtract the mean and divide by the std per channel.
nms=True is not available for this family: export raises NotImplementedError.
Detection, экспорт по умолчанию
| Выход | Форма | Смысл |
|---|---|---|
dets | [batch, queries, 4] | Boxes as cx, cy, w, h, normalized 0 to 1 of the input. 300 queries. |
labels | [batch, queries, columns] | Raw class logits per query, sigmoid not applied. The COCO checkpoints have 91 columns, where column k is COCO category id k. For other checkpoints column j is class j. |
Постобработка
- Apply sigmoid to labels.
- Flatten the scores of one image to queries x columns and take the top k over all of them, with k equal to queries (300). For flat index i, the query is i // columns and the column is i % columns. One query can yield several classes.
- Keep the entries whose score is strictly above the confidence threshold (0.25 by default). There is no NMS.
- When labels has 91 columns and nc is 80 (the COCO checkpoints), the column is a COCO category id. Class i is the i-th id, counting from 0, in this list: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90. Drop entries whose id is not in the list. With any other column count the column is the class.
- Convert the query's box to x1 = cx - w / 2, y1 = cy - h / 2, x2 = cx + w / 2, y2 = cy + h / 2.
- Map boxes back to the original image: multiply x by the original width and y by the original height. The input was stretched, so no pad offset applies. LibreYOLO does not clip these boxes.
Instance segmentation, экспорт по умолчанию
| Выход | Форма | Смысл |
|---|---|---|
dets | [batch, queries, 4] | Boxes as cx, cy, w, h, normalized 0 to 1 of the input. 100 queries for sizes n and s, 200 for m and l, 300 for x and xx. |
labels | [batch, queries, columns] | Raw class logits per query, sigmoid not applied. 91 columns for the COCO checkpoints, where column k is COCO category id k. |
masks | [batch, queries, mask_h, mask_w] | Raw mask logits per query over the whole input, at a quarter of the input size: 78 x 78 at 312 x 312. |
Постобработка
- Select, threshold, map classes and decode boxes exactly as for detection, with k equal to queries.
- Take the mask of each kept query and resize the logits straight to the original image size with bilinear, half-pixel centers and no antialiasing (cv2.resize INTER_LINEAR on the float logits gives the same).
- A pixel is foreground when its resized logit is above 0.
Pose, экспорт по умолчанию
| Выход | Форма | Смысл |
|---|---|---|
dets | [batch, queries, 4] | Boxes as cx, cy, w, h, normalized 0 to 1 of the input. 100 queries. |
labels | [batch, queries, columns] | Raw class logits per query, sigmoid not applied, with the keypoint class term already added inside the graph. Column 0 is an empty slot and column j + 1 is class j, so the person checkpoint has 2 columns. |
keypoints | [batch, queries, columns * num_keypoints, 8] | One block of num_keypoints rows per label column, 2 x 17 = 34 rows here. Each row is x, y normalized 0 to 1 of the input, findable logit, visible logit, log_l11, l21, log_l22 and a class logit term. The num_keypoints_per_class metadata key ([0, 17]) says how many rows of each block are real keypoints. |
Постобработка
- Apply sigmoid to labels. Flatten to queries x columns and take the top k over all of them, with k equal to queries (100). For flat index i, the query is i // columns and the column is i % columns.
- For each entry take its column's keypoint block: rows column * num_keypoints onward, of which the first num_keypoints_per_class[column] are used.
- Rescore each entry whose column has keypoints. Per used keypoint, with a = log_l11, b = l21, d = log_l22 and p = sigmoid(findable logit): sigma = exp(-2a) + exp(-2d) + b^2 * exp(-2a - 2d). Then trace = log(sum of p * sigma / sum of p) over the used keypoints, and score = score * exp(-0.2 * trace). Scores can go above 1.
- Drop entries whose column is 0. The class is column - 1.
- Keep the entries whose new score is strictly above the confidence threshold (0.25 by default). There is no NMS.
- Decode and map the box as for detection. LibreYOLO does not clip these boxes.
- Keypoint x is x * original width and keypoint y is y * original height. Keypoint confidence is sigmoid(findable logit). LibreYOLO does not use the visible logit.
Oriented boxes, экспорт по умолчанию
| Выход | Форма | Смысл |
|---|---|---|
dets | [batch, queries, 4] | Rotated boxes as cx, cy, w, h, normalized 0 to 1 of the input. 300 queries. |
labels | [batch, queries, columns] | Raw class logits per query, sigmoid not applied. Column j is class j. The 6-class checkpoint has 7 columns: the last one is not a class and LibreYOLO does not drop it. |
angles | [batch, queries, 1] | Rotation in radians from -pi / 2 to pi / 2, tanh already applied, measured on the square input. The width side points along (cos(angle), sin(angle)) with y pointing down. |
Постобработка
- Select and threshold as for detection, with k equal to queries (300). The column is the class.
- The stretch scales x and y by different amounts, so map each box back through its corners. In normalized input units, with c = cos(angle) and s = sin(angle), the corners are (cx, cy) - u - v, + u - v, + u + v and - u + v, with u = (c * w / 2, s * w / 2) and v = (-s * h / 2, c * h / 2).
- Multiply corner x by the original width and corner y by the original height.
- Fit cv2.minAreaRect to the 4 corners and convert its angle to radians. Raise w and h to at least 1e-4. If h > w, swap them and add pi / 2 to the angle. Then wrap the angle to [-pi / 2, pi / 2) with angle = (angle + pi / 2) mod pi - pi / 2.
- The result is cx, cy, w, h, angle in original-image pixels, with w the long side.
Чтобы проверить собственную реализацию, пропустите тот же файл через LibreYOLO: LibreYOLO("model.onnx").predict("image.jpg") возвращает эталонные результаты. Проверено на LibreYOLO 1.7.0.
Чекпойнты
Все опубликованные файлы весов этого семейства.
| Файл | Вход (пикс.) | Лицензия весов |
|---|---|---|
| Detection | ||
| LibreRFDETRl.pt | 704 | apache-2.0 |
| LibreRFDETRm.pt | 576 | apache-2.0 |
| LibreRFDETRn.pt | 384 | apache-2.0 |
| LibreRFDETRs.pt | 512 | apache-2.0 |
| LibreRFDETRm-ui.pt | mit | |
| Instance segmentation | ||
| LibreRFDETRn-seg.pt | 312 | apache-2.0 |
| LibreRFDETRs-seg.pt | 384 | apache-2.0 |
| LibreRFDETRm-seg.pt | 432 | apache-2.0 |
| LibreRFDETRl-seg.pt | 504 | apache-2.0 |
| LibreRFDETRx-seg.pt | 624 | apache-2.0 |
| LibreRFDETRxx-seg.pt | 768 | apache-2.0 |
| Pose | ||
| LibreRFDETRx-pose.pt | 576 | apache-2.0 |
| Oriented boxes | ||
| LibreRFDETRn-obb.pt | 384 | cc-by-4.0 |
| LibreRFDETRs-obb.pt | 512 | cc-by-4.0 |
| LibreRFDETRm-obb.pt | 576 | cc-by-4.0 |
| LibreRFDETRl-obb.pt | 704 | cc-by-4.0 |
Все перечисленные выше файлы уже доступны в организации LibreYOLO и скачиваются при первом использовании.
Лицензирование
Проверяйте лицензию в репозитории конкретных весов на Hugging Face. Она указана для каждого чекпойнта в организации LibreYOLO и может различаться даже внутри одного семейства. Этот репозиторий считается авторитетным источником, а сводка ниже описывает условия на момент последней проверки страницы.
Это описание соответствующих лицензий, а не юридическая консультация. Если ответ важен для коммерческого использования, прочитайте лицензии самостоятельно и проконсультируйтесь с юристом.
- Оригинальная работа
- RF-DETR, Roboflow
- Лицензия исходного проекта
- Apache-2.0
- Исходный код проекта
- github.com/roboflow/rf-detr
- Код 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.
Цитирование
@inproceedings{robinson2026rfdetr,
title = {RF-DETR: Real-Time Detection Transformer},
author = {Robinson, Isaac and Robicheaux, Peter and Popov, Matvei and Ramanan, Deva and Peri, Neehar},
booktitle = {International Conference on Learning Representations (ICLR)},
year = {2026},
url = {https://arxiv.org/abs/2511.09554}
}Скопировано из блока цитирования авторов на странице github.com/roboflow/rf-detr#citation.