DFINE¶
The public, backend-agnostic detector class: build from typed params, load released
weights, and predict / train / val / export / benchmark. Backend details never
leak through its kwargs.
For task-oriented, copy-paste recipes see the examples cookbook and
the runnable templates/.
Build a model¶
from dfine import DFINE, DFINEConfig
# From a released checkpoint — size + num_classes inferred, weights downloaded + loaded.
model = DFINE.from_pretrained("dfine-s")
# From a size preset (ImageNet backbone); every field is overridable inline.
model = DFINE(size="l", num_classes=80, imgsz=640, device="cuda")
# From a bare size + your own weights.
model = DFINE(size="m", num_classes=3).load("runs/train/best.pth")
# From a fully custom config object.
cfg = DFINEConfig.preset("s", num_classes=3, class_names=["cat", "dog", "bird"])
model = DFINE(config=cfg)
imgsz is a build-time choice
The encoder's positional embeddings are precomputed for the model's imgsz, so
predict/export/benchmark must use that same size. To run at a different
resolution, rebuild: DFINE(size=…, imgsz=…).
Predict¶
results = model.predict("street.jpg", conf=0.4) # list[Results], one per image
r = results[0]
r.boxes.xyxy, r.boxes.conf, r.boxes.cls # tensors, original-image scale
r.save("out.jpg")
# Folders, globs, and lists all work; save flags write a run dir.
model.predict("images/", save=True, save_txt=True, save_crop=True)
See Results & Boxes for the returned containers.
Train, validate, export¶
# Fine-tune on a COCO root (loaders built for you). Multi-GPU: devices=N.
model.train(data="coco/", epochs=72, batch_size=8, devices=2)
# 12 COCO metrics (+ optional analytics plots).
metrics = model.val(data="coco/", plots=True)
print(metrics["AP"])
# Deployable graph (postprocessor fused in).
model.export(format="onnx", simplify=True)
Inspect and time¶
model.info(verbose=True) # layers / params / gradients / GFLOPs
model.benchmark(runs=100, batch=1) # {"ms_per_image", "fps", "device", ...}
Video¶
model.predict_video("in.mp4", output="out.mp4", track=True) # annotated mp4 + IDs
for r in model.predict_video("in.mp4", stream=True): # per-frame Results
...
API reference¶
dfine.model.DFINE ¶
DFINE(size: str | None = None, *, config: DFINEConfig | None = None, weights: str | PathLike | None = None, device: str | device | None = None, **params)
Config-first D-FINE detector with an ultralytics-style predict.
Source code in dfine/model.py
from_pretrained
classmethod
¶
Build a model matching a released checkpoint and load its weights.
name is a catalogue entry ("dfine-s", "dfine-l-obj365" ...); the
size and num_classes are taken from it. See dfine models.
Source code in dfine/model.py
load ¶
Load weights into the model, in place.
weights is either a catalogue name (downloaded + cached) or a local
.pth path. Returns self for chaining: DFINE(size="s").load("dfine-s").
Source code in dfine/model.py
predict ¶
predict(source, conf: float = 0.25, imgsz: int | None = None, mask_thresh: float = 0.5, *, save: bool = False, save_txt: bool = False, save_crop: bool = False, save_conf: bool = False, project: str = 'runs/detect', name: str = 'predict') -> list[Results]
Detect objects in source (path / PIL / array, or a list of them).
A source string that is a directory runs over all images in it (sorted), and
one with glob magic (e.g. "imgs/*.jpg") over the matches; a list may mix folders,
globs and explicit images. An empty directory/glob raises FileNotFoundError.
Returns one :class:~dfine.results.Results per image; boxes are in the
original pixel scale. conf drops low-scoring detections. For a
task="segment" model, each result also carries per-instance
:class:~dfine.results.Masks (original scale), thresholded at mask_thresh.
For a task="sem_seg" model each result instead carries a
:class:~dfine.results.SemSeg label map (uint8, original scale) and no boxes.
Set any of save (annotated image), save_txt (YOLO-format labels under
labels/; save_conf appends the score) or save_crop (per-detection
crops under crops/) to write results to a fresh run directory
project/name (auto-incremented to predict2, predict3, … so runs never
clobber). Filenames come from each source path's stem, else image{i}.
Source code in dfine/model.py
benchmark ¶
Measure forward-pass inference speed on random input at the model's resolution.
Runs warmup untimed then runs timed forward passes (the postprocessor is not
included — this is the compute-bound model latency), synchronizing CUDA around the
timed region. Returns {"imgsz", "batch", "runs", "device", "ms_per_image", "fps"}
and logs a one-line summary. imgsz must equal the model's imgsz (the encoder's
positional embeddings are precomputed for it).
Source code in dfine/model.py
info ¶
Model summary: layer/parameter/gradient counts (+ GFLOPs if thop is installed).
Returns {"layers", "parameters", "gradients", "gflops"} (gflops is None
when thop is unavailable) and logs a one-line summary. With verbose=True also
logs the per-top-level-module (backbone/encoder/decoder) parameter breakdown.
Source code in dfine/model.py
train ¶
train(train_loader=None, epochs: int | None = None, *, data: str | PathLike | None = None, batch_size: int = 4, num_workers: int = 4, augment: bool = True, remap_mscoco_category: bool | None = None, val_split: float = 0.2, devices: int | None = None, val_loader=None, val_fn=None, output_dir: str = 'runs/train', resume: str | PathLike | bool | None = None, use_wandb: bool = False, visualize: bool = True, val_plots: bool = False)
Fine-tune the model (Phase 4).
Provide the data one of two ways:
data="path/to/coco"— a standard COCO dataset root (train/+annotations/instances_train.json, optionalval/; a stock MS-COCOtrain2017/layout is auto-detected too). The train loader (full two-phase augmentation + multi-scale) and, if present, a val loader are built for you via :func:~dfine.train.dataset.build_coco_dataloaders.batch_size,num_workers,augmentandremap_mscoco_categorytune that build (setremap_mscoco_category=Truefor stock 80-class MS-COCO ids). For atask="segment"/"sem_seg"model,data=is instead a YOLO-style root (images/+labels/: polygon.txtfor segment, class-id.pngfor sem_seg) built via :func:~dfine.train.seg_dataset.build_seg_dataloaders. Train/val are split fromimages/{train,val}subdirs if present, else a deterministicval_splitfraction (default0.2; set0to train on everything) of the flat root; the seg val loader is auto-scored with mask AP (segment) / mIoU (sem_seg).train_loader=...— a ready dataloader yielding(samples, targets)batches:samplesa floatBCHWimage tensor, eachtargeta dict withlabels(LongTensor) andboxes(cxcywh, normalized).
Multi-GPU: pass devices=N to train on N GPUs — this call becomes the
launcher and spawns one DDP worker per GPU (no torchrun needed); it requires
data= (in-memory loaders can't be shipped to workers). Alternatively launch
the script yourself with torchrun --nproc_per_node=N and call train(...)
without devices — each worker detects the distributed env and joins the group.
Optimizer groups, LR schedule, EMA, AMP and grad-clip all come from this
model's :class:~dfine.config.DFINEConfig. Progress is visualized like upstream
D-FINE: a live tqdm progress bar (total loss + lr; the full per-term loss
breakdown streams to TensorBoard) plus TensorBoard scalars and a loss_curve.png
under output_dir (and W&B if use_wandb); only rank 0 writes them. Returns
self; the trained (EMA) weights replace self.model.
Checkpoints (rank 0): last.pth after every epoch, best.pth whenever the
primary validation metric improves (detection AP / mask mAP_50_95_mask /
mIoU), and — when config.checkpoint_freq > 0 — a resumable
weights/epoch{N}.pth snapshot every checkpoint_freq epochs.
Resume: pass resume= to continue an interrupted run — a checkpoint path, or
True for output_dir/last.pth. Model, optimizer, LR scheduler, EMA and the
best metric are restored and training picks up at the saved epoch + 1.
When a val_loader is available (passed, or auto-built from data) and no
val_fn is given, COCO metrics are computed each epoch via
:func:~dfine.train.evaluator.coco_val_fn and logged alongside the loss.
Pass val_plots=True to also render the full validation-analytics bundle
(confusion matrix, P/R/F1 curves, per-class AP, worst-predictions gallery) every
epoch under output_dir/val/epoch{N}/ — the same artifacts as
val(plots=True), kept per epoch. Needs matplotlib (the [train] extra) and
contiguous labels; it is ignored (with a warning) when
remap_mscoco_category=True or for segment/sem_seg tasks. Off by default
since it adds per-epoch compute and disk.
Source code in dfine/model.py
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 | |
val ¶
val(data: str | PathLike | None = None, *, val_loader=None, batch_size: int = 4, num_workers: int = 4, remap_mscoco_category: bool | None = None, plots: bool = False, output_dir: str = 'runs/val') -> dict[str, float]
Evaluate the model on a COCO val set and return the metrics dict.
Provide the data one of two ways (mutually exclusive):
data="path/to/coco"— a COCO root; the val loader is built fromval/+annotations/instances_val.jsonfor you (a stock MS-COCOval2017/layout is auto-detected too).val_loader=...— a ready loader frombuild_coco_dataloader(its dataset must carry the ground-truth.coco).
Returns the 12 standard COCO metrics keyed by name (AP is the primary
mAP@[.50:.95]); see :data:~dfine.train.evaluator.COCO_STAT_NAMES. For stock
MS-COCO ground truth (sparse category ids), build the model with
remap_mscoco_category=True so predicted labels match the annotations.
With plots=True also writes a confusion matrix + precision–recall curves and
logs the per-class AP table under output_dir (default runs/val); needs
matplotlib (the [train] extra). The confusion matrix assumes contiguous labels,
so plots is ignored (with a warning) when remap_mscoco_category=True.
Source code in dfine/model.py
export ¶
export(format: str = 'onnx', file: str | PathLike | None = None, *, imgsz: int | None = None, batch: int = 1, dynamic: bool = True, simplify: bool = False, opset: int = 16) -> Path
Export the model to a deployable graph (Phase 3).
format="onnx" (default) writes a single ONNX graph, batch dim dynamic by
default; format="torchscript" writes a .torchscript traced at a fixed
batch/imgsz (torch-only, no ONNX toolchain). The outputs follow the model's
task:
detect—(images, orig_target_sizes)→(labels, boxes, scores).segment— same inputs →(labels, boxes, scores, masks)(masks are the top-k queries' sigmoid maps at 1/4 res; threshold/resize/clip on the host).sem_seg—images→sem_seg[N, H, W]uint8 label map (argmax fused in; resize to the original size on the host).
Returns the output :class:~pathlib.Path. ONNX needs pip install pydfine[export];
TorchScript needs only torch. file defaults to dfine-<size>.<ext>. ONNX-only
knobs (dynamic/simplify/opset) are ignored for TorchScript. Use
:func:dfine.export.tensorrt_command for a downstream trtexec engine. Export
traces on CPU so the saved artifact is portable regardless of the live model's device.
Source code in dfine/model.py
predict_video ¶
predict_video(source, output: str | PathLike = 'output.mp4', conf: float = 0.25, imgsz: int | None = None, stream: bool = False, track: bool = False)
Detect objects frame-by-frame in a video.
With stream=True returns a generator of per-frame :class:Results and
writes nothing. Otherwise writes an annotated video to output (original
resolution/fps) and returns its :class:~pathlib.Path.
With track=True each frame's detections are run through a ByteTrack tracker
so boxes carry a persistent boxes.id across frames (rendered as #id and
colored per track). Needs scipy (the [track] extra).