Repository navigation
RF-DETR 1.12.0 gives native and exported models one prediction API, adds INT8 exports, and speeds up inference on CUDA and Apple Silicon.
- Predict from images, folders, video files, cameras, and RTSP streams through one RFDETRInference API for native and exported models.
- Export INT8 engines for TensorRT, ONNX, and OpenVINO with
quantization="int8". - Get faster default inference: CUDA graphs on CUDA, inductor on Apple silicon, and batches prepared while the last one runs.
- Set a confidence threshold per class with ClassThresholds.
Eight behavior changes need a look, mostly RFDETR.inference() returning a predictor and stricter Kornia training settings; see the Migration guide. Unknown predict() keywords and TRTInference are deprecated.
✨ Spotlights / highlights
One prediction API for native and exported models
RFDETRInference runs a live model, a native checkpoint or any supported export through the same preprocessing and decoding, and returns Supervision detections. It reads directories, globs, video files, cameras, RTSP and .streams manifests, and stream=True yields results as they arrive. (#1563, #1577)
from rfdetr import RFDETRInference, RFDETRSmall
predictor = RFDETRSmall().inference() # independent, compiled snapshot
detections = predictor.predict("image.jpg")
onnx = RFDETRInference("output/inference_model.onnx")
for result in onnx.predict("video.mp4", stream=True):
...Performance per hardware
RFDETRSmall, batch 1, end to end (preprocessing, forward, postprocessing) through RFDETRInference or the inference() snapshot. Compare within a row, not across machines.
| Hardware | Fastest route | Precision | Latency [ms] | FPS [img/s] |
|---|---|---|---|---|
| NVIDIA L4 | TensorRT .trt engine |
fp16 | 3.57 | 280 |
| Apple M4 Max (40-core GPU) | inference() inductor |
fp16 | 10.3 | 97.4 |
| x86 CPU (Colab, 4 cores / 8 threads) | OpenVINO IR | fp32 | 373.7 | 2.7 |
On the L4 the inference() CUDA graph in fp16 reaches 3.60 ms, level with the engine at batch 1. On the M4 Max inference() inductor in fp16 runs 10.3 ms against 20.0 ms for eager predict(). On x86 the run-to-run spread is 10 to 17% of the mean, so gaps under about 100 ms are noise. Results for NVIDIA T4, A100 and RTX PRO 6000 and for all four model sizes are in the "Measured Performance by Hardware" section of the export docs index; the mobile and edge CPU tables are pending a rerun.
INT8 exports for TensorRT, ONNX and OpenVINO
quantization="int8" with calibration_data builds INT8 TensorRT engines for detection, segmentation and keypoint models, and static INT8 for ONNX and OpenVINO. On an RTX 5070 and a Tesla T4, TensorRT INT8 ran 1.08× to 1.41× faster than FP16 and was 25% to 39% smaller, at a cost of 0.27 to 1.01 AP points at batch 1. (#1595, #1627, #1560)
model.export(format="tensorrt", quantization="int8", calibration_data="path/to/images", batch_size=8)Faster default inference
RFDETR.inference() now captures a CUDA graph on CUDA and compiles with inductor on MPS. CUDA prediction prepares the next batch while the current one runs and decodes baseline JPEG batches with nvjpeg. In one benchmark (L4, RF-DETR Nano, FP16, batch 1), CUDA graph replay cut median end-to-end latency from 9.719 ms to 3.884 ms with identical COCO AP. (#1547, #1668, #1670, #1672)
Per-class confidence thresholds
Name the classes that need their own bar and give the rest a default. (#1635)
from rfdetr import ClassThresholds
detections = model.predict(image, threshold=ClassThresholds({"person": 0.35, "traffic light": 0.6}, default=0.5))Smaller Plus models and a backbone registry
RFDETRAtto, RFDETRFemto and RFDETRPico ship through rfdetr_plus (pip install "rfdetr[plus]", Platform Model License 1.0: commercial use is included when deploying on Roboflow, and commercial self-hosting needs the Enterprise add-on). rfdetr.models.backbone.register_backbone lets an extension package supply a non-DINOv2 encoder. (#1568)
🔄 Migration guide
Each change below failed or behaved differently on 1.11.x with no deprecation shim.
RFDETR.inference() returns a predictor
The return value is now an independent RFDETRInference, and the inplace keyword is rejected. (#1563)
# Before (1.11.x)
model.inference(compile=True, inplace=True)
detections = model.predict(image)
# After (1.12.0)
predictor = model.inference(compile=True)
detections = predictor.predict(image)Each predictor owns a copy of the current base weights; delete it when you no longer need its runtime. The default compile backend now follows the device: a CUDA graph on CUDA, inductor on MPS, TorchScript elsewhere. Pass compile_backend="torchscript" for the previous default.
Kornia training rejects padded batches
Detection and segmentation training with a Kornia-resolved augmentation_backend raises ValueError during setup when square_resize_div_64=False or multi_scale="per-sample". (#1680)
# After: pick one
model.train(..., square_resize_div_64=True, multi_scale="per-batch") # or "off"
model.train(..., augmentation_backend="torchvision") # or "albumentations"Kornia Affine configs
Affine(translate_px=...) is now applied; 1.11.2 ignored it. Combinations Kornia cannot reproduce (rotation, scale, shear, a nonzero fill, reflected borders) raise ValueError when the pipeline is built, so use augmentation_backend="cpu" (Albumentations, rfdetr[augment]) to keep them. (#1607)
An Affine config without rotate no longer rotates images; it used to sample a random ±15° rotation. Set rotate=(-15, 15) to keep the old behavior. The built-in presets are unaffected. (#1679)
Core ML float16 outputs
format="coreml" with coreml_precision="float16" now returns float32 output arrays, because the .mlpackage is converted as an iOS 15 program. Read outputs as float32. coreml_precision="float32" bundles are unchanged. (#1604)
rfdetr[onnx] drops polygraphy and onnx_graphsurgeon
A host that exports to TensorRT or TFLite with rfdetr[onnx] plus a separately installed tensorrt or onnx2tf must install the missing package itself. (#1589)
pip install polygraphy onnx_graphsurgeonSegmentation eval outputs
In eval mode, a segmentation LWDETR no longer returns pred_masks in aux_outputs or enc_outputs. Code that runs SetCriterion on eval-mode outputs must pass all_layer_masks=True; the final pred_masks are unchanged. (#1628)
RFDETR.export(batch_size=...) is validated first
batch_size must be an integer. A bool, 2.0, "2" or None now raises ValueError before the forward pass; a bool used to export batch size 1. (#1556)
Deprecations and removals to act on
- Unknown keyword arguments to
RFDETR.predict()are ignored with aFutureWarningand will raiseTypeErrorin v2.0.0.stream,batch,vid_strideandstream_bufferraiseTypeErrornow; useRFDETRInferencefor them. (#1563, #1577) TRTInferenceandOpenVINOInferenceare deprecated and scheduled for removal in v1.15.0. UseRFDETRInferenceon the exported artifact.OpenVINOInferencenow defaultsinference_precisionto"f32"on every device except NPU; passinference_precision=Noneto restore the device default.- The
rfdetr.datasets.aug_configmodule is removed after deprecation since v1.9.0. Import the presets fromrfdetr.datasets.aug_configs. (#1662)
📝 Notable changes
🚀 Added
- Unified inference — public
RFDETRInference, versioned export metadata (embedded in ONNX,<artifact>.rfdetr.jsonsidecars elsewhere),RFDETR.write_export_metadatafor older exports, andruntime_optionsfor per-format runtime settings. (#1563) - Streaming and expanded inputs —
RFDETRInference.predict()reads videos, directories, globs, CSV and.streamsmanifests, cameras, RTSP and HTTP live sources, YouTube and the screen, withstream,batch,vid_strideandstream_buffer;RFDETR.predict()accepts any iterable of images and a BCHW tensor as one batch. Newrfdetr[stream]extra. (#1577) - Per-class thresholds —
predict(threshold=ClassThresholds(...)). (#1635) - TensorRT — INT8 engines for detection, segmentation and keypoint models with SmoothQuant and MLP bias correction on detection;
trt_metadata=Truewrites an<engine>.jsondescription;trt_hardware_compatibilityandtrt_version_compatiblebuild engines other GPUs or TensorRT releases can load;trt_timing_cachereuses kernel timings;TRTInference(cuda_graph=True)replays the launch from a CUDA graph. (#1595, #1627, #1638, #1642, #1645, #1581, #1580, #1579, #1583) - Static INT8 for ONNX and OpenVINO with
quantization="int8"andcalibration_data. (#1560) - Core ML —
notesand the RF-DETR version stored in.mlpackagemetadata;coreml_neural_engine=Truemoves the model onto the Neural Engine (resampleandcaststill run on the CPU). (#1609, #1586) - Runtime helpers — public
rfdetr.export.inference(TRTInference,load_executorch_method,preprocess_to_nchw,decode_detections,DecodedDetections) andrfdetr.export.benchmark(measure_latency,measure_memory). (#1585) RFDETR.inference(compile_backend="cudagraph")— direct CUDA Graph replay for fixed batch size and resolution. (#1547)- Plus models and backbones —
RFDETRAtto,RFDETRFemto,RFDETRPico;register_backbone;ModelConfig.dim_feedforward;RFDETRModelModule(load_encoder_weights=False). (#1568) - Training — Kornia augmentation for keypoints (#1606);
eval_backend="hotcoco_streaming"(#1590, #1614);build_trainer(extra_callbacks=[...])(#1629). RFDETR.predict(antialias=...)— opt-in antialiased resizing. (#1525)
⚠️ Breaking Changes
- Kornia training — padded batches (
square_resize_div_64=False,multi_scale="per-sample") raiseValueError. Usesquare_resize_div_64=Truewithmulti_scale="per-batch"or"off", oraugmentation_backend="torchvision"or"albumentations". (#1680) RFDETR.inference()— returns an independentRFDETRInference;inplaceis removed. Capture the return value and callpredictor.predict(...); passcompile_backend="torchscript"for the previous default backend. (#1563)- Core ML — float16 bundles return float32 outputs. Read float32, or cast with
astype(np.float16). (#1604) rfdetr[onnx]— no longer installspolygraphyoronnx_graphsurgeon. Runpip install polygraphy onnx_graphsurgeonfor TensorRT or TFLite exports. (#1589)- Kornia
Affine—translate_pxis applied, unsupported combinations raise, and an unsetrotateno longer rotates. Useaugmentation_backend="cpu"for unsupported combinations, and setrotate=(-15, 15)for the old rotation. (#1607, #1679) - Segmentation eval — no
pred_masksin auxiliary outputs unlessall_layer_masks=True. Pass it when you compute a loss on eval-mode outputs. (#1628) export(batch_size=...)— non-integer values raiseValueError. Pass a positive integer such asbatch_size=1. (#1556)
🌱 Changed
- Faster inference defaults — CUDA
inference()captures a CUDA graph; MPS compiles with inductor, fusesF.grid_sample(and folds LayerScale unless the inductor backend is used); CUDA prediction on an owned model prepares the next batch ahead; baseline JPEG batches decode with nvjpeg; ONNX Runtime on CUDA preprocesses on the GPU with IO binding. (#1672, #1668, #1666, #1670) - Batching —
predict()withoutbatchruns a directory or glob in batches of eight on models without a fixed batch size and on dynamic-batch exports; passbatch=1for the previous results. (#1664, #1672) - Host copies — non-CUDA accelerators copy boxes, scores and labels once per batch. (#1664, #1668)
- Training speed — Triton-fused clip, AdamW and EMA for single-GPU compiled BF16 (#1529);
vernier>=0.6.0as the default eval backend (#1661); GPU RLE encoding of segmentation masks (#1615); last-layer-only masks in segmentation eval (#1628); depthwise convolutions use cuDNN on compute capability 8.0 and newer (#1513); the progress bar shows the running mean of loss terms (#1625). - Dependencies —
hotcoco>=1.2.1,<1.3,rfdetr_plus>=1.1.0,ultrafast-pycocotools>=0.1.13. (#1590, #1614, #1568, #1584) - Export — arguments and packages are checked before the forward pass; LiteRT samples deformable attention from pixel rows; ExecuTorch XNNPACK keeps attention in the delegate; TensorRT refuses a non-int8
quantizationor straycalibration_data. (#1556, #1587, #1601, #1595) - Weights — pretrained weights download from
repo.roboflow.com/rfdetr. (#1600) - Deprecated-model warnings now name the replacement class. (#1618)
🗑️ Deprecated
- Unknown keyword arguments to
RFDETR.predict(); removal asTypeErrorin v2.0.0. (#1563) TRTInferenceandOpenVINOInference; removed in v1.15.0. (#1563)
❌ Removed
rfdetr.datasets.aug_config, deprecated since v1.9.0. Import fromrfdetr.datasets.aug_configs. (#1662)onnxsim,onnx_graphsurgeonandpolygraphyfrom the[onnx]extra, andpolygraphyandonnxsimfrom[tflite]. (#1589, #1563)- The private
OnnxOptimizer,onnx_simplifyand_onnx.symbolicmodules. (#1589)
🔧 Fixed
- Prediction: keypoint
covarianceon frames with no detections (#1681); bfloat16 tensors as source images (#1682);inference()on CUDA segmentation models under deterministic mode (#1673); keypoint scores in fp16 and bf16 (#1632). - Training and checkpoints:
from_checkpoint("run.pth")loads the file it was given (#1683); a checkpoint-derivednum_classesno longer blocks dataset alignment (#1674); resuming applies a changedlrorweight_decay(#1619);BestModelCallbackhonors the Lightning checkpoint lifecycle (#1678); an invalidbetterinBestMetricSingleraisesValueError(#1608). - Augmentation: segmentation boxes follow the transformed masks and empty masks are dropped (#1658); Kornia keeps continuous box edges (#1621); torchvision keypoint flips use continuous coordinates (#1597).
- Export:
tfliteconverts with onnx2tf 2.4.3 on a fresh install (#1563); Core ML segmentation masks line up on the Neural Engine (#1657); FP16 sigmoid in the shared export decoder (#1648);output_namekeeps dots (#1641); metadata type checking no longer fails on Windows (#1640). - Evaluation and data: mixed keypoint-count mAP and mAR (#1686); COCO polygon parts with fewer than three points are skipped (#1644); per-class table class names print verbatim (#1598);
evaluate()no longer downloads encoder weights (#1568). - Loading: no DINOv2 skip warnings on pretrained load (#1653); the class-count warning wording is clearer (#1654); a TorchScript error falls back to eager losses (#1649); the CLI parses the shipped configs and builds the trainer (#1629); the sine-embedding frequencies build in float32 for half-precision Inductor compiles (#1616).
🏆 Contributors
- Lương Thanh Hoàng Phú (@lthphuw, LinkedIn) — built INT8 TensorRT engines for detection, segmentation and keypoint models with
quantization="int8"; added hardware- and version-compatible TensorRT engines, CUDA-graph launch replay and kernel-timing reuse; added onethresholdper class inpredict. - Lee Clement (@leeclemnet, LinkedIn) — unified native and exported model prediction behind one inference path; expanded prediction inputs and added streaming; added
coreml_neural_engineto run Core ML exports fully on the Neural Engine. - Jesús Royeth (@JESUSROYETH, LinkedIn) — added direct CUDA Graph replay for inference; fused AdamW and EMA updates with Triton; added Kornia augmentation support for keypoints.
- Raghav Rathi (@raghav-rathi, LinkedIn) — encoded segmentation masks to COCO RLE on the GPU; computed only the last decoder layer's masks in segmentation models; fixed the CLI to parse the shipped configs and build the trainer correctly.
- Barsam Ershadi (@BarsamErshadi, LinkedIn) — fixed
from_checkpointto load weights from the file it was given; fixed bfloat16 source images and keypoint covariance on empty frames in prediction; rejected padded Kornia batches for every model. - Luís Condados (@Gabriellgpc, LinkedIn) — sped up the RF-DETR-Seg training step.
- Matvei Popov (@Matvezy, LinkedIn) — added a backbone registry and Plus model exports for the smaller RF-DETR sizes.
- Erle Carrara (@ecarrara) — switched pretrained weight downloads to the Roboflow repository; cached pretrained weights across CI jobs.
- Tamil Adhavan S K (@adhavan18, LinkedIn) — added opt-in antialiased resizing in
predict. - Yonghye Kwon (@developer0hye, LinkedIn) — sped up
ufcocoevaluation by loading box-only detections from one array. - Noé Fontana (@NoeFontana, LinkedIn) — moved training to vernier 0.6 for faster evaluation.
- Vlad Voropaev (@voropaevv, LinkedIn) — made
BestModelCallbackhonor the Lightning checkpoint lifecycle; added MPS threshold and output-alignment test coverage. - Christoph Deil (@cdeil, LinkedIn) — preserved continuous box edges in Kornia augmentation.
- Ali Tharwat (@Ali-Tharwat, LinkedIn) — recomputed segmentation boxes from transformed masks in augmentation.
- A Aswanth Raj (@aswanth-07, LinkedIn) — preserved half-precision keypoint trace scores; fixed Windows export metadata type checking.
- Raphael Fakhri (@RaphaelFakhri, LinkedIn) — skipped COCO polygon parts with fewer than three points.
- Mikhail (@mikeedi) — computed FP16 sigmoid in export with a higher-precision buffer.
- Mohammad Hijjawi (@MohammadHijjawi97, LinkedIn) — kept dots that are part of an export
output_name; printed class names verbatim in the per-class metrics tab. - JANG BYUNGKUN (@8rulerstar) — silenced DINOv2 weight warnings when loading pretrained RF-DETR; clarified the message when a set
num_classesis kept over the checkpoint's. - @TurboJonte — stopped a checkpoint-derived
num_classesfrom blocking the dataset's class count. - Raashish Aggarwal (@raashish1601) — rejected an invalid
bettervalue inBestMetricSingle. - @MaverickTopG — fixed keypoint horizontal flip to use continuous coordinates.
- Erik (@Erol444, LinkedIn) — documented what Apache 2.0 and PML 1.0 mean for commercial use.
- @CodewithGuptaShubh — fixed outdated development setup instructions in the docs.
- Jirka Borovec (@Borda, LinkedIn) — added static INT8 for ONNX and OpenVINO and public runtime paths for exports; made prediction faster with ahead-of-time CUDA batch preparation, GPU JPEG decoding and MPS defaults; expanded
hotcoco_streamingas an eval backend; wrote the how-it-works explainers, reorganized export docs and cookbooks, and prepared this release.
Automated contributions: @copilot-swe-agent, @pre-commit-ci
Full changelog: 1.11.0...1.12.0
Co-authored with /oss:release.