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. Коммерческое использование
LibreRFDETRs, детекция на видео при 512 px.

Установка

RF-DETR требует собственного extra, который подтягивает transformers для бэкбона.

bash
pip install "libreyolo[rfdetr]"

Без неё загрузка чекпойнта или имени модели RF-DETR, из Python или CLI, останавливается с ошибкой, в которой указана эта строка установки.

Предсказание

Веса скачиваются с Hugging Face при первом запуске и кэшируются локально.

Python
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)
CLI
libreyolo predict model=LibreRFDETRs.pt source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg save=True
Видео
from 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Параметры (млн)
LibreRFDETRn38451.430.47
LibreRFDETRs51255.232.11
LibreRFDETRm57657.433.69
LibreRFDETRl70458.633.93

COCO val2017, 500 images. Измерено системой бенчмарков LibreYOLO и опубликовано на Vision Analysis, где сравниваются задержки на разном оборудовании и в разных средах выполнения и хранятся полные записи запусков.

Обучение

Обучение начинается с опубликованного чекпойнта — для всех четырёх задач. pretrained=False вместо этого заново инициализирует всю сеть, включая бэкбон, и обучает её с нуля.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs.pt")model.train(data="my-dataset.yaml", epochs=50, imgsz=512, batch=8, lr0=1e-4)
CLI
libreyolo train model=LibreRFDETRs.pt data=my-dataset.yaml \  epochs=50 imgsz=512 batch=8 lr0=1e-4
LoRA
from libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs.pt")model.train(data="my-dataset.yaml", epochs=50, lora=True)
Multi-GPU
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, измеренные на любом датасете в том формате, на котором вы обучались.

Python
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"])
CLI
libreyolo val model=LibreRFDETRs.pt data=my-dataset.yaml imgsz=512
Валидация на COCO
# Во встроенный yaml для COCO зашит скрипт скачивания, поэтому нужно# явное разрешение, если датасет ещё не лежит локально.libreyolo val model=LibreRFDETRn.pt data=coco.yaml imgsz=384 \  allow_download_scripts=True

Экспорт

ЗадачаONNXTorchScriptExecuTorchTensorRTOpenVINOPaddleMNNRKNNncnnTFLiteCoreMLCore AI
DetectionDetection 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 segmentationInstance 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: не поддерживается
PosePose 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 boxesOriented 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, тоже поддерживается, но тогда предобработку и постобработку придётся писать самостоятельно.

Python
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. Они описаны на странице каждого# формата.
CLI
libreyolo export model=LibreRFDETRs.pt format=onnx imgsz=512libreyolo export model=LibreRFDETRs.pt format=tensorrt imgsz=512 half=True
Использование экспортированного файла
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Фабрика выбирает загрузчик по расширению файла, поэтому# экспортированный артефакт загружается как любой чекпойнт и# возвращает тот же объект Results.model = LibreYOLO("LibreRFDETRs.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)
Без LibreYOLO
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.

Постобработка

  1. Apply sigmoid to labels.
  2. 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.
  3. Keep the entries whose score is strictly above the confidence threshold (0.25 by default). There is no NMS.
  4. 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.
  5. Convert the query's box to x1 = cx - w / 2, y1 = cy - h / 2, x2 = cx + w / 2, y2 = cy + h / 2.
  6. 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.

Постобработка

  1. Select, threshold, map classes and decode boxes exactly as for detection, with k equal to queries.
  2. 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).
  3. 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.

Постобработка

  1. 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.
  2. 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.
  3. 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.
  4. Drop entries whose column is 0. The class is column - 1.
  5. Keep the entries whose new score is strictly above the confidence threshold (0.25 by default). There is no NMS.
  6. Decode and map the box as for detection. LibreYOLO does not clip these boxes.
  7. 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.

Постобработка

  1. Select and threshold as for detection, with k equal to queries (300). The column is the class.
  2. 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).
  3. Multiply corner x by the original width and corner y by the original height.
  4. 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.
  5. 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.pt704apache-2.0
LibreRFDETRm.pt576apache-2.0
LibreRFDETRn.pt384apache-2.0
LibreRFDETRs.pt512apache-2.0
LibreRFDETRm-ui.ptmit
Instance segmentation
LibreRFDETRn-seg.pt312apache-2.0
LibreRFDETRs-seg.pt384apache-2.0
LibreRFDETRm-seg.pt432apache-2.0
LibreRFDETRl-seg.pt504apache-2.0
LibreRFDETRx-seg.pt624apache-2.0
LibreRFDETRxx-seg.pt768apache-2.0
Pose
LibreRFDETRx-pose.pt576apache-2.0
Oriented boxes
LibreRFDETRn-obb.pt384cc-by-4.0
LibreRFDETRs-obb.pt512cc-by-4.0
LibreRFDETRm-obb.pt576cc-by-4.0
LibreRFDETRl-obb.pt704cc-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.

Проверено с LibreYOLO v1.6.0. Таблицы поддержки, чекпойнты и результаты бенчмарков на этой странице сгенерированы из выпущенной библиотеки и опубликованных весов, а не написаны вручную.