akrao9 commited on
Commit
404414e
·
verified ·
1 Parent(s): ae8b506

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +233 -0
app.py ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Boomer FLA — Hugging Face Space demo (ZeroGPU / RTX Pro 6000 Blackwell + Gradio)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from pathlib import Path
7
+
8
+ # ZeroGPU Spaces: ~/.cache is often read-only — use /tmp for HF + diffusers caches.
9
+ _hf_root = Path(os.environ.get("HF_HOME", "/tmp/huggingface"))
10
+ for _sub in ("hub", "modules", "transformers", "diffusers"):
11
+ (_hf_root / _sub).mkdir(parents=True, exist_ok=True)
12
+ os.environ.setdefault("HF_HOME", str(_hf_root))
13
+ os.environ.setdefault("HUGGINGFACE_HUB_CACHE", str(_hf_root / "hub"))
14
+ os.environ.setdefault("HF_MODULES_CACHE", str(_hf_root / "modules"))
15
+ os.environ.setdefault("TRANSFORMERS_CACHE", str(_hf_root / "transformers"))
16
+ os.environ.setdefault("DIFFUSERS_CACHE", str(_hf_root / "diffusers"))
17
+
18
+ import gc
19
+ import sys
20
+
21
+ import gradio as gr
22
+ import spaces
23
+ import torch
24
+ from huggingface_hub import snapshot_download
25
+
26
+ MODEL_ID = os.environ.get("BOOMER_MODEL_ID", "akrao9/Boomer-T2I")
27
+ DEFAULT_STEPS = 32
28
+ DEFAULT_CFG = 4.5
29
+ DEFAULT_CFG_RESCALE = 0.5
30
+
31
+ EXAMPLE_PROMPTS: list[tuple[str, str]] = [
32
+ (
33
+ "Cyberpunk Highland",
34
+ "A sweeping cinematic view of a futuristic Scottish highland at twilight, glowing neon purple and blue moss creeping over ancient rock formations, distant futuristic spires reflecting off a dark loch, dramatic low-angle photography.",
35
+ ),
36
+ (
37
+ "Volcanic Caldera",
38
+ "A high-contrast shot looking down into an active volcanic caldera, vibrant flowing rivers of orange lava cutting through pitch-black obsidian stone, thick plumes of dark smoke catching the crimson glow, hyper-detailed geological textures.",
39
+ ),
40
+ (
41
+ "Nordic Winter Fjords",
42
+ "A breathtaking winter view of deep Norwegian fjords during the blue hour, snow-laden mountain slopes plunging into dark mirror-like ocean water, vibrant emerald green Northern Lights stretching across the sky, crisp and ultra-clear atmospheric rendering.",
43
+ ),
44
+ (
45
+ "Ancient Sunken Ruins",
46
+ "A wide landscape shot of ancient stone ruins submerged in a shallow, crystal-clear tropical ocean, vibrant coral reefs and schools of exotic fish visible beneath the surface, sun rays slicing through the water, warm cinematic lighting.",
47
+ ),
48
+ ]
49
+
50
+
51
+ def _hf_token() -> str | None:
52
+ """Return HF token from Space secrets; None if unset (do not pass token=True)."""
53
+ for key in ("HF_TOKEN", "HUGGING_FACE_HUB_TOKEN", "HUGGING_HUB_TOKEN"):
54
+ value = os.environ.get(key, "").strip()
55
+ if value:
56
+ return value
57
+ return None
58
+
59
+
60
+ _hf = _hf_token()
61
+ if _hf is None:
62
+ print(
63
+ "WARNING: No HF_TOKEN secret found. Add one in Space Settings → Secrets "
64
+ "(required for gated Gemma text encoder).",
65
+ flush=True,
66
+ )
67
+
68
+ print(f"Loading Boomer pipeline from {MODEL_ID} ...", flush=True)
69
+ _model_dir = Path(
70
+ snapshot_download(
71
+ MODEL_ID,
72
+ token=_hf,
73
+ ignore_patterns=["*.png", "*.jpg", "*.jpeg"],
74
+ )
75
+ )
76
+ if str(_model_dir) not in sys.path:
77
+ sys.path.insert(0, str(_model_dir))
78
+
79
+ from pipeline_boomer import BoomerPipeline # noqa: E402
80
+
81
+ pipe = BoomerPipeline.from_pretrained(str(_model_dir), torch_dtype=torch.bfloat16, token=_hf)
82
+ pipe.to("cuda")
83
+ pipe._hf_token = _hf
84
+
85
+ print("Pre-loading VAE on cuda ...", flush=True)
86
+ pipe._ensure_vae()
87
+ if _hf is not None:
88
+ print("Pre-loading text encoder on cuda ...", flush=True)
89
+ pipe._ensure_text_encoder()
90
+ else:
91
+ print("Skipping text encoder preload (HF_TOKEN not set).", flush=True)
92
+ print("Model ready.", flush=True)
93
+
94
+
95
+ def _resolve_seed(seed: float | int | None) -> int:
96
+ if seed is None or int(seed) < 0:
97
+ return torch.randint(0, 2**32 - 1, (1,)).item()
98
+ return int(seed)
99
+
100
+
101
+ # ZeroGPU "large" = half NVIDIA RTX Pro 6000 Blackwell MIG slice (48 GB VRAM).
102
+ @spaces.GPU(size="large", duration=150)
103
+ def generate_image(
104
+ prompt: str,
105
+ seed: float,
106
+ steps: float,
107
+ cfg_scale: float,
108
+ ) -> tuple[object, str]:
109
+ prompt = (prompt or "").strip()
110
+ if not prompt:
111
+ raise gr.Error("Please enter a prompt before generating.")
112
+ if pipe._hf_token is None:
113
+ raise gr.Error(
114
+ "HF_TOKEN Space secret is required. In Space Settings → Secrets, add "
115
+ "HF_TOKEN with a Hugging Face token that has accepted the "
116
+ "Gemma Terms of Use (https://ai.google.dev/gemma/terms)."
117
+ )
118
+
119
+ resolved_seed = _resolve_seed(seed)
120
+ step_count = max(1, int(steps))
121
+ cfg = float(cfg_scale)
122
+
123
+ if torch.cuda.is_available():
124
+ torch.cuda.empty_cache()
125
+
126
+ result = pipe(
127
+ prompt,
128
+ steps=step_count,
129
+ seed=resolved_seed,
130
+ cfg_scale=cfg,
131
+ cfg_rescale=DEFAULT_CFG_RESCALE,
132
+ offload_text_encoder=True,
133
+ )
134
+ image = result[0]
135
+ gc.collect()
136
+ if torch.cuda.is_available():
137
+ torch.cuda.empty_cache()
138
+
139
+ status = (
140
+ f"Done — seed {resolved_seed}, steps {step_count}, CFG {cfg:.1f}. "
141
+ "1024×1024px via STORK-2."
142
+ )
143
+ return image, status
144
+
145
+
146
+ def reset_form() -> tuple[str, None, str, float]:
147
+ return "", None, "Reset.", -1.0
148
+
149
+
150
+ def build_ui() -> gr.Blocks:
151
+ example_rows = [[text, -1, DEFAULT_STEPS, DEFAULT_CFG] for _, text in EXAMPLE_PROMPTS]
152
+
153
+ with gr.Blocks(title="Boomer FLA") as demo:
154
+ gr.Markdown(
155
+ """
156
+ # Boomer FLA — Text to Image
157
+ Generate **1024×1024** images from text. **Best for landscapes and scenic
158
+ environments** — not reliable for humans or portraits (JourneyDB + FineT2I training).
159
+ Runs on **ZeroGPU** (NVIDIA RTX Pro 6000 Blackwell, 48 GB). First run may
160
+ take a minute while a GPU is allocated.
161
+ """
162
+ )
163
+
164
+ with gr.Row(equal_height=False):
165
+ with gr.Column(scale=3):
166
+ prompt = gr.Textbox(
167
+ label="Prompt",
168
+ placeholder="Describe the image you want to generate ...",
169
+ lines=5,
170
+ )
171
+ with gr.Accordion("Advanced settings", open=False):
172
+ seed = gr.Number(
173
+ label="Seed (-1 = random)",
174
+ value=-1,
175
+ precision=0,
176
+ )
177
+ steps = gr.Slider(
178
+ label="Denoising steps",
179
+ minimum=16,
180
+ maximum=64,
181
+ step=1,
182
+ value=DEFAULT_STEPS,
183
+ )
184
+ cfg_scale = gr.Slider(
185
+ label="CFG scale",
186
+ minimum=1.0,
187
+ maximum=8.0,
188
+ step=0.1,
189
+ value=DEFAULT_CFG,
190
+ )
191
+ with gr.Row():
192
+ generate_btn = gr.Button("Generate", variant="primary")
193
+ reset_btn = gr.Button("Reset")
194
+ output = gr.Image(label="Generated image", type="pil", height=640)
195
+ status = gr.Textbox(label="Status", interactive=False)
196
+
197
+ with gr.Column(scale=2):
198
+ gr.Markdown("### Example prompts")
199
+ gr.Markdown("Click an example to **generate immediately**.")
200
+ gr.Examples(
201
+ examples=example_rows,
202
+ inputs=[prompt, seed, steps, cfg_scale],
203
+ outputs=[output, status],
204
+ fn=generate_image,
205
+ run_on_click=True,
206
+ cache_examples=False,
207
+ label="",
208
+ examples_per_page=4,
209
+ )
210
+
211
+ generate_btn.click(
212
+ fn=generate_image,
213
+ inputs=[prompt, seed, steps, cfg_scale],
214
+ outputs=[output, status],
215
+ )
216
+ reset_btn.click(
217
+ fn=reset_form,
218
+ outputs=[prompt, output, status, seed],
219
+ )
220
+
221
+ prompt.submit(
222
+ fn=generate_image,
223
+ inputs=[prompt, seed, steps, cfg_scale],
224
+ outputs=[output, status],
225
+ )
226
+
227
+ return demo
228
+
229
+
230
+ demo = build_ui()
231
+
232
+ if __name__ == "__main__":
233
+ demo.launch()