matthewkram commited on
Commit
0d627a0
·
verified ·
1 Parent(s): 6c4f4bc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -49
app.py CHANGED
@@ -10,6 +10,7 @@ import numpy as np
10
  import cv2
11
  import subprocess
12
  import tempfile
 
13
 
14
  class WanAnimateApp:
15
  def __init__(self):
@@ -20,22 +21,31 @@ class WanAnimateApp:
20
  variant="fp16",
21
  device_map="cpu"
22
  )
 
23
  self.pipe.enable_model_cpu_offload()
24
  self.pipe.enable_vae_slicing()
25
 
26
- def predict(self, ref_img, video, model_id, model):
27
- if ref_img is None:
28
- return None, "Upload image and video."
 
 
 
 
 
 
 
29
  try:
30
- # Local processing
31
- ref_image = Image.open(ref_img).convert("RGB").resize((576, 320))
32
- motion_hint = ""
33
- if video:
34
- cap = cv2.VideoCapture(video)
35
- frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
36
- cap.release()
37
- motion_hint = f", dynamic motion from {frame_count} frames"
38
- prompt = f"High-quality animation of the character in the image{motion_hint}, smooth movements, detailed."
 
39
  num_frames = 25 if model == "wan-pro" else 14
40
  num_steps = 25 if model == "wan-pro" else 15
41
  generator = torch.Generator(device="cpu").manual_seed(42)
@@ -46,7 +56,7 @@ class WanAnimateApp:
46
  generator=generator,
47
  decode_chunk_size=2
48
  ).frames[0]
49
- # Save with ffmpeg (no moviepy)
50
  temp_dir = tempfile.mkdtemp()
51
  for i, frame in enumerate(output):
52
  frame.save(f"{temp_dir}/frame_{i:04d}.png")
@@ -63,43 +73,43 @@ class WanAnimateApp:
63
  def start_app():
64
  app = WanAnimateApp()
65
 
66
- with gr.Blocks(title="Wan2.2-Animate (No API)") as demo:
67
  gr.HTML("""
68
- <div style="padding: 2rem; text-align: center;">
69
- <h1>Wan2.2-Animate: Local Version (No API)</h1>
70
- <p>Animate character from image + video. CPU: 5–15 min.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  </div>
72
  """)
 
73
  gr.HTML("""
74
- <details><summary>Usage</summary>
75
- Move Mode: Animate image with video movements. Mix Mode: Replace video character with image.
76
- Use small files (512x512 image, 2–5s video).
77
- </details>
78
- """)
79
- with gr.Row():
80
- with gr.Column():
81
- ref_img = gr.Image(label="Reference Image", type="filepath", sources=["upload"])
82
- video = gr.Video(label="Template Video", sources=["upload"])
83
- with gr.Row():
84
- model_id = gr.Dropdown(label="Mode", choices=["wan2.2-animate-move", "wan2.2-animate-mix"], value="wan2.2-animate-move")
85
- model = gr.Dropdown(label="Quality", choices=["wan-pro", "wan-std"], value="wan-std")
86
- run_button = gr.Button("Generate")
87
- with gr.Column():
88
- output_video = gr.Video(label="Output Video")
89
- output_status = gr.Textbox(label="Status")
90
- run_button.click(
91
- fn=app.predict,
92
- inputs=[ref_img, video, model_id, model],
93
- outputs=[output_video, output_status],
94
- )
95
- gr.Examples(
96
- examples=[["examples/1.jpg", "examples/1.mp4", "wan2.2-animate-move", "wan-std"]],
97
- inputs=[ref_img, video, model_id, model],
98
- outputs=[output_video, output_status],
99
- fn=app.predict,
100
- cache_examples=False,
101
- )
102
- demo.queue(concurrency_limit=1).launch(server_name="0.0.0.0", server_port=7860)
103
-
104
- if __name__ == "__main__":
105
- start_app()
 
10
  import cv2
11
  import subprocess
12
  import tempfile
13
+ import shutil
14
 
15
  class WanAnimateApp:
16
  def __init__(self):
 
21
  variant="fp16",
22
  device_map="cpu"
23
  )
24
+ self.pipe.reset_device_map() # Фикс: Сброс карты устройств перед offload
25
  self.pipe.enable_model_cpu_offload()
26
  self.pipe.enable_vae_slicing()
27
 
28
+ def predict(
29
+ self,
30
+ ref_img,
31
+ video,
32
+ model_id,
33
+ model,
34
+ ):
35
+ if ref_img is None or video is None:
36
+ return None, "Upload both image and video."
37
+
38
  try:
39
+ # Local processing (no OSS/API)
40
+ ref_image = Image.open(ref_img).convert("RGB").resize((576, 320)) # SVD res
41
+ cap = cv2.VideoCapture(video)
42
+ frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
43
+ cap.release()
44
+ motion_hint = f", dynamic motion from {frame_count} frames"
45
+ if model_id == "wan2.2-animate-move":
46
+ prompt = f"Animate the character in the reference image{motion_hint}, high quality, smooth movements."
47
+ else:
48
+ prompt = f"Replace the character in the video with the reference image{motion_hint}, seamless, detailed."
49
  num_frames = 25 if model == "wan-pro" else 14
50
  num_steps = 25 if model == "wan-pro" else 15
51
  generator = torch.Generator(device="cpu").manual_seed(42)
 
56
  generator=generator,
57
  decode_chunk_size=2
58
  ).frames[0]
59
+ # Save with ffmpeg (stable, no moviepy)
60
  temp_dir = tempfile.mkdtemp()
61
  for i, frame in enumerate(output):
62
  frame.save(f"{temp_dir}/frame_{i:04d}.png")
 
73
  def start_app():
74
  app = WanAnimateApp()
75
 
76
+ with gr.Blocks(title="Wan2.2-Animate (Local CPU)") as demo:
77
  gr.HTML("""
78
+ <div style="padding: 2rem; text-align: center; max-width: 1200px; margin: 0 auto; font-family: Arial, sans-serif;">
79
+ <h1 style="font-size: 2.5rem; font-weight: bold; margin-bottom: 0.5rem; color: #333;">
80
+ Wan2.2-Animate: Unified Character Animation and Replacement with Holistic Replication
81
+ </h1>
82
+ <h3 style="font-size: 1.5rem; font-weight: bold; margin-bottom: 0.5rem; color: #333;">
83
+ Local version without API (SVD Proxy)
84
+ </h3>
85
+ <div style="font-size: 1.25rem; margin-bottom: 1.5rem; color: #555;">
86
+ Tongyi Lab, Alibaba
87
+ </div>
88
+ <div style="display: flex; flex-wrap: wrap; justify-content: center; gap: 1rem; margin-bottom: 1rem;">
89
+ <a href="https://arxiv.org/abs/2509.14055" target="_blank" style="display: inline-flex; align-items: center; padding: 0.5rem 1rem; background-color: #f0f0f0; color: #333; text-decoration: none; border-radius: 9999px; font-weight: 500;">
90
+ <span style="margin-right: 0.5rem;">📄</span>Paper
91
+ </a>
92
+ <a href="https://github.com/Wan-Video/Wan2.2" target="_blank" style="display: inline-flex; align-items: center; padding: 0.5rem 1rem; background-color: #f0f0f0; color: #333; text-decoration: none; border-radius: 9999px; font-weight: 500;">
93
+ <span style="margin-right: 0.5rem;">💻</span>GitHub
94
+ </a>
95
+ <a href="https://huggingface.co/Wan-AI/Wan2.2-Animate-14B" target="_blank" style="display: inline-flex; align-items: center; padding: 0.5rem 1rem; background-color: #f0f0f0; color: #333; text-decoration: none; border-radius: 9999px; font-weight: 500;">
96
+ <span style="margin-right: 0.5rem;">🤗</span>HF Model
97
+ </a>
98
+ <a href="https://www.modelscope.cn/models/Wan-AI/Wan2.2-Animate-14B" target="_blank" style="display: inline-flex; align-items: center; padding: 0.5rem 1rem; background-color: #f0f0f0; color: #333; text-decoration: none; border-radius: 9999px; font-weight: 500;">
99
+ <span style="margin-right: 0.5rem;">🤖</span>MS Model
100
+ </a>
101
+ </div>
102
+ <div style="display: flex; flex-wrap: wrap; justify-content: center; gap: 1rem;">
103
+ <a href="https://huggingface.co/spaces/Wan-AI/Wan2.2-Animate" target="_blank" style="display: inline-flex; align-items: center; padding: 0.5rem 1rem; background-color: #f0f0f0; color: #333; text-decoration: none; border-radius: 9999px; font-weight: 500;">
104
+ <span style="margin-right: 0.5rem;">🤗</span>HF Space
105
+ </a>
106
+ <a href="https://www.modelscope.cn/studios/Wan-AI/Wan2.2-Animate" target="_blank" style="display: inline-flex; align-items: center; padding: 0.5rem 1rem; background-color: #f0f0f0; color: #333; text-decoration: none; border-radius: 9999px; font-weight: 500;">
107
+ <span style="margin-right: 0.5rem;">🤖</span>MS Studio
108
+ </a>
109
+ </div>
110
  </div>
111
  """)
112
+
113
  gr.HTML("""
114
+ <details>
115
+ <summary>‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪��‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪‪