Download benchmark.py from abbaab/DGFF: direct link, hf CLI and curl.
- Browser
- Download file 5.07 kB
-
https://huggingface.co/abbaab/DGFF/resolve/main/benchmark.py
- Command line
-
hf download hf://abbaab/DGFF/benchmark.py
-
curl -L -o benchmark.py https://huggingface.co/abbaab/DGFF/resolve/main/benchmark.py
5.07 kB
| import time | |
| import torch | |
| import torch.nn as nn | |
| from ultralytics import YOLO | |
| from thop import profile | |
| from models import LLEN, DGFFModule | |
| torch.manual_seed(0) | |
| IMG_SIZE = 256 # matches training crop size in the paper | |
| N_WARMUP = 5 | |
| N_TIMED = 30 | |
| device = torch.device('cpu') | |
| print("=" * 70) | |
| print("1. PARAMETER COUNTS") | |
| print("=" * 70) | |
| llen = LLEN(base_ch=32).to(device).eval() | |
| dgff = DGFFModule(yolo_weights='yolov8n.pt', llen_base_ch=32, freeze_backbone=True).to(device).eval() | |
| llen_params = sum(p.numel() for p in llen.parameters()) | |
| dgff_total, dgff_trainable = dgff.count_parameters() | |
| backbone_params = sum(p.numel() for p in dgff.backbone.parameters()) | |
| adapter_params = dgff_total - backbone_params | |
| print(f"LLEN total params : {llen_params:,}") | |
| print(f"DGFF backbone (frozen) params: {backbone_params:,}") | |
| print(f"DGFF adapter (trainable) params: {adapter_params:,}") | |
| print(f"DGFF module total params : {dgff_total:,}") | |
| # Full YOLOv8n detector (backbone+neck+head) for actual detection inference | |
| yolo_full = YOLO('yolov8n.pt') | |
| yolo_det_params = sum(p.numel() for p in yolo_full.model.parameters()) | |
| print(f"Full YOLOv8n detector params : {yolo_det_params:,}") | |
| print() | |
| print("=" * 70) | |
| print("2. FLOPs (thop, single image, {}x{})".format(IMG_SIZE, IMG_SIZE)) | |
| print("=" * 70) | |
| dummy = torch.rand(1, 3, IMG_SIZE, IMG_SIZE) | |
| # LLEN alone (Pass-1-equivalent / inference-time enhancement) | |
| macs_llen, params_llen = profile(llen, inputs=(dummy,), verbose=False) | |
| print(f"LLEN forward : {macs_llen/1e9:.3f} GMACs ({2*macs_llen/1e9:.3f} GFLOPs)") | |
| # DGFF module alone (backbone truncated to 10 layers + 3 adapters) -- TRAINING ONLY | |
| macs_dgff, params_dgff = profile(dgff, inputs=(dummy,), verbose=False) | |
| print(f"DGFF module forward (train-only): {macs_dgff/1e9:.3f} GMACs ({2*macs_dgff/1e9:.3f} GFLOPs)") | |
| # Full YOLOv8n detector alone (inference-time detection step) | |
| yolo_model = yolo_full.model.to(device).eval() | |
| macs_yolo, params_yolo = profile(yolo_model, inputs=(dummy,), verbose=False) | |
| print(f"Full YOLOv8n detector forward : {macs_yolo/1e9:.3f} GMACs ({2*macs_yolo/1e9:.3f} GFLOPs)") | |
| print() | |
| print("Pipeline totals:") | |
| raw_flops = 2 * macs_yolo | |
| llen_only_flops = 2 * macs_llen + 2 * macs_yolo | |
| dgff_train_flops = 2 * macs_llen + 2 * macs_dgff + 2 * macs_llen + 2 * macs_yolo # pass1 LLEN + DGFF + pass2 LLEN + detect | |
| dgff_infer_flops = llen_only_flops # DGFF discarded at inference -> identical to LLEN-only | |
| print(f" Raw -> Detect : {raw_flops/1e9:.3f} GFLOPs") | |
| print(f" LLEN-only -> Detect (inference) : {llen_only_flops/1e9:.3f} GFLOPs") | |
| print(f" DGFF TRAINING (2-pass + adapters) : {dgff_train_flops/1e9:.3f} GFLOPs") | |
| print(f" DGFF INFERENCE (adapters discarded) : {dgff_infer_flops/1e9:.3f} GFLOPs (identical arch. to LLEN-only)") | |
| print() | |
| print("=" * 70) | |
| print("3. CPU LATENCY (single-core sandbox CPU -- relative comparison only)") | |
| print("=" * 70) | |
| def time_forward(fn, n_warmup=N_WARMUP, n_timed=N_TIMED): | |
| with torch.no_grad(): | |
| for _ in range(n_warmup): | |
| fn() | |
| times = [] | |
| for _ in range(n_timed): | |
| t0 = time.perf_counter() | |
| fn() | |
| times.append(time.perf_counter() - t0) | |
| times.sort() | |
| return sum(times) / len(times), times[len(times) // 2] | |
| mean_llen, med_llen = time_forward(lambda: llen(dummy)) | |
| mean_yolo, med_yolo = time_forward(lambda: yolo_model(dummy)) | |
| mean_dgff, med_dgff = time_forward(lambda: dgff(dummy)) | |
| print(f"LLEN forward : mean {mean_llen*1000:.2f} ms | median {med_llen*1000:.2f} ms") | |
| print(f"Full YOLOv8n forward : mean {mean_yolo*1000:.2f} ms | median {med_yolo*1000:.2f} ms") | |
| print(f"DGFF module forward (train-only) : mean {mean_dgff*1000:.2f} ms | median {med_dgff*1000:.2f} ms") | |
| raw_latency = mean_yolo | |
| llen_only_latency = mean_llen + mean_yolo | |
| dgff_infer_latency = llen_only_latency # identical arch at inference | |
| dgff_train_latency = 2 * mean_llen + mean_dgff + mean_yolo # 2-pass LLEN + DGFF extraction/adapters + detect | |
| print() | |
| print("Pipeline latency (mean, ms/image):") | |
| print(f" Raw -> Detect : {raw_latency*1000:.2f} ms ({1/raw_latency:.1f} FPS)") | |
| print(f" LLEN-only -> Detect (inference) : {llen_only_latency*1000:.2f} ms ({1/llen_only_latency:.1f} FPS)") | |
| print(f" DGFF INFERENCE (adapters discarded): {dgff_infer_latency*1000:.2f} ms ({1/dgff_infer_latency:.1f} FPS)") | |
| print(f" DGFF TRAINING (2-pass, for ref.) : {dgff_train_latency*1000:.2f} ms ({1/dgff_train_latency:.1f} FPS)") | |
| print() | |
| print("=" * 70) | |
| print("4. SANITY CHECK vs paper-reported parameter counts") | |
| print("=" * 70) | |
| print(f"Paper claims LLEN = 4,844,803 | measured = {llen_params:,} | match={llen_params==4844803}") | |
| print(f"Paper claims DGFF total = 1,359,120 | measured = {dgff_total:,} | match={dgff_total==1359120}") | |
| print(f"Paper claims adapters = 86,464 | measured = {adapter_params:,} | match={adapter_params==86464}") | |
| print(f"Paper claims backbone = 1,272,656 | measured = {backbone_params:,} | match={backbone_params==1272656}") | |