1.6.0

roboflow/rf-detr1.6.0Mar 20, 2026by Borda

AI Summary

Major version introducing PyTorch Lightning training, multi-GPU support, and configuration improvements.

Key Highlights

  • PyTorch Lightning training stack with modular building blocks and YAML config support.
  • Multi-GPU DDP support directly via `model.train()` without custom trainer.
  • `batch_size='auto'` for automatic batch size discovery and gradient accumulation adjustment.
  • Segmentation support in the synthetic dataset generator.
  • `set_attn_implementation` switch for DINOv2 backbone at runtime.

Breaking Changes

  • `transformers` >=5.1.0 is now required (DINOv2 backbone uses v5 API).
  • `draw_synthetic_shape` return type changed from `np.ndarray` to `Tuple[np.ndarray, List[float]]`.
  • Optional extras renamed: `rfdetr[metrics]` -> `rfdetr[loggers]`, `rfdetr[onnxexport]` -> `rfdetr[onnx]`.

New Features

  • Composable PyTorch Lightning training blocks (`RFDETRModelModule`, `RFDETRDataModule`, etc.).
  • `batch_size='auto'` for automatic batch size discovery.
  • Synthetic dataset generation with `with_segmentation=True`.
  • `ModelContext` promoted to public API for inspecting metadata.
  • `backbone_lora` and `freeze_encoder` in `ModelConfig`.
  • CLI entry point `python -m rfdetr`.
  • Package marked as PEP 561 compliant (`py.typed`).

Full Release Notes

## πŸš€ Added

- **Composable PyTorch Lightning training building blocks.** The training stack is now built on [PyTorch Lightning](https://lightning.ai) and exposed as modular, swap-in pieces β€” like Lego. Use the familiar one-liner if that's all you need, or snap the blocks together yourself for full control: custom callbacks, multi-GPU strategies, YAML config files, and programmatic trainer construction. (#757, #794, closes #709)

	**Level 1 β€” same API as always:**
	
	```python
	from rfdetr import RFDETRSmall
	
	model = RFDETRSmall()
	model.train(dataset_dir="path/to/dataset", epochs=50)
	```
	
	**Level 2 β€” assemble your own training from building blocks:**
	
	```python
	from rfdetr import RFDETRModelModule, RFDETRDataModule, build_trainer
	from rfdetr.training import RFDETREMACallback, COCOEvalCallback, BestModelCallback
	from pytorch_lightning import Trainer
	
	# Each block is a standard PTL component β€” swap, subclass, or extend any piece
	module = RFDETRModelModule(model_config=..., train_config=...)
	datamodule = RFDETRDataModule(dataset_dir="path/to/dataset", train_config=...)
	
	# build_trainer() wires up all RF-DETR callbacks for you ...
	trainer = build_trainer(train_config=...)
	
	# ... or compose your own from individual callbacks
	trainer = Trainer(
	    max_epochs=50,
	    callbacks=[
	        RFDETREMACallback(decay=0.9998),   # exponential moving average
	        COCOEvalCallback(),                # COCO mAP evaluation
	        BestModelCallback(),               # save best checkpoint
	        # ... add your own Lightning callbacks here
	    ],
	)
	
	trainer.fit(module, datamodule)
	```
	
	**Level 3 β€” YAML config + CLI, zero Python required:**
	
	```yaml
	# configs/rfdetr-base.yaml
	model:
	  class_path: rfdetr.RFDETRSmall
	trainer:
	  max_epochs: 50
	  precision: "16-mixed"
	  devices: 4  # 4-GPU DDP, no code changes
	```
	
	```bash
	rfdetr fit --config configs/rfdetr-base.yaml
	```

- **Multi-GPU DDP via `model.train()`.** Pass `strategy`, `devices`, and `num_nodes` directly to the familiar one-liner β€” no custom trainer required. Single-GPU behaviour is unchanged when these are omitted. (#808, closes #803)

	```python
	model.train(
	    dataset_dir="path/to/dataset",
	    epochs=50,
	    strategy="ddp",
	    devices=4,
	)
	```

- **`batch_size='auto'` for automatic batch size discovery.** RF-DETR runs a lightweight CUDA memory probe before training starts to find the largest safe micro-batch size, then recommends `grad_accum_steps` to hit a configurable effective batch size target (default 16). The resolved values are logged so you always know what was used. (#814)

	```python
	model.train(
	    dataset_dir="path/to/dataset",
	    batch_size="auto",
	    auto_batch_target_effective=16,  # optional, default 16
	)
	# Logs: "safe micro-batch = 3, grad_accum_steps = 4, effective_batch_size = 12"
	```

- **Segmentation support in the synthetic dataset generator.** `generate_coco_dataset(with_segmentation=True)` produces COCO-format polygon annotations alongside bounding boxes, enabling end-to-end segmentation fine-tuning with fully synthetic data. (#781)

- **`set_attn_implementation` on DINOv2 backbone.** Switch between `"eager"` and `"sdpa"` attention implementations at runtime without re-initialising the model. (#760)

- **`ModelContext` is now a public API.** `_ModelContext` has been promoted to `ModelContext` and exported from `rfdetr`. Use `model.context` to inspect `class_names`, `num_classes`, and related metadata after training or loading a checkpoint. (#835)

	```python
	model = RFDETRSmall()
	model.train(dataset_dir="path/to/dataset", epochs=10)
	
	print(model.context.class_names)   # ['cat', 'dog', ...]
	print(model.context.num_classes)   # 2
	```

- **`backbone_lora` and `freeze_encoder` in `ModelConfig`.** Both fine-tuning control flags are now first-class fields in `ModelConfig`, letting you configure them through the public API or YAML config. (#829)

- **`eval_max_dets`, `eval_interval`, and `log_per_class_metrics`** promoted to `TrainConfig` fields for explicit control over COCO evaluation behaviour.

- **`python -m rfdetr` entry point.** The CLI is now invokable as `python -m rfdetr`, in addition to the `rfdetr` console script.

- **`py.typed` marker** added β€” RF-DETR is now PEP 561–compliant; type checkers will discover inline type hints automatically.

## ⚠️ Breaking Changes

- **`transformers` >=5.1.0 now required.** The DINOv2 windowed-attention backbone uses the transformers v5 API. Projects pinned to transformers v4 must either upgrade or pin `rfdetr<1.6.0`. (#760, closes #730)

- **`draw_synthetic_shape` return type changed.** The function now returns `Tuple[np.ndarray, List[float]]` β€” `(image, polygon)` β€” instead of just `np.ndarray`. Update any call site that unpacks only the image. (#781)

	```python
	# Before
	img = draw_synthetic_shape(canvas, shape, color)
	
	# After
	img, polygon = draw_synthetic_shape(canvas, shape, color)
	```

- **Optional extras renamed.** The PyPI install extras have been renamed for clarity:

	| Before | After |
	| --- | --- |
	| `rfdetr[metrics]` | `rfdetr[loggers]` |
	| `rfdetr[onnxexport]` | `rfdetr[onnx]` |

## πŸ—‘οΈ Deprecated

- **`rfdetr.deploy`** β€” this internal module now redirects to `rfdetr.export` with a `DeprecationWarning`. The user-facing `model.export()` API is unchanged. If you import directly from `rfdetr.deploy.*`, migrate to `rfdetr.export.*` before v1.7.

- **`rfdetr.util.*`** β€” redirects to `rfdetr.utilities.*` with a `DeprecationWarning`. Migrate at your convenience before v1.7.

## 🌱 Changed

- **Albumentations 1.x and 2.x both supported.** The version constraint is now `albumentations>=1.4.24,<3.0.0`. Configs using the old `height`/`width` keyword arguments are automatically adapted to the 2.x `size=(height, width)` API. (#786, closes #779)

- **Current learning rate shown in the training progress bar.** The live progress bar now displays the active learning rate alongside loss so you can see scheduler changes in real time. (#809, closes #804)

- **Faster `import rfdetr` startup.** `supervision`, `pytorch_lightning`, and several other heavy dependencies are no longer imported at module load time β€” they are loaded on first use instead. Cold-import time drops measurably in inference-only environments. (#801)

## πŸ”§ Fixed

- Fixed checkpoint loading into a model with a different architecture (segmentation vs. detection, or `patch_size` mismatch) β€” RF-DETR now raises a descriptive `ValueError` with actionable guidance before `load_state_dict` ever fires, replacing a cryptic tensor-size `RuntimeError`. (#810, closes #806)

- Fixed `class_names` not reflecting dataset labels on `model.predict()` after training β€” class names are now synced from the dataset at the end of training so inference always uses the correct label list. (#816)

- Fixed detection head reinitialization incorrectly overwriting fine-tuned weights when loading a checkpoint with fewer classes than the model default. The second `reinitialize_detection_head` call now only fires in the backbone-pretrain scenario. (#815, closes #813, #509)

- Fixed `grid_sample` and bicubic interpolation silently falling back to CPU on Apple Silicon (MPS) β€” both operations now run natively on MPS via a custom implementation, restoring full GPU utilisation on Mac. (#821)

- Fixed `early_stopping=False` in `TrainConfig` being silently ignored β€” the setting now propagates correctly and training runs to completion when disabled. (#835)

- Fixed `ValueError: matrix entries are not finite` crash in `HungarianMatcher` when the cost matrix contains `NaN` or `Inf` values β€” non-finite entries are now replaced with a large finite sentinel before Hungarian assignment, and a warning is emitted at most once per matcher instance. (#787, closes #784)

- Fixed YOLO dataset validation rejecting `data.yml` β€” both `.yaml` and `.yml` extensions are now accepted. (#777, closes #775)

- Fixed degenerate bounding boxes (zero width or height) causing `ValueError` in Albumentations validation β€” they are now silently dropped before the transform pipeline runs. (#825)

---

## πŸ† Contributors

A special welcome to our new contributors and a big thank you to everyone who helped with this release:

* **Haocheng Lu** (@HaochengLu) – *Automatic batch size discovery (`batch_size='auto'`)*
* **Omkar Kabde** (@omkar-334) ([LinkedIn](https://www.linkedin.com/in/omkar-kabde/)) – *Transformers v5 migration for the DINOv2 backbone*
* **Jirka Borovec** (@Borda) ([LinkedIn](https://www.linkedin.com/in/jirka-borovec/)) – *PyTorch Lightning migration, DDP support, MPS fixes, Albumentations 2.x support, HungarianMatcher fix, deferred imports, package restructure*

---

**Full Changelog**: https://github.com/roboflow/rf-detr/compare/1.5.2...v1.6.0