Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -10,6 +10,7 @@ import warnings
|
|
| 10 |
import time
|
| 11 |
import gc
|
| 12 |
import uuid
|
|
|
|
| 13 |
|
| 14 |
import cv2
|
| 15 |
import numpy as np
|
|
@@ -189,24 +190,32 @@ def interpolate_bits(frames_np, multiplier=2, scale=1.0):
|
|
| 189 |
# Process Frames
|
| 190 |
# Load first frame into GPU
|
| 191 |
I1 = to_tensor(frames_np[0])
|
| 192 |
-
|
| 193 |
-
for i in range(T - 1):
|
| 194 |
-
I0 = I1
|
| 195 |
-
# Add original frame to output
|
| 196 |
-
output_frames.append(from_tensor(I0))
|
| 197 |
-
|
| 198 |
-
# Load next frame
|
| 199 |
-
I1 = to_tensor(frames_np[i+1])
|
| 200 |
|
| 201 |
-
|
| 202 |
-
mid_tensors = make_inference(I0, I1, n_interp)
|
| 203 |
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
|
| 208 |
-
|
| 209 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
|
| 211 |
# Cleanup
|
| 212 |
del I0, I1, mid_tensors
|
|
@@ -349,8 +358,9 @@ def get_inference_duration(
|
|
| 349 |
if guidance_scale > 1:
|
| 350 |
gen_time = gen_time * 1.8
|
| 351 |
|
| 352 |
-
|
| 353 |
-
|
|
|
|
| 354 |
inter_time = (total_out_frames * 0.02)
|
| 355 |
print(inter_time)
|
| 356 |
gen_time += inter_time
|
|
@@ -410,23 +420,27 @@ def run_inference(
|
|
| 410 |
raw_frames_np = result.frames[0] # Returns (T, H, W, C) float32
|
| 411 |
pipe.scheduler = original_scheduler
|
| 412 |
|
| 413 |
-
|
|
|
|
| 414 |
start = time.time()
|
| 415 |
-
print(f"Processing frames (RIFE Multiplier: {
|
| 416 |
rife_model.device()
|
| 417 |
rife_model.flownet = rife_model.flownet.half()
|
| 418 |
-
final_frames = interpolate_bits(raw_frames_np, multiplier=int(
|
| 419 |
print("Interpolation time passed:", time.time() - start)
|
| 420 |
else:
|
| 421 |
final_frames = list(raw_frames_np)
|
| 422 |
|
| 423 |
-
final_fps = FIXED_FPS * int(
|
| 424 |
|
| 425 |
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmpfile:
|
| 426 |
video_path = tmpfile.name
|
| 427 |
|
| 428 |
start = time.time()
|
| 429 |
-
|
|
|
|
|
|
|
|
|
|
| 430 |
print(f"Export time passed, {final_fps} FPS:", time.time() - start)
|
| 431 |
|
| 432 |
return video_path, task_name
|
|
@@ -446,7 +460,7 @@ def generate_video(
|
|
| 446 |
quality=5,
|
| 447 |
scheduler="UniPCMultistep",
|
| 448 |
flow_shift=6.0,
|
| 449 |
-
frame_multiplier=
|
| 450 |
video_component=True,
|
| 451 |
progress=gr.Progress(track_tqdm=True),
|
| 452 |
):
|
|
@@ -543,7 +557,7 @@ CSS = """
|
|
| 543 |
|
| 544 |
|
| 545 |
with gr.Blocks(delete_cache=(3600, 10800)) as demo:
|
| 546 |
-
gr.Markdown("## WAMU - Wan 2.2 I2V (14B)
|
| 547 |
gr.Markdown("#### ℹ️ **A Note on Performance:** This version prioritizes a straightforward setup over maximum speed, so performance may vary.")
|
| 548 |
gr.Markdown("Run Wan 2.2 in just 4-8 steps, fp8 quantization & AoT compilation - compatible with 🧨 diffusers and ZeroGPU")
|
| 549 |
|
|
@@ -552,19 +566,19 @@ with gr.Blocks(delete_cache=(3600, 10800)) as demo:
|
|
| 552 |
input_image_component = gr.Image(type="pil", label="Input Image", sources=["upload", "clipboard"])
|
| 553 |
prompt_input = gr.Textbox(label="Prompt", value=default_prompt_i2v)
|
| 554 |
duration_seconds_input = gr.Slider(minimum=MIN_DURATION, maximum=MAX_DURATION, step=0.1, value=3.5, label="Duration (seconds)", info=f"Clamped to model's {MIN_FRAMES_MODEL}-{MAX_FRAMES_MODEL} frames at {FIXED_FPS}fps.")
|
| 555 |
-
steps_slider = gr.Slider(minimum=1, maximum=30, step=1, value=6, label="Inference Steps")
|
| 556 |
frame_multi = gr.Dropdown(
|
| 557 |
-
choices=[
|
| 558 |
-
value=
|
| 559 |
-
label="
|
| 560 |
-
info="
|
| 561 |
)
|
| 562 |
with gr.Accordion("Advanced Settings", open=False):
|
| 563 |
-
last_image_component = gr.Image(type="pil", label="Last Image (Optional)")
|
| 564 |
negative_prompt_input = gr.Textbox(label="Negative Prompt", value=default_negative_prompt, info="Used if any Guidance Scale > 1.", lines=3)
|
| 565 |
quality_slider = gr.Slider(minimum=1, maximum=10, step=1, value=6, label="Video Quality", info="If set to 10, the generated video may be too large and won't play in the Gradio preview.")
|
| 566 |
seed_input = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=42, interactive=True)
|
| 567 |
randomize_seed_checkbox = gr.Checkbox(label="Randomize seed", value=True, interactive=True)
|
|
|
|
| 568 |
guidance_scale_input = gr.Slider(minimum=0.0, maximum=10.0, step=0.5, value=1, label="Guidance Scale - high noise stage", info="Values above 1 increase GPU usage and may take longer to process.")
|
| 569 |
guidance_scale_2_input = gr.Slider(minimum=0.0, maximum=10.0, step=0.5, value=1, label="Guidance Scale 2 - low noise stage")
|
| 570 |
scheduler_dropdown = gr.Dropdown(
|
|
@@ -576,7 +590,7 @@ with gr.Blocks(delete_cache=(3600, 10800)) as demo:
|
|
| 576 |
flow_shift_slider = gr.Slider(minimum=0.5, maximum=15.0, step=0.1, value=3.0, label="Flow Shift")
|
| 577 |
play_result_video = gr.Checkbox(label="Display result", value=True, interactive=True)
|
| 578 |
org_name = "TestOrganizationPleaseIgnore"
|
| 579 |
-
gr.Markdown(f"[ZeroGPU
|
| 580 |
|
| 581 |
generate_button = gr.Button("Generate Video", variant="primary")
|
| 582 |
|
|
@@ -626,4 +640,5 @@ if __name__ == "__main__":
|
|
| 626 |
demo.queue().launch(
|
| 627 |
mcp_server=True,
|
| 628 |
css=CSS,
|
|
|
|
| 629 |
)
|
|
|
|
| 10 |
import time
|
| 11 |
import gc
|
| 12 |
import uuid
|
| 13 |
+
from tqdm import tqdm
|
| 14 |
|
| 15 |
import cv2
|
| 16 |
import numpy as np
|
|
|
|
| 190 |
# Process Frames
|
| 191 |
# Load first frame into GPU
|
| 192 |
I1 = to_tensor(frames_np[0])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
|
| 194 |
+
total_steps = T - 1
|
|
|
|
| 195 |
|
| 196 |
+
with tqdm(total=total_steps, desc="Interpolating", unit="frame") as pbar:
|
| 197 |
+
|
| 198 |
+
for i in range(total_steps):
|
| 199 |
+
I0 = I1
|
| 200 |
+
# Add original frame to output
|
| 201 |
+
output_frames.append(from_tensor(I0))
|
| 202 |
+
|
| 203 |
+
# Load next frame
|
| 204 |
+
I1 = to_tensor(frames_np[i+1])
|
| 205 |
+
|
| 206 |
+
# Generate intermediate frames
|
| 207 |
+
mid_tensors = make_inference(I0, I1, n_interp)
|
| 208 |
|
| 209 |
+
# Append intermediate frames
|
| 210 |
+
for mid in mid_tensors:
|
| 211 |
+
output_frames.append(from_tensor(mid))
|
| 212 |
+
|
| 213 |
+
if (i + 1) % 50 == 0:
|
| 214 |
+
pbar.update(50)
|
| 215 |
+
pbar.update(total_steps % 50)
|
| 216 |
+
|
| 217 |
+
# Add the very last frame
|
| 218 |
+
output_frames.append(from_tensor(I1))
|
| 219 |
|
| 220 |
# Cleanup
|
| 221 |
del I0, I1, mid_tensors
|
|
|
|
| 358 |
if guidance_scale > 1:
|
| 359 |
gen_time = gen_time * 1.8
|
| 360 |
|
| 361 |
+
frame_factor = frame_multiplier // FIXED_FPS
|
| 362 |
+
if frame_factor > 1:
|
| 363 |
+
total_out_frames = (num_frames * frame_factor) - num_frames
|
| 364 |
inter_time = (total_out_frames * 0.02)
|
| 365 |
print(inter_time)
|
| 366 |
gen_time += inter_time
|
|
|
|
| 420 |
raw_frames_np = result.frames[0] # Returns (T, H, W, C) float32
|
| 421 |
pipe.scheduler = original_scheduler
|
| 422 |
|
| 423 |
+
frame_factor = frame_multiplier // FIXED_FPS
|
| 424 |
+
if frame_factor > 1:
|
| 425 |
start = time.time()
|
| 426 |
+
print(f"Processing frames (RIFE Multiplier: {frame_factor}x)...")
|
| 427 |
rife_model.device()
|
| 428 |
rife_model.flownet = rife_model.flownet.half()
|
| 429 |
+
final_frames = interpolate_bits(raw_frames_np, multiplier=int(frame_factor))
|
| 430 |
print("Interpolation time passed:", time.time() - start)
|
| 431 |
else:
|
| 432 |
final_frames = list(raw_frames_np)
|
| 433 |
|
| 434 |
+
final_fps = FIXED_FPS * int(frame_factor)
|
| 435 |
|
| 436 |
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmpfile:
|
| 437 |
video_path = tmpfile.name
|
| 438 |
|
| 439 |
start = time.time()
|
| 440 |
+
with tqdm(total=3, desc="Rendering Media", unit="clip") as pbar:
|
| 441 |
+
pbar.update(2)
|
| 442 |
+
export_to_video(final_frames, video_path, fps=final_fps, quality=quality)
|
| 443 |
+
pbar.update(1)
|
| 444 |
print(f"Export time passed, {final_fps} FPS:", time.time() - start)
|
| 445 |
|
| 446 |
return video_path, task_name
|
|
|
|
| 460 |
quality=5,
|
| 461 |
scheduler="UniPCMultistep",
|
| 462 |
flow_shift=6.0,
|
| 463 |
+
frame_multiplier=16,
|
| 464 |
video_component=True,
|
| 465 |
progress=gr.Progress(track_tqdm=True),
|
| 466 |
):
|
|
|
|
| 557 |
|
| 558 |
|
| 559 |
with gr.Blocks(delete_cache=(3600, 10800)) as demo:
|
| 560 |
+
gr.Markdown("## WAMU - Wan 2.2 I2V (14B) 🐢")
|
| 561 |
gr.Markdown("#### ℹ️ **A Note on Performance:** This version prioritizes a straightforward setup over maximum speed, so performance may vary.")
|
| 562 |
gr.Markdown("Run Wan 2.2 in just 4-8 steps, fp8 quantization & AoT compilation - compatible with 🧨 diffusers and ZeroGPU")
|
| 563 |
|
|
|
|
| 566 |
input_image_component = gr.Image(type="pil", label="Input Image", sources=["upload", "clipboard"])
|
| 567 |
prompt_input = gr.Textbox(label="Prompt", value=default_prompt_i2v)
|
| 568 |
duration_seconds_input = gr.Slider(minimum=MIN_DURATION, maximum=MAX_DURATION, step=0.1, value=3.5, label="Duration (seconds)", info=f"Clamped to model's {MIN_FRAMES_MODEL}-{MAX_FRAMES_MODEL} frames at {FIXED_FPS}fps.")
|
|
|
|
| 569 |
frame_multi = gr.Dropdown(
|
| 570 |
+
choices=[FIXED_FPS, FIXED_FPS*2, FIXED_FPS*4, FIXED_FPS*8],
|
| 571 |
+
value=FIXED_FPS,
|
| 572 |
+
label="Video Fluidity (Frames per Second)",
|
| 573 |
+
info="Extra frames will be generated using flow estimation, which estimates motion between frames to make the video smoother."
|
| 574 |
)
|
| 575 |
with gr.Accordion("Advanced Settings", open=False):
|
| 576 |
+
last_image_component = gr.Image(type="pil", label="Last Image (Optional)", sources=["upload", "clipboard"])
|
| 577 |
negative_prompt_input = gr.Textbox(label="Negative Prompt", value=default_negative_prompt, info="Used if any Guidance Scale > 1.", lines=3)
|
| 578 |
quality_slider = gr.Slider(minimum=1, maximum=10, step=1, value=6, label="Video Quality", info="If set to 10, the generated video may be too large and won't play in the Gradio preview.")
|
| 579 |
seed_input = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=42, interactive=True)
|
| 580 |
randomize_seed_checkbox = gr.Checkbox(label="Randomize seed", value=True, interactive=True)
|
| 581 |
+
steps_slider = gr.Slider(minimum=1, maximum=30, step=1, value=6, label="Inference Steps")
|
| 582 |
guidance_scale_input = gr.Slider(minimum=0.0, maximum=10.0, step=0.5, value=1, label="Guidance Scale - high noise stage", info="Values above 1 increase GPU usage and may take longer to process.")
|
| 583 |
guidance_scale_2_input = gr.Slider(minimum=0.0, maximum=10.0, step=0.5, value=1, label="Guidance Scale 2 - low noise stage")
|
| 584 |
scheduler_dropdown = gr.Dropdown(
|
|
|
|
| 590 |
flow_shift_slider = gr.Slider(minimum=0.5, maximum=15.0, step=0.1, value=3.0, label="Flow Shift")
|
| 591 |
play_result_video = gr.Checkbox(label="Display result", value=True, interactive=True)
|
| 592 |
org_name = "TestOrganizationPleaseIgnore"
|
| 593 |
+
gr.Markdown(f"[ZeroGPU help, tips and troubleshooting](https://huggingface.co/datasets/{org_name}/help/blob/main/gpu_help.md)")
|
| 594 |
|
| 595 |
generate_button = gr.Button("Generate Video", variant="primary")
|
| 596 |
|
|
|
|
| 640 |
demo.queue().launch(
|
| 641 |
mcp_server=True,
|
| 642 |
css=CSS,
|
| 643 |
+
show_error=True,
|
| 644 |
)
|