Move offline-mode patch inside each GPU function's own body
Browse filesLive 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>
|
@@ -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]
|