someone-in-the-world Claude Sonnet 4.6 commited on
Commit
4585687
·
2 Parent(s): 2381b78a104380

Merge main into ja: apply Experimental-Turbo changes to Japanese space

Browse files
Files changed (3) hide show
  1. app.py +43 -6
  2. static/mode_toggle.js +1 -1
  3. templates/app.html +2 -2
app.py CHANGED
@@ -4,6 +4,9 @@ import time
4
  import threading
5
  import traceback
6
 
 
 
 
7
  import gradio as gr
8
  import numpy as np
9
  import spaces
@@ -34,6 +37,33 @@ print("torch.__version__ =", torch.__version__, flush=True)
34
  print("Using device:", device, flush=True)
35
  print(f"CUDA device_count={torch.cuda.device_count()}, is_available={torch.cuda.is_available()}", flush=True)
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  # TF32 matmul: ~10-15% free speedup on Ampere/Hopper (bfloat16 accumulation paths benefit too)
38
  torch.backends.cuda.matmul.allow_tf32 = True
39
  torch.backends.cudnn.allow_tf32 = True
@@ -70,7 +100,7 @@ _hb = _start_heartbeat("transformer")
70
  _transformer = QwenImageTransformer2DModel.from_pretrained(
71
  "prithivMLmods/Qwen-Image-Edit-Rapid-AIO-V23",
72
  torch_dtype=dtype,
73
- device_map="cuda",
74
  )
75
  _hb.set()
76
  print(f"[startup] transformer loaded in {time.perf_counter()-_t0_load:.1f}s", flush=True)
@@ -82,7 +112,7 @@ pipe = QwenImageEditPlusPipeline.from_pretrained(
82
  "FireRedTeam/FireRed-Image-Edit-1.1",
83
  transformer=_transformer,
84
  torch_dtype=dtype,
85
- ).to(device)
86
  _hb.set()
87
  print(f"[startup] pipeline loaded in {time.perf_counter()-_t1_load:.1f}s", flush=True)
88
 
@@ -372,11 +402,15 @@ def _infer_gpu(pil_images, prompt, seed, guidance_scale, steps, width, height, m
372
  print(f"[infer] GPU: {p.name}, total={p.total_memory/1024**3:.1f}GB, cap={p.major}.{p.minor}")
373
  torch.cuda.reset_peak_memory_stats()
374
 
 
 
 
 
 
 
 
375
  print(f"[infer] {_gpu_mem_str(_cuda_ok)} — t={time.perf_counter()-t0:.1f}s")
376
 
377
- torch.cuda.empty_cache()
378
- print(f"[infer] cache cleared — {_gpu_mem_str(_cuda_ok)}")
379
-
380
  print(f"[infer] {len(pil_images)} image(s) pre-decoded, output={width}x{height}, seed={seed}")
381
 
382
  generator = torch.Generator(device=device).manual_seed(seed)
@@ -418,6 +452,9 @@ def _infer_gpu(pil_images, prompt, seed, guidance_scale, steps, width, height, m
418
  timer.print_timings()
419
  raise
420
  finally:
 
 
 
421
  gc.collect()
422
  torch.cuda.empty_cache()
423
  print(f"[infer] ===== END t={time.perf_counter()-t0:.1f}s =====")
@@ -432,7 +469,7 @@ with gr.Blocks() as demo:
432
  guidance_scale = gr.Slider(minimum=1.0, maximum=10.0, step=0.1, value=1.0, elem_id="gradio-guidance", elem_classes="hidden-input", container=False)
433
  steps = gr.Slider(minimum=1, maximum=50, step=1, value=4, elem_id="gradio-steps", elem_classes="hidden-input", container=False)
434
  mode = gr.Textbox(value="fast", elem_id="gradio-mode", elem_classes="hidden-input", container=False)
435
- gpu_duration = gr.Slider(minimum=10, maximum=120, step=5, value=20, elem_id="gradio-gpu-duration", elem_classes="hidden-input", container=False)
436
  result = gr.Image(elem_id="gradio-result", elem_classes="hidden-input", container=False, format="png")
437
 
438
  example_idx = gr.Textbox(value="", elem_id="example-idx-input", elem_classes="hidden-input", container=False)
 
4
  import threading
5
  import traceback
6
 
7
+ # cudaMallocAsync bypasses NVML memory queries that fail on MIG GPU instances
8
+ os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "backend:cudaMallocAsync")
9
+
10
  import gradio as gr
11
  import numpy as np
12
  import spaces
 
37
  print("Using device:", device, flush=True)
38
  print(f"CUDA device_count={torch.cuda.device_count()}, is_available={torch.cuda.is_available()}", flush=True)
39
 
40
+
41
+ def _log_env():
42
+ import importlib.metadata as _meta
43
+ if torch.cuda.is_available():
44
+ p = torch.cuda.get_device_properties(0)
45
+ print(f"[env] GPU: {p.name}, VRAM={p.total_memory/1024**3:.1f}GB, cap={p.major}.{p.minor}", flush=True)
46
+ print(f"[env] CUDA (torch build): {torch.version.cuda}", flush=True)
47
+ print(f"[env] cuDNN: {torch.backends.cudnn.version()}", flush=True)
48
+ for pkg in ["spaces", "diffusers", "transformers", "gradio", "accelerate", "peft", "torchvision"]:
49
+ try:
50
+ print(f"[env] {pkg}=={_meta.version(pkg)}", flush=True)
51
+ except Exception as e:
52
+ print(f"[env] {pkg}==? ({e})", flush=True)
53
+ try:
54
+ mem = {}
55
+ with open("/proc/meminfo") as f:
56
+ for line in f:
57
+ k, v = line.split(":", 1)
58
+ mem[k.strip()] = v.strip()
59
+ total_gb = int(mem["MemTotal"].split()[0]) / 1024**2
60
+ avail_gb = int(mem["MemAvailable"].split()[0]) / 1024**2
61
+ print(f"[env] RAM: {total_gb:.0f}GB total, {avail_gb:.0f}GB available", flush=True)
62
+ except Exception as e:
63
+ print(f"[env] RAM: unavailable ({e})", flush=True)
64
+
65
+ _log_env()
66
+
67
  # TF32 matmul: ~10-15% free speedup on Ampere/Hopper (bfloat16 accumulation paths benefit too)
68
  torch.backends.cuda.matmul.allow_tf32 = True
69
  torch.backends.cudnn.allow_tf32 = True
 
100
  _transformer = QwenImageTransformer2DModel.from_pretrained(
101
  "prithivMLmods/Qwen-Image-Edit-Rapid-AIO-V23",
102
  torch_dtype=dtype,
103
+ device_map="cpu",
104
  )
105
  _hb.set()
106
  print(f"[startup] transformer loaded in {time.perf_counter()-_t0_load:.1f}s", flush=True)
 
112
  "FireRedTeam/FireRed-Image-Edit-1.1",
113
  transformer=_transformer,
114
  torch_dtype=dtype,
115
+ )
116
  _hb.set()
117
  print(f"[startup] pipeline loaded in {time.perf_counter()-_t1_load:.1f}s", flush=True)
118
 
 
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
+ # Sequential offload: only the component currently doing work (text_encoder,
406
+ # then transformer, then vae — see model_cpu_offload_seq) sits on GPU at a
407
+ # time, instead of the full ~37GB pipeline resident simultaneously. Needed
408
+ # to fit on smaller MIG slices (e.g. the 47GB 2g.48gb partition) without OOM.
409
+ if getattr(pipe.transformer, "_hf_hook", None) is None:
410
+ pipe.enable_model_cpu_offload(device=device)
411
+ print(f"[infer] enabled sequential cpu offload on {device}")
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}")
415
 
416
  generator = torch.Generator(device=device).manual_seed(seed)
 
452
  timer.print_timings()
453
  raise
454
  finally:
455
+ # No manual pipe.to("cpu") — that fights the offload hooks' own device
456
+ # bookkeeping. Hooks already return each component to CPU after its
457
+ # forward; empty_cache() just reclaims the freed GPU blocks.
458
  gc.collect()
459
  torch.cuda.empty_cache()
460
  print(f"[infer] ===== END t={time.perf_counter()-t0:.1f}s =====")
 
469
  guidance_scale = gr.Slider(minimum=1.0, maximum=10.0, step=0.1, value=1.0, elem_id="gradio-guidance", elem_classes="hidden-input", container=False)
470
  steps = gr.Slider(minimum=1, maximum=50, step=1, value=4, elem_id="gradio-steps", elem_classes="hidden-input", container=False)
471
  mode = gr.Textbox(value="fast", elem_id="gradio-mode", elem_classes="hidden-input", container=False)
472
+ gpu_duration = gr.Slider(minimum=10, maximum=120, step=5, value=30, elem_id="gradio-gpu-duration", elem_classes="hidden-input", container=False)
473
  result = gr.Image(elem_id="gradio-result", elem_classes="hidden-input", container=False, format="png")
474
 
475
  example_idx = gr.Textbox(value="", elem_id="example-idx-input", elem_classes="hidden-input", container=False)
static/mode_toggle.js CHANGED
@@ -1,6 +1,6 @@
1
  () => {
2
  window.__selectedMode = 'fast';
3
- var MODE_GPU_DURATION = { fast: 20, high_detail: 30 };
4
  window.__setMode = function(m) {
5
  window.__selectedMode = m;
6
  var fast = document.getElementById('mode-btn-fast');
 
1
  () => {
2
  window.__selectedMode = 'fast';
3
+ var MODE_GPU_DURATION = { fast: 30, high_detail: 60 };
4
  window.__setMode = function(m) {
5
  window.__selectedMode = m;
6
  var fast = document.getElementById('mode-btn-fast');
templates/app.html CHANGED
@@ -120,8 +120,8 @@
120
  <div class="settings-group-body">
121
  <div class="slider-row">
122
  <label>GPU時間(秒)</label>
123
- <input type="range" id="custom-gpu-duration" min="10" max="120" step="5" value="20">
124
- <span class="slider-val" id="custom-gpu-duration-val">20</span>
125
  </div>
126
  <div class="slider-row">
127
  <label>シード</label>
 
120
  <div class="settings-group-body">
121
  <div class="slider-row">
122
  <label>GPU時間(秒)</label>
123
+ <input type="range" id="custom-gpu-duration" min="10" max="120" step="5" value="30">
124
+ <span class="slider-val" id="custom-gpu-duration-val">30</span>
125
  </div>
126
  <div class="slider-row">
127
  <label>シード</label>