Skip to content

feat(detect): Add RF-DETR (rf-detr) detection and instance masks #2431

Closed

Description

@inureyes

Related to #2382 (listed there; scheduled outside its DAG because it rides mlxcel detect)

Problem / Background

RF-DETR (Roboflow, ICLR 2026) is a real-time closed-vocabulary detector on a windowed DINOv2 backbone with a C2f multi-scale projector, two-stage query selection and a deformable decoder, with an optional instance-segmentation head. Its output is boxes, COCO labels and scores (plus masks for the seg variants), which is exactly the mlxcel detect contract RT-DETRv2 already uses; #524 ranked it as the cheapest family there to re-scope for that reason. mlxcel cannot load it today.

Surface decision: RF-DETR registers in mlxcel detect beside rt_detr_v2 through the Detector trait and load_detector dispatch that #2412 introduces (#2413 adds the same contract if it lands first, and changes threshold to Option<f32>), not in the #2349 predict surface. Masks from the segmentation variants leave detect through a new --masks-dir <DIR> flag (one PNG per detection, path recorded in the JSON output). Rejected alternative: routing the segmentation variants through mlxcel predict, which would give one model two commands and make box-only users depend on the dense-prediction surface.

Upstream reference

Current Behavior

  • src/commands/detect.rs:30 run_detect hard-codes RtDetrV2Predictor::from_pretrained at :55; sort_reading_order is at :141. DetectArgs (src/main.rs:890-906) has --model, --image, --threshold (default 0.3) and --format.
  • src/vision/detection/mod.rs:28-31 re-exports only RT-DETRv2 types; Detection (src/vision/detection/rt_detr_v2/predictor.rs:37-47) is bbox, score, label, class_name.
  • Reusable RT-DETRv2 pieces: bilinear grid_sample (src/vision/detection/rt_detr_v2/layers.rs), inverse_sigmoid and Mlp (src/vision/detection/rt_detr_v2/transformer.rs:35 and :50), the deformable sampling loop (transformer.rs:88-230), and image decoding plus PIL-equivalent bilinear resize through image::imageops::FilterType::Triangle (src/vision/detection/rt_detr_v2/processor.rs:154-180).
  • feat(detect): Add PP-DocLayoutV3 layout detection with reading order #2412 and feat(detect): Add YOLO11 detector for OmniParser v2 icon detection #2413 (both open) each specify the Detector trait, load_detector dispatch on config.json model_type, Detection moved to mod.rs, and per-detector default thresholds; whichever lands second registers into the first one's dispatch.
  • The feat: Add dense-prediction output surface: mlxcel predict, map and keypoint files #2349 src/vision/dense/interpolate.rs port (open) provides resize_bilinear_nhwc (with align_corners) and resize_bicubic_nhwc, matching upstream mlx_vlm/models/interpolate.py, which RF-DETR's segmentation head imports.
  • feat: Port DINOv2 backbone (dinov2, dinov2_with_registers) for dense models #2350 ports a standard DINOv2 and explicitly leaves the RF-DETR windowed variant out of scope.

Proposed Solution

New module src/vision/detection/rfdetr/ (config.rs, backbone.rs, projector.rs, transformer.rs, segmentation.rs, sanitize.rs, predictor.rs, tests.rs).

Scope

In scope: the module above, dispatch registration, Detection.mask, --masks-dir, docs (docs/supported-models.md detection section, the detect CLI docs).

Out of scope: conversion from Roboflow .pth checkpoints (needs PyTorch; the MLX checkpoints load directly), video and realtime modes, exclude_classes, annotators, exposing RF-DETR through mlxcel predict or the server.

Implementation Notes

Acceptance Criteria

  • mlxcel detect -m models/rfdetr-base-fp32 -i street.jpg --format json prints COCO detections in pixel l, t, r, b.
  • Raw-output parity against mlx-vlm on mlx-community/rfdetr-base-fp32 for one committed image at 560x560: pred_logits and pred_boxes max abs error within 1e-3 in f32; final detections after NMS match (same labels, boxes within 1 px). It fails on current code.
  • Segmentation: mlxcel detect -m models/rfdetr-seg-small-fp32 -i street.jpg --format json --masks-dir out/ writes one PNG per detection and the JSON mask paths; per-mask IoU against upstream at least 0.98.
  • Unit tests, each failing on current code: _window_partition / _window_unpartition round-trip; per-class NMS on synthetic boxes against upstream _nms_per_class; bbox_reparam decode on a hand-computed case; sanitize idempotence; --masks-dir on a detection-only model errors.
  • RT-DETRv2 detect output is unchanged (existing detect and RT-DETRv2 tests pass).
  • mlxcel arch --json lists rf-detr; docs updated.

Verification

cargo build --release --features metal,accelerate
cargo test --workspace --profile test-fast --features metal,accelerate rfdetr
cargo test --workspace --profile test-fast --features metal,accelerate rt_detr
cargo test --workspace --profile test-fast --features metal,accelerate detect
cargo test --workspace --profile test-fast --features metal,accelerate
cargo clippy --workspace --all-targets -- -D warnings
cargo fmt --check
./target/release/mlxcel detect -m models/rfdetr-seg-small-fp32 -i /path/to/street.jpg --format json --masks-dir /tmp/rfdetr-masks

Dependencies

Blocked by #2412 (Detector trait and load_detector dispatch; #2413 provides the same contract if it merges first, in which case only that one is required) and #2349 (interpolate.rs resize functions and the conv-permutation guard).

Activity

  1. added
    status:blockedBlocked by dependencies or other issues
    type:enhancementNew features, capabilities, or significant additions
    area:modelsModel architectures, weights, loading, metadata
    area:cliCommand-line interface / CLI flags
    modelsize:small4-bit checkpoint <= 10GB; fast iteration, safe for smoke tests
    on Oct 16, 2026
  2. added and removed
    status:blockedBlocked by dependencies or other issues
    on Oct 23, 2026
  3. added a commit that references this issue on Oct 25, 2026
    511dce9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:cliCommand-line interface / CLI flagsarea:modelsModel architectures, weights, loading, metadatamodelsize:small4-bit checkpoint <= 10GB; fast iteration, safe for smoke testsmodeltype:vlmVision-language modelpriority:lowLow prioritystatus:doneCompletedtype:enhancementNew features, capabilities, or significant additions

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions