Skip to content

Add LibreRFDETRm-ui (UI-DETR-1), match upstream RF-DETR resize, make Results.plot() render every task - #897

Merged
EHxuban11 merged 12 commits into
devfrom
896-ui-detr
Sep 25, 2026
Merged

EHxuban11 merged 12 commits into
devfrom
896-ui-detr

Conversation

@EHxuban11

@EHxuban11 EHxuban11 commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

What: add the UI-DETR-1 weights as an RF-DETR dataset variant (LibreRFDETRm-ui.pt), and fix two RF-DETR bugs it exposed.
Why: #896. UI-DETR-1 (racineai, MIT) is an RF-DETR-M fine-tune for class-agnostic UI element detection, so it needs weights, not a new family.

  • WEIGHT_VARIANTS = ("ui",) on RF-DETR, so LibreRFDETRm-ui.pt auto-downloads from LibreYOLO/LibreRFDETRm-ui.
  • PUBLISHED_WEIGHT_VARIANTS limits variant downloads to the published (size, task, variant) triples; names like LibreRFDETRs-ui.pt or LibreRFDETRm-seg-ui.pt raise FileNotFoundError listing the valid name instead of hitting a 404.
  • RF-DETR predict/val resize is now bilinear without antialiasing (cv2 float32), matching RF-DETR training and upstream predict() since rf-detr 1.9.0 (fix(inference): disable antialias in predict() resize to match training roboflow/rf-detr#1206). Before this, PIL bilinear antialiased on downscale and boxes drifted on large inputs.
  • Single-output upstream RF-DETR heads (one-category training set) now convert as nc=1, not nc=80 with 79 placeholder names.
  • Weights uploaded to https://huggingface.co/LibreYOLO/LibreRFDETRm-ui (tensors identical to upstream model state, strict schema validation passes) and added to the LibreYOLO Models collection. Auto-download from a clean directory verified.
  • Results.plot() renders every predict output (boxes, masks, OBB, keypoints, classify top-5, points, OCR, semantic, panoptic, gaze). It raised NotImplementedError for all of them. Returns a BGR np.ndarray (pil=True for PIL) and takes conf, labels, boxes, masks, probs, line_width, img, show, save, filename. One renderer, drawing.draw_results, now backs plot(), predict(save=True), video saving, L2CS and every exported-model backend, so a plot matches the saved file.
  • Results.orig_img (BGR) keeps in-memory and URL sources. Local files are reopened from path; collected video/GIF results keep no frames and plot() decodes frame_idx on demand, so directory and video predictions do not hold every image.
  • Docs: nomenclature, weights/LICENSE_NOTICE.txt, upload-skill whitelist, CHANGELOG.

Parity vs upstream rfdetr 1.10.1 at conf 0.3 (5 UI screenshots, 6 COCO images; UI-DETR-1 and stock RF-DETR-M):

UI boxes matched IoU>0.9 UI median IoU COCO median IoU
before 26-60 per image 0.71-0.88 0.968-0.999
after, PyTorch all 0.999-1.000 1.000
after, ONNX all 0.999-1.000 1.000

ONNX vs PyTorch on UI-DETR-1: identical boxes at conf >= 0.3; differences only in boxes below conf 0.26.

Check (plot): draw_results is a move of _save_annotated_image's per-task branches; saved detect/segment/pose images are pixel-identical before and after the refactor (YOLO9, RF-DETR-seg, YOLO-NAS-pose). Classification saves now draw the top-5, and tracked results show track IDs.

Greptile notes: the "single-logit head mislabelled" finding is not a bug. RF-DETR uses sigmoid/focal classification with no background logit; a one-category upstream dataset gives a one-output head, and upstream rfdetr predicts class 0 for every UI-DETR-1 box, which this conversion matches box for box.

Known limits: in-memory image lists keep their sources (the caller already holds them); a collected remote video stream cannot be re-decoded, so pass stream=True to plot its frames.

Check: the resize change affects every RF-DETR detect/seg/obb predict, val and ONNX runtime (pose keeps its antialiased path; LW-DETR/DETR/Deformable DETR have their own preprocess and are untouched). RF-DETR-M COCO mAP50-95 on a 200-image val subset: 0.6195 -> 0.6179.

Not verified:

  • Full COCO val (5k) mAP delta.
  • The six Roboflow Universe training-dataset licenses were not opened individually; the authors declare the merged training data MIT.
  • Local PR gate: 7677 passed; 3 ONNX parity failures (DEIM, RT-DETRv2, D-FINE-seg) also fail on clean dev on this machine and pass in dev CI.

Closes #896.

Opened by an agent.

Code provenance

  • Original code written for this PR.
  • The antialias-free resize follows the behavior of roboflow/rf-detr commit 09ca8f54 (v1.9.0, Apache-2.0); no code was copied.
  • Weights (hosted on HF, not in this repo): racineai/UI-DETR-1, HF revision 0f0dda5, MIT; fine-tuned from RF-DETR-M (roboflow/rf-detr, Apache-2.0) with a DINOv2 backbone (Apache-2.0).

RetriggerConfidence Score: 5/5

The PR appears safe to merge; no new actionable issue or outstanding previous finding remains.

Fix All in CursorFindings

  1. P1 UI weights cannot auto-download. ▶
Summary

The PR adds UI-DETR-1 as an RF-DETR-M weight variant, changes RF-DETR inference resize to match upstream behavior, and gives prediction results a shared renderer for plotting and saving.

  • The changes since the previous review retain decoded sources for gaze and OCR results from in-memory images, URLs, and streamed video.
  • Collected video results release source frames and decode them on demand.

Reviews (4) · Last reviewed commit: "Keep the source image on gaze and OCR re..."

FILENAME_PREFIX: ClassVar[str] = "LibreRFDETR"
# Dataset-variant weights: ``-ui`` is the class-agnostic UI element
# detector (UI-DETR-1, racineai, MIT), an RF-DETR-M fine-tune.
WEIGHT_VARIANTS: ClassVar[tuple[str, ...]] = ("ui",)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 UI weights cannot auto-download. If the Hugging Face mirror remains unavailable as stated in the PR, loading LibreRFDETRm-ui.pt without a local copy sends the user to a URL that returns 404. The advertised auto-download workflow fails, so users cannot obtain the new variant that way. Publish the weights before advertising it as downloadable.

Fix in Cursor Fix in Codex

Comment thread libreyolo/models/rfdetr/model.py
@EHxuban11 EHxuban11 changed the title Add LibreRFDETRm-ui (UI-DETR-1) and match upstream RF-DETR resize Add LibreRFDETRm-ui (UI-DETR-1), match upstream RF-DETR resize, make Results.plot() render every task Sep 24, 2026
@EHxuban11

Copy link
Copy Markdown
Contributor Author

Handoff (end of 2026-09-24)

State of this PR at head 32ec7879 (branch 896-ui-detr, based on current dev):

Done

  • LibreRFDETRm-ui.pt is uploaded to https://huggingface.co/LibreYOLO/LibreRFDETRm-ui (MIT, 5-file contract, strict schema validation passes, tensors bit-identical to upstream model state) and added to the LibreYOLO Models collection. Auto-download from a clean directory verified.
  • RF-DETR predict/val resize now matches upstream rfdetr >= 1.9.0 (no antialias). Parity vs rfdetr 1.10.1: all boxes IoU > 0.9 on UI screenshots and COCO images, PyTorch and ONNX.
  • Results.plot() renders every task through drawing.draw_results, shared with predict(save=True), video saving, L2CS and all export backends.
  • Local Greptile (greptile review --agent --branch dev, after git branch -f dev origin/dev) last scored 3/5 with its one finding fixed in 32ec7879. The remaining notes are listed in the description as a false positive (single-logit head) and known limits.
  • Local PR gate: 7677 passed. test_detr_cpu_export_matrix ONNX parity for DEIM / RT-DETRv2 / D-FINE-seg fails on macOS on clean dev too (passes in CI).

Next steps

  1. Wait for the unit-test jobs and the Greptile bot on 32ec7879 (both pending at handoff). The two inline Greptile comments on model.py:108 are from the first commit and already addressed: the weights are uploaded, and unpublished variant names raise FileNotFoundError.
  2. Fix any new valid bot finding by pushing a commit. Then it's a maintainer merge.

Open decisions (not in this PR)

  • predict() treats numpy arrays as RGB when color_format="auto". The ecosystem convention is BGR (cv2.imread). Changing it changes predictions for array inputs.
  • 18 LibreYOLO HF repos ship no LICENSE file (e.g. LibreRFDETR{n,s,m,l}-cls, LibreYOLO9{t,s,m,c}-cls, LibreYOLO9P2s-visdrone, LibrePPOCR{t,l}-ocr).

Done outside the repo (HF, no code change)

  • Replaced the YOLOX (Megvii) LICENSE that was wrongly copied into 20 HF repos with each upstream's verbatim LICENSE: LibreRFDETR{n,s,m,l} and their -pose repos (roboflow/rf-detr), LibreRTDETR{r18,r34,r50,r50m,r101,l,x} (lyuwenyu/RT-DETR), LibreDEIM{n,s,m,l,x} (ShihuaHuang95/DEIM). Only the YOLOX repos mention Megvii now.

Comment thread libreyolo/utils/results.py
@EHxuban11
EHxuban11 merged commit 4d6d702 into dev Sep 25, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant