Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #1010 +/- ##
========================================
- Coverage 80% 77% -3%
========================================
Files 101 101
Lines 8519 8523 +4
========================================
- Hits 6836 6549 -287
- Misses 1683 1974 +291 🚀 New features to boost your workflow:
|
…nnotated detections
…onnx2tf - Add `_imagenet_normalize()` helper with `_IMAGENET_MEAN`/`_IMAGENET_STD` constants; normalize all four `_prepare_calibration_data` branches from [0,1] to ImageNet [-2.1,2.6] range — fixes INT8 quantization accuracy where wrong-range data was passed to onnx2tf for representative calibration - Remove false module docstring claim that onnx2tf auto-applies normalization via default `quant_norm_mean`/`quant_norm_std`; no such params were in `convert_kwargs` - Fix stale `test_detections_below_threshold_filtered` docstring that described logits as "zero" when they are -10.0 (`sigmoid(0)=0.5 > 0.3` would break the assertion) --- Co-authored-by: Claude Code <noreply@anthropic.com>
…ackbone
- Add `_fold_constant_expands`: constant-folds all-constant Expand nodes into initializers, fixing onnx2tf 1.26+ "Output tensors of a Functional model must be the output of a TensorFlow Layer" error on transformer position-embedding grids
- Add `_patch_onnx_for_tflite`: surgical graph patcher replacing the old `_simplify_onnx` (full onnxsim) to avoid Tile/Concat rank-mismatch regressions
- Add auto-retry with `{stem}_auto.json` param_replacement_file when first conversion fails — onnx2tf generates this file itself on TopK errors
- Patch installed onnx2tf TopK.py line 69: `int(k_tensor)` → `int(k_tensor.flat[0])` to handle 1-D shape-(1,) numpy arrays without TypeError; removed the `_fix_topk_k_shape` function that violated ONNX spec by squeezing k to 0-D (breaking `infer_shapes` and leaving Indices.dtype=None)
- Fix three stale unit tests: path assertion now expects `_simplified/` patched ONNX, ndarray/file calibration tests now assert ImageNet-normalised output
End-to-end: rfdetr-small converts to float32 (111 MB) and float16 (57 MB) TFLite; SavedModel inference produces real logit range (−8.2–−3.9) not stuck at focal-loss prior bias (~−4.6 → 0.01)
---
Co-authored-by: Claude Code <noreply@anthropic.com>
…hvision for inference - Replace default BICUBIC resampling in `_run_inference` with BILINEAR to match Torchvision's `InterpolationMode.BILINEAR` and avoid confidence degradation from pixel mismatches. - Add regression test to verify preprocessing tensors align with BILINEAR-resized inputs. - Improve logging for ambiguous TFLite output matching, falling back to shape or positional order with detailed warnings.
…nto releasing/1.7
…se best weights - After trainer.fit(), BestModelCallback writes checkpoint_best_total.pth but only reloads it into module.model when run_test=True; without this fix, predict() and export() silently use the final-epoch EMA weights instead of the best-epoch weights, causing a mismatch vs from_checkpoint() results - Load checkpoint_best_total.pth into module.model (unwrapping compiled _orig_mod) before the sync-back; guarded with try/except so missing checkpoint is non-fatal --- Co-authored-by: Claude Code <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RF-DETR 1.7.0
This release adds TFLite export, GPU-side augmentation for segmentation, multi-channel input support (grayscale and multispectral), PyTorch Lightning checkpoint loading, and several developer-facing builder APIs that make custom model construction far easier. It also moves
peftto an opt-in extra and removes the long-deprecatedrfdetr.util/rfdetr.deployimport paths — see Breaking Changes below before upgrading.🚀 Added
TFLite export. New
model.export(format="tflite")converts through ONNX usingonnx2tf. FP32 and FP16 outputs are always produced; INT8 quantization is available with a calibration image directory. Requirespip install 'rfdetr[onnx]'. (feat(export): add TFLite export support with FP32/FP16/INT8 #920)Kornia GPU augmentation now supports instance segmentation. Images, boxes, and per-instance masks are augmented in sync on the GPU via
RFDETRDataModule.on_after_batch_transfer. Previouslyaugmentation_backend="gpu"/"auto"was silently ignored for segmentation models. The mask buffer is[B, N_max, H, W]float32 — roughly 500 MB atB=8, N_max=50, H=W=560; useaugmentation_backend="cpu"on cards with limited VRAM. (feat: Phase 2 Kornia GPU augmentation for segmentation masks #1003)Grayscale and multispectral imagery support. RF-DETR models now accept inputs with any number of channels, not just 3. The pretrained DINOv2 patch-embedding weights are automatically adapted to the specified channel count at construction time — no extra dependencies. (Grayscale and Multispectral Imagery Support #180)
PyTorch Lightning
.ckptfiles accepted aspretrain_weights. Keys are auto-normalized from PTL format (state_dictwithmodel.-prefixed keys,hyper_parameters→args) so thatload_pretrain_weights, class-name extraction, and compatibility checks work without manual conversion. (Support PTL.ckptfiles aspretrain_weights#951)rfdetr.from_checkpoint(path). New top-level convenience function that loads a checkpoint and infers the correct model subclass automatically — no need to know or pass the class. Equivalent toRFDETR.from_checkpoint(path). (Addfrom_checkpointmethod that directly infers the model class #664)skip_best_epochsparameter forRFDETR.train()andTrainConfig. The first N epochs are excluded from best-checkpoint selection and early-stopping comparison, so strong pretrained weights or resumed checkpoints can't lock in a suboptimal early score. (feat: skip_best_epochs parameter for training #1000)augmentation_backendfield onTrainConfig("cpu"/"auto"/"gpu"): opt-in GPU-side augmentation via Kornia. CPU path is unchanged and remains the default. Install withpip install 'rfdetr[kornia]'. (feat: Phase 2 Kornia GPU augmentation for segmentation masks #1003)RF_HOMEenvironment variable controls where pretrained model weights are cached (default:~/.roboflow/models). Bare filenames passed aspretrain_weights(e.g."rf-detr-base.pth") resolve relative to this directory; paths with a directory component are used as-is with parent directories created automatically. (Save weights to custom folder of user 's choice #130)training_config.jsonis now saved to the output directory after training completes. Captures the fullTrainConfig,ModelConfig, effective training parameters, class names, and number of classes — useful for reproducibility and debugging predictions from older checkpoints. (Feature: save complete training configuration to disk after training #194)Native RLE annotation support in the COCO segmentation pipeline.
convert_coco_poly_to_masknow decodes both compressed (string counts) and uncompressed (int-list counts) RLE formats alongside polygons. Malformed annotations now raise instead of being silently swallowed. (feat: add native RLE annotation support in COCO segmentation pipeline #897)ONNX export filenames include the model variant name (e.g.
rfdetr-medium.onnx) instead of the genericinference_model.onnx. Exporting multiple variants to the same directory no longer overwrites previous exports. (feat: include variant name in ONNX export filename #910)Background images (no matching label file) are included in YOLO detection datasets as empty-detection samples instead of being silently dropped. Both detection and segmentation paths now use
_LazyYoloDetectionDatasetfor consistent behaviour. (Add background image support for YOLO detection #915)RFDETR.predict(include_source_image=...)— opt-out flag (defaultTrue) to skip storing the source image indetections.metadata["source_image"]; set toFalseto reduce memory use when the image is not needed for annotation. (Fix inference optimization cleanup and download temp-file races #912)model_nameis now stored in checkpoint files during training so thatRFDETR.from_checkpoint()can resolve the correct model class directly from the checkpoint, without requiring the caller to pass a class hint. Backward-compatible: checkpoints withoutmodel_namecontinue to resolve via filename matching. (feat: store model_name in checkpoint for model identification #895)rfdetr_versionis now stored in checkpoint files during training for provenance tracking and compatibility hints. (Addrfdetr_versionto checkpoint payloads #918)dinov2_with_registers_windowed_smallbackbone is now available as a config option inModelConfig.encoder. (Update config.py add dinov2 with registers #236)Builder API surface (advanced users)
build_model_from_config(model_config, train_config=None, defaults=MODEL_DEFAULTS)— config-native alternative tobuild_model(build_namespace(mc, tc)); accepts Pydantic config objects directly. (refactor: config-nativebuild_{model|criterion}_from_config#845)build_criterion_from_config(model_config, train_config, defaults=MODEL_DEFAULTS)— config-native alternative tobuild_criterion_and_postprocessors(build_namespace(mc, tc)). (refactor: config-nativebuild_{model|criterion}_from_config#845)ModelDefaultsdataclass andMODEL_DEFAULTSsingleton — exposes the 35 hardcoded architectural constants previously buried insidebuild_namespace(). Customise withdataclasses.replace(MODEL_DEFAULTS, ...). (refactor: config-nativebuild_{model|criterion}_from_config#845)BuilderArgs— a@runtime_checkabletyping.Protocoldocumenting the minimum attribute set consumed bybuild_model(),build_backbone(),build_transformer(), andbuild_criterion_and_postprocessors(). (refactor: BuilderArgs Protocol + ModelConfig/TrainConfig field deduplication #841)peftis no longer installed by default. It has moved to the[lora]and[train]optional extras. If you use LoRA fine-tuning, install withpip install 'rfdetr[lora]'. Existingrfdetr[train]installs continue to includepeft. (chore: packaging pins + move peft to [lora] extra, fix eager backbone import #838)🗑️ Deprecated
rfdetr.util.*andrfdetr.deploy.*import paths — both shim packages remain active in 1.7.0 and emitDeprecationWarning. Userfdetr.utilities.*andrfdetr.export.*instead. Removal in v1.9. (chore: add __getattr__ hook for rfdetr.util/rfdetr.deploy removal #839)RFDETRBase— useRFDETRNano,RFDETRSmall,RFDETRMedium, orRFDETRLargeinstead. EmitsDeprecationWarningon instantiation; scheduled for removal in v2.0. (deprecate RFDETRBase and RFDETRSegPreview #900)RFDETRSegPreview— useRFDETRSegNano,RFDETRSegSmall,RFDETRSegMedium, orRFDETRSegLargeinstead. EmitsDeprecationWarningon instantiation; scheduled for removal in v2.0. (deprecate RFDETRBase and RFDETRSegPreview #900)build_namespace(model_config, train_config)— usebuild_model_from_config,build_criterion_from_config, or_namespace_from_configsdirectly. Removal in v1.9. (refactor: config-nativebuild_{model|criterion}_from_config#845)load_pretrain_weights(nn_model, model_config, train_config)— thetrain_configpositional argument is no longer used and emitsDeprecationWarning. Removal in v1.9. (refactor: config-nativebuild_{model|criterion}_from_config#845)TrainConfig.group_detr,TrainConfig.ia_bce_loss,TrainConfig.segmentation_head,TrainConfig.num_select,ModelConfig.cls_loss_coef— each now emitsDeprecationWarningwhen set on the wrong config object. Removal in v1.9.SegmentationTrainConfigusers: remove thenum_selectoverride — the model config value is always used. (refactor: BuilderArgs Protocol + ModelConfig/TrainConfig field deduplication #841)🔧 Fixed
Fixed ONNX/TRT dynamic batch inference.
gen_encoder_output_proposalsandTransformer.forwardextracted the batch size as a Python int and passed it totorch.full,.view(N_, ...),.expand(N_, ...), and.repeat(bs, ...), baking the training batch size into the exported graph. TRT engines built with--minShapessmaller than the trace batch failed at inference withReshape: reshaping failed. All six call sites now use ONNX-symbolic equivalents (zeros_like,-1reshapes,expand(memory.shape[0], ...)). (Refactor proposal generation in transformer.py for ONNX/TRT dynamic batching compatibility #950)Fixed
RFDETRModelModule.on_load_checkpointcrashing withRuntimeErroron resume from a different image resolution. DINOv2 positional embeddings in the checkpoint are now bicubic-interpolated to matchmodel_config.positional_encoding_sizebefore PyTorch Lightning applies the state dict. (fix: interpolate PE inon_load_checkpointfor resume #1002)Fixed training failure when
square_resize_div_64=False. The non-square resize pipeline (SmallestMaxSize+LongestMaxSize) did not guarantee output dimensions divisible bypatch_size * num_windows, causingWindowedDinov2WithRegistersEmbeddings.forwardto raiseValueError. APadIfNeededstep is now appended in both train and val/test pipelines. (fix: pad non-square resize outputs to multiples of patch_size * num_windows #991)Fixed YOLO segmentation training out-of-memory on large datasets.
supervision.DetectionDataset.from_yolo(force_masks=True)was eager-rasterising H×W boolean masks at dataset construction time (≈1 GB per 1 000 images at 1024 px). A new_LazyYoloDetectionDatasetstores polygon coordinates only and defers dense mask rasterisation to__getitem__, keeping RAM proportional to annotation count. (Lazily materialize YOLO segmentation masks at sample fetch time #851)Fixed
_namespace.pyregression whereTrainConfig.num_select=300silently overrode model-specific values of 100–200 for segmentation variants.num_selectin the builder namespace now always reads fromModelConfig. (refactor: BuilderArgs Protocol + ModelConfig/TrainConfig field deduplication #841)Fixed
models/weights.py:load_pretrain_weightsnow correctly auto-aligns the model head when the checkpoint has fewer classes than the configured default, preventing a silent mismatch whennum_classeswas not explicitly set. (refactor: config-nativebuild_{model|criterion}_from_config#845)Fixed
RFDETRLargeinitialization showing two conflictingValueErrors. When the deprecated-config fallback retry also fails, the fallback now re-raises the original error without chained context, so users see a single deterministic message. (Suppress chained fallback exceptions for RFDETR patch-size #975)Fixed
WindowedDinov2WithRegistersEmbeddings.forward()failing silently under-Owhen input spatial dimensions are not divisible bypatch_size * num_windows. It now raisesValueErrorwith a clear message identifying the divisor and actual shape. (Enhance WindowedDinov2 input validation and fix tensor reshaping #167)class_namelookup for pretrained models (#988). The fix in fix: correctclass_namelookup for pretrained COCO models #1005 was reverted (bd1634b9) due to a regression. A follow-up fix is planned; in the meantime,class_namefor pretrained COCO models may be missing or incorrect. Workaround: read class names from the model'sclass_namesattribute directly.🏆 Contributors
A special welcome to our new contributors and a big thank you to everyone who helped with this release:
RF_HOMEweight cache directorytraining_config.jsonreproducibility outputdinov2_with_registers_windowed_smallbackbone optionfrom_checkpointmodel-class auto-resolutionmodel_namestorage + typing modernizationskip_best_epochsparameterAutomated contributions: @copilot, @pre-commit-ci[bot]
Full changelog: 1.6.5...1.7.0