BoxOfColors Claude Sonnet 5 commited on
Commit
035533f
Β·
1 Parent(s): 78108d3

Move offline-mode patch inside each GPU function's own body

Browse files

Live repro (direct HTTP call to /gradio_api/queue/join for MMAudio's
_run_mmaudio, bypassing the browser) showed the previous fix (78108d3,
patching inside _catch_oom's wrapper) still didn't stop the live ~4GB
open_clip re-download. _catch_oom's wrapper sits *outside* the raw
function β€” it's the code that dispatches the call, not necessarily the
code that runs inside the actual ZeroGPU worker. This codebase's own
docstrings already documented that @spaces.GPU functions run in a
genuinely separate "GPU worker process" (kwargs are silently dropped,
paths must exist in the worker's own filesystem), which points at the
same boundary.

Added _ensure_offline_in_worker() (with a diagnostic print of pid +
the resulting is_offline_mode()) and call it as literally the first
line of all six raw GPU function bodies (_taro_gpu_infer,
_mmaudio_gpu_infer, _hunyuan_gpu_infer, and the three _regen_*_gpu
variants), so it runs wherever each function's own bytecode actually
executes, regardless of how @spaces.GPU dispatches the call.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Files changed (1) hide show
  1. app.py +27 -0
app.py CHANGED
@@ -228,6 +228,7 @@ cavp_ckpt_path, onset_ckpt_path, taro_ckpt_path = _fut_taro.result()
228
  mmaudio_model_path, mmaudio_vae_path, mmaudio_synchformer_path = _fut_mmaudio.result()
229
  bigvgan_local_dir = _fut_bigvgan.result()
230
  print(f"[startup] All downloads done in {time.perf_counter() - _t_dl_start:.1f}s")
 
231
 
232
  # Force any later HF Hub call to be cache-only. With every encoder cache
233
  # pre-populated above from the user's mirror, downstream from_pretrained()
@@ -252,6 +253,26 @@ os.environ["HF_HUB_OFFLINE"] = "1"
252
  import huggingface_hub.constants as _hf_constants
253
  _hf_constants.HF_HUB_OFFLINE = True
254
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  # ================================================================== #
256
  # SHARED CONSTANTS / HELPERS #
257
  # ================================================================== #
@@ -1109,6 +1130,7 @@ def _taro_gpu_infer(video_file, seed_val, cfg_scale, num_steps, mode,
1109
  crossfade_s, crossfade_db, num_samples):
1110
  """GPU-only TARO inference β€” model loading + feature extraction + diffusion.
1111
  Returns list of (wavs_list, onset_feats) per sample."""
 
1112
  seed_val = _resolve_seed(seed_val)
1113
  crossfade_s = float(crossfade_s)
1114
  num_samples = int(num_samples)
@@ -1294,6 +1316,7 @@ def _mmaudio_gpu_infer(video_file, prompt, negative_prompt, seed_val,
1294
  tmp files that don't exist in the GPU worker's process.
1295
  """
1296
  print(f"[_mmaudio_gpu_infer] START video={video_file!r} silent={silent_video!r} clip_start={clip_start_s} clip_dur={clip_dur_s} num_samples={num_samples}")
 
1297
  _ensure_syspath("MMAudio")
1298
  from mmaudio.eval_utils import generate, load_video
1299
  from mmaudio.model.flow_matching import FlowMatching
@@ -1465,6 +1488,7 @@ def _hunyuan_gpu_infer(video_file, prompt, negative_prompt, seed_val,
1465
  import traceback as _tb
1466
  print(f"[_hunyuan_gpu_infer] START video={video_file!r} model_size={model_size!r} "
1467
  f"num_steps={num_steps!r} clip_start={clip_start_s} clip_dur={clip_dur_s}")
 
1468
  try:
1469
  _ensure_syspath("HunyuanVideo-Foley")
1470
  from hunyuanvideo_foley.utils.model_utils import denoise_process
@@ -1675,6 +1699,7 @@ def _regen_taro_gpu(video_file, seg_idx, seg_meta_json,
1675
  seed_val, cfg_scale, num_steps, mode,
1676
  crossfade_s, crossfade_db, slot_id=None):
1677
  """GPU-only TARO regen β€” returns new_wav for a single segment."""
 
1678
  meta = json.loads(seg_meta_json)
1679
  seg_idx = int(seg_idx)
1680
  seg_start_s, seg_end_s = meta["segments"][seg_idx]
@@ -1753,6 +1778,7 @@ def _regen_mmaudio_gpu(video_file, seg_idx, seg_meta_json,
1753
  cfg_strength, num_steps, crossfade_s, crossfade_db,
1754
  slot_id=None):
1755
  """GPU-only MMAudio regen β€” returns (new_wav, sr) for a single segment."""
 
1756
  meta = json.loads(seg_meta_json)
1757
  seg_idx = int(seg_idx)
1758
  seg_start, seg_end = meta["segments"][seg_idx]
@@ -1847,6 +1873,7 @@ def _regen_hunyuan_gpu(video_file, seg_idx, seg_meta_json,
1847
  guidance_scale, num_steps, model_size,
1848
  crossfade_s, crossfade_db, slot_id=None):
1849
  """GPU-only HunyuanFoley regen β€” returns (new_wav, sr) for a single segment."""
 
1850
  meta = json.loads(seg_meta_json)
1851
  seg_idx = int(seg_idx)
1852
  seg_start, seg_end = meta["segments"][seg_idx]
 
228
  mmaudio_model_path, mmaudio_vae_path, mmaudio_synchformer_path = _fut_mmaudio.result()
229
  bigvgan_local_dir = _fut_bigvgan.result()
230
  print(f"[startup] All downloads done in {time.perf_counter() - _t_dl_start:.1f}s")
231
+ print(f"[startup] main process pid={os.getpid()}")
232
 
233
  # Force any later HF Hub call to be cache-only. With every encoder cache
234
  # pre-populated above from the user's mirror, downstream from_pretrained()
 
253
  import huggingface_hub.constants as _hf_constants
254
  _hf_constants.HF_HUB_OFFLINE = True
255
 
256
+ def _ensure_offline_in_worker():
257
+ """Re-assert offline mode from inside a @spaces.GPU function's own body.
258
+
259
+ The module-level patch above (and an earlier attempt inside _catch_oom's
260
+ wrapper, which sits *outside* the raw function) both failed to stop
261
+ MMAudio's open_clip CLIP loader from re-downloading its ~4GB checkpoint
262
+ live during GPU inference β€” confirmed via a direct HTTP repro against the
263
+ deployed Space. This codebase's own docstrings already document that
264
+ @spaces.GPU functions run in a genuinely separate "GPU worker process"
265
+ (see e.g. _mmaudio_gpu_infer: "kwargs are silently dropped" / paths must
266
+ "exist in the GPU worker's process"), so any patch applied by code that
267
+ merely *wraps* the call β€” rather than running inside the function body
268
+ that's actually shipped to and executed by that worker β€” never reaches
269
+ it. Calling this as literally the first line of each raw GPU function
270
+ guarantees it runs wherever that function's own bytecode runs."""
271
+ os.environ["HF_HUB_OFFLINE"] = "1"
272
+ _hf_constants.HF_HUB_OFFLINE = True
273
+ print(f"[_ensure_offline_in_worker] pid={os.getpid()} HF_HUB_OFFLINE={_hf_constants.HF_HUB_OFFLINE} "
274
+ f"is_offline_mode()={_hf_constants.is_offline_mode()}")
275
+
276
  # ================================================================== #
277
  # SHARED CONSTANTS / HELPERS #
278
  # ================================================================== #
 
1130
  crossfade_s, crossfade_db, num_samples):
1131
  """GPU-only TARO inference β€” model loading + feature extraction + diffusion.
1132
  Returns list of (wavs_list, onset_feats) per sample."""
1133
+ _ensure_offline_in_worker()
1134
  seed_val = _resolve_seed(seed_val)
1135
  crossfade_s = float(crossfade_s)
1136
  num_samples = int(num_samples)
 
1316
  tmp files that don't exist in the GPU worker's process.
1317
  """
1318
  print(f"[_mmaudio_gpu_infer] START video={video_file!r} silent={silent_video!r} clip_start={clip_start_s} clip_dur={clip_dur_s} num_samples={num_samples}")
1319
+ _ensure_offline_in_worker()
1320
  _ensure_syspath("MMAudio")
1321
  from mmaudio.eval_utils import generate, load_video
1322
  from mmaudio.model.flow_matching import FlowMatching
 
1488
  import traceback as _tb
1489
  print(f"[_hunyuan_gpu_infer] START video={video_file!r} model_size={model_size!r} "
1490
  f"num_steps={num_steps!r} clip_start={clip_start_s} clip_dur={clip_dur_s}")
1491
+ _ensure_offline_in_worker()
1492
  try:
1493
  _ensure_syspath("HunyuanVideo-Foley")
1494
  from hunyuanvideo_foley.utils.model_utils import denoise_process
 
1699
  seed_val, cfg_scale, num_steps, mode,
1700
  crossfade_s, crossfade_db, slot_id=None):
1701
  """GPU-only TARO regen β€” returns new_wav for a single segment."""
1702
+ _ensure_offline_in_worker()
1703
  meta = json.loads(seg_meta_json)
1704
  seg_idx = int(seg_idx)
1705
  seg_start_s, seg_end_s = meta["segments"][seg_idx]
 
1778
  cfg_strength, num_steps, crossfade_s, crossfade_db,
1779
  slot_id=None):
1780
  """GPU-only MMAudio regen β€” returns (new_wav, sr) for a single segment."""
1781
+ _ensure_offline_in_worker()
1782
  meta = json.loads(seg_meta_json)
1783
  seg_idx = int(seg_idx)
1784
  seg_start, seg_end = meta["segments"][seg_idx]
 
1873
  guidance_scale, num_steps, model_size,
1874
  crossfade_s, crossfade_db, slot_id=None):
1875
  """GPU-only HunyuanFoley regen β€” returns (new_wav, sr) for a single segment."""
1876
+ _ensure_offline_in_worker()
1877
  meta = json.loads(seg_meta_json)
1878
  seg_idx = int(seg_idx)
1879
  seg_start, seg_end = meta["segments"][seg_idx]