#!/usr/bin/env python3 """ MIMO - Fast Startup Version for HuggingFace Spaces Minimal imports to prevent timeout, full features loaded on demand """ import os import gradio as gr # Optional: small warmup function so Spaces runtime detects a GPU task and removes # the startup warning "No @spaces.GPU function detected". This does NOT import # heavy ML libs; it only checks environment lazily at call. If spaces package # isn't available the decorator import will fail silently. try: # keep ultra-safe import spaces @spaces.GPU def warmup_gpu(): # lightweight, returns availability flag try: # defer torch import until after user installs heavy deps import importlib torch_spec = importlib.util.find_spec("torch") if torch_spec is None: return {"cuda": False, "detail": "torch not installed yet"} import torch # type: ignore return {"cuda": torch.cuda.is_available()} except Exception as _e: # noqa: N806 return {"cuda": False, "detail": str(_e)} except Exception: # spaces not present; ignore – minimal build still works pass def create_simple_interface(): """Create a simple interface that loads quickly""" def setup_and_load(): """Force-clean and install modern stack, stub missing functorch symbol early, then validate. Steps: 1. Uninstall conflicting packages (torch, torchvision, diffusers, transformers, peft, accelerate, safetensors). 2. Install torch/torchvision first (CPU build to reduce risk) then other libs pinned. 3. Pre-create functorch eager_transforms.grad_and_value stub if absent BEFORE importing transformers/diffusers. 4. Validate imports. """ try: import subprocess, sys, importlib, traceback, types def run(cmd): try: subprocess.check_call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) return True except Exception: return False def pip_install(spec): ok = run([sys.executable, '-m', 'pip', 'install', '--no-cache-dir', spec]) return ok, (f"Installed {spec}" if ok else f"Failed {spec}") messages = [] # 1. Force uninstall uninstall_list = [ 'diffusers', 'transformers', 'torchvision', 'torch', 'peft', 'accelerate', 'safetensors' ] for pkg in uninstall_list: run([sys.executable, '-m', 'pip', 'uninstall', '-y', pkg]) messages.append("Forced uninstall of prior core packages (best-effort)") # 2. Install core (CPU torch to avoid GPU wheel delays; pipeline mainly uses GPU later if available) core_specs = [ 'torch==2.0.1', 'torchvision==0.15.2' ] for spec in core_specs: ok, msg = pip_install(spec) messages.append(msg) # 3. Pre-stub functorch symbol before any heavy imports try: import importlib fx_mod = importlib.import_module('torch._functorch.eager_transforms') if not hasattr(fx_mod, 'grad_and_value'): # Create lightweight placeholder using autograd backward pass simulation def grad_and_value(f): def wrapper(*a, **kw): import torch x = f(*a, **kw) try: if isinstance(x, torch.Tensor) and x.requires_grad: g = torch.autograd.grad(x, [t for t in a if isinstance(t, torch.Tensor) and t.requires_grad], allow_unused=True) else: g = None except Exception: g = None return g, x return wrapper setattr(fx_mod, 'grad_and_value', grad_and_value) messages.append('Stubbed functorch.grad_and_value') else: messages.append('functorch.grad_and_value present') except Exception as e: messages.append(f'Could not prepare functorch stub: {e}') # 4. Install remainder # Phase 1: Core ML libs (force clean versions) stack_specs_phase1 = [ "huggingface_hub==0.23.0", "safetensors==0.4.5", "diffusers==0.21.4", "transformers==4.35.2", "peft==0.7.1", "accelerate==0.25.0", ] for spec in stack_specs_phase1: ok, msg = pip_install(spec) messages.append(msg) # Phase 2: Utility libs needed by app_hf_spaces.py stack_specs_phase2 = [ "einops==0.7.0", "opencv-python-headless==4.8.1.78", "imageio==2.31.6", "imageio-ffmpeg==0.4.8", "tqdm==4.66.1", ] for spec in stack_specs_phase2: ok, msg = pip_install(spec) messages.append(msg) # Patch diffusers to disable ONNX (avoid _CAFFE2_ATEN_FALLBACK errors) try: import sys if 'diffusers' not in sys.modules: import diffusers.utils.import_utils as diff_imports diff_imports.is_onnx_available = lambda: False messages.append('Patched diffusers.is_onnx_available = False') except Exception as e: messages.append(f'ONNX patch failed (non-critical): {e}') # Defer tensorflow until after core validation to reduce failure surface deferred_tensorflow = 'tensorflow-cpu==2.13.0' # 5. Validate imports with diffusers fallback chain def try_import(autoencoder_strict=False): import importlib import torch # noqa: F401 import diffusers # noqa: F401 import transformers # noqa: F401 if autoencoder_strict: # direct AutoencoderKL import path changed in some versions from diffusers import AutoencoderKL # noqa: F401 return True # Try import with fallback: 0.21.4 → 0.20.2 diffusers_versions = ["0.21.4", "0.20.2"] last_error = None for idx, ver in enumerate(diffusers_versions): try: # Reinstall target diffusers version fresh each attempt run([sys.executable, '-m', 'pip', 'uninstall', '-y', 'diffusers']) ok, msg = pip_install(f'diffusers=={ver}') messages.append(msg) if not ok: last_error = msg continue # Relax autoencoder import for first attempts (some versions restructure) strict = (ver == diffusers_versions[-1]) try_import(autoencoder_strict=strict) messages.append(f'diffusers import OK at {ver} (strict={strict})') last_error = None break except Exception as e: last_error = str(e) messages.append(f'diffusers version {ver} failed: {e}') if last_error: messages.append(f'Final diffusers import failure after fallbacks: {last_error}') return '❌ Setup failed during import validation\n' + '\n'.join(messages) # Install deferred tensorflow optionally ok_tf, msg_tf = pip_install(deferred_tensorflow) messages.append(msg_tf) # Secondary optional: attempt AutoencoderKL explicit import to ensure availability (soft) try: from diffusers import AutoencoderKL # noqa: F401 except Exception as e: messages.append(f'Warning: AutoencoderKL direct import not required but failed: {e}') # 6. Try app import try: from app_hf_spaces import CompleteMIMO, gradio_interface # noqa: F401 except Exception as e: tb = traceback.format_exc(limit=2) messages.append(f'App import partial failure: {e}\n{tb}') return '⚠️ Core libs installed but app import failed\n' + '\n'.join(messages) return '✅ Clean stack installed! Please refresh to load full MIMO.\n' + '\n'.join(messages) except Exception as e: return f'❌ Setup failed: {e}' with gr.Blocks(title="MIMO - Loading...", theme=gr.themes.Soft()) as demo: gr.HTML("""

🎭 MIMO - Character Video Synthesis

Loading complete implementation...

Click the button below to install remaining dependencies and activate full features.

""") setup_btn = gr.Button("� Install Dependencies & Activate MIMO", variant="primary", size="lg") status = gr.Textbox(label="Status", interactive=False, lines=3) setup_btn.click(fn=setup_and_load, outputs=[status]) gr.HTML("""

Why this approach?

To prevent HuggingFace Spaces build timeout, we use minimal dependencies at startup.

Full MIMO features (Character Animation + Video Editing) will be available after setup.

""") return demo """ We do NOT attempt to import the full heavy implementation during build/startup. The previous version tried a best-effort import inside a try/except. Even though it failed fast, it still triggered Python to resolve heavy modules (torch/diffusers) which aren't installed in the minimal build image. That adds noise and (in some cases) delays. We now always start with the light interface; the user explicitly chooses to install heavy dependencies. Keeping changes minimal per user request: no extra files or new features, just a safer lazy-loading path. """ # Always start with minimal interface (no premature heavy imports) app = create_simple_interface() if __name__ == "__main__": app.launch( server_name="0.0.0.0", server_port=7860, share=False, show_error=True )