Load all model variants at module scope for ZeroGPU

#7
by a7543 - opened
Files changed (1) hide show
  1. app.py +11 -25
app.py CHANGED
@@ -3,15 +3,12 @@
3
  Gradio Space demo with a single unified interface: image presence selects
4
  editing vs. generation, while the model control selects fast vs. quality.
5
  """
6
- import gc
7
  import os
8
- import threading
9
 
10
  # Use flash_attention_2 for the HF text encoder (flash_attn is installed via wheel)
11
  os.environ.setdefault("VF_HF_ATTN_IMPL", "flash_attention_2")
12
 
13
  import spaces # MUST be first (after env setup)
14
- import torch
15
  import gradio as gr
16
  from PIL import Image
17
 
@@ -28,27 +25,16 @@ MODEL_VARIANTS = {
28
  },
29
  }
30
 
31
- _pipe_slots = {
32
- "t2i": {"variant": "turbo", "pipe": MageFlowPipeline.from_pretrained(MODEL_VARIANTS["turbo"]["t2i"], device="cuda")},
33
- "edit": {"variant": "turbo", "pipe": MageFlowPipeline.from_pretrained(MODEL_VARIANTS["turbo"]["edit"], device="cuda")},
 
 
 
 
 
 
34
  }
35
- _pipe_lock = threading.Lock()
36
-
37
-
38
- def _get_pipe(task: str, variant: str):
39
- """Keep one loaded variant per task, matching the original two-pipeline footprint."""
40
- with _pipe_lock:
41
- slot = _pipe_slots.get(task)
42
- if slot and slot["variant"] == variant:
43
- return slot["pipe"]
44
- if slot:
45
- del _pipe_slots[task]
46
- del slot
47
- gc.collect()
48
- torch.cuda.empty_cache()
49
- pipe = MageFlowPipeline.from_pretrained(MODEL_VARIANTS[variant][task], device="cuda")
50
- _pipe_slots[task] = {"variant": variant, "pipe": pipe}
51
- return pipe
52
 
53
 
54
  def _recommended(variant: str, image):
@@ -91,7 +77,7 @@ def generate(
91
 
92
  if image is not None:
93
  # Route to the edit model when an image is provided.
94
- pipe_edit = _get_pipe("edit", model_variant)
95
  if isinstance(image, str):
96
  image = Image.open(image)
97
  refs = [image.convert("RGB")]
@@ -115,7 +101,7 @@ def generate(
115
 
116
  # No image: route to the text-to-image model.
117
  # Content-safety gate: blocked requests return a blank image.
118
- pipe_t2i = _get_pipe("t2i", model_variant)
119
  verdict = pipe_t2i.model.txt_enc.screen_text(prompt)
120
  if verdict.violates:
121
  return Image.new("RGB", (int(width), int(height)), (255, 255, 255))
 
3
  Gradio Space demo with a single unified interface: image presence selects
4
  editing vs. generation, while the model control selects fast vs. quality.
5
  """
 
6
  import os
 
7
 
8
  # Use flash_attention_2 for the HF text encoder (flash_attn is installed via wheel)
9
  os.environ.setdefault("VF_HF_ATTN_IMPL", "flash_attention_2")
10
 
11
  import spaces # MUST be first (after env setup)
 
12
  import gradio as gr
13
  from PIL import Image
14
 
 
25
  },
26
  }
27
 
28
+ # ZeroGPU requires every model to be placed on CUDA at module scope: the backend
29
+ # registers the weights, offloads them to disk at startup, and streams them into
30
+ # VRAM for each @spaces.GPU call. Loading inside the GPU function instead would
31
+ # charge every switch to the caller's GPU quota and is not carried across the
32
+ # forked GPU workers.
33
+ PIPES = {
34
+ (task, variant): MageFlowPipeline.from_pretrained(spec[task], device="cuda")
35
+ for variant, spec in MODEL_VARIANTS.items()
36
+ for task in ("t2i", "edit")
37
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
 
40
  def _recommended(variant: str, image):
 
77
 
78
  if image is not None:
79
  # Route to the edit model when an image is provided.
80
+ pipe_edit = PIPES[("edit", model_variant)]
81
  if isinstance(image, str):
82
  image = Image.open(image)
83
  refs = [image.convert("RGB")]
 
101
 
102
  # No image: route to the text-to-image model.
103
  # Content-safety gate: blocked requests return a blank image.
104
+ pipe_t2i = PIPES[("t2i", model_variant)]
105
  verdict = pipe_t2i.model.txt_enc.screen_text(prompt)
106
  if verdict.violates:
107
  return Image.new("RGB", (int(width), int(height)), (255, 255, 255))