ozilion commited on
Commit
e632d6b
·
verified ·
1 Parent(s): 2fc221b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +178 -200
app.py CHANGED
@@ -3,86 +3,50 @@ import torch
3
  import os
4
  import gc
5
  import numpy as np
6
- from PIL import Image
7
  import tempfile
8
  from typing import Optional, Tuple
9
  import time
10
 
11
- # Check if we're running on Hugging Face Spaces
12
- IS_SPACES = os.environ.get("SPACE_ID") is not None
13
 
14
- def check_system():
15
- """Check system capabilities"""
16
- gpu_available = torch.cuda.is_available()
17
- gpu_memory = 0
18
- if gpu_available:
19
- gpu_memory = torch.cuda.get_device_properties(0).total_memory / (1024**3)
20
-
21
- return {
22
- "gpu_available": gpu_available,
23
- "gpu_memory": gpu_memory,
24
- "is_spaces": IS_SPACES
25
- }
26
 
27
- def load_ltx_model():
28
- """Load LTX-Video model with optimizations for HF Spaces"""
29
  try:
30
  from diffusers import LTXVideoPipeline
31
- from diffusers.utils import export_to_video
32
-
33
- system_info = check_system()
34
 
35
- # Model loading strategy based on available resources
36
- model_id = "Lightricks/LTX-Video"
37
 
38
- if system_info["gpu_available"] and system_info["gpu_memory"] > 12:
39
- # High-end GPU setup
40
- pipe = LTXVideoPipeline.from_pretrained(
41
- model_id,
42
- torch_dtype=torch.bfloat16,
43
- variant="fp16"
44
- ).to("cuda")
45
- device = "cuda"
46
- dtype = torch.bfloat16
47
- elif system_info["gpu_available"] and system_info["gpu_memory"] > 6:
48
- # Mid-range GPU setup with optimizations
49
- pipe = LTXVideoPipeline.from_pretrained(
50
- model_id,
51
- torch_dtype=torch.float16,
52
- variant="fp16",
53
- low_cpu_mem_usage=True
54
- ).to("cuda")
55
- device = "cuda"
56
- dtype = torch.float16
57
- else:
58
- # CPU fallback or low memory GPU
59
- pipe = LTXVideoPipeline.from_pretrained(
60
- model_id,
61
- torch_dtype=torch.float32,
62
- low_cpu_mem_usage=True
63
- )
64
- device = "cpu"
65
- dtype = torch.float32
66
-
67
- # Enable memory efficient attention if available
68
- if hasattr(pipe, "enable_memory_efficient_attention"):
69
- pipe.enable_memory_efficient_attention()
70
 
71
- # Enable CPU offload for low memory setups
72
- if system_info["gpu_memory"] < 16 and device == "cuda":
73
- pipe.enable_sequential_cpu_offload()
 
 
 
 
 
74
 
75
- return pipe, device, dtype, system_info
 
76
 
77
- except ImportError:
78
- return None, "cpu", torch.float32, {"error": "diffusers library not installed or LTX model not available"}
79
  except Exception as e:
80
- return None, "cpu", torch.float32, {"error": f"Model loading failed: {str(e)}"}
 
81
 
82
- # Initialize model
83
- print("Loading LTX-Video model...")
84
- PIPE, DEVICE, DTYPE, SYSTEM_INFO = load_ltx_model()
85
 
 
86
  def generate_video(
87
  prompt: str,
88
  negative_prompt: str = "",
@@ -93,49 +57,48 @@ def generate_video(
93
  guidance_scale: float = 7.5,
94
  seed: int = -1
95
  ) -> Tuple[Optional[str], str]:
96
- """Generate video using LTX-Video model"""
 
 
97
 
98
- if PIPE is None:
99
- error_msg = f"❌ Model not loaded: {SYSTEM_INFO.get('error', 'Unknown error')}"
100
- return None, error_msg
 
 
 
101
 
102
  # Input validation
103
  if not prompt.strip():
104
  return None, "❌ Please enter a valid prompt."
105
 
106
- if len(prompt) > 500:
107
- return None, "❌ Prompt too long. Please keep it under 500 characters."
108
 
109
- # Adjust parameters based on system capabilities
110
- if DEVICE == "cpu":
111
- num_frames = min(num_frames, 16) # Limit frames for CPU
112
- num_inference_steps = min(num_inference_steps, 15)
113
- height = min(height, 256)
114
- width = min(width, 256)
115
- elif SYSTEM_INFO.get("gpu_memory", 0) < 8:
116
- num_frames = min(num_frames, 20)
117
- height = min(height, 512)
118
- width = min(width, 512)
119
 
120
  try:
121
- # Clear cache
122
- if DEVICE == "cuda":
123
- torch.cuda.empty_cache()
124
  gc.collect()
125
 
126
  # Set seed for reproducibility
127
  generator = None
128
- if seed != -1:
129
- generator = torch.Generator(device=DEVICE).manual_seed(seed)
130
- else:
131
  seed = np.random.randint(0, 2**32 - 1)
132
- generator = torch.Generator(device=DEVICE).manual_seed(seed)
133
 
 
 
 
134
  start_time = time.time()
135
 
136
  # Generate video
137
- with torch.autocast(DEVICE, dtype=DTYPE):
138
- result = PIPE(
139
  prompt=prompt,
140
  negative_prompt=negative_prompt if negative_prompt else None,
141
  num_frames=num_frames,
@@ -143,136 +106,159 @@ def generate_video(
143
  width=width,
144
  num_inference_steps=num_inference_steps,
145
  guidance_scale=guidance_scale,
146
- generator=generator
147
  )
148
 
149
  end_time = time.time()
150
  generation_time = end_time - start_time
151
 
152
- # Save video to temporary file
153
  video_frames = result.frames[0]
154
 
155
  with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp_file:
156
- # Convert frames to video
157
  from diffusers.utils import export_to_video
158
  export_to_video(video_frames, tmp_file.name, fps=8)
159
  video_path = tmp_file.name
160
 
 
 
 
 
161
  success_msg = f"""
162
- ✅ Video generated successfully!
163
 
164
  📝 Prompt: {prompt}
165
  🎬 Frames: {num_frames}
166
- 📐 Resolution: {width}x{height}
167
- ⚙️ Steps: {num_inference_steps}
168
- 🎯 Guidance: {guidance_scale}
169
  🎲 Seed: {seed}
170
  ⏱️ Generation Time: {generation_time:.1f}s
171
- 🖥️ Device: {DEVICE}
172
  """
173
 
174
  return video_path, success_msg
175
 
176
  except torch.cuda.OutOfMemoryError:
177
- return None, "❌ GPU memory exceeded. Try reducing resolution, frames, or inference steps."
 
 
 
178
  except Exception as e:
 
 
179
  return None, f"❌ Generation failed: {str(e)}"
180
 
181
  def get_system_info():
182
- """Get detailed system information"""
183
- info = f"""
184
- ## 🖥️ System Information
 
185
 
186
- **Hardware:**
187
- - GPU Available: {'✅' if SYSTEM_INFO.get('gpu_available', False) else '❌'}
188
- - GPU Memory: {SYSTEM_INFO.get('gpu_memory', 0):.1f} GB
189
- - Device: {DEVICE}
190
- - Data Type: {DTYPE}
191
 
192
  **Environment:**
 
193
  - Hugging Face Spaces: {'✅' if IS_SPACES else '❌'}
194
- - PyTorch Version: {torch.__version__}
 
 
195
 
196
  **Model Status:**
197
- - LTX-Video Loaded: {'✅' if PIPE is not None else ''}
198
- """
199
-
200
- if "error" in SYSTEM_INFO:
201
- info += f"\n**Error:** {SYSTEM_INFO['error']}"
202
 
203
- return info
 
 
 
 
 
204
 
205
  # Create Gradio interface
206
- with gr.Blocks(title="LTX-Video Generator", theme=gr.themes.Soft()) as demo:
207
 
208
  gr.Markdown("""
209
- # 🎬 LTX-Video Generator by Lightricks
 
 
210
 
211
- Generate high-quality videos from text descriptions using the LTX-Video model.
212
  """)
213
 
 
 
 
 
 
214
  with gr.Tab("🎥 Generate Video"):
215
  with gr.Row():
216
  with gr.Column(scale=1):
217
  prompt_input = gr.Textbox(
218
  label="📝 Video Prompt",
219
- placeholder="A serene lake surrounded by mountains at sunset...",
220
  lines=3,
221
  max_lines=5
222
  )
223
 
224
  negative_prompt_input = gr.Textbox(
225
  label="🚫 Negative Prompt (Optional)",
226
- placeholder="blurry, low quality, distorted...",
227
  lines=2
228
  )
229
 
230
- with gr.Row():
231
- num_frames = gr.Slider(
232
- minimum=8,
233
- maximum=50,
234
- value=25,
235
- step=1,
236
- label="🎬 Number of Frames"
237
- )
 
 
 
 
 
 
 
 
 
238
 
239
- num_steps = gr.Slider(
240
- minimum=10,
241
- maximum=50,
242
- value=20,
243
- step=1,
244
- label="⚙️ Inference Steps"
245
- )
246
-
247
- with gr.Row():
248
- width = gr.Dropdown(
249
- choices=[256, 512, 768, 1024],
250
- value=512,
251
- label="📐 Width"
252
- )
253
 
254
- height = gr.Dropdown(
255
- choices=[256, 512, 768, 1024],
256
- value=512,
257
- label="📏 Height"
258
- )
 
 
 
 
 
 
 
 
 
259
 
260
- with gr.Row():
261
- guidance_scale = gr.Slider(
262
- minimum=1.0,
263
- maximum=20.0,
264
- value=7.5,
265
- step=0.5,
266
- label="🎯 Guidance Scale"
267
- )
268
-
269
- seed = gr.Number(
270
- label="🎲 Seed (-1 for random)",
271
- value=-1,
272
- precision=0
273
- )
274
 
275
- generate_btn = gr.Button("🎬 Generate Video", variant="primary", size="lg")
 
 
276
 
277
  with gr.Column(scale=1):
278
  video_output = gr.Video(
@@ -299,63 +285,55 @@ with gr.Blocks(title="LTX-Video Generator", theme=gr.themes.Soft()) as demo:
299
  # Example prompts
300
  gr.Examples(
301
  examples=[
302
- ["A majestic waterfall cascading down rocky cliffs", "", 25, 512, 512, 20, 7.5, 42],
303
- ["A cute kitten playing with colorful yarn balls", "blurry, low quality", 20, 512, 512, 20, 8.0, 123],
304
- ["Time-lapse of clouds moving over a city skyline", "", 30, 768, 512, 25, 7.0, 456],
305
- ["A peaceful forest with sunlight filtering through trees", "dark, gloomy", 25, 512, 768, 20, 7.5, 789]
306
  ],
307
  inputs=[prompt_input, negative_prompt_input, num_frames, height, width, num_steps, guidance_scale, seed]
308
  )
309
 
310
  with gr.Tab("ℹ️ System Info"):
311
- with gr.Row():
312
- info_btn = gr.Button("🔍 Check System Status", variant="secondary")
313
-
314
  system_output = gr.Markdown()
315
 
316
- info_btn.click(
317
- fn=get_system_info,
318
- outputs=system_output
319
- )
320
-
321
- # Initial system info display
322
- demo.load(
323
- fn=get_system_info,
324
- outputs=system_output
325
- )
326
 
327
- with gr.Tab("📚 Usage Tips"):
328
  gr.Markdown("""
329
- ## 💡 Tips for Better Results
 
 
330
 
331
- **Prompt Writing:**
332
- - Be descriptive and specific
333
- - Include camera movements (zoom, pan, etc.)
334
- - Specify lighting and mood
335
- - Mention style if desired (cinematic, artistic, etc.)
336
 
337
- **Parameter Tuning:**
338
- - **Frames:** More frames = longer video but slower generation
339
- - **Inference Steps:** Higher steps = better quality but slower
340
- - **Guidance Scale:** 7-9 usually works best
341
- - **Resolution:** Start with 512x512 for faster results
342
 
343
- **Performance:**
344
- - CPU generation is slower but works on all systems
345
- - GPU generation requires sufficient VRAM
346
- - Lower settings if you encounter memory errors
347
 
348
- **Negative Prompts:** Help avoid unwanted elements
349
- - Common: "blurry, low quality, distorted, pixelated"
350
- - Specific: "text, watermark, signature, logo"
 
351
  """)
352
 
353
- # Launch configuration
354
  if __name__ == "__main__":
 
355
  demo.launch(
356
  share=False,
357
- server_name="0.0.0.0",
358
  server_port=7860,
359
- show_error=True,
360
- show_api=False
361
  )
 
3
  import os
4
  import gc
5
  import numpy as np
 
6
  import tempfile
7
  from typing import Optional, Tuple
8
  import time
9
 
10
+ # ZeroGPU import - bu çok önemli!
11
+ import spaces
12
 
13
+ # Check if running in ZeroGPU environment
14
+ IS_ZERO_GPU = os.environ.get("SPACES_ZERO_GPU") == "true"
15
+ IS_SPACES = os.environ.get("SPACE_ID") is not None
 
 
 
 
 
 
 
 
 
16
 
17
+ def load_model():
18
+ """Load LTX-Video model - this will run on ZeroGPU when decorated"""
19
  try:
20
  from diffusers import LTXVideoPipeline
 
 
 
21
 
22
+ print("🔄 Loading LTX-Video model...")
 
23
 
24
+ pipe = LTXVideoPipeline.from_pretrained(
25
+ "Lightricks/LTX-Video",
26
+ torch_dtype=torch.bfloat16,
27
+ use_safetensors=True,
28
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ # ZeroGPU optimizations
31
+ if IS_ZERO_GPU:
32
+ pipe = pipe.to("cuda")
33
+ # Enable memory optimizations
34
+ pipe.enable_vae_slicing()
35
+ pipe.enable_vae_tiling()
36
+ if hasattr(pipe, 'enable_memory_efficient_attention'):
37
+ pipe.enable_memory_efficient_attention()
38
 
39
+ print("✅ Model loaded successfully!")
40
+ return pipe
41
 
 
 
42
  except Exception as e:
43
+ print(f" Model loading failed: {e}")
44
+ return None
45
 
46
+ # Global model variable - will be loaded when needed
47
+ MODEL = None
 
48
 
49
+ @spaces.GPU(duration=120) # ZeroGPU decorator - 2 dakika GPU kullanımı
50
  def generate_video(
51
  prompt: str,
52
  negative_prompt: str = "",
 
57
  guidance_scale: float = 7.5,
58
  seed: int = -1
59
  ) -> Tuple[Optional[str], str]:
60
+ """Generate video using LTX-Video with ZeroGPU"""
61
+
62
+ global MODEL
63
 
64
+ # Load model if not already loaded
65
+ if MODEL is None:
66
+ MODEL = load_model()
67
+
68
+ if MODEL is None:
69
+ return None, "❌ Model loading failed. Please try again."
70
 
71
  # Input validation
72
  if not prompt.strip():
73
  return None, "❌ Please enter a valid prompt."
74
 
75
+ if len(prompt) > 300:
76
+ return None, "❌ Prompt too long. Please keep it under 300 characters."
77
 
78
+ # ZeroGPU optimizations - limit parameters for stability
79
+ num_frames = min(num_frames, 25) # Max 25 frames
80
+ num_inference_steps = min(num_inference_steps, 25) # Max 25 steps
81
+ height = min(height, 768) # Max 768px
82
+ width = min(width, 768) # Max 768px
 
 
 
 
 
83
 
84
  try:
85
+ # Clear CUDA cache
86
+ torch.cuda.empty_cache()
 
87
  gc.collect()
88
 
89
  # Set seed for reproducibility
90
  generator = None
91
+ if seed == -1:
 
 
92
  seed = np.random.randint(0, 2**32 - 1)
 
93
 
94
+ generator = torch.Generator(device="cuda").manual_seed(seed)
95
+
96
+ print(f"🎬 Generating video: {prompt}")
97
  start_time = time.time()
98
 
99
  # Generate video
100
+ with torch.autocast("cuda", dtype=torch.bfloat16):
101
+ result = MODEL(
102
  prompt=prompt,
103
  negative_prompt=negative_prompt if negative_prompt else None,
104
  num_frames=num_frames,
 
106
  width=width,
107
  num_inference_steps=num_inference_steps,
108
  guidance_scale=guidance_scale,
109
+ generator=generator,
110
  )
111
 
112
  end_time = time.time()
113
  generation_time = end_time - start_time
114
 
115
+ # Export video
116
  video_frames = result.frames[0]
117
 
118
  with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp_file:
119
+ # Export to video file
120
  from diffusers.utils import export_to_video
121
  export_to_video(video_frames, tmp_file.name, fps=8)
122
  video_path = tmp_file.name
123
 
124
+ # Clear memory
125
+ torch.cuda.empty_cache()
126
+ gc.collect()
127
+
128
  success_msg = f"""
129
+ ✅ Video generated successfully with ZeroGPU!
130
 
131
  📝 Prompt: {prompt}
132
  🎬 Frames: {num_frames}
133
+ 📐 Resolution: {width}x{height}
134
+ ⚙️ Inference Steps: {num_inference_steps}
135
+ 🎯 Guidance Scale: {guidance_scale}
136
  🎲 Seed: {seed}
137
  ⏱️ Generation Time: {generation_time:.1f}s
138
+ 🖥️ ZeroGPU: {'✅' if IS_ZERO_GPU else '❌'}
139
  """
140
 
141
  return video_path, success_msg
142
 
143
  except torch.cuda.OutOfMemoryError:
144
+ torch.cuda.empty_cache()
145
+ gc.collect()
146
+ return None, "❌ GPU memory exceeded. Try reducing frames, resolution, or inference steps."
147
+
148
  except Exception as e:
149
+ torch.cuda.empty_cache()
150
+ gc.collect()
151
  return None, f"❌ Generation failed: {str(e)}"
152
 
153
  def get_system_info():
154
+ """Get system information"""
155
+ gpu_info = "Not available"
156
+ if torch.cuda.is_available():
157
+ gpu_info = f"{torch.cuda.get_device_name(0)} ({torch.cuda.get_device_properties(0).total_memory / 1024**3:.1f} GB)"
158
 
159
+ return f"""
160
+ ## 🖥️ System Information
 
 
 
161
 
162
  **Environment:**
163
+ - ZeroGPU: {'✅ Active' if IS_ZERO_GPU else '❌ Not detected'}
164
  - Hugging Face Spaces: {'✅' if IS_SPACES else '❌'}
165
+ - CUDA Available: {'✅' if torch.cuda.is_available() else '❌'}
166
+ - GPU: {gpu_info}
167
+ - PyTorch: {torch.__version__}
168
 
169
  **Model Status:**
170
+ - LTX-Video: {'✅ Loaded' if MODEL is not None else '⏳ Will load on first use'}
 
 
 
 
171
 
172
+ **ZeroGPU Benefits:**
173
+ - ✅ Free GPU access
174
+ - ✅ A100 40GB GPU
175
+ - ✅ Automatic resource management
176
+ - ⏱️ 120 second timeout per generation
177
+ """
178
 
179
  # Create Gradio interface
180
+ with gr.Blocks(title="LTX-Video with ZeroGPU", theme=gr.themes.Soft()) as demo:
181
 
182
  gr.Markdown("""
183
+ # 🚀 LTX-Video Generator (ZeroGPU Powered)
184
+
185
+ Generate high-quality videos from text using Lightricks' LTX-Video model, powered by **ZeroGPU**!
186
 
187
+ **Free GPU access** - No need to upgrade your Space hardware!
188
  """)
189
 
190
+ if IS_ZERO_GPU:
191
+ gr.Markdown("✅ **ZeroGPU Active** - You have free access to A100 GPU!")
192
+ else:
193
+ gr.Markdown("⚠️ **ZeroGPU not detected** - Make sure you've enabled ZeroGPU in your Space settings.")
194
+
195
  with gr.Tab("🎥 Generate Video"):
196
  with gr.Row():
197
  with gr.Column(scale=1):
198
  prompt_input = gr.Textbox(
199
  label="📝 Video Prompt",
200
+ placeholder="A serene mountain lake reflecting the aurora borealis...",
201
  lines=3,
202
  max_lines=5
203
  )
204
 
205
  negative_prompt_input = gr.Textbox(
206
  label="🚫 Negative Prompt (Optional)",
207
+ placeholder="blurry, low quality, distorted, text, watermark...",
208
  lines=2
209
  )
210
 
211
+ with gr.Accordion("🔧 Advanced Settings", open=False):
212
+ with gr.Row():
213
+ num_frames = gr.Slider(
214
+ minimum=8,
215
+ maximum=25, # Limited for ZeroGPU
216
+ value=16,
217
+ step=1,
218
+ label="🎬 Number of Frames"
219
+ )
220
+
221
+ num_steps = gr.Slider(
222
+ minimum=10,
223
+ maximum=25, # Limited for ZeroGPU
224
+ value=20,
225
+ step=1,
226
+ label="⚙️ Inference Steps"
227
+ )
228
 
229
+ with gr.Row():
230
+ width = gr.Dropdown(
231
+ choices=[256, 512, 768], # Limited for ZeroGPU
232
+ value=512,
233
+ label="📐 Width"
234
+ )
235
+
236
+ height = gr.Dropdown(
237
+ choices=[256, 512, 768], # Limited for ZeroGPU
238
+ value=512,
239
+ label="📏 Height"
240
+ )
 
 
241
 
242
+ with gr.Row():
243
+ guidance_scale = gr.Slider(
244
+ minimum=1.0,
245
+ maximum=15.0,
246
+ value=7.5,
247
+ step=0.5,
248
+ label="🎯 Guidance Scale"
249
+ )
250
+
251
+ seed = gr.Number(
252
+ label="🎲 Seed (-1 for random)",
253
+ value=-1,
254
+ precision=0
255
+ )
256
 
257
+ generate_btn = gr.Button("🚀 Generate Video with ZeroGPU", variant="primary", size="lg")
 
 
 
 
 
 
 
 
 
 
 
 
 
258
 
259
+ gr.Markdown("""
260
+ **⏱️ Note:** Each generation uses 2 minutes of ZeroGPU time.
261
+ """)
262
 
263
  with gr.Column(scale=1):
264
  video_output = gr.Video(
 
285
  # Example prompts
286
  gr.Examples(
287
  examples=[
288
+ ["A majestic eagle soaring over snow-capped mountains", "blurry, low quality", 16, 512, 512, 20, 7.5, 42],
289
+ ["Ocean waves gently lapping on a tropical beach at sunset", "", 20, 512, 512, 20, 8.0, 123],
290
+ ["A steaming cup of coffee on a rainy window sill", "text, watermark", 16, 512, 512, 15, 7.0, 456],
291
+ ["Cherry blossoms falling in a peaceful Japanese garden", "", 20, 768, 512, 20, 7.5, 789]
292
  ],
293
  inputs=[prompt_input, negative_prompt_input, num_frames, height, width, num_steps, guidance_scale, seed]
294
  )
295
 
296
  with gr.Tab("ℹ️ System Info"):
297
+ info_btn = gr.Button("🔍 Check System Status", variant="secondary")
 
 
298
  system_output = gr.Markdown()
299
 
300
+ info_btn.click(fn=get_system_info, outputs=system_output)
301
+ demo.load(fn=get_system_info, outputs=system_output)
 
 
 
 
 
 
 
 
302
 
303
+ with gr.Tab("📚 ZeroGPU Guide"):
304
  gr.Markdown("""
305
+ ## 🚀 ZeroGPU Nedir?
306
+
307
+ **ZeroGPU**, Hugging Face'in ücretsiz GPU hizmetidir:
308
 
309
+ ### ✅ Avantajları:
310
+ - **Ücretsiz A100 GPU** erişimi
311
+ - **40GB GPU belleği**
312
+ - Otomatik kaynak yönetimi
313
+ - CPU Basic Space'te bile çalışır
314
 
315
+ ### ⚙️ Nasıl Etkinleştirilir:
316
+ 1. Space Settings Advanced ZeroGPU etkinleştir
317
+ 2. `requirements.txt`'e `spaces` ekle
318
+ 3. Kodda `@spaces.GPU()` decorator kullan
 
319
 
320
+ ### 📊 Limitler:
321
+ - Fonksiyon başına max 120 saniye
322
+ - Eşzamanlı kullanım sınırı
323
+ - Yoğun zamanlarda kuyruk
324
 
325
+ ### 💡 İpuçları:
326
+ - Küçük parametrelerle başlayın
327
+ - İlk çalıştırma model yükleme nedeniyle uzun sürebilir
328
+ - Hata alırsanız birkaç saniye bekleyip tekrar deneyin
329
  """)
330
 
331
+ # Launch the app
332
  if __name__ == "__main__":
333
+ demo.queue(max_size=10) # ZeroGPU için queue gerekli
334
  demo.launch(
335
  share=False,
336
+ server_name="0.0.0.0",
337
  server_port=7860,
338
+ show_error=True
 
339
  )