Spaces:
Running on Zero
Running on Zero
Commit ·
994c9a0
1
Parent(s): a104380
Try full pipeline GPU residency before falling back to cpu offload
Browse filesEach ZeroGPU call runs in a fresh worker (offload hooks are always unset
at entry), so enable_model_cpu_offload bought no cross-call reuse — it
just replaced one bulk pipe.to(device) transfer with several slower,
hook-managed component transfers, adding ~55s of pure data movement to a
~62s call per the FireRed-Dev logs. Try the fast full-GPU path first and
only fall back to offload on an actual CUDA OOM (small MIG slices).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
app.py
CHANGED
|
@@ -402,13 +402,22 @@ def _infer_gpu(pil_images, prompt, seed, guidance_scale, steps, width, height, m
|
|
| 402 |
print(f"[infer] GPU: {p.name}, total={p.total_memory/1024**3:.1f}GB, cap={p.major}.{p.minor}")
|
| 403 |
torch.cuda.reset_peak_memory_stats()
|
| 404 |
|
| 405 |
-
#
|
| 406 |
-
#
|
| 407 |
-
#
|
| 408 |
-
#
|
|
|
|
|
|
|
| 409 |
if getattr(pipe.transformer, "_hf_hook", None) is None:
|
| 410 |
-
|
| 411 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 412 |
print(f"[infer] {_gpu_mem_str(_cuda_ok)} — t={time.perf_counter()-t0:.1f}s")
|
| 413 |
|
| 414 |
print(f"[infer] {len(pil_images)} image(s) pre-decoded, output={width}x{height}, seed={seed}")
|
|
@@ -452,9 +461,11 @@ def _infer_gpu(pil_images, prompt, seed, guidance_scale, steps, width, height, m
|
|
| 452 |
timer.print_timings()
|
| 453 |
raise
|
| 454 |
finally:
|
| 455 |
-
# No manual pipe.to("cpu")
|
| 456 |
-
#
|
| 457 |
-
#
|
|
|
|
|
|
|
| 458 |
gc.collect()
|
| 459 |
torch.cuda.empty_cache()
|
| 460 |
print(f"[infer] ===== END t={time.perf_counter()-t0:.1f}s =====")
|
|
|
|
| 402 |
print(f"[infer] GPU: {p.name}, total={p.total_memory/1024**3:.1f}GB, cap={p.major}.{p.minor}")
|
| 403 |
torch.cuda.reset_peak_memory_stats()
|
| 404 |
|
| 405 |
+
# Each ZeroGPU call runs in a fresh worker (hooks are always unset here),
|
| 406 |
+
# so cpu_offload buys no cross-call reuse — it only trades one bulk
|
| 407 |
+
# to(device) transfer for several slower hook-managed ones. Try moving
|
| 408 |
+
# the full ~37GB pipeline to GPU in one shot first (fast); only fall back
|
| 409 |
+
# to enable_model_cpu_offload (keeps one component resident at a time) if
|
| 410 |
+
# that OOMs on a smaller MIG slice (e.g. the 47GB 2g.48gb partition).
|
| 411 |
if getattr(pipe.transformer, "_hf_hook", None) is None:
|
| 412 |
+
try:
|
| 413 |
+
pipe.to(device)
|
| 414 |
+
print(f"[infer] moved full pipe to {device} — t={time.perf_counter()-t0:.1f}s")
|
| 415 |
+
except torch.cuda.OutOfMemoryError:
|
| 416 |
+
print(f"[infer] OOM moving full pipe to {device}, falling back to cpu offload")
|
| 417 |
+
pipe.to("cpu")
|
| 418 |
+
torch.cuda.empty_cache()
|
| 419 |
+
pipe.enable_model_cpu_offload(device=device)
|
| 420 |
+
print(f"[infer] enabled cpu offload on {device} (fallback)")
|
| 421 |
print(f"[infer] {_gpu_mem_str(_cuda_ok)} — t={time.perf_counter()-t0:.1f}s")
|
| 422 |
|
| 423 |
print(f"[infer] {len(pil_images)} image(s) pre-decoded, output={width}x{height}, seed={seed}")
|
|
|
|
| 461 |
timer.print_timings()
|
| 462 |
raise
|
| 463 |
finally:
|
| 464 |
+
# No manual pipe.to("cpu"): in the offload-fallback case that fights the
|
| 465 |
+
# hooks' own device bookkeeping (they return each component to CPU after
|
| 466 |
+
# its forward), and in the normal fast-path case the worker's GPU access
|
| 467 |
+
# is reclaimed by ZeroGPU when this call returns regardless — paying for
|
| 468 |
+
# a D2H transfer here would just be wasted GPU-billed time.
|
| 469 |
gc.collect()
|
| 470 |
torch.cuda.empty_cache()
|
| 471 |
print(f"[infer] ===== END t={time.perf_counter()-t0:.1f}s =====")
|