akia1996 commited on
Commit
ec8483d
ยท
verified ยท
1 Parent(s): 2ec8e4e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +382 -0
app.py ADDED
@@ -0,0 +1,382 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import torch
4
+ import spaces
5
+ from PIL import Image
6
+ import tempfile
7
+ import subprocess
8
+ import sys
9
+ import time
10
+ import shutil
11
+ from huggingface_hub import snapshot_download
12
+
13
+ # Configuration
14
+ MODEL_NAME = "Skywork/Matrix-Game-2.0"
15
+ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
16
+
17
+ print(f"๐Ÿš€ Matrix-Game-2.0 Clean Setup")
18
+ print(f"๐Ÿ“ฑ Device: {DEVICE}")
19
+ print(f"๐Ÿ”ฅ CUDA: {torch.cuda.is_available()}")
20
+ if torch.cuda.is_available():
21
+ print(f"๐ŸŽฎ GPU: {torch.cuda.get_device_name()}")
22
+
23
+ @spaces.GPU(duration=900) # 15 minutes
24
+ def generate_matrix_video(input_image, num_frames, seed, use_streaming):
25
+ """
26
+ Matrix-Game-2.0 generation following official workflow
27
+ """
28
+ if input_image is None:
29
+ return None, "โŒ Please upload an input image"
30
+
31
+ log = ["๐Ÿš€ **MATRIX-GAME-2.0 CLEAN GENERATION**\n"]
32
+ original_cwd = os.getcwd()
33
+
34
+ try:
35
+ # Step 1: Clone repository (official workflow)
36
+ log.append("๐Ÿ“ฅ **STEP 1: git clone Matrix-Game**")
37
+ base_dir = os.getcwd()
38
+ matrix_root = os.path.join(base_dir, "Matrix-Game")
39
+
40
+ # Clean previous installation
41
+ if os.path.exists(matrix_root):
42
+ shutil.rmtree(matrix_root)
43
+ log.append("๐Ÿงน Cleaned previous installation")
44
+
45
+ # Clone fresh repository
46
+ clone_result = subprocess.run([
47
+ 'git', 'clone', 'https://github.com/SkyworkAI/Matrix-Game.git'
48
+ ], capture_output=True, text=True, timeout=300, cwd=base_dir)
49
+
50
+ if clone_result.returncode != 0:
51
+ log.append(f"โŒ Clone failed: {clone_result.stderr}")
52
+ return None, "\n".join(log)
53
+
54
+ log.append("โœ… Repository cloned successfully")
55
+
56
+ # Step 2: cd Matrix-Game/Matrix-Game-2 (official workflow)
57
+ log.append("\n๐Ÿ“‚ **STEP 2: cd Matrix-Game/Matrix-Game-2**")
58
+ matrix_2_dir = os.path.join(matrix_root, "Matrix-Game-2")
59
+
60
+ if not os.path.exists(matrix_2_dir):
61
+ log.append(f"โŒ Matrix-Game-2 not found: {matrix_2_dir}")
62
+ return None, "\n".join(log)
63
+
64
+ # Change to Matrix-Game-2 directory (as per official instructions)
65
+ os.chdir(matrix_2_dir)
66
+ log.append(f"โœ… Changed to: {os.getcwd()}")
67
+
68
+ # Verify key files exist
69
+ key_files = ['inference.py', 'requirements.txt', 'setup.py', 'configs']
70
+ for file in key_files:
71
+ if os.path.exists(file):
72
+ log.append(f"โœ… {file} found")
73
+ else:
74
+ log.append(f"โŒ {file} missing")
75
+ return None, "\n".join(log)
76
+
77
+ # Step 3: pip install -r requirements.txt (official workflow)
78
+ log.append("\n๐Ÿ“ฆ **STEP 3: pip install -r requirements.txt**")
79
+
80
+ req_result = subprocess.run([
81
+ sys.executable, "-m", "pip", "install", "-r", "requirements.txt",
82
+ "--no-cache-dir", "--force-reinstall"
83
+ ], capture_output=True, text=True, timeout=600)
84
+
85
+ if req_result.returncode == 0:
86
+ log.append("โœ… Requirements installed successfully")
87
+ else:
88
+ log.append(f"โš ๏ธ Requirements warning (continuing): {req_result.stderr[:200]}")
89
+
90
+ # Step 4: python setup.py develop (official workflow)
91
+ log.append("\n๐Ÿ”ง **STEP 4: python setup.py develop**")
92
+
93
+ setup_result = subprocess.run([
94
+ sys.executable, "setup.py", "develop"
95
+ ], capture_output=True, text=True, timeout=300)
96
+
97
+ if setup_result.returncode == 0:
98
+ log.append("โœ… Setup.py completed successfully")
99
+ else:
100
+ log.append(f"โš ๏ธ Setup.py warning (continuing): {setup_result.stderr[:200]}")
101
+
102
+ # Step 5: Download model weights
103
+ log.append("\n๐Ÿ“ฅ **STEP 5: Download model weights**")
104
+
105
+ try:
106
+ model_path = snapshot_download(
107
+ repo_id=MODEL_NAME,
108
+ cache_dir=os.path.join(base_dir, "model_cache"),
109
+ force_download=False
110
+ )
111
+ log.append(f"โœ… Model downloaded: {os.path.basename(model_path)}")
112
+ except Exception as e:
113
+ log.append(f"โŒ Model download failed: {e}")
114
+ return None, "\n".join(log)
115
+
116
+ # Step 6: Prepare input image
117
+ log.append("\n๐Ÿ’พ **STEP 6: Prepare input image**")
118
+
119
+ temp_dir = tempfile.mkdtemp(prefix="matrix_game_")
120
+ input_path = os.path.join(temp_dir, "input.jpg")
121
+
122
+ # Create outputs directory (relative path as per official instructions)
123
+ outputs_dir = "outputs"
124
+ if os.path.exists(outputs_dir):
125
+ shutil.rmtree(outputs_dir)
126
+ os.makedirs(outputs_dir, exist_ok=True)
127
+
128
+ # Resize image if too large (for memory efficiency)
129
+ original_size = input_image.size
130
+ if max(input_image.size) > 1024:
131
+ ratio = 1024 / max(input_image.size)
132
+ new_size = (int(input_image.size[0] * ratio), int(input_image.size[1] * ratio))
133
+ input_image = input_image.resize(new_size, Image.Resampling.LANCZOS)
134
+ log.append(f"๐Ÿ“ท Image resized: {original_size} โ†’ {input_image.size}")
135
+ else:
136
+ log.append(f"๐Ÿ“ท Image size: {input_image.size}")
137
+
138
+ input_image.save(input_path, "JPEG", quality=90)
139
+
140
+ # Step 7: Configure inference paths
141
+ log.append("\n๐Ÿ”ง **STEP 7: Configure inference**")
142
+
143
+ # Find config file (relative path)
144
+ config_dir = "configs/inference_yaml"
145
+ config_path = None
146
+
147
+ if os.path.exists(config_dir):
148
+ yaml_files = [f for f in os.listdir(config_dir) if f.endswith(('.yaml', '.yml'))]
149
+ if yaml_files:
150
+ config_path = os.path.join(config_dir, yaml_files[0])
151
+ log.append(f"โœ… Config found: {config_path}")
152
+
153
+ if not config_path:
154
+ log.append(f"โŒ No config found in {config_dir}")
155
+ return None, "\n".join(log)
156
+
157
+ # Find checkpoint
158
+ checkpoint_path = None
159
+ for root, dirs, files in os.walk(model_path):
160
+ for file in files:
161
+ if file.endswith(('.bin', '.pt', '.pth', '.safetensors')):
162
+ checkpoint_path = os.path.join(root, file)
163
+ break
164
+ if checkpoint_path:
165
+ break
166
+
167
+ if not checkpoint_path:
168
+ log.append(f"โŒ No checkpoint found in {model_path}")
169
+ return None, "\n".join(log)
170
+
171
+ log.append(f"โœ… Checkpoint: {os.path.basename(checkpoint_path)}")
172
+
173
+ # Step 8: Run inference (official workflow)
174
+ log.append("\n๐Ÿš€ **STEP 8: Matrix-Game inference**")
175
+
176
+ script_name = "inference_streaming.py" if use_streaming else "inference.py"
177
+
178
+ # Build command exactly as per official instructions
179
+ cmd = [sys.executable, script_name]
180
+ cmd.extend([
181
+ "--config_path", config_path,
182
+ "--checkpoint_path", checkpoint_path,
183
+ "--img_path", input_path,
184
+ "--output_folder", outputs_dir,
185
+ "--seed", str(seed),
186
+ "--pretrained_model_path", model_path
187
+ ])
188
+
189
+ # Add num_output_frames for regular inference
190
+ if not use_streaming:
191
+ cmd.extend(["--num_output_frames", str(num_frames)])
192
+
193
+ log.append(f"๐Ÿ”ง Running: python {script_name}")
194
+ log.append(f"๐Ÿ“‚ Working directory: {os.getcwd()}")
195
+ log.append(f"โš™๏ธ Frames: {num_frames} | Seed: {seed} | Streaming: {use_streaming}")
196
+
197
+ # Set environment for subprocess
198
+ env = os.environ.copy()
199
+ env['PYTHONPATH'] = matrix_2_dir
200
+
201
+ try:
202
+ # Run the inference with proper timeout
203
+ log.append("โœ… Starting Matrix-Game generation...")
204
+
205
+ process = subprocess.Popen(
206
+ cmd,
207
+ stdout=subprocess.PIPE,
208
+ stderr=subprocess.PIPE,
209
+ text=True,
210
+ cwd=matrix_2_dir,
211
+ env=env
212
+ )
213
+
214
+ # Wait for completion with timeout
215
+ try:
216
+ stdout, stderr = process.communicate(timeout=900) # 15 minutes
217
+ except subprocess.TimeoutExpired:
218
+ process.terminate()
219
+ process.wait()
220
+ log.append("โฐ Timeout: Generation took too long (>15 min)")
221
+ return None, "\n".join(log)
222
+
223
+ log.append(f"๐Ÿ”ง Process completed with code: {process.returncode}")
224
+
225
+ if process.returncode != 0:
226
+ log.append(f"โŒ Inference failed:")
227
+ log.append(f"Error: {stderr[:500]}")
228
+ log.append(f"Output: {stdout[:200]}")
229
+ return None, "\n".join(log)
230
+
231
+ log.append("โœ… Inference completed successfully!")
232
+
233
+ except Exception as e:
234
+ log.append(f"โŒ Process error: {str(e)}")
235
+ return None, "\n".join(log)
236
+
237
+ # Step 9: Find generated videos
238
+ log.append("\n๐Ÿ“ **STEP 9: Find generated videos**")
239
+
240
+ video_files = []
241
+ outputs_abs = os.path.join(matrix_2_dir, outputs_dir)
242
+
243
+ for root, dirs, files in os.walk(outputs_abs):
244
+ for file in files:
245
+ if file.lower().endswith(('.mp4', '.avi', '.mov', '.mkv', '.webm')):
246
+ video_path = os.path.join(root, file)
247
+ video_files.append(video_path)
248
+ log.append(f"๐ŸŽฅ Video found: {file}")
249
+
250
+ if video_files:
251
+ final_video = video_files[0]
252
+ file_size = os.path.getsize(final_video) / 1e6
253
+
254
+ log.append(f"\n๐ŸŽ‰ **SUCCESS!**")
255
+ log.append(f"๐Ÿ“Š Video size: {file_size:.1f} MB")
256
+ log.append(f"๐Ÿ“ท Input: {original_size}")
257
+ log.append(f"๐ŸŽฎ GPU: {torch.cuda.get_device_name() if torch.cuda.is_available() else 'CPU'}")
258
+ log.append(f"โœจ Matrix-Game-2.0 generation complete!")
259
+
260
+ return final_video, "\n".join(log)
261
+ else:
262
+ log.append("โŒ No videos generated")
263
+
264
+ # Debug: list all files in outputs
265
+ if os.path.exists(outputs_abs):
266
+ all_files = []
267
+ for root, dirs, files in os.walk(outputs_abs):
268
+ for file in files:
269
+ all_files.append(file)
270
+ log.append(f"๐Ÿ“„ Files in outputs: {all_files}")
271
+
272
+ return None, "\n".join(log)
273
+
274
+ except Exception as e:
275
+ log.append(f"\nโŒ **CRITICAL ERROR:** {str(e)}")
276
+ import traceback
277
+ log.append(f"๐Ÿ“œ Full traceback: {traceback.format_exc()}")
278
+ return None, "\n".join(log)
279
+
280
+ finally:
281
+ # Always return to original directory
282
+ os.chdir(original_cwd)
283
+
284
+ # Clean Gradio interface (avoiding Gradio 4.44.0 bugs)
285
+ with gr.Blocks(
286
+ title="Matrix-Game-2.0 Clean",
287
+ css=".container { max-width: 1200px; margin: auto; }"
288
+ ) as demo:
289
+
290
+ gr.HTML("""
291
+ <div style="text-align: center; padding: 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 15px; margin-bottom: 30px;">
292
+ <h1 style="margin: 0; font-size: 2.8em;">๐ŸŽฎ Matrix-Game-2.0</h1>
293
+ <p style="margin: 15px 0; font-size: 1.3em;">Interactive World Model - Clean Implementation</p>
294
+ <p style="margin: 0; opacity: 0.9;">โšก Real-time generation at 25 FPS | ๐ŸŽฏ Precise control | ๐ŸŒ Complex environments</p>
295
+ </div>
296
+ """)
297
+
298
+ with gr.Row():
299
+ with gr.Column():
300
+ gr.Markdown("### ๐Ÿ“ท Input Configuration")
301
+
302
+ input_image = gr.Image(
303
+ label="Input Image",
304
+ type="pil",
305
+ height=300
306
+ )
307
+
308
+ gr.Markdown("### โš™๏ธ Generation Settings")
309
+
310
+ with gr.Row():
311
+ num_frames = gr.Slider(
312
+ minimum=50,
313
+ maximum=300,
314
+ value=150,
315
+ step=25,
316
+ label="Number of Frames"
317
+ )
318
+
319
+ seed = gr.Number(
320
+ value=42,
321
+ label="Seed",
322
+ precision=0
323
+ )
324
+
325
+ use_streaming = gr.Checkbox(
326
+ label="Streaming Mode",
327
+ value=False
328
+ )
329
+
330
+ generate_btn = gr.Button(
331
+ "๐Ÿš€ Generate Matrix-Game Video",
332
+ variant="primary",
333
+ size="lg"
334
+ )
335
+
336
+ gr.Markdown("""
337
+ ### ๐Ÿ’ก Usage Tips:
338
+ - **Upload**: Clear images with good depth and structure
339
+ - **Frames**: 150 frames โ‰ˆ 6 seconds at 25 FPS
340
+ - **Time**: Generation takes 5-15 minutes depending on complexity
341
+ - **Streaming**: Continuous generation mode (experimental)
342
+ - **Best results**: Landscapes, cityscapes, or structured scenes
343
+ """)
344
+
345
+ with gr.Column():
346
+ gr.Markdown("### ๐ŸŽฅ Generated Video")
347
+
348
+ output_video = gr.Video(
349
+ label="Matrix-Game Video Output",
350
+ height=400
351
+ )
352
+
353
+ gr.Markdown("### ๐Ÿ“Š Generation Log")
354
+
355
+ status_log = gr.Textbox(
356
+ label="Detailed Status and Progress",
357
+ lines=20,
358
+ max_lines=25,
359
+ show_copy_button=True
360
+ )
361
+
362
+ # Connect the generation function
363
+ generate_btn.click(
364
+ fn=generate_matrix_video,
365
+ inputs=[input_image, num_frames, seed, use_streaming],
366
+ outputs=[output_video, status_log],
367
+ show_progress=True
368
+ )
369
+
370
+ gr.HTML("""
371
+ <div style="text-align: center; padding: 25px; margin-top: 30px; border-top: 2px solid #eee;">
372
+ <p style="margin-bottom: 15px;">
373
+ ๐Ÿ“– <a href="https://arxiv.org/pdf/2508.13009" target="_blank" style="text-decoration: none;">Research Paper</a> |
374
+ ๐Ÿ’ป <a href="https://github.com/SkyworkAI/Matrix-Game" target="_blank" style="text-decoration: none;">GitHub Repository</a> |
375
+ ๐Ÿค— <a href="https://huggingface.co/Skywork/Matrix-Game-2.0" target="_blank" style="text-decoration: none;">Model Hub</a>
376
+ </p>
377
+ <p style="margin: 0;"><em>โšก Powered by Skywork AI | Clean Implementation avoiding setup issues</em></p>
378
+ </div>
379
+ """)
380
+
381
+ if __name__ == "__main__":
382
+ demo.launch(share=True)