observantdistressed commited on
Commit
505a4ff
Β·
1 Parent(s): 26c0722

fix: launch Gradio before load_models so Space leaves BUILDING

Browse files

The ~77GB checkpoint download ran before demo.launch(), so HF never got a
healthcheck response and stayed on Building. Load models in a background
thread after the module-level demo is constructed; show a status banner.

Files changed (2) hide show
  1. app.py +30 -3
  2. ui.py +17 -9
app.py CHANGED
@@ -136,9 +136,37 @@ from lora.sources.civarchive import ( # noqa: F401
136
  )
137
 
138
 
139
- # ── Side-effect: kick off the model load on import unless tests say otherwise ──
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  if not os.environ.get("H3_TEST_MODE"):
141
- load_models()
142
 
143
 
144
  if __name__ == "__main__":
@@ -150,5 +178,4 @@ if __name__ == "__main__":
150
  # physical mergeβ†’denoiseβ†’unmerge critical section so shared weights stay clean.
151
  # - There is no application-level FIFO job queue; task IDs are isolation/diagnostic
152
  # handles, not queue tickets.
153
- demo = build_ui()
154
  demo.launch(show_error=True, theme=gr.themes.Base(), css=CSS)
 
136
  )
137
 
138
 
139
+ # ── Startup ───────────────────────────────────────────────────────────────────
140
+ # IMPORTANT: do NOT call load_models() at import time. Hugging Face marks the
141
+ # Space as BUILDING until the Gradio HTTP server accepts connections. The H3
142
+ # checkpoint is ~77 GB; loading it before launch() left the Space stuck on
143
+ # "Building" for the entire download. Load models after the UI is up instead.
144
+
145
+ def _startup_load():
146
+ """Load transformer + VAEs once the Gradio server is listening."""
147
+ if os.environ.get("H3_TEST_MODE"):
148
+ return status()
149
+ err = load_models()
150
+ return status() if not err else f"**Load error:** {err}"
151
+
152
+
153
+ # Module-level `demo` so the Spaces Gradio runtime can find it (not only under
154
+ # ``if __name__ == "__main__"``).
155
+ demo = build_ui()
156
+
157
+ # Wire a load callback if the UI exposes a status banner; otherwise load in a
158
+ # background thread so launch() is never blocked.
159
+ import threading as _threading
160
+
161
+ def _bg_load():
162
+ try:
163
+ _startup_load()
164
+ except Exception as _e:
165
+ from state import _log
166
+ _log(f"background load_models failed: {_e}", "ERROR")
167
+
168
  if not os.environ.get("H3_TEST_MODE"):
169
+ _threading.Thread(target=_bg_load, name="h3-load-models", daemon=True).start()
170
 
171
 
172
  if __name__ == "__main__":
 
178
  # physical mergeβ†’denoiseβ†’unmerge critical section so shared weights stay clean.
179
  # - There is no application-level FIFO job queue; task IDs are isolation/diagnostic
180
  # handles, not queue tickets.
 
181
  demo.launch(show_error=True, theme=gr.themes.Base(), css=CSS)
ui.py CHANGED
@@ -10,6 +10,7 @@ import os
10
 
11
  import gradio as gr
12
 
 
13
  from config import (
14
  CANVASES,
15
  DEFAULT_CANVAS,
@@ -254,6 +255,9 @@ def build_ui():
254
  """Construct and return the Gradio `Blocks` instance."""
255
  with gr.Blocks(title="minimax h3 turbo + lora's") as demo:
256
  gr.Markdown(INTRO)
 
 
 
257
 
258
  with gr.Row():
259
  with gr.Column():
@@ -438,16 +442,20 @@ def build_ui():
438
  [],
439
  )
440
 
441
- # ── Refresh community dropdown after startup ────────────────────────────────
442
- # _community_lora_choices() runs at build time when the UI is constructed.
443
- # The bucket IS mounted by then (load_models() runs at line 2303), but the
444
- # choices may still be empty if the bucket listing is slow. This load()
445
- # callback re-populates the dropdown when the page connects. We return a
446
- # gr.Dropdown (not gr.update) β€” the recommended Gradio 6 pattern.
447
  def _refresh_community_dd():
448
- choices = _community_lora_choices() or None
449
- return gr.Dropdown(choices=choices, interactive=True)
450
- demo.load(_refresh_community_dd, None, community_lora_dropdown, api_name=False)
 
 
 
 
 
 
 
 
 
451
  # Also refresh when the user opens (focuses) the dropdown β€” covers cases
452
  # where demo.load() fires before the bucket is fully listed.
453
  community_lora_dropdown.focus(
 
10
 
11
  import gradio as gr
12
 
13
+ from model import status as _model_status
14
  from config import (
15
  CANVASES,
16
  DEFAULT_CANVAS,
 
255
  """Construct and return the Gradio `Blocks` instance."""
256
  with gr.Blocks(title="minimax h3 turbo + lora's") as demo:
257
  gr.Markdown(INTRO)
258
+ status_banner = gr.Markdown(
259
+ value="**Loading model weights** (transformer + VAEs, ~77 GB). The UI is up; generation waits until load finishes β€” watch Space logs.",
260
+ )
261
 
262
  with gr.Row():
263
  with gr.Column():
 
442
  [],
443
  )
444
 
445
+ # ── Refresh community dropdown / status after page connect ──────────────
 
 
 
 
 
446
  def _refresh_community_dd():
447
+ choices = _community_lora_choices() or []
448
+ return gr.update(choices=choices)
449
+ def _on_page_load():
450
+ choices = _community_lora_choices() or []
451
+ try:
452
+ from model import status as _st
453
+ banner = _st()
454
+ except Exception as _e:
455
+ banner = f"Status unavailable: {_e}"
456
+ return gr.update(choices=choices), banner
457
+
458
+ demo.load(_on_page_load, None, [community_lora_dropdown, status_banner], api_name=False)
459
  # Also refresh when the user opens (focuses) the dropdown β€” covers cases
460
  # where demo.load() fires before the bucket is fully listed.
461
  community_lora_dropdown.focus(