|
|
import os |
|
|
import gradio as gr |
|
|
import torch |
|
|
import spaces |
|
|
from PIL import Image |
|
|
import tempfile |
|
|
import subprocess |
|
|
import sys |
|
|
import time |
|
|
import shutil |
|
|
from huggingface_hub import snapshot_download |
|
|
|
|
|
|
|
|
MODEL_NAME = "Skywork/Matrix-Game-2.0" |
|
|
DEVICE = "cuda" if torch.cuda.is_available() else "cpu" |
|
|
|
|
|
print(f"๐ Matrix-Game-2.0 Clean Setup") |
|
|
print(f"๐ฑ Device: {DEVICE}") |
|
|
print(f"๐ฅ CUDA: {torch.cuda.is_available()}") |
|
|
if torch.cuda.is_available(): |
|
|
print(f"๐ฎ GPU: {torch.cuda.get_device_name()}") |
|
|
|
|
|
@spaces.GPU(duration=900) |
|
|
def generate_matrix_video(input_image, num_frames, seed, use_streaming): |
|
|
""" |
|
|
Matrix-Game-2.0 generation following official workflow |
|
|
""" |
|
|
if input_image is None: |
|
|
return None, "โ Please upload an input image" |
|
|
|
|
|
log = ["๐ **MATRIX-GAME-2.0 CLEAN GENERATION**\n"] |
|
|
original_cwd = os.getcwd() |
|
|
|
|
|
try: |
|
|
|
|
|
log.append("๐ฅ **STEP 1: git clone Matrix-Game**") |
|
|
base_dir = os.getcwd() |
|
|
matrix_root = os.path.join(base_dir, "Matrix-Game") |
|
|
|
|
|
|
|
|
if os.path.exists(matrix_root): |
|
|
shutil.rmtree(matrix_root) |
|
|
log.append("๐งน Cleaned previous installation") |
|
|
|
|
|
|
|
|
clone_result = subprocess.run([ |
|
|
'git', 'clone', 'https://github.com/SkyworkAI/Matrix-Game.git' |
|
|
], capture_output=True, text=True, timeout=300, cwd=base_dir) |
|
|
|
|
|
if clone_result.returncode != 0: |
|
|
log.append(f"โ Clone failed: {clone_result.stderr}") |
|
|
return None, "\n".join(log) |
|
|
|
|
|
log.append("โ
Repository cloned successfully") |
|
|
|
|
|
|
|
|
log.append("\n๐ **STEP 2: cd Matrix-Game/Matrix-Game-2**") |
|
|
matrix_2_dir = os.path.join(matrix_root, "Matrix-Game-2") |
|
|
|
|
|
if not os.path.exists(matrix_2_dir): |
|
|
log.append(f"โ Matrix-Game-2 not found: {matrix_2_dir}") |
|
|
return None, "\n".join(log) |
|
|
|
|
|
|
|
|
os.chdir(matrix_2_dir) |
|
|
log.append(f"โ
Changed to: {os.getcwd()}") |
|
|
|
|
|
|
|
|
key_files = ['inference.py', 'requirements.txt', 'setup.py', 'configs'] |
|
|
for file in key_files: |
|
|
if os.path.exists(file): |
|
|
log.append(f"โ
{file} found") |
|
|
else: |
|
|
log.append(f"โ {file} missing") |
|
|
return None, "\n".join(log) |
|
|
|
|
|
|
|
|
log.append("\n๐ฆ **STEP 3: pip install -r requirements.txt**") |
|
|
|
|
|
req_result = subprocess.run([ |
|
|
sys.executable, "-m", "pip", "install", "-r", "requirements.txt", |
|
|
"--no-cache-dir", "--force-reinstall" |
|
|
], capture_output=True, text=True, timeout=600) |
|
|
|
|
|
if req_result.returncode == 0: |
|
|
log.append("โ
Requirements installed successfully") |
|
|
else: |
|
|
log.append(f"โ ๏ธ Requirements warning (continuing): {req_result.stderr[:200]}") |
|
|
|
|
|
|
|
|
log.append("\n๐ง **STEP 3.5: Install missing dependencies**") |
|
|
|
|
|
critical_deps = [ |
|
|
"omegaconf", "einops", "transformers", "accelerate", |
|
|
"diffusers", "opencv-python", "imageio", "imageio-ffmpeg" |
|
|
] |
|
|
|
|
|
for dep in critical_deps: |
|
|
try: |
|
|
dep_result = subprocess.run([ |
|
|
sys.executable, "-m", "pip", "install", dep, "--no-cache-dir" |
|
|
], capture_output=True, text=True, timeout=120) |
|
|
|
|
|
if dep_result.returncode == 0: |
|
|
log.append(f"โ
{dep} installed") |
|
|
else: |
|
|
log.append(f"โ ๏ธ {dep} warning: {dep_result.stderr[:100]}") |
|
|
except Exception as e: |
|
|
log.append(f"โ ๏ธ {dep} error: {str(e)[:100]}") |
|
|
|
|
|
|
|
|
log.append("\n๐ง **STEP 4: python setup.py develop**") |
|
|
|
|
|
setup_result = subprocess.run([ |
|
|
sys.executable, "setup.py", "develop" |
|
|
], capture_output=True, text=True, timeout=300) |
|
|
|
|
|
if setup_result.returncode == 0: |
|
|
log.append("โ
Setup.py completed successfully") |
|
|
else: |
|
|
log.append(f"โ ๏ธ Setup.py warning (continuing): {setup_result.stderr[:200]}") |
|
|
|
|
|
|
|
|
log.append("\n๐ฅ **STEP 5: Download model weights**") |
|
|
|
|
|
try: |
|
|
model_path = snapshot_download( |
|
|
repo_id=MODEL_NAME, |
|
|
cache_dir=os.path.join(base_dir, "model_cache"), |
|
|
force_download=False |
|
|
) |
|
|
log.append(f"โ
Model downloaded: {os.path.basename(model_path)}") |
|
|
except Exception as e: |
|
|
log.append(f"โ Model download failed: {e}") |
|
|
return None, "\n".join(log) |
|
|
|
|
|
|
|
|
log.append("\n๐พ **STEP 6: Prepare input image**") |
|
|
|
|
|
temp_dir = tempfile.mkdtemp(prefix="matrix_game_") |
|
|
input_path = os.path.join(temp_dir, "input.jpg") |
|
|
|
|
|
|
|
|
outputs_dir = "outputs" |
|
|
if os.path.exists(outputs_dir): |
|
|
shutil.rmtree(outputs_dir) |
|
|
os.makedirs(outputs_dir, exist_ok=True) |
|
|
|
|
|
|
|
|
original_size = input_image.size |
|
|
if max(input_image.size) > 1024: |
|
|
ratio = 1024 / max(input_image.size) |
|
|
new_size = (int(input_image.size[0] * ratio), int(input_image.size[1] * ratio)) |
|
|
input_image = input_image.resize(new_size, Image.Resampling.LANCZOS) |
|
|
log.append(f"๐ท Image resized: {original_size} โ {input_image.size}") |
|
|
else: |
|
|
log.append(f"๐ท Image size: {input_image.size}") |
|
|
|
|
|
input_image.save(input_path, "JPEG", quality=90) |
|
|
|
|
|
|
|
|
log.append("\n๐ง **STEP 7: Configure inference**") |
|
|
|
|
|
|
|
|
config_dir = "configs/inference_yaml" |
|
|
config_path = None |
|
|
|
|
|
if os.path.exists(config_dir): |
|
|
yaml_files = [f for f in os.listdir(config_dir) if f.endswith(('.yaml', '.yml'))] |
|
|
if yaml_files: |
|
|
config_path = os.path.join(config_dir, yaml_files[0]) |
|
|
log.append(f"โ
Config found: {config_path}") |
|
|
|
|
|
if not config_path: |
|
|
log.append(f"โ No config found in {config_dir}") |
|
|
return None, "\n".join(log) |
|
|
|
|
|
|
|
|
checkpoint_path = None |
|
|
for root, dirs, files in os.walk(model_path): |
|
|
for file in files: |
|
|
if file.endswith(('.bin', '.pt', '.pth', '.safetensors')): |
|
|
checkpoint_path = os.path.join(root, file) |
|
|
break |
|
|
if checkpoint_path: |
|
|
break |
|
|
|
|
|
if not checkpoint_path: |
|
|
log.append(f"โ No checkpoint found in {model_path}") |
|
|
return None, "\n".join(log) |
|
|
|
|
|
log.append(f"โ
Checkpoint: {os.path.basename(checkpoint_path)}") |
|
|
|
|
|
|
|
|
log.append("\n๐ **STEP 8: Matrix-Game inference**") |
|
|
|
|
|
script_name = "inference_streaming.py" if use_streaming else "inference.py" |
|
|
|
|
|
|
|
|
cmd = [sys.executable, script_name] |
|
|
cmd.extend([ |
|
|
"--config_path", config_path, |
|
|
"--checkpoint_path", checkpoint_path, |
|
|
"--img_path", input_path, |
|
|
"--output_folder", outputs_dir, |
|
|
"--seed", str(seed), |
|
|
"--pretrained_model_path", model_path |
|
|
]) |
|
|
|
|
|
|
|
|
if not use_streaming: |
|
|
cmd.extend(["--num_output_frames", str(num_frames)]) |
|
|
|
|
|
log.append(f"๐ง Running: python {script_name}") |
|
|
log.append(f"๐ Working directory: {os.getcwd()}") |
|
|
log.append(f"โ๏ธ Frames: {num_frames} | Seed: {seed} | Streaming: {use_streaming}") |
|
|
|
|
|
|
|
|
env = os.environ.copy() |
|
|
env['PYTHONPATH'] = matrix_2_dir |
|
|
|
|
|
try: |
|
|
|
|
|
log.append("โ
Starting Matrix-Game generation...") |
|
|
|
|
|
process = subprocess.Popen( |
|
|
cmd, |
|
|
stdout=subprocess.PIPE, |
|
|
stderr=subprocess.PIPE, |
|
|
text=True, |
|
|
cwd=matrix_2_dir, |
|
|
env=env |
|
|
) |
|
|
|
|
|
|
|
|
try: |
|
|
stdout, stderr = process.communicate(timeout=900) |
|
|
except subprocess.TimeoutExpired: |
|
|
process.terminate() |
|
|
process.wait() |
|
|
log.append("โฐ Timeout: Generation took too long (>15 min)") |
|
|
return None, "\n".join(log) |
|
|
|
|
|
log.append(f"๐ง Process completed with code: {process.returncode}") |
|
|
|
|
|
if process.returncode != 0: |
|
|
log.append(f"โ Inference failed:") |
|
|
log.append(f"Error: {stderr[:500]}") |
|
|
log.append(f"Output: {stdout[:200]}") |
|
|
return None, "\n".join(log) |
|
|
|
|
|
log.append("โ
Inference completed successfully!") |
|
|
|
|
|
except Exception as e: |
|
|
log.append(f"โ Process error: {str(e)}") |
|
|
return None, "\n".join(log) |
|
|
|
|
|
|
|
|
log.append("\n๐ **STEP 9: Find generated videos**") |
|
|
|
|
|
video_files = [] |
|
|
outputs_abs = os.path.join(matrix_2_dir, outputs_dir) |
|
|
|
|
|
for root, dirs, files in os.walk(outputs_abs): |
|
|
for file in files: |
|
|
if file.lower().endswith(('.mp4', '.avi', '.mov', '.mkv', '.webm')): |
|
|
video_path = os.path.join(root, file) |
|
|
video_files.append(video_path) |
|
|
log.append(f"๐ฅ Video found: {file}") |
|
|
|
|
|
if video_files: |
|
|
final_video = video_files[0] |
|
|
file_size = os.path.getsize(final_video) / 1e6 |
|
|
|
|
|
log.append(f"\n๐ **SUCCESS!**") |
|
|
log.append(f"๐ Video size: {file_size:.1f} MB") |
|
|
log.append(f"๐ท Input: {original_size}") |
|
|
log.append(f"๐ฎ GPU: {torch.cuda.get_device_name() if torch.cuda.is_available() else 'CPU'}") |
|
|
log.append(f"โจ Matrix-Game-2.0 generation complete!") |
|
|
|
|
|
return final_video, "\n".join(log) |
|
|
else: |
|
|
log.append("โ No videos generated") |
|
|
|
|
|
|
|
|
if os.path.exists(outputs_abs): |
|
|
all_files = [] |
|
|
for root, dirs, files in os.walk(outputs_abs): |
|
|
for file in files: |
|
|
all_files.append(file) |
|
|
log.append(f"๐ Files in outputs: {all_files}") |
|
|
|
|
|
return None, "\n".join(log) |
|
|
|
|
|
except Exception as e: |
|
|
log.append(f"\nโ **CRITICAL ERROR:** {str(e)}") |
|
|
import traceback |
|
|
log.append(f"๐ Full traceback: {traceback.format_exc()}") |
|
|
return None, "\n".join(log) |
|
|
|
|
|
finally: |
|
|
|
|
|
os.chdir(original_cwd) |
|
|
|
|
|
|
|
|
with gr.Blocks( |
|
|
title="Matrix-Game-2.0 Clean", |
|
|
css=".container { max-width: 1200px; margin: auto; }" |
|
|
) as demo: |
|
|
|
|
|
gr.HTML(""" |
|
|
<div style="text-align: center; padding: 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 15px; margin-bottom: 30px;"> |
|
|
<h1 style="margin: 0; font-size: 2.8em;">๐ฎ Matrix-Game-2.0</h1> |
|
|
<p style="margin: 15px 0; font-size: 1.3em;">Interactive World Model - Clean Implementation</p> |
|
|
<p style="margin: 0; opacity: 0.9;">โก Real-time generation at 25 FPS | ๐ฏ Precise control | ๐ Complex environments</p> |
|
|
</div> |
|
|
""") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(): |
|
|
gr.Markdown("### ๐ท Input Configuration") |
|
|
|
|
|
input_image = gr.Image( |
|
|
label="Input Image", |
|
|
type="pil", |
|
|
height=300 |
|
|
) |
|
|
|
|
|
gr.Markdown("### โ๏ธ Generation Settings") |
|
|
|
|
|
with gr.Row(): |
|
|
num_frames = gr.Slider( |
|
|
minimum=50, |
|
|
maximum=300, |
|
|
value=150, |
|
|
step=25, |
|
|
label="Number of Frames" |
|
|
) |
|
|
|
|
|
seed = gr.Number( |
|
|
value=42, |
|
|
label="Seed", |
|
|
precision=0 |
|
|
) |
|
|
|
|
|
use_streaming = gr.Checkbox( |
|
|
label="Streaming Mode", |
|
|
value=False |
|
|
) |
|
|
|
|
|
generate_btn = gr.Button( |
|
|
"๐ Generate Matrix-Game Video", |
|
|
variant="primary", |
|
|
size="lg" |
|
|
) |
|
|
|
|
|
gr.Markdown(""" |
|
|
### ๐ก Usage Tips: |
|
|
- **Upload**: Clear images with good depth and structure |
|
|
- **Frames**: 150 frames โ 6 seconds at 25 FPS |
|
|
- **Time**: Generation takes 5-15 minutes depending on complexity |
|
|
- **Streaming**: Continuous generation mode (experimental) |
|
|
- **Best results**: Landscapes, cityscapes, or structured scenes |
|
|
""") |
|
|
|
|
|
with gr.Column(): |
|
|
gr.Markdown("### ๐ฅ Generated Video") |
|
|
|
|
|
output_video = gr.Video( |
|
|
label="Matrix-Game Video Output", |
|
|
height=400 |
|
|
) |
|
|
|
|
|
gr.Markdown("### ๐ Generation Log") |
|
|
|
|
|
status_log = gr.Textbox( |
|
|
label="Detailed Status and Progress", |
|
|
lines=20, |
|
|
max_lines=25, |
|
|
show_copy_button=True |
|
|
) |
|
|
|
|
|
|
|
|
generate_btn.click( |
|
|
fn=generate_matrix_video, |
|
|
inputs=[input_image, num_frames, seed, use_streaming], |
|
|
outputs=[output_video, status_log], |
|
|
show_progress=True |
|
|
) |
|
|
|
|
|
gr.HTML(""" |
|
|
<div style="text-align: center; padding: 25px; margin-top: 30px; border-top: 2px solid #eee;"> |
|
|
<p style="margin-bottom: 15px;"> |
|
|
๐ <a href="https://arxiv.org/pdf/2508.13009" target="_blank" style="text-decoration: none;">Research Paper</a> | |
|
|
๐ป <a href="https://github.com/SkyworkAI/Matrix-Game" target="_blank" style="text-decoration: none;">GitHub Repository</a> | |
|
|
๐ค <a href="https://huggingface.co/Skywork/Matrix-Game-2.0" target="_blank" style="text-decoration: none;">Model Hub</a> |
|
|
</p> |
|
|
<p style="margin: 0;"><em>โก Powered by Skywork AI | Clean Implementation avoiding setup issues</em></p> |
|
|
</div> |
|
|
""") |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch(share=True) |