π Summary
RF-DETR 1.8.3 is a focused patch release with one new capability and three correctness fixes. The headline addition is optimize_for_inference(inplace=True) β a memory-efficient inference path that skips the deep-copy of the base model, useful on memory-constrained GPUs and edge devices. On the bug-fix side: keypoint horizontal-flip augmentation now correctly swaps left/right pairs (previously labels were corrupted on flip); bounding boxes are clamped to image bounds so objects at image edges no longer produce negative or out-of-frame coordinates; and default loss coefficients for segmentation and keypoint fine-tuning are restored to their intended values after a regression introduced in v1.7.
β¨ Spotlights
In-place inference optimization
optimize_for_inference(inplace=True) exports the model using the loaded weights directly β no deep-copy β reducing peak memory during the optimization step by roughly 0.5Γ model weight. After inplace optimization, the base model is cleared: export() raises RuntimeError and remove_optimized_model() issues a UserWarning and returns cleanly. The new is_optimized_inplace property lets you check the current state.
model = RFDETRSmall()
# Default: deep-copy kept, fully reversible
model.optimize_for_inference(compile=False, dtype="float16")
model.remove_optimized_model() # works fine
# New: inplace, lowest possible memory β irreversible
model.optimize_for_inference(compile=False, inplace=True, dtype="float16")
print(model.is_optimized_inplace) # TrueCorrect keypoint flip augmentation
Keypoint training now correctly swaps symmetric pairs during horizontal flip augmentation. CocoKeypointSchema and YoloKeypointSchema both gain a keypoint_flip_pairs field, populated automatically from keypoint names (COCO left/right convention) or from flip_idx (YOLO pose). infer_coco_keypoint_schema and infer_yolo_keypoint_schema are also re-exported from the public rfdetr.datasets namespace.
from rfdetr.datasets import infer_coco_keypoint_schema # now public
schema = infer_coco_keypoint_schema("path/to/_annotations.coco.json")
print(schema.keypoint_flip_pairs) # [1, 2, 3, 4, ...] β auto-inferred
model.train(dataset_dir=DATASET_DIR, epochs=50, keypoint_schema=schema)Native COCO format (dataset_file="coco") is supported alongside "roboflow" and "yolo".
Bounding box coordinates clamped to image bounds
Predicted boxes are now guaranteed to lie within [0, width] Γ [0, height]. Model regression output is unbounded β objects near image edges could previously produce negative x1/y1 or x2/y2 values exceeding image dimensions. scale_fct is also cast to boxes.dtype to avoid dtype mismatch with fp16 inference.
Loss coefficient defaults corrected
Two training config defaults were silently wrong since v1.7:
SegmentationTrainConfig.cls_loss_coefwas5.0β now1.0, restoring the effective weight from before the v1.7TrainConfigownership migration.KeypointTrainConfig.keypoint_nll_loss_coefwas0.5β now1.0, aligning the NLL term with all other keypoint loss weights.
If your current fine-tuned runs relied on the old defaults, pass the values explicitly to maintain continuity.
π Migration guide
No breaking API changes in this release.
Segmentation fine-tuning β cls_loss_coef default change: if you fine-tune segmentation models without setting cls_loss_coef explicitly, your loss balance shifts. To reproduce prior runs:
from rfdetr.config import SegmentationTrainConfig
config = SegmentationTrainConfig(cls_loss_coef=5.0)Keypoint fine-tuning β keypoint_nll_loss_coef default change: to reproduce prior runs:
from rfdetr.config import KeypointTrainConfig
config = KeypointTrainConfig(keypoint_nll_loss_coef=0.5)Keypoint horizontal-flip augmentation now active: flip augmentation was disabled for keypoints in v1.8.1 because pair swapping was not yet implemented. With this release it is enabled automatically when keypoint_flip_pairs is non-empty. Datasets without left/right keypoint naming conventions infer zero pairs and skip ReplayCompose automatically β no action required.
π Notable changes
π Added
optimize_for_inference(inplace=True)β keyword-only arg onRFDETR.optimize_for_inference(); skips deep-copy for memory-constrained inference-only deployments. Requirescompile=False. (#1089)RFDETR.is_optimized_inplaceβ property returningTrueafter a successful inplace optimization. (#1089)CocoKeypointSchema.keypoint_flip_pairsandYoloKeypointSchema.keypoint_flip_pairsβ flat list of horizontal-flip swap pairs, inferred from keypoint names (COCO) orflip_idx(YOLO). (#1164)infer_coco_keypoint_schemaandinfer_yolo_keypoint_schemare-exported fromrfdetr.datasets(public namespace). (#1164)
π± Changed
- Horizontal flip detection in
AlbumentationsWrappernow uses AlbumentationsReplayComposereplay metadata instead of heuristic bbox-center mirroring; eliminates false positives. Falls back toalb.Composewith aUserWarningonalbumentations <1.3. (#1164) - Keypoint schema inference now supports native COCO format (
dataset_file="coco") alongside"roboflow"and"yolo". (#1164) _keypoint_schema_cachekey changed fromdataset_dirto(dataset_file, dataset_dir)tuple to prevent cross-format cache collisions. (#1164)SegmentationTrainConfig.cls_loss_coefdefault:5.0β1.0. (#1165)KeypointTrainConfig.keypoint_nll_loss_coefdefault:0.5β1.0. (#1165)
π§ Fixed
- Predicted bounding boxes clamped to
[0, width] Γ [0, height]inPostProcess._postprocess_boxes();scale_fctalso cast toboxes.dtypefor fp16 safety. (#1168) SegmentationTrainConfig.cls_loss_coefdefault corrected from5.0to1.0β restores the pre-v1.7 effective classification loss weight. (#1165)KeypointTrainConfig.keypoint_nll_loss_coefdefault restored to1.0. (#1165)optimize_for_inference()flag ordering fixed:_optimized_inplaceset beforemodel.model = Noneso exception recovery sees correct state. (#1089)remove_optimized_model()now issuesUserWarningand returns cleanly after inplace optimization instead of raisingRuntimeError. (#1089)export()now raisesRuntimeErrorimmediately if called after inplace optimization. (#1089)
π Contributors
- Jonas Pirner (@pirnerjonas) β added in-place inference optimization for memory-efficient deployment
- Alessandro Brunello (@Armaggheddon, LinkedIn) β fixed postprocessor to clamp predicted boxes to image bounds
- Jirka Borovec (@Borda, LinkedIn) β restored loss coefficient defaults, fixed keypoint flip-pair augmentation, restructured test layout
Full changelog: 1.8.2...1.8.3