RF-DETR
Un transformer de detección que predice un conjunto fijo de objetos en lugar de una rejilla densa, por lo que no necesita NMS en inferencia. LibreYOLO lo soporta para cuatro tareas.
- Tareas
- detection, instance segmentation, pose, oriented boxes
- Tamaños
- n, s, m, l for detection and oriented boxes; n through xx for segmentation; x for pose
- Instalación
pip install "libreyolo[rfdetr]"- Nivel de compatibilidad
- Emblemático, desde v1.0.0. Las funciones se diseñan y validan por completo en GPU primero aquí.
- Licencias
- Código MIT, pesos Apache-2.0. Uso comercial
Instalación
RF-DETR necesita su propio extra, que instala transformers para el backbone.
pip install "libreyolo[rfdetr]"Sin él, cargar un checkpoint o un nombre de modelo RF-DETR, desde Python o el CLI, se detiene con un error que indica esta línea de instalación.
Predicción
Los pesos se descargan de Hugging Face en el primer uso y se guardan en la caché local.
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") # Cualquier fuente que acepta la biblioteca: archivo, carpeta, URL,# índice de webcam, stream RTSP o una lista .streamsfor result in model.predict("clip.mp4", stream=True, save=True): print(len(result.boxes))El objeto Results devuelto es el mismo que devuelven todas las familias, así
que cambiar a otro detector es un cambio de una línea. conf y max_det
filtran la selección de queries; no hay un paso de NMS que ajustar. Consulta
predicción para fuentes, streaming y manejo de resultados.
Las rutas de detección, segmentación y cajas orientadas usan redimensionado bilineal de OpenCV en coma flotante sin antialiasing; pose conserva el redimensionado con antialiasing. Un imgsz=(height, width) rectangular debe respetar la cuadrícula de patches y ventanas de la tarea. El inventario de checkpoints incluye el detector de interfaces de usuario. Los histogramas de eventos usan el perfil de entrada registrado.
Variantes
Cuatro tamaños de detección, de n a l, y cuatro tareas que comparten una
misma arquitectura: la segmentación, la pose y las cajas orientadas reutilizan
el decoder de detección con una cabeza distinta, así que aceptan los mismos
argumentos. La segmentación añade x y xx, y la pose solo existe en x. Los
tamaños tienen un número de parámetros similar y se diferencian sobre todo en la
resolución de entrada.
| Checkpoint | Entrada (px) | mAP 50-95 | Parámetros (M) |
|---|---|---|---|
| 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. Medido con el sistema de benchmarks de LibreYOLO y publicado en Vision Analysis, donde se comparan la latencia entre distintos hardwares y runtimes y se conservan los registros completos de las ejecuciones.
Entrenamiento
El entrenamiento parte de un checkpoint publicado, para las cuatro tareas.
pretrained=False, en cambio, reinicializa toda la red, backbone incluido, y
entrena desde cero.
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=-1Dos argumentos importan aquí más que en un detector CNN. Mantén lr0 en 1e-4
o por debajo, porque los detectores transformer divergen con learning rates que
un modelo YOLO tolera. Deja imgsz en la resolución nativa del checkpoint salvo
que tengas un motivo para cambiarla. La entrada debe ser divisible exactamente
por el tamaño de patch del backbone multiplicado por el número de ventanas;
LibreYOLO lo comprueba antes de empezar la ejecución e indica los tamaños
válidos más cercanos.
El fine-tuning de segmentación parte de un checkpoint de segmentación, porque
RF-DETR no tiene transferencia de detección a segmentación.
libreyolo train model=LibreRFDETRn-seg.pt task=segment carga ese checkpoint, y
un checkpoint de detección con task=segment se detiene con un error.
Consulta entrenamiento para datasets, aumento de datos (data augmentation), multi-GPU y loggers.
Las ejecuciones nuevas usan output_dir=None por defecto, que se resuelve a un directorio runs/train/rfdetr_exp incrementado con exist_ok=False. Una ejecución reanudada sigue escribiendo en el directorio de ejecución de su checkpoint. Los datasets de pose multiclase usan kpt_names indexado por índice o nombre de clase; una lista vacía indica una clase solo con cajas. Las predicciones rellenan los keypoints hasta kpt_shape; el criterio de selección por mAP de keypoints no puntúa las clases solo con cajas.
Validación
val() devuelve un diccionario de claves metrics/ que cubren mAP 50,
mAP 50-95, mAP 75 y el recall promedio de COCO, medidas contra cualquier dataset
en el formato con el que entrenaste.
from libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs.pt") # val() devuelve un dict plano, no un objetometrics = 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# El yaml de COCO incluido lleva un script de descarga embebido, así# que necesita permiso explícito salvo que el dataset ya esté en local.libreyolo val model=LibreRFDETRn.pt data=coco.yaml imgsz=384 \ allow_download_scripts=TrueExportación
| Tarea | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Detection | Detection to ONNX: compatible | Detection to TorchScript: compatible | Detection to ExecuTorch: compatible | Detection to TensorRT: compatible. Runtime parity coverage lives in tests/e2e/test_tensorrt.py. | Detection to OpenVINO: compatible. Runtime parity coverage lives in tests/e2e/test_openvino.py. | Detection to Paddle: no compatible | Detection to MNN: compatible | Detection to RKNN: no compatible | Detection to ncnn: no compatible | Detection to TFLite: no compatible | Detection to CoreML: compatible. Conversion is available, but runtime parity requires a macOS runner. | Detection to Core AI: compatible |
| Instance segmentation | Instance segmentation to ONNX: compatible | Instance segmentation to TorchScript: compatible | Instance segmentation to ExecuTorch: compatible | Instance segmentation to TensorRT: compatible. A published Apache-2.0 trained segmentation checkpoint exports and reloads, but public top-k class membership changes. | Instance segmentation to OpenVINO: compatible. After Hungarian query alignment, the converted-runtime element match rate is 69.0%, below the validation bar. | Instance segmentation to Paddle: no compatible | Instance segmentation to MNN: no compatible | Instance segmentation to RKNN: no compatible | Instance segmentation to ncnn: no compatible | Instance segmentation to TFLite: no compatible | Instance segmentation to CoreML: no compatible | Instance segmentation to Core AI: no compatible |
| Pose | Pose to ONNX: compatible | Pose to TorchScript: compatible | Pose to ExecuTorch: compatible | Pose to TensorRT: compatible. 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: compatible. After Hungarian query alignment, the converted-runtime element match rate is 72.75%, below the validation bar. | Pose to Paddle: no compatible | Pose to MNN: no compatible | Pose to RKNN: no compatible | Pose to ncnn: no compatible | Pose to TFLite: no compatible | Pose to CoreML: no compatible | Pose to Core AI: no compatible |
| Oriented boxes | Oriented boxes to ONNX: compatible | Oriented boxes to TorchScript: compatible | Oriented boxes to ExecuTorch: compatible | Oriented boxes to TensorRT: compatible. A deterministic synthetic OBB fixture exports and reloads, but public top-k class membership changes. | Oriented boxes to OpenVINO: compatible. After Hungarian query alignment, the converted-runtime element match rate is 91.25%, below the validation bar. | Oriented boxes to Paddle: no compatible | Oriented boxes to MNN: no compatible | Oriented boxes to RKNN: no compatible | Oriented boxes to ncnn: no compatible | Oriented boxes to TFLite: no compatible | Oriented boxes to CoreML: no compatible | Oriented boxes to Core AI: no compatible |
Un artefacto exportado se vuelve a cargar con LibreYOLO() según su extensión
de archivo, así que un archivo .onnx o .engine se comporta como un
checkpoint y devuelve el mismo Results. Ejecutar el grafo en un runtime pelado,
sin LibreYOLO instalado, también está soportado, pero entonces el preprocesado y
el postprocesado corren de tu cuenta.
from libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs.pt")model.export(format="onnx", imgsz=512)model.export(format="tensorrt", imgsz=512, half=True) # Argumentos aceptados para todos los formatos:## format "onnx" | "torchscript" | "executorch" | "tensorrt"# | "openvino" | "paddle" | "mnn" | "rknn" | "ncnn"# | "tflite" | "coreml" | "coreai".# "engine" es un alias de tensorrt, "litert" de tflite.# imgsz int, o (alto, ancho). Por defecto, la resolución nativa# del checkpoint.# batch int, por defecto 1.# half bool, exporta en FP16. Por defecto False.# int8 bool, exporta en INT8. Por defecto False. Necesita `data`.# data ruta a un YAML de dataset, usado para calibrar int8.# fraction float, fracción del conjunto de calibración a usar.# Por defecto 1.0.# dynamic bool, ejes dinámicos. Por defecto True.# simplify bool, ejecuta la simplificación del grafo ONNX.# Por defecto True.# opset int, opset de ONNX. Se elige por familia si no se indica.# device str, dispositivo en el que trazar. Por defecto, el del# modelo.# output_path str, por defecto un nombre derivado del checkpoint.# verbose bool, por defecto False.# allow_download_scripts bool, por defecto False. Permite Python# embebido en un YAML de dataset que haya que descargar.## Algunos formatos aceptan argumentos extra propios, como una# plataforma objetivo de RKNN. Están documentados en la página de# cada formato.libreyolo export model=LibreRFDETRs.pt format=onnx imgsz=512libreyolo export model=LibreRFDETRs.pt format=tensorrt imgsz=512 half=Truefrom libreyolo import LibreYOLO, SAMPLE_IMAGE # La factoría enruta según la extensión del archivo, así que un# artefacto exportado se carga como cualquier checkpoint y devuelve# el mismo objeto Results.model = LibreYOLO("LibreRFDETRs.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)import numpy as npimport onnxruntime as ort # Ejecutar el grafo directamente implica hacer tu propio preprocesado# y postprocesado. Inspecciona la firma antes de conectar nada.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)Entradas y salidas ONNX
| Tensor | input float32 [batch, 3, height, width] |
|---|---|
| Color | RGB |
| Escalado | píxel / 255 |
| Normalización | media [0.485,0.456,0.406], desviación típica [0.229,0.224,0.225] |
| Redimensionado | 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, exportación por defecto
| Salida | Forma | Significado |
|---|---|---|
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. |
Posprocesado
- 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, exportación por defecto
| Salida | Forma | Significado |
|---|---|---|
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. |
Posprocesado
- 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, exportación por defecto
| Salida | Forma | Significado |
|---|---|---|
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. |
Posprocesado
- 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, exportación por defecto
| Salida | Forma | Significado |
|---|---|---|
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. |
Posprocesado
- 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.
Para comprobar tu propia implementación, pasa el mismo archivo por LibreYOLO: LibreYOLO("model.onnx").predict("image.jpg") devuelve los resultados de referencia. Verificado con LibreYOLO 1.7.0.
Checkpoints
Todos los archivos de pesos publicados de esta familia.
| Archivo | Entrada (px) | Licencia de los pesos |
|---|---|---|
| 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 |
Todos los archivos anteriores existen hoy en la organización de LibreYOLO y se descargan la primera vez que se usan.
Licencia
Comprueba la licencia en el repositorio de Hugging Face de los pesos concretos que descargues. Cada checkpoint de la organización de LibreYOLO incluye una, y no siempre es la misma en toda una familia. Ese repositorio es la fuente autorizada; el resumen siguiente describe qué se aplicaba cuando se verificó esta página por última vez.
Esta es una descripción de las licencias implicadas, no asesoramiento legal. Si la respuesta es importante a nivel comercial, lee las licencias y busca tu propio asesoramiento.
- Trabajo original
- RF-DETR, Roboflow
- Licencia del proyecto original
- Apache-2.0
- Fuente del proyecto original
- github.com/roboflow/rf-detr
- Código de LibreYOLO
- MIT
- Pesos
- Apache-2.0, republicados en huggingface.co/LibreYOLO
- Interpretación
- 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.
Cita
@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}
}Copiado del bloque de cita de los autores en github.com/roboflow/rf-detr#citation.