Download mps_probe.py from abbaab/DGFF: direct link, hf CLI and curl.
- Browser
- Download file 3.82 kB
-
https://huggingface.co/abbaab/DGFF/resolve/main/mps_probe.py
- Command line
-
hf download hf://abbaab/DGFF/mps_probe.py
-
curl -L -o mps_probe.py https://huggingface.co/abbaab/DGFF/resolve/main/mps_probe.py
3.82 kB
| """ | |
| mps_probe.py β answers ONE question: will the Table 6 ablation | |
| (real_ablation_cell.py, which trains LLEN+DGFFModule directly, NOT via | |
| Ultralytics) run on MPS or fall back to CPU on this machine/environment? | |
| This does NOT test Ultralytics detector training (that's a separate code | |
| path and separate question, already known to be slow on this setup). | |
| This tests the actual custom training loop the ablation uses. | |
| Strictly time-bounded: 10 iterations only, so this finishes in well under | |
| a minute even in the worst case. Needs models.py in the same directory. | |
| """ | |
| import time | |
| import torch | |
| print(f"torch version: {torch.__version__}") | |
| print(f"MPS built: {torch.backends.mps.is_built()}") | |
| print(f"MPS available: {torch.backends.mps.is_available()}") | |
| if not torch.backends.mps.is_available(): | |
| print("\nMPS is NOT available in this environment. The ablation will run " | |
| "on CPU. Given today's CPU timings for a much smaller model were " | |
| "already very slow, expect the ablation to be impractically slow " | |
| "too -- don't start it blind. Consider a different conda env/torch " | |
| "build (this one is on Python 3.14.2 / torch 2.10.0, both very new " | |
| "-- an older, more established torch build may have better MPS " | |
| "support) before committing to a long run.") | |
| raise SystemExit | |
| device = torch.device('mps') | |
| print(f"\nUsing device: {device}") | |
| from models import LLEN, DGFFModule # same file used for benchmark.py earlier | |
| BATCH = 4 # matches paper's Phase 1 batch size | |
| CROP = 256 # matches paper's Phase 1 crop size | |
| N_ITERS = 10 | |
| print(f"\nBuilding LLEN + DGFFModule on {device}...") | |
| llen = LLEN(base_ch=32).to(device) | |
| dgff = DGFFModule(yolo_weights='yolov8n.pt', llen_base_ch=32, freeze_backbone=True).to(device) | |
| trainable = list(llen.parameters()) + list(dgff.adapter_p3.parameters()) + \ | |
| list(dgff.adapter_p4.parameters()) + list(dgff.adapter_p5.parameters()) | |
| optimiser = torch.optim.Adam(trainable, lr=1e-4) | |
| l1 = torch.nn.L1Loss() | |
| dummy_low = torch.rand(BATCH, 3, CROP, CROP, device=device) | |
| dummy_high = torch.rand(BATCH, 3, CROP, CROP, device=device) | |
| print(f"Running {N_ITERS} timed training iterations " | |
| f"(batch={BATCH}, crop={CROP}x{CROP}, matches paper's Phase 1 settings)...") | |
| # warmup (first MPS call compiles kernels -- don't count this) | |
| enhanced = llen(dummy_low) | |
| p4, p5, p3 = dgff(enhanced) | |
| guided = llen(dummy_low, dgff_p5=p5, dgff_p4=p4, dgff_p3=p3) | |
| loss = l1(guided, dummy_high) | |
| loss.backward() | |
| torch.mps.synchronize() | |
| times = [] | |
| for i in range(N_ITERS): | |
| torch.mps.synchronize() | |
| t0 = time.perf_counter() | |
| optimiser.zero_grad() | |
| enhanced = llen(dummy_low) | |
| p4, p5, p3 = dgff(enhanced) | |
| guided = llen(dummy_low, dgff_p5=p5, dgff_p4=p4, dgff_p3=p3) | |
| loss = l1(guided, dummy_high) | |
| loss.backward() | |
| optimiser.step() | |
| torch.mps.synchronize() | |
| dt = time.perf_counter() - t0 | |
| times.append(dt) | |
| print(f" iter {i+1}/{N_ITERS}: {dt:.3f}s") | |
| mean_iter = sum(times) / len(times) | |
| print(f"\nMean time/iteration: {mean_iter:.3f}s") | |
| # ββ extrapolate to full ablation cost ββ | |
| TRAIN_PAIRS = 485 # paper's LOL train set size | |
| iters_per_epoch = TRAIN_PAIRS / BATCH | |
| ablation_epochs = 50 | |
| n_configs = 4 | |
| total_iters = iters_per_epoch * ablation_epochs * n_configs | |
| est_seconds = total_iters * mean_iter | |
| print(f"\n=== Extrapolated full ablation cost (4 configs x {ablation_epochs} epochs) ===") | |
| print(f" ~{iters_per_epoch:.0f} iterations/epoch x {ablation_epochs} epochs x {n_configs} configs " | |
| f"= {total_iters:.0f} total iterations") | |
| print(f" Estimated total time: {est_seconds/3600:.1f} hours") | |
| print(f" (paper's Phase 1: 200 epochs, single config, reported as 7.6h on MPS -- " | |
| f"this is a rough sanity cross-check on the estimate above)") | |