1.11.1
data-privacy-stack/presidio1.11.1Sep 30, 2026by Borda
Upgrading?
AI Summary
This release serves as a correctness patch for RF-DETR, fixing silent failures in LoRA checkpoint loading, TensorRT inference input validation, and COCO crowd region evaluation metrics.
Key Highlights
- LoRA backbone checkpoints now load correctly instead of silently failing.
- TensorRT inference now raises explicit errors for invalid inputs (device, dtype, non-contiguous) rather than returning wrong results.
- Crowd-region mAP evaluation now matches pycocotools standards.
- API renamed: `RFDETRModelModule.clip_gradients` is now `configure_gradient_clipping`.
Breaking Changes
- `RFDETRModelModule.clip_gradients` renamed to `configure_gradient_clipping`.
- `TRTInference` now raises `ValueError` for invalid inputs instead of returning wrong detections.
- `TensorRTExporter.build_engine` now raises `ValueError` for `dynamic_batch=True` ONNX without specific config.
- `RFDETR.from_checkpoint()` now raises `ValueError` instead of `KeyError: 'args'` for invalid checkpoints.
New Features
- Added `rfdetr.export._benchmark` helpers for latency and memory measurement.
- Added `decode_pil_image` and `decode_pil_image_bytes` for direct PIL decoding.
- Added `CrowdRegion` and `crowd_regions_from_coco` utilities for evaluation.
- Added `rfdetr.utilities.package.is_installed()` for dependency checking.
- Added `Exporter.check_dependencies` as an overridable classmethod hook.
Full Release Notes
RF-DETR 1.11.1 is a correctness patch. It turns silent wrong results into loud, correct ones:
- **LoRA backbone** — `backbone_lora=True` checkpoints trained on a random encoder, no error. Now loads correctly.
- **TensorRT inference** — wrong-device/dtype/non-contiguous inputs returned wrong detections, no error. Now refused.
- **Crowd-region mAP** — val/test mAP overcounted false positives on COCO crowd regions. Now matches pycocotools.
**Most users need no action.** 4 of the 5 "breaking" changes only affect code that was already getting a wrong result or an uncaught `KeyError` — this release just stops hiding it. See the Migration guide for exact before/after code.
**The one real API change**: `RFDETRModelModule.clip_gradients` → `configure_gradient_clipping`. Only affects code that calls `clip_gradients` directly, or relies on `super().clip_gradients(...)` inside an override.
Everything else is a bug fix or documentation update.
## ✨ Spotlights
### `backbone_lora=True` checkpoints silently trained a random encoder — now fixed
`RFDETR.from_checkpoint()`, `RFDETRSmall(pretrain_weights=...)`, and `train()` all loaded a LoRA checkpoint *before* wrapping the encoder with LoRA, so none of the stored PEFT-named weights matched — the encoder silently stayed at random initialization, and `evaluate()` scored near zero with no error.
```python
# Before (1.11.0): silent — encoder never actually reloads
model = RFDETRLarge(pretrain_weights="checkpoint_best_total.pth", backbone_lora=True)
model.evaluate() # mAP50:95 ≈ 0.0001 — looks broken, no exception
# After (1.11.1): encoder is wrapped before load, weights match
model = RFDETRLarge(pretrain_weights="checkpoint_best_total.pth", backbone_lora=True)
model.evaluate() # mAP50:95 ≈ 0.6221 — same as the in-memory trained model
```
Measured: RF-DETR Large `@640`, LoRA-tuned on 262 COCO person images. ([#1543](https://github.com/roboflow/rf-detr/pull/1543))
### `last.ckpt` and interval checkpoints now carry enough to reload
```python
# Before (1.11.0)
RFDETR.from_checkpoint("output/last.ckpt") # KeyError: 'args'
# After (1.11.1)
model = RFDETR.from_checkpoint("output/last.ckpt") # rebuilds trained resolution/architecture
```
Files written by 1.11.0 and earlier can't be repaired in place — `from_checkpoint` now raises a named `ValueError` pointing at `checkpoint_best_ema.pth` and `training_config.json` instead. ([#1561](https://github.com/roboflow/rf-detr/pull/1561))
### Val/test mAP now matches pycocotools on COCO crowd regions
Detections inside `iscrowd=1` regions no longer count as false positives. Numbers shift on crowd-labelled data — Nano COCO val2017: 0.4802 → 0.4842 mAP. Training is unchanged. ([#1532](https://github.com/roboflow/rf-detr/pull/1532))
### `TRTInference` refuses inputs TensorRT would misread
```python
# Before (1.11.0): silent wrong output
trt_model(image_tensor.to(memory_format=torch.channels_last)) # 13 detections → 0, no error
# After (1.11.1): explicit refusal
trt_model(image_tensor.to(memory_format=torch.channels_last))
# ValueError: Input 'input' is not contiguous (strides (...)), and TensorRT reads it as dense
# row-major memory. Pass tensor.contiguous().
```
([#1546](https://github.com/roboflow/rf-detr/pull/1546))
### `RFDETRModelModule.clip_gradients` renamed → `configure_gradient_clipping` (Breaking)
```python
# Before (1.11.0)
class MyModule(RFDETRModelModule):
def clip_gradients(self, optimizer, gradient_clip_val=None, gradient_clip_algorithm=None): ...
# After (1.11.1)
class MyModule(RFDETRModelModule):
def configure_gradient_clipping(self, optimizer, gradient_clip_val=None, gradient_clip_algorithm=None): ...
```
Moves the keypoint fp16 clipping fix onto the Lightning hook meant for it — `clip_gradients` itself now reverts to Lightning's base implementation. Narrower than it looks: `configure_gradient_clipping`'s non-fused branch calls `self.clip_gradients(...)` (dynamic dispatch, not `super()`), so a subclass overriding only `clip_gradients` with self-contained logic still runs unchanged. Actually affected: code calling `clip_gradients` directly, a subclass override relying on `super().clip_gradients(...)` for RF-DETR's old fused-aware logic, and any `clip_gradients` override on the fused-AdamW path (never reached there, in 1.11.0 or 1.11.1 — see `MIGRATION.md` for the full breakdown). ([#1537](https://github.com/roboflow/rf-detr/pull/1537), [#1549](https://github.com/roboflow/rf-detr/pull/1549))
## 🔄 Migration guide
5 breaking changes — 1 API rename, 3 stricter-validation changes, 1 exception-type change. All are covered in full, with before/after code, in [MIGRATION.md](./MIGRATION.md); none were previously documented in `docs/getting-started/migration.md`.
A new overridable classmethod, `Exporter.check_dependencies` (`src/rfdetr/export/base.py`), lets a custom exporter subclass judge whether the host has what it needs to build, separately from `_check_capabilities` judging the request. Not documented yet in `docs/exports/blueprint.md` — only relevant to third-party `Exporter` subclasses, no action needed for `RFDETR.export()` callers. ([#1542](https://github.com/roboflow/rf-detr/pull/1542))
## 📝 Notable changes
### 🚀 Added
- `rfdetr.export._benchmark` (private): `measure_latency` and `measure_memory` helpers shared by the new per-hardware export cookbooks (CUDA-event timing on GPU, wall-clock/RSS otherwise). Replaces the ONNX-only `rfdetr.export._onnx.inference._onnx_runtime`, which is removed. ([#1530](https://github.com/roboflow/rf-detr/pull/1530))
- `decode_pil_image` / `decode_pil_image_bytes` (`rfdetr.datasets.io_utils`) — decode straight to a PIL image under the same decoder policy as the array-out decoders, without the NumPy round trip. ([#1551](https://github.com/roboflow/rf-detr/pull/1551))
- `CrowdRegion` / `crowd_regions_from_coco` (`rfdetr.datasets.coco`) — reads `iscrowd=1` annotations back from a COCO API for evaluation metrics that need to score them. ([#1532](https://github.com/roboflow/rf-detr/pull/1532))
- `resize_masks_nearest` (`rfdetr.evaluation.matching`) — nearest-neighbor mask resize used by the new crowd-region evaluation path. ([#1532](https://github.com/roboflow/rf-detr/pull/1532))
- `rfdetr.utilities.package` (new module): `is_installed(name)` — checks whether a package is importable without importing it, used by the new fail-fast TensorRT dependency check. ([#1542](https://github.com/roboflow/rf-detr/pull/1542))
- `Exporter.check_dependencies` (`src/rfdetr/export/base.py`) — new overridable classmethod hook; see Migration guide. ([#1542](https://github.com/roboflow/rf-detr/pull/1542))
### ⚠️ Breaking Changes
- `RFDETRModelModule.clip_gradients` is renamed to `configure_gradient_clipping`; `clip_gradients` reverts to Lightning's base implementation. Only affects direct callers of `clip_gradients`, a `super().clip_gradients(...)` call inside an override, or an override on the fused-AdamW path — a self-contained `clip_gradients` override still runs on the non-fused path via `self.clip_gradients(...)` dispatch. See `MIGRATION.md`. ([#1537](https://github.com/roboflow/rf-detr/pull/1537), [#1549](https://github.com/roboflow/rf-detr/pull/1549))
- `TRTInference` now raises `ValueError` for an input on another device, of another dtype, or non-contiguous, instead of returning wrong detections. ([#1546](https://github.com/roboflow/rf-detr/pull/1546))
- `TensorRTExporter.build_engine` now raises `ValueError` on a `dynamic_batch=True` ONNX unless its `TensorRTConfig` sets `dynamic_batch=True` and `max_batch_size`. `RFDETR.export()` is unaffected. ([#1542](https://github.com/roboflow/rf-detr/pull/1542))
- `RFDETR.from_checkpoint()` on a checkpoint with no `"args"` now raises `ValueError` instead of `KeyError: 'args'`. ([#1561](https://github.com/roboflow/rf-detr/pull/1561))
- Loading a `backbone_lora=True` checkpoint without `peft` installed now raises `ImportError` instead of silently loading a random encoder. ([#1543](https://github.com/roboflow/rf-detr/pull/1543))
### 🌱 Changed
- Export cookbooks restructured per hardware target (`export-cuda`/`export-cpu`/`export-mobile`/ `export-apple`), replacing 4 per-format ones; adds first coverage for ONNX, OpenVINO, LiteRT, CoreAI. ([#1530](https://github.com/roboflow/rf-detr/pull/1530))
- `RFDETR.from_checkpoint()` no longer restores `device` from `model_config` — the loading host's default wins; pass `device=` explicitly. ([#1534](https://github.com/roboflow/rf-detr/pull/1534), [#1561](https://github.com/roboflow/rf-detr/pull/1561))
- `[coreai]` extra pins `coreai-torch==0.4.3`, widens Python range to `<3.15`, and declares a uv conflict with `[tflite]`. ([#1527](https://github.com/roboflow/rf-detr/pull/1527))
- The `e2e_onnxruntime` pytest marker is renamed `e2e_onnx` in `pyproject.toml`. Contributor-facing only: `pytest -m e2e_onnxruntime` now silently selects nothing (pytest doesn't error on an unmatched `-m`) — update local invocations and CI configs to `e2e_onnx`. ([#1530](https://github.com/roboflow/rf-detr/pull/1530))
- `amp_dtype="auto"` now picks fp16 on CUDA GPUs without native bf16 (T4, V100); bf16 only when every selected GPU is Ampere or newer. Loss curves/checkpoints across this change are not comparable on pre-Ampere GPUs. ([#1538](https://github.com/roboflow/rf-detr/pull/1538))
- Val/test mAP now ignores detections on COCO crowd regions, matching pycocotools. ([#1532](https://github.com/roboflow/rf-detr/pull/1532))
- `TrainConfig.clip_max_norm` now rejects a negative value at construction instead of silently training unclipped. ([#1537](https://github.com/roboflow/rf-detr/pull/1537), [#1549](https://github.com/roboflow/rf-detr/pull/1549))
### ❌ Removed
- `rfdetr.export._onnx.inference._onnx_runtime` (private ONNX-only benchmark helper) — superseded by `rfdetr.export._benchmark`. ([#1530](https://github.com/roboflow/rf-detr/pull/1530))
### 🔧 Fixed
- YOLO datasets stored under a directory named `images` now resolve their labels directory correctly. ([#1557](https://github.com/roboflow/rf-detr/pull/1557))
- `last.ckpt`/interval checkpoints record model class, config, class names, and rfdetr version; `from_checkpoint` no longer loses the dataset's class names. ([#1561](https://github.com/roboflow/rf-detr/pull/1561))
- COCO training on non-JPEG images (or JPEG without `simplejpeg`) is back to 1.10 decode speed — up to 27% faster per batch on large BMP files. ([#1551](https://github.com/roboflow/rf-detr/pull/1551))
- `format="coreai"` works with `coreai-torch` 0.4.3. ([#1527](https://github.com/roboflow/rf-detr/pull/1527))
- `from_checkpoint("checkpoint_best_total.pth")` rebuilds the trained architecture instead of falling back to class defaults. ([#1534](https://github.com/roboflow/rf-detr/pull/1534))
- Keypoint fp16 training clips the real gradient (was clipping before GradScaler unscale, silently stalling training). ([#1537](https://github.com/roboflow/rf-detr/pull/1537), [#1549](https://github.com/roboflow/rf-detr/pull/1549))
- `amp_dtype="auto"` no longer selects emulated bf16 on T4/V100 — Colab T4 Nano step 443ms → 226ms in fp16. ([#1538](https://github.com/roboflow/rf-detr/pull/1538))
- Crowd-region detections no longer counted as false positives in COCO eval. ([#1532](https://github.com/roboflow/rf-detr/pull/1532))
- `TRTInference.build_engine` no longer truncates an existing `.trt` file on a failed build. ([#1546](https://github.com/roboflow/rf-detr/pull/1546))
- An undeserializable TensorRT engine reports a named `RuntimeError` instead of `AttributeError`. ([#1546](https://github.com/roboflow/rf-detr/pull/1546))
- `TRTInference(device=...)` now loads and runs the engine on that device (was mixing GPUs). ([#1546](https://github.com/roboflow/rf-detr/pull/1546))
- TensorRT export refusal messages name working export settings instead of a bare flag. ([#1546](https://github.com/roboflow/rf-detr/pull/1546))
- `backbone_lora=True` checkpoints reload their trained backbone (was silently random-init; measured val mAP50:95 0.0001 → 0.6221). ([#1543](https://github.com/roboflow/rf-detr/pull/1543))
- `RFDETR.export(format="tensorrt")` without `tensorrt` installed fails before the ONNX export with a named `ImportError`. ([#1542](https://github.com/roboflow/rf-detr/pull/1542))
- `compile=True` with default `multi_scale` stops recompiling the transformer per resolution. ([#1539](https://github.com/roboflow/rf-detr/pull/1539))
- COCO segmentation datasets mixing annotated and box-only instances keep every mask. ([#1558](https://github.com/roboflow/rf-detr/pull/1558))
- Fixed JSON serialization in the COCO val-subset builder. ([`fd3bb991`](https://github.com/roboflow/rf-detr/commit/fd3bb991), no PR — direct commit)
### 📚 Documentation
- Documented `TrainConfig.eval_backend` in the advanced training guide. ([#1526](https://github.com/roboflow/rf-detr/pull/1526))
- Scoped the static INT8 export limit to TFLite specifically. ([#1559](https://github.com/roboflow/rf-detr/pull/1559))
## 🏆 Contributors
- **Jirka Borovec** (@Borda, [LinkedIn](https://linkedin.com/in/jirka-borovec)) — restructured export cookbooks by hardware target, replacing four per-format notebooks; fixed JSON serialization in the COCO val-subset builder; unified export CI jobs into one matrix.
- **Lương Thanh Hoàng Phú** (@lthphuw, [LinkedIn](https://linkedin.com/in/phu-lth)) — hardened `TRTInference` to reject mismatched device/dtype/contiguity instead of returning silently wrong detections; fixed checkpoints to record training args and model config so `from_checkpoint` no longer raises `KeyError`; fixed LoRA backbone reload, which had silently stayed at random init.
- **Raghav Rathi** (@raghav-rathi, [LinkedIn](https://www.linkedin.com/in/raghavrathi00/)) — fixed keypoint gradient clipping under fp16, which ran before GradScaler unscale and silently stalled training; fixed `amp_dtype="auto"` selecting emulated bf16 on GPUs without native support; excluded COCO crowd-region detections from val/test mAP.
- **Mohammad Hijjawi** (@MohammadHijjawi97, [LinkedIn](https://www.linkedin.com/in/mohammadhijjawi)) — fixed COCO segmentation to keep all masks when an image's first annotation has no `segmentation` field; fixed YOLO labels-directory resolution for datasets nested under an `images` directory.
- **Christoph Deil** (@cdeil, [LinkedIn](https://www.linkedin.com/in/christophdeil)) — fixed CoreAI export compatibility with `coreai-torch` 0.4.3 after it removed `AIProgram.optimize()`.
*Automated contributions from claude[bot], pre-commit-ci[bot], Copilot Autofix powered by AI, copilot-swe-agent[bot], OpenAI Codex, Claude Sonnet 5, Claude Opus 5 (1M context), and Claude Opus 5.5 supported this release.*
---
**Full changelog**: https://github.com/roboflow/rf-detr/compare/1.11.0...1.11.1
Related Repositories
public-apis/public-apis★ 491,124
A collective list of free APIs
NousResearch/hermes-agent★ 255,892
The agent that grows with you
yt-dlp/yt-dlp★ 199,988
A feature-rich command-line audio/video downloader
microsoft/markitdown★ 191,477
Python tool for converting files and office documents to Markdown.
Significant-Gravitas/AutoGPT★ 187,699
AutoGPT is the vision of accessible AI for everyone, to use and to build on. Our mission is to provide the tools, so that you can focus on what matters.