artificialguybr commited on
Commit
46166d5
·
verified ·
1 Parent(s): ff2a81a

Initial commit: Juggernaut Z Image ZeroGPU Space

Browse files
Files changed (3) hide show
  1. README.md +53 -7
  2. app.py +377 -0
  3. requirements.txt +7 -0
README.md CHANGED
@@ -1,13 +1,59 @@
1
  ---
2
- title: JUGGERNAUT Z IMAGE
3
- emoji: 🐢
4
- colorFrom: red
5
- colorTo: gray
6
  sdk: gradio
7
- sdk_version: 6.14.0
8
- python_version: '3.13'
9
  app_file: app.py
10
  pinned: false
 
 
 
 
 
 
 
 
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: JUGGERNAUT-Z-IMAGE
3
+ emoji: 🎨
4
+ colorFrom: yellow
5
+ colorTo: red
6
  sdk: gradio
7
+ sdk_version: "6.9.0"
8
+ python_version: "3.10"
9
  app_file: app.py
10
  pinned: false
11
+ tags:
12
+ - text-to-image
13
+ - image-generation
14
+ - juggernaut
15
+ - z-image
16
+ - lumina2
17
+ - rundiffusion
18
+ - zero-gpu
19
+ short_description: Juggernaut Z - Cinematic fine-tune of Z-Image Base model
20
  ---
21
 
22
+ # Juggernaut Z Image
23
+
24
+ A ZeroGPU Space for generating images with **Juggernaut Z** by RunDiffusion — a cinematic fine-tune of the Z-Image Base model.
25
+
26
+ ## Features
27
+
28
+ - 🎨 **Cinematic Quality**: Tuned for dramatic lighting, sharper focus, and refined skin texture
29
+ - ⚡ **ZeroGPU**: Runs on Hugging Face's free GPU infrastructure
30
+ - 🖼️ **Multiple Resolutions**: From 720x720 up to 1680x720 (and custom sizes)
31
+ - 🎛️ **Full CFG Control**: Supports Classifier-Free Guidance for precise prompt adherence
32
+ - 🌱 **Seed Control**: Reproducible generation with seed randomization option
33
+
34
+ ## Model Details
35
+
36
+ - **Base Model**: [Tongyi-MAI/Z-Image](https://huggingface.co/Tongyi-MAI/Z-Image)
37
+ - **Fine-tune**: [RunDiffusion/Juggernaut-Z-Image](https://huggingface.co/RunDiffusion/Juggernaut-Z-Image)
38
+ - **Architecture**: Lumina2 (Single-Stream Diffusion Transformer)
39
+ - **License**: Apache 2.0
40
+
41
+ ## Recommended Settings
42
+
43
+ | Parameter | Default | Range |
44
+ |-----------|---------|-------|
45
+ | CFG Scale | 6.0 | 3.0 – 9.0 |
46
+ | Steps | 35 | 25 – 50 |
47
+ | Resolution | 1024×1024 | 512×512 – 2048×2048 |
48
+
49
+ ## Links
50
+
51
+ - [RunDiffusion](https://www.rundiffusion.com/)
52
+ - [Prompt Guide](https://www.rundiffusion.com/juggernaut-z-prompt-guide)
53
+ - [Base Model](https://huggingface.co/Tongyi-MAI/Z-Image)
54
+
55
+ ## Credits
56
+
57
+ - Fine-tuned by **Team Juggernaut**
58
+ - Training by **KandooAI**
59
+ - Published by **RunDiffusion**
app.py ADDED
@@ -0,0 +1,377 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Juggernaut Z Image Generation Demo
3
+ ZeroGPU Space for RunDiffusion/Juggernaut-Z-Image
4
+ """
5
+
6
+ import spaces
7
+ import random
8
+ import re
9
+ import torch
10
+ import gradio as gr
11
+ from diffusers import ZImagePipeline
12
+
13
+ # ==================== Configuration ====================
14
+ MODEL_PATH = "RunDiffusion/Juggernaut-Z-Image"
15
+
16
+ # ==================== Resolution Choices ====================
17
+ RES_CHOICES = {
18
+ "720": [
19
+ "720x720 ( 1:1 )",
20
+ "896x512 ( 16:9 )",
21
+ "512x896 ( 9:16 )",
22
+ "832x544 ( 3:2 )",
23
+ "544x832 ( 2:3 )",
24
+ "800x576 ( 4:3 )",
25
+ "576x800 ( 3:4 )",
26
+ ],
27
+ "1024": [
28
+ "1024x1024 ( 1:1 )",
29
+ "1152x896 ( 9:7 )",
30
+ "896x1152 ( 7:9 )",
31
+ "1152x864 ( 4:3 )",
32
+ "864x1152 ( 3:4 )",
33
+ "1248x832 ( 3:2 )",
34
+ "832x1248 ( 2:3 )",
35
+ "1280x720 ( 16:9 )",
36
+ "720x1280 ( 9:16 )",
37
+ "1344x576 ( 21:9 )",
38
+ "576x1344 ( 9:21 )",
39
+ ],
40
+ "1280": [
41
+ "1280x1280 ( 1:1 )",
42
+ "1440x1120 ( 9:7 )",
43
+ "1120x1440 ( 7:9 )",
44
+ "1472x1104 ( 4:3 )",
45
+ "1104x1472 ( 3:4 )",
46
+ "1536x1024 ( 3:2 )",
47
+ "1024x1536 ( 2:3 )",
48
+ "1536x864 ( 16:9 )",
49
+ "864x1536 ( 9:16 )",
50
+ "1680x720 ( 21:9 )",
51
+ "720x1680 ( 9:21 )",
52
+ ],
53
+ }
54
+
55
+ RESOLUTION_SET = []
56
+ for resolutions in RES_CHOICES.values():
57
+ RESOLUTION_SET.extend(resolutions)
58
+
59
+ EXAMPLE_PROMPTS = [
60
+ ["Cinematic portrait of a cyberpunk warrior, neon lights reflecting off chrome armor, rain-soaked streets, dramatic lighting, 8k, photorealistic"],
61
+ ["Ethereal forest scene with bioluminescent mushrooms, misty atmosphere, magical lighting, fantasy art style"],
62
+ ["Majestic mountain landscape at golden hour, snow-capped peaks, alpine lake reflection, cinematic photography"],
63
+ ["Futuristic cityscape at night, flying cars, holographic billboards, cyberpunk aesthetic, highly detailed"],
64
+ ["Portrait of an elegant woman in Victorian dress, ornate jewelry, soft natural lighting, studio portrait"],
65
+ ]
66
+
67
+ # ==================== Helper Functions ====================
68
+ def get_resolution(resolution: str) -> tuple[int, int]:
69
+ """Parse resolution string to width and height."""
70
+ match = re.search(r"(\d+)\s*[×x]\s*(\d+)", resolution)
71
+ if match:
72
+ return int(match.group(1)), int(match.group(2))
73
+ return 1024, 1024
74
+
75
+
76
+ # ==================== Model Loading (Global Context) ====================
77
+ print(f"Loading Juggernaut Z pipeline from {MODEL_PATH}...")
78
+ pipe = ZImagePipeline.from_pretrained(
79
+ MODEL_PATH,
80
+ torch_dtype=torch.bfloat16,
81
+ low_cpu_mem_usage=False,
82
+ )
83
+ pipe.to("cuda")
84
+ print("Pipeline loaded successfully!")
85
+
86
+
87
+ # ==================== Generation Function ====================
88
+ @spaces.GPU
89
+ def generate(
90
+ prompt: str,
91
+ negative_prompt: str = "",
92
+ resolution: str = "1024x1024 ( 1:1 )",
93
+ seed: int = 42,
94
+ num_inference_steps: int = 35,
95
+ guidance_scale: float = 6.0,
96
+ cfg_normalization: bool = False,
97
+ ):
98
+ if not prompt or not prompt.strip():
99
+ raise gr.Error("Prompt is required.")
100
+
101
+ width, height = get_resolution(resolution)
102
+ generator = torch.Generator("cuda").manual_seed(int(seed))
103
+
104
+ image = pipe(
105
+ prompt=prompt.strip(),
106
+ negative_prompt=negative_prompt.strip() if negative_prompt else None,
107
+ height=height,
108
+ width=width,
109
+ num_inference_steps=int(num_inference_steps),
110
+ guidance_scale=float(guidance_scale),
111
+ cfg_normalization=bool(cfg_normalization),
112
+ generator=generator,
113
+ ).images[0]
114
+
115
+ meta = {
116
+ "model": MODEL_PATH,
117
+ "prompt": prompt,
118
+ "negative_prompt": negative_prompt,
119
+ "resolution": f"{width} x {height}",
120
+ "guidance_scale": guidance_scale,
121
+ "steps": num_inference_steps,
122
+ "seed": seed,
123
+ "cfg_normalization": cfg_normalization,
124
+ }
125
+
126
+ return image, meta
127
+
128
+
129
+ # ==================== Custom Theme ====================
130
+ CSS = """
131
+ @import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&family=Fira+Code:wght@400;500&display=swap');
132
+
133
+ :root {
134
+ --bg: #080a0e;
135
+ --surf: #0d1017;
136
+ --card: #111520;
137
+ --border: #1c2133;
138
+ --border2: #252d45;
139
+ --amber: #f59e0b;
140
+ --gold: #fbbf24;
141
+ --cream: #fef3c7;
142
+ --text: #e2e8f8;
143
+ --muted: #4a5578;
144
+ --r: 14px;
145
+ --r-sm: 8px;
146
+ }
147
+
148
+ *, *::before, *::after { box-sizing: border-box; }
149
+
150
+ body, .gradio-container {
151
+ background: var(--bg) !important;
152
+ font-family: 'Outfit', sans-serif !important;
153
+ color: var(--text) !important;
154
+ }
155
+
156
+ .gradio-container::before {
157
+ content: '';
158
+ position: fixed; inset: 0; pointer-events: none; z-index: 0;
159
+ background:
160
+ radial-gradient(ellipse 70% 50% at 50% -10%, rgba(245,158,11,0.07) 0%, transparent 65%),
161
+ radial-gradient(ellipse 40% 30% at 90% 90%, rgba(251,191,36,0.04) 0%, transparent 60%);
162
+ }
163
+
164
+ .app-hero { padding: 52px 0 28px; text-align: center; }
165
+
166
+ .app-hero h1 {
167
+ font-size: 3rem; font-weight: 800; letter-spacing: -0.05em;
168
+ line-height: 1; margin: 0 0 12px;
169
+ background: linear-gradient(135deg, var(--cream) 0%, var(--gold) 40%, var(--amber) 100%);
170
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
171
+ }
172
+
173
+ .app-hero .tagline {
174
+ color: var(--muted); font-size: 0.88rem; font-weight: 300;
175
+ letter-spacing: 0.06em; text-transform: uppercase; margin: 0 0 20px;
176
+ }
177
+
178
+ .app-hero .pills { display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; }
179
+
180
+ .app-hero .pill {
181
+ background: var(--card); border: 1px solid var(--border2); border-radius: 100px;
182
+ padding: 4px 14px; font-size: 0.74rem; font-weight: 500; color: var(--muted);
183
+ font-family: 'Fira Code', monospace;
184
+ }
185
+
186
+ .app-hero .pill.gold { color: var(--amber); border-color: rgba(245,158,11,0.3); }
187
+
188
+ .sec-label {
189
+ font-size: 0.62rem !important; font-weight: 700 !important;
190
+ letter-spacing: 0.15em !important; text-transform: uppercase !important;
191
+ color: var(--amber) !important; margin: 0 0 8px !important; display: block;
192
+ }
193
+
194
+ label > span {
195
+ font-family: 'Outfit', sans-serif !important; font-size: 0.72rem !important;
196
+ font-weight: 500 !important; color: var(--muted) !important;
197
+ text-transform: uppercase; letter-spacing: 0.08em;
198
+ }
199
+
200
+ textarea, input[type="text"] {
201
+ background: var(--surf) !important; border: 1px solid var(--border) !important;
202
+ border-radius: var(--r-sm) !important; color: var(--text) !important;
203
+ font-family: 'Outfit', sans-serif !important; font-size: 0.95rem !important;
204
+ transition: border-color 0.2s, box-shadow 0.2s;
205
+ }
206
+
207
+ textarea:focus, input[type="text"]:focus {
208
+ border-color: var(--amber) !important;
209
+ box-shadow: 0 0 0 3px rgba(245,158,11,0.12) !important;
210
+ outline: none !important;
211
+ }
212
+
213
+ .gen-btn {
214
+ background: linear-gradient(135deg, var(--amber), #d97706) !important;
215
+ border: none !important; border-radius: var(--r) !important;
216
+ color: #000 !important; font-family: 'Outfit', sans-serif !important;
217
+ font-weight: 700 !important; font-size: 1rem !important;
218
+ height: 54px !important; width: 100% !important;
219
+ letter-spacing: 0.02em !important; cursor: pointer !important;
220
+ transition: opacity 0.18s, transform 0.15s, box-shadow 0.2s !important;
221
+ box-shadow: 0 4px 20px rgba(245,158,11,0.28) !important;
222
+ }
223
+
224
+ .gen-btn:hover {
225
+ opacity: 0.88 !important; transform: translateY(-1px) !important;
226
+ box-shadow: 0 8px 30px rgba(245,158,11,0.48) !important;
227
+ }
228
+
229
+ .gen-btn:active { transform: translateY(0) !important; }
230
+
231
+ .result-gallery .grid-wrap {
232
+ background: var(--surf) !important;
233
+ border: 1px solid var(--border) !important;
234
+ border-radius: var(--r) !important;
235
+ }
236
+
237
+ .result-gallery img { border-radius: 10px !important; }
238
+
239
+ .gr-accordion {
240
+ background: var(--card) !important; border: 1px solid var(--border) !important;
241
+ border-radius: var(--r) !important; margin-top: 10px !important;
242
+ }
243
+
244
+ ::-webkit-scrollbar { width: 5px; }
245
+ ::-webkit-scrollbar-track { background: var(--surf); }
246
+ ::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 3px; }
247
+ ::-webkit-scrollbar-thumb:hover { background: var(--amber); }
248
+ """
249
+
250
+
251
+ # ==================== Gradio Interface ====================
252
+ with gr.Blocks(css=CSS) as demo:
253
+ gr.HTML("""
254
+ <div class="app-hero">
255
+ <h1>Juggernaut Z</h1>
256
+ <p class="tagline">Cinematic Fine-tune of Z-Image Base</p>
257
+ <div class="pills">
258
+ <span class="pill gold">ZeroGPU ⚡</span>
259
+ <span class="pill">RunDiffusion</span>
260
+ <span class="pill">Lumina2</span>
261
+ <span class="pill">bfloat16</span>
262
+ </div>
263
+ </div>
264
+ """)
265
+
266
+ with gr.Row():
267
+ with gr.Column(scale=1, min_width=320):
268
+ gr.HTML('<span class="sec-label">① Prompt</span>')
269
+ prompt = gr.Textbox(
270
+ label="",
271
+ lines=5,
272
+ placeholder="Cinematic portrait of a warrior queen, golden armor, dramatic lighting, 8k, photorealistic...",
273
+ container=False,
274
+ )
275
+
276
+ gr.HTML('<div style="height:8px"></div>')
277
+ negative_prompt = gr.Textbox(
278
+ label="Negative prompt",
279
+ lines=2,
280
+ placeholder="Optional: describe what to avoid...",
281
+ value="",
282
+ )
283
+
284
+ gr.HTML('<div style="height:10px"></div>')
285
+ run_btn = gr.Button("▶ Generate", variant="primary", elem_classes=["gen-btn"])
286
+
287
+ gr.Examples(
288
+ examples=EXAMPLE_PROMPTS,
289
+ inputs=[prompt],
290
+ label="Example prompts",
291
+ )
292
+
293
+ with gr.Column(scale=1, min_width=320):
294
+ gr.HTML('<span class="sec-label">② Result</span>')
295
+ result = gr.Image(
296
+ label="",
297
+ type="pil",
298
+ height=512,
299
+ container=False,
300
+ elem_classes=["result-gallery"],
301
+ )
302
+
303
+ gr.HTML('<div style="height:8px"></div>')
304
+ gr.HTML('<span class="sec-label">Generation Metadata</span>')
305
+ metadata = gr.JSON(label="", show_label=False)
306
+
307
+ with gr.Accordion("⚙ Generation Settings", open=False):
308
+ gr.HTML('<span class="sec-label" style="margin-top:4px">Resolution</span>')
309
+ resolution = gr.Dropdown(
310
+ label="",
311
+ choices=RESOLUTION_SET,
312
+ value="1024x1024 ( 1:1 )",
313
+ container=False,
314
+ )
315
+
316
+ gr.HTML('<div style="height:10px"></div>')
317
+ with gr.Row():
318
+ guidance_scale = gr.Slider(
319
+ label="Guidance Scale",
320
+ minimum=3.0,
321
+ maximum=9.0,
322
+ step=0.5,
323
+ value=6.0,
324
+ )
325
+ num_inference_steps = gr.Slider(
326
+ label="Steps",
327
+ minimum=25,
328
+ maximum=50,
329
+ step=1,
330
+ value=35,
331
+ )
332
+
333
+ with gr.Row():
334
+ seed = gr.Slider(
335
+ label="Seed",
336
+ minimum=0,
337
+ maximum=2_147_483_647,
338
+ step=1,
339
+ value=42,
340
+ )
341
+ randomize_seed = gr.Checkbox(
342
+ label="Randomize seed",
343
+ value=False,
344
+ )
345
+
346
+ cfg_normalization = gr.Checkbox(
347
+ label="CFG Normalization",
348
+ value=False,
349
+ info="Enable for more stable CFG behavior at high values",
350
+ )
351
+
352
+ def generate_wrapper(prompt, negative_prompt, resolution, seed, num_inference_steps, guidance_scale, cfg_normalization, randomize_seed):
353
+ if randomize_seed:
354
+ seed = random.randint(0, 2_147_483_647)
355
+ return generate(prompt, negative_prompt, resolution, seed, num_inference_steps, guidance_scale, cfg_normalization)
356
+
357
+ inputs = [
358
+ prompt, negative_prompt, resolution, seed,
359
+ num_inference_steps, guidance_scale, cfg_normalization, randomize_seed,
360
+ ]
361
+
362
+ run_btn.click(
363
+ fn=generate_wrapper,
364
+ inputs=inputs,
365
+ outputs=[result, metadata],
366
+ api_name="generate",
367
+ )
368
+ prompt.submit(
369
+ fn=generate_wrapper,
370
+ inputs=inputs,
371
+ outputs=[result, metadata],
372
+ api_name=False,
373
+ )
374
+
375
+
376
+ demo.queue(max_size=20)
377
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ diffusers>=0.33.0
2
+ torch>=2.0.0
3
+ gradio>=6.9.0
4
+ spaces>=0.30.0
5
+ accelerate>=0.25.0
6
+ safetensors>=0.4.0
7
+ huggingface-hub>=0.25.0