ozilion commited on
Commit
e6fb807
Β·
verified Β·
1 Parent(s): 2ed26c9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +279 -241
app.py CHANGED
@@ -6,116 +6,181 @@ import numpy as np
6
  import tempfile
7
  from typing import Optional, Tuple
8
  import time
9
- import subprocess
10
- import sys
11
 
12
  # ZeroGPU import
13
  try:
14
  import spaces
15
  SPACES_AVAILABLE = True
16
- print("βœ… Spaces library loaded successfully")
17
  except ImportError:
18
- print("⚠️ Spaces library not available")
19
  SPACES_AVAILABLE = False
20
- # Create dummy decorator
21
- def spaces_gpu_decorator(duration=60):
22
- def decorator(func):
23
- return func
24
- return decorator
25
- spaces = type('spaces', (), {'GPU': spaces_gpu_decorator})()
26
 
27
- # Environment checks
28
  IS_ZERO_GPU = os.environ.get("SPACES_ZERO_GPU") == "true"
29
  IS_SPACES = os.environ.get("SPACE_ID") is not None
30
 
31
- print(f"Environment: ZeroGPU={IS_ZERO_GPU}, Spaces={IS_SPACES}")
32
-
33
- def check_and_install_requirements():
34
- """Check and install missing requirements"""
35
  try:
36
- import diffusers
37
- print(f"βœ… Diffusers version: {diffusers.__version__}")
38
- return True
39
- except ImportError:
40
- print("❌ Diffusers not found, attempting to install...")
 
 
41
  try:
42
- subprocess.check_call([sys.executable, "-m", "pip", "install", "diffusers[torch]>=0.30.0"])
43
- subprocess.check_call([sys.executable, "-m", "pip", "install", "transformers>=4.35.0"])
44
- subprocess.check_call([sys.executable, "-m", "pip", "install", "accelerate"])
45
- import diffusers
46
- print(f"βœ… Diffusers installed successfully: {diffusers.__version__}")
47
- return True
 
 
 
 
 
 
 
 
48
  except Exception as e:
49
- print(f"❌ Failed to install diffusers: {e}")
50
- return False
 
 
 
51
 
52
- def load_model_safe():
53
- """Safely load the LTX-Video model with comprehensive error handling"""
54
-
55
- # First, ensure requirements are installed
56
- if not check_and_install_requirements():
57
- return None, "Failed to install required packages"
58
-
59
  try:
60
- print("πŸ”„ Attempting to load LTX-Video model...")
61
 
62
- # Import after installation
63
- from diffusers import LTXVideoPipeline
64
- import torch
65
 
66
- model_id = "Lightricks/LTX-Video"
 
 
 
 
 
67
 
68
- # Check available memory
69
- if torch.cuda.is_available():
70
- gpu_memory = torch.cuda.get_device_properties(0).total_memory / (1024**3)
71
- print(f"πŸ“Š Available GPU memory: {gpu_memory:.1f} GB")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
- # Load with conservative settings
74
- print("πŸ“₯ Loading pipeline...")
75
- pipe = LTXVideoPipeline.from_pretrained(
76
- model_id,
77
- torch_dtype=torch.bfloat16,
78
- use_safetensors=True,
79
- variant="fp16"
80
- )
81
 
82
- # Move to GPU if available
83
- if torch.cuda.is_available():
84
- pipe = pipe.to("cuda")
85
- print("πŸš€ Model moved to GPU")
 
 
 
 
86
 
87
- # Enable optimizations
88
- try:
89
- pipe.enable_vae_slicing()
90
- pipe.enable_vae_tiling()
91
- print("⚑ Memory optimizations enabled")
92
- except Exception as e:
93
- print(f"⚠️ Some optimizations failed: {e}")
94
 
95
- print("βœ… Model loaded successfully!")
96
- return pipe, None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
- except ImportError as e:
99
- error_msg = f"Import error: {e}. Please check if diffusers is properly installed."
100
- print(f"❌ {error_msg}")
101
- return None, error_msg
102
 
103
  except Exception as e:
104
- error_msg = f"Model loading failed: {str(e)}"
105
- print(f"❌ {error_msg}")
106
- return None, error_msg
107
 
108
- # Global model variable
109
  MODEL = None
 
 
110
  MODEL_ERROR = None
111
 
112
  def initialize_model():
113
- """Initialize model on first use"""
114
- global MODEL, MODEL_ERROR
115
- if MODEL is None and MODEL_ERROR is None:
116
- print("πŸš€ Initializing model for first use...")
117
- MODEL, MODEL_ERROR = load_model_safe()
118
- return MODEL is not None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
  @spaces.GPU(duration=120) if SPACES_AVAILABLE else lambda x: x
121
  def generate_video(
@@ -128,45 +193,85 @@ def generate_video(
128
  guidance_scale: float = 7.5,
129
  seed: int = -1
130
  ) -> Tuple[Optional[str], str]:
131
- """Generate video using LTX-Video with ZeroGPU"""
132
-
133
- global MODEL, MODEL_ERROR
134
 
135
- # Initialize model if needed
136
- if not initialize_model():
137
- error_msg = f"❌ Model initialization failed: {MODEL_ERROR or 'Unknown error'}"
138
- return None, error_msg
139
 
140
  # Input validation
141
  if not prompt.strip():
142
  return None, "❌ Please enter a valid prompt."
143
 
144
- if len(prompt) > 200:
145
- return None, "❌ Prompt too long. Please keep it under 200 characters."
146
-
147
- # Limit parameters for stability
148
- num_frames = min(max(num_frames, 8), 24)
149
- num_inference_steps = min(max(num_inference_steps, 10), 25)
150
  height = min(max(height, 256), 768)
151
  width = min(max(width, 256), 768)
152
 
 
 
 
 
153
  try:
154
  # Clear memory
155
  if torch.cuda.is_available():
156
  torch.cuda.empty_cache()
157
  gc.collect()
158
 
159
- # Set seed
160
- if seed == -1:
161
- seed = np.random.randint(0, 2**32 - 1)
162
 
163
- generator = torch.Generator(device="cuda" if torch.cuda.is_available() else "cpu").manual_seed(seed)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
- print(f"🎬 Generating: '{prompt[:50]}...'")
166
- start_time = time.time()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
 
168
- # Generate video
169
- with torch.autocast("cuda" if torch.cuda.is_available() else "cpu", dtype=torch.bfloat16):
 
 
 
 
170
  result = MODEL(
171
  prompt=prompt,
172
  negative_prompt=negative_prompt if negative_prompt.strip() else None,
@@ -175,49 +280,32 @@ def generate_video(
175
  width=width,
176
  num_inference_steps=num_inference_steps,
177
  guidance_scale=guidance_scale,
178
- generator=generator,
179
  )
180
-
181
- end_time = time.time()
182
- generation_time = end_time - start_time
183
-
184
- # Save video
185
- video_frames = result.frames[0]
186
-
187
- with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp_file:
188
- try:
189
  from diffusers.utils import export_to_video
190
  export_to_video(video_frames, tmp_file.name, fps=8)
191
  video_path = tmp_file.name
192
- except Exception as e:
193
- # Fallback: save as individual frames if export fails
194
- print(f"⚠️ Video export failed, trying alternative: {e}")
195
- return None, f"❌ Video export failed: {str(e)}"
196
-
197
- # Clear memory
198
- if torch.cuda.is_available():
199
- torch.cuda.empty_cache()
200
- gc.collect()
201
-
202
- success_msg = f"""βœ… Video generated successfully!
203
 
204
- πŸ“ **Prompt:** {prompt}
205
- 🎬 **Frames:** {num_frames}
206
- πŸ“ **Resolution:** {width}x{height}
207
- βš™οΈ **Inference Steps:** {num_inference_steps}
208
- 🎯 **Guidance Scale:** {guidance_scale}
209
- 🎲 **Seed:** {seed}
210
- ⏱️ **Generation Time:** {generation_time:.1f}s
211
- πŸ–₯️ **Device:** {'CUDA' if torch.cuda.is_available() else 'CPU'}
212
- ⚑ **ZeroGPU:** {'βœ…' if IS_ZERO_GPU else '❌'}"""
213
-
214
- return video_path, success_msg
215
-
216
- except torch.cuda.OutOfMemoryError:
217
- if torch.cuda.is_available():
218
- torch.cuda.empty_cache()
219
- gc.collect()
220
- return None, "❌ GPU memory exceeded. Try reducing frames/resolution or try again in a moment."
221
 
222
  except Exception as e:
223
  if torch.cuda.is_available():
@@ -226,165 +314,115 @@ def generate_video(
226
  return None, f"❌ Generation failed: {str(e)}"
227
 
228
  def get_system_info():
229
- """Get comprehensive system information"""
230
-
231
- # Check package versions
232
- package_info = {}
233
- try:
234
- import diffusers
235
- package_info['diffusers'] = diffusers.__version__
236
- except ImportError:
237
- package_info['diffusers'] = '❌ Not installed'
238
 
 
239
  try:
240
- import transformers
241
- package_info['transformers'] = transformers.__version__
242
- except ImportError:
243
- package_info['transformers'] = '❌ Not installed'
244
-
245
- # GPU info
246
- gpu_info = "❌ Not available"
247
- gpu_memory = 0
248
- if torch.cuda.is_available():
249
  try:
250
- gpu_info = torch.cuda.get_device_name(0)
251
- gpu_memory = torch.cuda.get_device_properties(0).total_memory / (1024**3)
252
- except:
253
- gpu_info = "βœ… Available (details unavailable)"
 
 
 
 
 
 
 
 
 
 
254
 
255
- return f"""## πŸ–₯️ System Information
 
256
 
257
  **Environment:**
258
- - πŸš€ ZeroGPU: {'βœ… Active' if IS_ZERO_GPU else '❌ Not detected'}
259
  - 🏠 HF Spaces: {'βœ…' if IS_SPACES else '❌'}
260
  - πŸ”₯ CUDA: {'βœ…' if torch.cuda.is_available() else '❌'}
261
- - πŸ–₯️ GPU: {gpu_info} ({gpu_memory:.1f} GB)
262
 
263
  **Packages:**
264
  - PyTorch: {torch.__version__}
265
- - Diffusers: {package_info.get('diffusers', 'Unknown')}
266
- - Transformers: {package_info.get('transformers', 'Unknown')}
267
- - Spaces: {'βœ…' if SPACES_AVAILABLE else '❌'}
268
 
269
  **Model Status:**
270
- - LTX-Video: {'βœ… Loaded' if MODEL is not None else '⏳ Will load on first use' if MODEL_ERROR is None else f'❌ Error: {MODEL_ERROR}'}
 
271
 
272
- **Tips:**
273
- {'🎯 Ready to generate!' if MODEL is not None else '⚑ First generation will take longer due to model loading'}"""
274
-
275
- def test_dependencies():
276
- """Test if all dependencies are working"""
277
- results = []
278
-
279
- # Test torch
280
- try:
281
- import torch
282
- results.append(f"βœ… PyTorch {torch.__version__}")
283
- if torch.cuda.is_available():
284
- results.append(f"βœ… CUDA {torch.version.cuda}")
285
- else:
286
- results.append("⚠️ CUDA not available")
287
- except Exception as e:
288
- results.append(f"❌ PyTorch: {e}")
289
-
290
- # Test diffusers
291
- try:
292
- import diffusers
293
- results.append(f"βœ… Diffusers {diffusers.__version__}")
294
- except Exception as e:
295
- results.append(f"❌ Diffusers: {e}")
296
-
297
- # Test transformers
298
- try:
299
- import transformers
300
- results.append(f"βœ… Transformers {transformers.__version__}")
301
- except Exception as e:
302
- results.append(f"❌ Transformers: {e}")
303
-
304
- return "\n".join(results)
305
 
306
  # Create Gradio interface
307
- with gr.Blocks(title="LTX-Video ZeroGPU", theme=gr.themes.Soft()) as demo:
308
 
309
  gr.Markdown("""
310
- # πŸš€ LTX-Video Generator (ZeroGPU)
311
 
312
- Generate high-quality videos from text using **Lightricks LTX-Video** model with **ZeroGPU**!
313
  """)
314
 
315
- # Status indicator
316
- with gr.Row():
317
- gr.Markdown(f"""
318
- **Status:** {'🟒 ZeroGPU Active' if IS_ZERO_GPU else '🟑 CPU Mode'} |
319
- **Environment:** {'HF Spaces' if IS_SPACES else 'Local'}
320
- """)
321
-
322
  with gr.Tab("πŸŽ₯ Generate Video"):
323
  with gr.Row():
324
  with gr.Column(scale=1):
325
  prompt_input = gr.Textbox(
326
  label="πŸ“ Video Prompt",
327
- placeholder="A majestic eagle soaring through mountain peaks...",
328
- lines=3,
329
- max_lines=5
330
  )
331
 
332
  negative_prompt_input = gr.Textbox(
333
- label="🚫 Negative Prompt (Optional)",
334
- placeholder="blurry, low quality, distorted...",
335
  lines=2
336
  )
337
 
338
- with gr.Accordion("βš™οΈ Settings", open=True):
339
- with gr.Row():
340
- num_frames = gr.Slider(8, 24, value=16, step=1, label="🎬 Frames")
341
- num_steps = gr.Slider(10, 25, value=20, step=1, label="πŸ”„ Steps")
342
-
343
- with gr.Row():
344
- width = gr.Dropdown([256, 512, 768], value=512, label="πŸ“ Width")
345
- height = gr.Dropdown([256, 512, 768], value=512, label="πŸ“ Height")
346
-
347
- with gr.Row():
348
- guidance_scale = gr.Slider(1.0, 12.0, value=7.5, step=0.5, label="🎯 Guidance")
349
- seed = gr.Number(value=-1, precision=0, label="🎲 Seed (-1=random)")
350
 
351
  generate_btn = gr.Button("πŸš€ Generate Video", variant="primary", size="lg")
352
 
353
  with gr.Column(scale=1):
354
  video_output = gr.Video(label="πŸŽ₯ Generated Video", height=400)
355
- result_text = gr.Textbox(label="πŸ“‹ Results", lines=6, show_copy_button=True)
356
 
357
- # Event handlers
358
  generate_btn.click(
359
  fn=generate_video,
360
  inputs=[prompt_input, negative_prompt_input, num_frames, height, width, num_steps, guidance_scale, seed],
361
  outputs=[video_output, result_text]
362
  )
363
 
364
- # Examples
365
  gr.Examples(
366
  examples=[
367
- ["A peaceful cat sleeping in a sunny garden", "", 16, 512, 512, 20, 7.5, 42],
368
- ["Ocean waves at sunset, cinematic view", "blurry", 20, 512, 512, 20, 8.0, 123],
369
- ["A hummingbird hovering near red flowers", "", 16, 512, 512, 15, 7.0, 456]
370
  ],
371
  inputs=[prompt_input, negative_prompt_input, num_frames, height, width, num_steps, guidance_scale, seed]
372
  )
373
 
374
  with gr.Tab("ℹ️ System Info"):
375
- info_btn = gr.Button("πŸ” Check System", variant="secondary")
376
  system_output = gr.Markdown()
377
 
378
  info_btn.click(fn=get_system_info, outputs=system_output)
379
  demo.load(fn=get_system_info, outputs=system_output)
380
-
381
- with gr.Tab("πŸ”§ Debug"):
382
- test_btn = gr.Button("πŸ§ͺ Test Dependencies")
383
- test_output = gr.Textbox(label="Test Results", lines=10)
384
-
385
- test_btn.click(fn=test_dependencies, outputs=test_output)
386
 
387
- # Launch
388
  if __name__ == "__main__":
389
  demo.queue(max_size=5)
390
  demo.launch(
 
6
  import tempfile
7
  from typing import Optional, Tuple
8
  import time
 
 
9
 
10
  # ZeroGPU import
11
  try:
12
  import spaces
13
  SPACES_AVAILABLE = True
 
14
  except ImportError:
 
15
  SPACES_AVAILABLE = False
16
+ class spaces:
17
+ @staticmethod
18
+ def GPU(duration=60):
19
+ def decorator(func):
20
+ return func
21
+ return decorator
22
 
 
23
  IS_ZERO_GPU = os.environ.get("SPACES_ZERO_GPU") == "true"
24
  IS_SPACES = os.environ.get("SPACE_ID") is not None
25
 
26
+ def load_ltx_model_manual():
27
+ """Manually load LTX-Video model using transformers"""
 
 
28
  try:
29
+ print("πŸ”„ Attempting to load LTX-Video with transformers...")
30
+
31
+ from transformers import AutoModel, AutoTokenizer, AutoProcessor
32
+
33
+ model_id = "Lightricks/LTX-Video"
34
+
35
+ # Try loading with AutoModel
36
  try:
37
+ processor = AutoProcessor.from_pretrained(model_id)
38
+ model = AutoModel.from_pretrained(
39
+ model_id,
40
+ torch_dtype=torch.float16,
41
+ low_cpu_mem_usage=True,
42
+ trust_remote_code=True # Important for new models
43
+ )
44
+
45
+ if torch.cuda.is_available():
46
+ model = model.to("cuda")
47
+
48
+ print("βœ… Model loaded with transformers")
49
+ return model, processor, None
50
+
51
  except Exception as e:
52
+ print(f"AutoModel failed: {e}")
53
+ return None, None, str(e)
54
+
55
+ except Exception as e:
56
+ return None, None, f"Manual loading failed: {e}"
57
 
58
+ def load_alternative_video_model():
59
+ """Load a working alternative video generation model"""
 
 
 
 
 
60
  try:
61
+ print("πŸ”„ Loading alternative video model...")
62
 
63
+ from diffusers import DiffusionPipeline
 
 
64
 
65
+ # Use Zeroscope or ModelScope as alternatives
66
+ alternatives = [
67
+ "cerspense/zeroscope_v2_576w",
68
+ "damo-vilab/text-to-video-ms-1.7b",
69
+ "ali-vilab/text-to-video-ms-1.7b"
70
+ ]
71
 
72
+ for model_id in alternatives:
73
+ try:
74
+ print(f"Trying {model_id}...")
75
+ pipe = DiffusionPipeline.from_pretrained(
76
+ model_id,
77
+ torch_dtype=torch.float16,
78
+ use_safetensors=True,
79
+ variant="fp16"
80
+ )
81
+
82
+ if torch.cuda.is_available():
83
+ pipe = pipe.to("cuda")
84
+
85
+ # Enable optimizations
86
+ pipe.enable_sequential_cpu_offload()
87
+ pipe.enable_vae_slicing()
88
+
89
+ print(f"βœ… Successfully loaded {model_id}")
90
+ return pipe, model_id, None
91
+
92
+ except Exception as e:
93
+ print(f"Failed to load {model_id}: {e}")
94
+ continue
95
 
96
+ return None, None, "All alternative models failed"
 
 
 
 
 
 
 
97
 
98
+ except Exception as e:
99
+ return None, None, f"Alternative loading failed: {e}"
100
+
101
+ def create_mock_video(prompt, num_frames=16, width=512, height=512):
102
+ """Create a mock video for demonstration"""
103
+ try:
104
+ import cv2
105
+ from PIL import Image, ImageDraw, ImageFont
106
 
107
+ # Create temporary video file
108
+ with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp_file:
109
+ video_path = tmp_file.name
 
 
 
 
110
 
111
+ # Video settings
112
+ fps = 8
113
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
114
+ out = cv2.VideoWriter(video_path, fourcc, fps, (width, height))
115
+
116
+ # Color themes
117
+ colors = [(255, 100, 100), (100, 255, 100), (100, 100, 255), (255, 255, 100)]
118
+
119
+ for i in range(num_frames):
120
+ # Create frame
121
+ img = Image.new('RGB', (width, height), color=colors[i % len(colors)])
122
+ draw = ImageDraw.Draw(img)
123
+
124
+ try:
125
+ font = ImageFont.truetype("arial.ttf", 24)
126
+ except:
127
+ font = ImageFont.load_default()
128
+
129
+ # Add text
130
+ draw.text((50, height//2 - 50), f"Frame {i+1}/{num_frames}", fill=(255, 255, 255), font=font)
131
+ draw.text((50, height//2), f"Prompt: {prompt[:30]}...", fill=(255, 255, 255), font=font)
132
+ draw.text((50, height//2 + 50), "DEMO MODE", fill=(0, 0, 0), font=font)
133
+
134
+ # Convert to OpenCV format
135
+ frame = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
136
+ out.write(frame)
137
 
138
+ out.release()
139
+ return video_path
 
 
140
 
141
  except Exception as e:
142
+ return None
 
 
143
 
144
+ # Global variables
145
  MODEL = None
146
+ PROCESSOR = None
147
+ MODEL_TYPE = None
148
  MODEL_ERROR = None
149
 
150
  def initialize_model():
151
+ """Initialize model with fallback options"""
152
+ global MODEL, PROCESSOR, MODEL_TYPE, MODEL_ERROR
153
+
154
+ if MODEL is not None:
155
+ return True
156
+
157
+ if MODEL_ERROR is not None:
158
+ return False
159
+
160
+ print("πŸš€ Initializing video model...")
161
+
162
+ # Strategy 1: Try manual LTX-Video loading
163
+ print("Trying LTX-Video...")
164
+ MODEL, PROCESSOR, error = load_ltx_model_manual()
165
+ if MODEL is not None:
166
+ MODEL_TYPE = "LTX-Video"
167
+ return True
168
+
169
+ print(f"LTX-Video failed: {error}")
170
+
171
+ # Strategy 2: Try alternative models
172
+ print("Trying alternative models...")
173
+ MODEL, MODEL_TYPE, error = load_alternative_video_model()
174
+ if MODEL is not None:
175
+ PROCESSOR = None # Diffusion pipeline doesn't need separate processor
176
+ return True
177
+
178
+ print(f"Alternative models failed: {error}")
179
+
180
+ # Strategy 3: Use mock generation
181
+ MODEL_TYPE = "mock"
182
+ MODEL_ERROR = "All models failed - using demo mode"
183
+ return False
184
 
185
  @spaces.GPU(duration=120) if SPACES_AVAILABLE else lambda x: x
186
  def generate_video(
 
193
  guidance_scale: float = 7.5,
194
  seed: int = -1
195
  ) -> Tuple[Optional[str], str]:
196
+ """Generate video with fallback strategies"""
 
 
197
 
198
+ # Initialize model
199
+ model_loaded = initialize_model()
 
 
200
 
201
  # Input validation
202
  if not prompt.strip():
203
  return None, "❌ Please enter a valid prompt."
204
 
205
+ # Limit parameters
206
+ num_frames = min(max(num_frames, 8), 25)
207
+ num_inference_steps = min(max(num_inference_steps, 10), 30)
 
 
 
208
  height = min(max(height, 256), 768)
209
  width = min(max(width, 256), 768)
210
 
211
+ # Set seed
212
+ if seed == -1:
213
+ seed = np.random.randint(0, 2**32 - 1)
214
+
215
  try:
216
  # Clear memory
217
  if torch.cuda.is_available():
218
  torch.cuda.empty_cache()
219
  gc.collect()
220
 
221
+ start_time = time.time()
 
 
222
 
223
+ if MODEL_TYPE == "mock" or not model_loaded:
224
+ # Mock generation
225
+ print("🎭 Using mock generation")
226
+ video_path = create_mock_video(prompt, num_frames, width, height)
227
+
228
+ if video_path:
229
+ end_time = time.time()
230
+ return video_path, f"""
231
+ 🎭 **Demo Video Generated**
232
+
233
+ πŸ“ Prompt: {prompt}
234
+ ⚠️ Note: This is a demo mode because video models couldn't be loaded.
235
+
236
+ 🎬 Frames: {num_frames}
237
+ πŸ“ Resolution: {width}x{height}
238
+ ⏱️ Time: {end_time - start_time:.1f}s
239
+ πŸ”§ Status: {MODEL_ERROR or 'Demo mode'}
240
+
241
+ πŸ’‘ **To enable real video generation:**
242
+ - Check if LTX-Video is available in your region
243
+ - Try upgrading diffusers: `pip install diffusers --upgrade`
244
+ - Or wait for official LTX-Video support in diffusers
245
+ """
246
+ else:
247
+ return None, "❌ Even demo generation failed"
248
 
249
+ elif MODEL_TYPE == "LTX-Video":
250
+ # Manual LTX-Video generation
251
+ print("πŸš€ Using LTX-Video")
252
+
253
+ # This would need the actual implementation based on the model's API
254
+ # For now, return a message about manual implementation needed
255
+ return None, f"""
256
+ ⚠️ **Manual Implementation Required**
257
+
258
+ LTX-Video model was loaded but requires custom generation code.
259
+ The model API is not yet standardized in diffusers.
260
+
261
+ πŸ“‹ **Next Steps:**
262
+ 1. Check Lightricks/LTX-Video model documentation
263
+ 2. Implement custom inference pipeline
264
+ 3. Or wait for official diffusers support
265
+
266
+ πŸ”§ **Current Status:** Model loaded, awaiting implementation
267
+ """
268
 
269
+ else:
270
+ # Alternative model generation
271
+ print(f"πŸ”„ Using {MODEL_TYPE}")
272
+
273
+ generator = torch.Generator(device="cuda" if torch.cuda.is_available() else "cpu").manual_seed(seed)
274
+
275
  result = MODEL(
276
  prompt=prompt,
277
  negative_prompt=negative_prompt if negative_prompt.strip() else None,
 
280
  width=width,
281
  num_inference_steps=num_inference_steps,
282
  guidance_scale=guidance_scale,
283
+ generator=generator
284
  )
285
+
286
+ # Export video
287
+ video_frames = result.frames[0]
288
+
289
+ with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp_file:
 
 
 
 
290
  from diffusers.utils import export_to_video
291
  export_to_video(video_frames, tmp_file.name, fps=8)
292
  video_path = tmp_file.name
293
+
294
+ end_time = time.time()
295
+
296
+ return video_path, f"""
297
+ βœ… **Video Generated Successfully!**
 
 
 
 
 
 
298
 
299
+ πŸ“ Prompt: {prompt}
300
+ πŸ€– Model: {MODEL_TYPE}
301
+ 🎬 Frames: {num_frames}
302
+ πŸ“ Resolution: {width}x{height}
303
+ βš™οΈ Steps: {num_inference_steps}
304
+ 🎯 Guidance: {guidance_scale}
305
+ 🎲 Seed: {seed}
306
+ ⏱️ Time: {end_time - start_time:.1f}s
307
+ πŸ–₯️ Device: {'CUDA' if torch.cuda.is_available() else 'CPU'}
308
+ """
 
 
 
 
 
 
 
309
 
310
  except Exception as e:
311
  if torch.cuda.is_available():
 
314
  return None, f"❌ Generation failed: {str(e)}"
315
 
316
  def get_system_info():
317
+ """Get system information"""
 
 
 
 
 
 
 
 
318
 
319
+ # Check what's available
320
  try:
321
+ from diffusers import __version__ as diffusers_version
322
+ available_pipelines = []
 
 
 
 
 
 
 
323
  try:
324
+ from diffusers import LTXVideoPipeline
325
+ available_pipelines.append("βœ… LTXVideoPipeline")
326
+ except ImportError:
327
+ available_pipelines.append("❌ LTXVideoPipeline")
328
+
329
+ try:
330
+ from diffusers import DiffusionPipeline
331
+ available_pipelines.append("βœ… DiffusionPipeline")
332
+ except ImportError:
333
+ available_pipelines.append("❌ DiffusionPipeline")
334
+
335
+ except ImportError:
336
+ diffusers_version = "❌ Not installed"
337
+ available_pipelines = ["❌ Diffusers not available"]
338
 
339
+ return f"""
340
+ ## πŸ–₯️ System Information
341
 
342
  **Environment:**
343
+ - πŸš€ ZeroGPU: {'βœ… Active' if IS_ZERO_GPU else '❌ Not detected'}
344
  - 🏠 HF Spaces: {'βœ…' if IS_SPACES else '❌'}
345
  - πŸ”₯ CUDA: {'βœ…' if torch.cuda.is_available() else '❌'}
 
346
 
347
  **Packages:**
348
  - PyTorch: {torch.__version__}
349
+ - Diffusers: {diffusers_version}
350
+ - Available Pipelines: {', '.join(available_pipelines)}
 
351
 
352
  **Model Status:**
353
+ - Current Model: {MODEL_TYPE or 'Not loaded'}
354
+ - Status: {'βœ… Ready' if MODEL is not None else '⚠️ ' + (MODEL_ERROR or 'Not initialized')}
355
 
356
+ **Recommendation:**
357
+ - LTX-Video is very new and may not be in stable diffusers yet
358
+ - Using alternative models or demo mode
359
+ - Check back later for official support
360
+ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
 
362
  # Create Gradio interface
363
+ with gr.Blocks(title="Video Generator with Fallbacks", theme=gr.themes.Soft()) as demo:
364
 
365
  gr.Markdown("""
366
+ # 🎬 Advanced Video Generator
367
 
368
+ Attempts to use LTX-Video, falls back to alternative models, or provides demo mode.
369
  """)
370
 
 
 
 
 
 
 
 
371
  with gr.Tab("πŸŽ₯ Generate Video"):
372
  with gr.Row():
373
  with gr.Column(scale=1):
374
  prompt_input = gr.Textbox(
375
  label="πŸ“ Video Prompt",
376
+ placeholder="A serene mountain lake at sunrise...",
377
+ lines=3
 
378
  )
379
 
380
  negative_prompt_input = gr.Textbox(
381
+ label="🚫 Negative Prompt",
382
+ placeholder="blurry, low quality...",
383
  lines=2
384
  )
385
 
386
+ with gr.Row():
387
+ num_frames = gr.Slider(8, 25, value=16, step=1, label="🎬 Frames")
388
+ num_steps = gr.Slider(10, 30, value=20, step=1, label="πŸ”„ Steps")
389
+
390
+ with gr.Row():
391
+ width = gr.Dropdown([256, 512, 768], value=512, label="πŸ“ Width")
392
+ height = gr.Dropdown([256, 512, 768], value=512, label="πŸ“ Height")
393
+
394
+ with gr.Row():
395
+ guidance_scale = gr.Slider(1.0, 15.0, value=7.5, step=0.5, label="🎯 Guidance")
396
+ seed = gr.Number(value=-1, precision=0, label="🎲 Seed")
 
397
 
398
  generate_btn = gr.Button("πŸš€ Generate Video", variant="primary", size="lg")
399
 
400
  with gr.Column(scale=1):
401
  video_output = gr.Video(label="πŸŽ₯ Generated Video", height=400)
402
+ result_text = gr.Textbox(label="πŸ“‹ Results", lines=8, show_copy_button=True)
403
 
 
404
  generate_btn.click(
405
  fn=generate_video,
406
  inputs=[prompt_input, negative_prompt_input, num_frames, height, width, num_steps, guidance_scale, seed],
407
  outputs=[video_output, result_text]
408
  )
409
 
 
410
  gr.Examples(
411
  examples=[
412
+ ["A peaceful cat in a sunny garden", "", 16, 512, 512, 20, 7.5, 42],
413
+ ["Ocean waves at golden hour", "blurry", 20, 512, 512, 20, 8.0, 123],
414
+ ["A butterfly on a flower", "", 16, 512, 512, 15, 7.0, 456]
415
  ],
416
  inputs=[prompt_input, negative_prompt_input, num_frames, height, width, num_steps, guidance_scale, seed]
417
  )
418
 
419
  with gr.Tab("ℹ️ System Info"):
420
+ info_btn = gr.Button("πŸ” Check System")
421
  system_output = gr.Markdown()
422
 
423
  info_btn.click(fn=get_system_info, outputs=system_output)
424
  demo.load(fn=get_system_info, outputs=system_output)
 
 
 
 
 
 
425
 
 
426
  if __name__ == "__main__":
427
  demo.queue(max_size=5)
428
  demo.launch(