feat(agent): dedupe near-duplicate crops before the SigLIP embed
Figure boxes are already NMS-merged (iou 0.6) and each YOLO detector self-NMSes, but the combined per-frame crop pile (figure→concept ∪ anatomy component→concept ∪ panel) was embedded with no cross-proposer dedup — so genuine near-duplicates slipped through (a figure box ≈ an anatomy component on a solo bust; overlapping booru head classes on one head), embedding the same region twice and burning a slot against max_regions. Add detectors.dedupe_crops(): a greedy, high-IoU (default 0.85), kind-aware pass over the pending (crop, template) list right before embed_batch — drop boxes that overlap ≥ iou within the same kind, keep the highest score. The high threshold is deliberate: it collapses only true near-identical boxes while preserving intentional nested crops across scopes (a whole figure vs a small head component sit well below it) and distinct kinds (concept vs panel). Env-tunable DEDUPE_IOU (≥1.0 disables). Runs on CPU before the GPU work, so it cuts both embed cost and region count. Temporal (cross-frame) dedup deferred. Build marker 2026-07-01.2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa
This commit is contained in:
@@ -40,6 +40,7 @@ from . import media, models
|
||||
from .client import FcClient
|
||||
from .config import Config
|
||||
from .crops import crop_region
|
||||
from .detectors import dedupe_crops
|
||||
|
||||
# Cap on the lease-retry backoff: when curator is unreachable (e.g. you redeploy
|
||||
# it while away), a downloader retries leasing with exponential backoff up to this
|
||||
@@ -629,6 +630,12 @@ class Worker:
|
||||
"score": score, "detector_version": "panel",
|
||||
}))
|
||||
if pending:
|
||||
# Drop near-duplicate crops (a figure box ≈ an anatomy
|
||||
# component, overlapping booru classes) before the embed so we
|
||||
# never SigLIP the same region twice — saves GPU and a slot
|
||||
# against max_regions. High-IoU + kind-aware, so intentional
|
||||
# nested crops (figure ⊃ head) survive.
|
||||
pending = dedupe_crops(pending, self.cfg.dedupe_iou)
|
||||
vecs = embedder.embed_batch([c for c, _ in pending])
|
||||
for (_c, tmpl), vec in zip(pending, vecs, strict=True):
|
||||
tmpl["siglip_embedding"] = vec
|
||||
|
||||
Reference in New Issue
Block a user