akhaliq HF Staff commited on
Commit
2473931
·
verified ·
1 Parent(s): 3cabae3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +463 -0
app.py ADDED
@@ -0,0 +1,463 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ from diffusers import ZImagePipeline
4
+ import os
5
+ from pathlib import Path
6
+
7
+ # Initialize the pipeline
8
+ print("Loading Z-Image Turbo model...")
9
+ pipe = ZImagePipeline.from_pretrained(
10
+ "Tongyi-MAI/Z-Image-Turbo",
11
+ torch_dtype=torch.bfloat16,
12
+ low_cpu_mem_usage=False,
13
+ )
14
+
15
+ # Move to GPU if available
16
+ device = "cuda" if torch.cuda.is_available() else "cpu"
17
+ pipe.to(device)
18
+
19
+ # Optional: Enable Flash Attention for better efficiency
20
+ try:
21
+ pipe.transformer.set_attention_backend("flash")
22
+ print("Flash Attention enabled")
23
+ except:
24
+ print("Flash Attention not available, using default")
25
+
26
+ print("Model loaded successfully!")
27
+
28
+ def generate_image(
29
+ prompt,
30
+ negative_prompt,
31
+ height,
32
+ width,
33
+ num_steps,
34
+ seed,
35
+ progress=gr.Progress(track_tqdm=True)
36
+ ):
37
+ """
38
+ Generate an image using Z-Image Turbo model.
39
+
40
+ Args:
41
+ prompt: Text description of the desired image
42
+ negative_prompt: What to avoid in the image
43
+ height: Image height
44
+ width: Image width
45
+ num_steps: Number of inference steps
46
+ seed: Random seed for reproducibility
47
+
48
+ Returns:
49
+ Generated PIL Image
50
+ """
51
+ if not prompt.strip():
52
+ raise gr.Error("Please enter a prompt to generate an image.")
53
+
54
+ # Set random seed for reproducibility
55
+ generator = torch.Generator(device).manual_seed(int(seed))
56
+
57
+ # Generate the image
58
+ progress(0, desc="Initializing generation...")
59
+
60
+ try:
61
+ result = pipe(
62
+ prompt=prompt,
63
+ negative_prompt=negative_prompt if negative_prompt.strip() else None,
64
+ height=int(height),
65
+ width=int(width),
66
+ num_inference_steps=int(num_steps),
67
+ guidance_scale=0.0, # Turbo models use 0 guidance
68
+ generator=generator,
69
+ )
70
+
71
+ image = result.images[0]
72
+ progress(1.0, desc="Complete!")
73
+
74
+ return image
75
+
76
+ except Exception as e:
77
+ raise gr.Error(f"Generation failed: {str(e)}")
78
+
79
+ # Apple-inspired CSS
80
+ apple_css = """
81
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
82
+
83
+ * {
84
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
85
+ }
86
+
87
+ .gradio-container {
88
+ max-width: 1200px !important;
89
+ margin: 0 auto !important;
90
+ background: linear-gradient(135deg, #f5f7fa 0%, #e8ecf1 100%) !important;
91
+ }
92
+
93
+ .main-header {
94
+ text-align: center;
95
+ padding: 2.5rem 1rem 1.5rem 1rem;
96
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
97
+ border-radius: 24px;
98
+ margin-bottom: 2rem;
99
+ box-shadow: 0 10px 40px rgba(102, 126, 234, 0.3);
100
+ }
101
+
102
+ .main-header h1 {
103
+ font-size: 2.5rem !important;
104
+ font-weight: 700 !important;
105
+ color: white !important;
106
+ margin: 0 0 0.5rem 0 !important;
107
+ letter-spacing: -0.5px;
108
+ }
109
+
110
+ .main-header p {
111
+ font-size: 1.1rem !important;
112
+ color: rgba(255, 255, 255, 0.9) !important;
113
+ margin: 0 !important;
114
+ font-weight: 400;
115
+ }
116
+
117
+ .attribution {
118
+ text-align: center;
119
+ margin-top: 0.5rem;
120
+ font-size: 0.9rem;
121
+ color: rgba(255, 255, 255, 0.8);
122
+ }
123
+
124
+ .attribution a {
125
+ color: white !important;
126
+ text-decoration: none;
127
+ font-weight: 600;
128
+ transition: opacity 0.2s;
129
+ }
130
+
131
+ .attribution a:hover {
132
+ opacity: 0.8;
133
+ }
134
+
135
+ .control-panel {
136
+ background: white;
137
+ border-radius: 20px;
138
+ padding: 1.5rem;
139
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
140
+ margin-bottom: 1.5rem;
141
+ }
142
+
143
+ .output-panel {
144
+ background: white;
145
+ border-radius: 20px;
146
+ padding: 1.5rem;
147
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
148
+ min-height: 600px;
149
+ }
150
+
151
+ .primary-btn {
152
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
153
+ border: none !important;
154
+ border-radius: 12px !important;
155
+ padding: 0.875rem 2rem !important;
156
+ font-size: 1rem !important;
157
+ font-weight: 600 !important;
158
+ color: white !important;
159
+ transition: all 0.3s ease !important;
160
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3) !important;
161
+ }
162
+
163
+ .primary-btn:hover {
164
+ transform: translateY(-2px) !important;
165
+ box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4) !important;
166
+ }
167
+
168
+ .secondary-btn {
169
+ background: #f3f4f6 !important;
170
+ border: 1px solid #e5e7eb !important;
171
+ border-radius: 12px !important;
172
+ padding: 0.875rem 2rem !important;
173
+ font-size: 1rem !important;
174
+ font-weight: 500 !important;
175
+ color: #374151 !important;
176
+ transition: all 0.3s ease !important;
177
+ }
178
+
179
+ .secondary-btn:hover {
180
+ background: #e5e7eb !important;
181
+ transform: translateY(-1px) !important;
182
+ }
183
+
184
+ textarea, input, .input-container {
185
+ border-radius: 12px !important;
186
+ border: 1.5px solid #e5e7eb !important;
187
+ transition: all 0.2s ease !important;
188
+ font-size: 0.95rem !important;
189
+ }
190
+
191
+ textarea:focus, input:focus {
192
+ border-color: #667eea !important;
193
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
194
+ }
195
+
196
+ .slider-container input[type="range"] {
197
+ accent-color: #667eea !important;
198
+ }
199
+
200
+ label {
201
+ font-weight: 600 !important;
202
+ color: #1f2937 !important;
203
+ font-size: 0.9rem !important;
204
+ margin-bottom: 0.5rem !important;
205
+ }
206
+
207
+ .example-card {
208
+ border-radius: 12px !important;
209
+ transition: all 0.3s ease !important;
210
+ cursor: pointer !important;
211
+ border: 2px solid transparent !important;
212
+ }
213
+
214
+ .example-card:hover {
215
+ border-color: #667eea !important;
216
+ transform: scale(1.02) !important;
217
+ }
218
+
219
+ .accordion {
220
+ border-radius: 12px !important;
221
+ border: 1.5px solid #e5e7eb !important;
222
+ overflow: hidden !important;
223
+ }
224
+
225
+ #output-image {
226
+ border-radius: 16px !important;
227
+ overflow: hidden !important;
228
+ }
229
+
230
+ .footer-note {
231
+ text-align: center;
232
+ padding: 1.5rem;
233
+ color: #6b7280;
234
+ font-size: 0.9rem;
235
+ margin-top: 2rem;
236
+ }
237
+
238
+ @media (max-width: 768px) {
239
+ .main-header h1 {
240
+ font-size: 1.75rem !important;
241
+ }
242
+
243
+ .main-header p {
244
+ font-size: 0.95rem !important;
245
+ }
246
+
247
+ .control-panel, .output-panel {
248
+ padding: 1rem;
249
+ }
250
+ }
251
+ """
252
+
253
+ # Example prompts
254
+ examples = [
255
+ [
256
+ "Young Chinese woman in red Hanfu, intricate embroidery. Impeccable makeup, red floral forehead pattern. Elaborate high bun, golden phoenix headdress, red flowers, beads. Holds round folding fan with lady, trees, bird. Neon lightning-bolt lamp (⚡️), bright yellow glow, above extended left palm. Soft-lit outdoor night background, silhouetted tiered pagoda (西安大雁塔), blurred colorful distant lights.",
257
+ "",
258
+ 1024,
259
+ 1024,
260
+ 9,
261
+ 42
262
+ ],
263
+ [
264
+ "A serene Japanese garden with cherry blossoms in full bloom, koi pond with crystal clear water, traditional wooden bridge, soft morning light filtering through trees, ultra detailed, photorealistic",
265
+ "blurry, low quality, distorted",
266
+ 1024,
267
+ 1024,
268
+ 9,
269
+ 123
270
+ ],
271
+ [
272
+ "Futuristic cyberpunk city at night, neon signs reflecting on wet streets, flying cars, towering skyscrapers with holographic advertisements, rain, cinematic lighting, highly detailed",
273
+ "daytime, bright, low quality",
274
+ 1024,
275
+ 1024,
276
+ 9,
277
+ 456
278
+ ],
279
+ [
280
+ "Majestic dragon soaring through clouds at sunset, scales shimmering with iridescent colors, mountains in background, fantasy art style, epic composition, dramatic lighting",
281
+ "cartoon, simple, flat",
282
+ 1024,
283
+ 1024,
284
+ 9,
285
+ 789
286
+ ],
287
+ [
288
+ "Cozy coffee shop interior, warm lighting, wooden furniture, plants on shelves, barista preparing coffee, steam rising from cup, bokeh background, inviting atmosphere",
289
+ "empty, cold, harsh lighting",
290
+ 1024,
291
+ 1024,
292
+ 9,
293
+ 321
294
+ ]
295
+ ]
296
+
297
+ # Create the Gradio interface
298
+ with gr.Blocks(
299
+ theme=gr.themes.Soft(
300
+ primary_hue="violet",
301
+ secondary_hue="purple",
302
+ neutral_hue="slate",
303
+ font=gr.themes.GoogleFont("Inter")
304
+ ),
305
+ css=apple_css,
306
+ title="Z-Image Turbo - AI Image Generator",
307
+ fill_height=False
308
+ ) as demo:
309
+
310
+ # Header
311
+ with gr.Row():
312
+ with gr.Column():
313
+ gr.HTML("""
314
+ <div class="main-header">
315
+ <h1>✨ Z-Image Turbo</h1>
316
+ <p>Create stunning images from text in seconds</p>
317
+ <div class="attribution">
318
+ Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a>
319
+ </div>
320
+ </div>
321
+ """)
322
+
323
+ with gr.Row():
324
+ # Left column - Controls
325
+ with gr.Column(scale=1, elem_classes="control-panel"):
326
+ prompt = gr.Textbox(
327
+ label="✍️ Prompt",
328
+ placeholder="Describe the image you want to create...",
329
+ lines=4,
330
+ max_lines=8
331
+ )
332
+
333
+ negative_prompt = gr.Textbox(
334
+ label="🚫 Negative Prompt (Optional)",
335
+ placeholder="What you don't want in the image...",
336
+ lines=2,
337
+ max_lines=4
338
+ )
339
+
340
+ with gr.Accordion("⚙️ Advanced Settings", open=False, elem_classes="accordion"):
341
+ with gr.Row():
342
+ width = gr.Slider(
343
+ minimum=512,
344
+ maximum=2048,
345
+ value=1024,
346
+ step=64,
347
+ label="Width",
348
+ elem_classes="slider-container"
349
+ )
350
+ height = gr.Slider(
351
+ minimum=512,
352
+ maximum=2048,
353
+ value=1024,
354
+ step=64,
355
+ label="Height",
356
+ elem_classes="slider-container"
357
+ )
358
+
359
+ num_steps = gr.Slider(
360
+ minimum=4,
361
+ maximum=20,
362
+ value=9,
363
+ step=1,
364
+ label="Inference Steps",
365
+ info="More steps = better quality but slower",
366
+ elem_classes="slider-container"
367
+ )
368
+
369
+ seed = gr.Number(
370
+ label="Seed",
371
+ value=42,
372
+ precision=0,
373
+ info="Use same seed for reproducible results"
374
+ )
375
+
376
+ random_seed_btn = gr.Button(
377
+ "🎲 Random Seed",
378
+ elem_classes="secondary-btn",
379
+ size="sm"
380
+ )
381
+
382
+ with gr.Row():
383
+ generate_btn = gr.Button(
384
+ "🎨 Generate Image",
385
+ variant="primary",
386
+ elem_classes="primary-btn",
387
+ size="lg"
388
+ )
389
+ clear_btn = gr.ClearButton(
390
+ [prompt, negative_prompt],
391
+ value="🗑️ Clear",
392
+ elem_classes="secondary-btn",
393
+ size="lg"
394
+ )
395
+
396
+ # Right column - Output
397
+ with gr.Column(scale=1, elem_classes="output-panel"):
398
+ output_image = gr.Image(
399
+ label="Generated Image",
400
+ type="pil",
401
+ elem_id="output-image",
402
+ show_label=False,
403
+ show_download_button=True,
404
+ show_share_button=True,
405
+ height=600
406
+ )
407
+
408
+ # Examples section
409
+ with gr.Row():
410
+ gr.Examples(
411
+ examples=examples,
412
+ inputs=[prompt, negative_prompt, height, width, num_steps, seed],
413
+ outputs=output_image,
414
+ fn=generate_image,
415
+ cache_examples=False,
416
+ label="💡 Try these examples",
417
+ examples_per_page=5,
418
+ elem_classes="example-card"
419
+ )
420
+
421
+ # Footer
422
+ gr.HTML("""
423
+ <div class="footer-note">
424
+ <p>Powered by <strong>Z-Image Turbo</strong> from Tongyi-MAI |
425
+ Optimized for fast, high-quality image generation</p>
426
+ <p style="margin-top: 0.5rem; font-size: 0.85rem;">
427
+ 💡 Tip: Be specific and detailed in your prompts for best results
428
+ </p>
429
+ </div>
430
+ """)
431
+
432
+ # Event handlers
433
+ def randomize_seed():
434
+ import random
435
+ return random.randint(0, 2**32 - 1)
436
+
437
+ random_seed_btn.click(
438
+ fn=randomize_seed,
439
+ inputs=[],
440
+ outputs=seed
441
+ )
442
+
443
+ generate_btn.click(
444
+ fn=generate_image,
445
+ inputs=[prompt, negative_prompt, height, width, num_steps, seed],
446
+ outputs=output_image,
447
+ api_name="generate"
448
+ )
449
+
450
+ # Also allow generation on Enter key in prompt
451
+ prompt.submit(
452
+ fn=generate_image,
453
+ inputs=[prompt, negative_prompt, height, width, num_steps, seed],
454
+ outputs=output_image
455
+ )
456
+
457
+ # Launch the app
458
+ if __name__ == "__main__":
459
+ demo.launch(
460
+ share=False,
461
+ show_error=True,
462
+ favicon_path=None
463
+ )