Spaces:
Running on Zero
Running on Zero
update app
Browse files
app.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
| 1 |
-
|
| 2 |
import spaces
|
| 3 |
import torch
|
| 4 |
from diffusers.pipelines.wan.pipeline_wan_i2v import WanImageToVideoPipeline
|
|
@@ -23,8 +22,6 @@ from torchao.quantization import Int8WeightOnlyConfig
|
|
| 23 |
|
| 24 |
import aoti
|
| 25 |
|
| 26 |
-
|
| 27 |
-
# โโโ Model & dimension constants โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 28 |
MODEL_ID = "Wan-AI/Wan2.2-I2V-A14B-Diffusers"
|
| 29 |
|
| 30 |
MAX_DIM = 832
|
|
@@ -43,7 +40,6 @@ MAX_DURATION = round(MAX_FRAMES_MODEL / FIXED_FPS, 1)
|
|
| 43 |
|
| 44 |
device = "cuda"
|
| 45 |
|
| 46 |
-
# โโโ Load Wan 2.2 I2V pipeline โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 47 |
pipe = WanImageToVideoPipeline.from_pretrained(
|
| 48 |
MODEL_ID,
|
| 49 |
transformer=WanTransformer3DModel.from_pretrained(
|
|
@@ -91,7 +87,6 @@ spaces.aoti_load(
|
|
| 91 |
repo_id='cbensimon/WanTransformer3DModel-sm120-cu130-raa',
|
| 92 |
)
|
| 93 |
|
| 94 |
-
# โโโ Load FLUX.2 Klein 4B upscaler pipeline โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 95 |
print("Loading FLUX.2 Klein 4B model...")
|
| 96 |
klein_pipe = Flux2KleinPipeline.from_pretrained(
|
| 97 |
"black-forest-labs/FLUX.2-klein-4B",
|
|
@@ -99,13 +94,9 @@ klein_pipe = Flux2KleinPipeline.from_pretrained(
|
|
| 99 |
).to(device)
|
| 100 |
print("FLUX.2 Klein 4B loaded successfully.")
|
| 101 |
|
| 102 |
-
|
| 103 |
-
# โโโ Prompts โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 104 |
default_prompt_i2v = "make this image come alive, cinematic motion, smooth animation"
|
| 105 |
default_negative_prompt = "่ฒ่ฐ่ณไธฝ, ่ฟๆ, ้ๆ, ็ป่ๆจก็ณไธๆธ
, ๅญๅน, ้ฃๆ ผ, ไฝๅ, ็ปไฝ, ็ป้ข, ้ๆญข, ๆดไฝๅ็ฐ, ๆๅทฎ่ดจ้, ไฝ่ดจ้, JPEGๅ็ผฉๆฎ็, ไธ้็, ๆฎ็ผบ็, ๅคไฝ็ๆๆ, ็ปๅพไธๅฅฝ็ๆ้จ, ็ปๅพไธๅฅฝ็่ธ้จ, ็ธๅฝข็, ๆฏๅฎน็, ๅฝขๆ็ธๅฝข็่ขไฝ, ๆๆ่ๅ, ้ๆญขไธๅจ็็ป้ข, ๆไนฑ็่ๆฏ, ไธๆก่
ฟ, ่ๆฏไบบๅพๅค, ๅ็่ตฐ"
|
| 106 |
|
| 107 |
-
|
| 108 |
-
# โโโ Image & frame helpers โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 109 |
def resize_image(image: Image.Image) -> Image.Image:
|
| 110 |
"""
|
| 111 |
Resizes an image to fit within the model's constraints, preserving aspect ratio as much as possible.
|
|
@@ -219,7 +210,6 @@ def upscale_single_frame(frame: Image.Image) -> Image.Image:
|
|
| 219 |
return result
|
| 220 |
|
| 221 |
|
| 222 |
-
# โโโ Video generation โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 223 |
def get_duration(
|
| 224 |
input_image,
|
| 225 |
prompt,
|
|
@@ -285,7 +275,6 @@ def generate_video(
|
|
| 285 |
return video_path, current_seed
|
| 286 |
|
| 287 |
|
| 288 |
-
# โโโ Full pipeline: generate โ extract frames โ upscale โ return card data โโโ
|
| 289 |
def generate_and_upscale(
|
| 290 |
input_image,
|
| 291 |
prompt,
|
|
@@ -317,7 +306,6 @@ def generate_and_upscale(
|
|
| 317 |
if not frames:
|
| 318 |
return video_path, current_seed, []
|
| 319 |
|
| 320 |
-
# Step 3: Upscale each frame
|
| 321 |
upscaled_pairs = []
|
| 322 |
for i, frame in enumerate(frames):
|
| 323 |
progress(i / len(frames), desc=f"Upscaling frame {i+1}/{len(frames)}...")
|
|
@@ -348,7 +336,7 @@ def run_pipeline(
|
|
| 348 |
- list of ImageSlider pairs for up to MAX_CARDS cards
|
| 349 |
- list of upscaled image paths for download buttons
|
| 350 |
"""
|
| 351 |
-
MAX_CARDS = 10
|
| 352 |
|
| 353 |
video_path, current_seed, upscaled_pairs = generate_and_upscale(
|
| 354 |
input_image, prompt, steps, negative_prompt,
|
|
@@ -356,7 +344,6 @@ def run_pipeline(
|
|
| 356 |
seed, randomize_seed, progress,
|
| 357 |
)
|
| 358 |
|
| 359 |
-
# Build outputs for each card slot
|
| 360 |
slider_outputs = []
|
| 361 |
download_outputs = []
|
| 362 |
visibility_outputs = []
|
|
@@ -373,8 +360,7 @@ def run_pipeline(
|
|
| 373 |
slider_outputs.append(None)
|
| 374 |
download_outputs.append(None)
|
| 375 |
visibility_outputs.append(gr.update(visible=False))
|
| 376 |
-
|
| 377 |
-
# Flatten: video, seed, then interleaved (slider, download, visibility) per card
|
| 378 |
results = [video_path, current_seed]
|
| 379 |
for i in range(MAX_CARDS):
|
| 380 |
results.append(slider_outputs[i])
|
|
@@ -383,9 +369,6 @@ def run_pipeline(
|
|
| 383 |
|
| 384 |
return results
|
| 385 |
|
| 386 |
-
|
| 387 |
-
# โโโ Build Gradio UI โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 388 |
-
|
| 389 |
css = '''
|
| 390 |
.upscale-card {
|
| 391 |
border: 1px solid var(--border-color-primary);
|
|
@@ -414,7 +397,6 @@ with gr.Blocks(title="wan2.2-i2v-fast") as demo:
|
|
| 414 |
)
|
| 415 |
|
| 416 |
with gr.Row():
|
| 417 |
-
# โโโ LEFT COLUMN: Inputs โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 418 |
with gr.Column(scale=1):
|
| 419 |
input_image_component = gr.Image(type="pil", label="Input Image", height=300)
|
| 420 |
prompt_input = gr.Textbox(
|
|
@@ -452,7 +434,6 @@ with gr.Blocks(title="wan2.2-i2v-fast") as demo:
|
|
| 452 |
|
| 453 |
generate_button = gr.Button("Generate Video & Upscale Frames", variant="primary")
|
| 454 |
|
| 455 |
-
# โโโ RIGHT COLUMN: Video + Upscale Cards โโโโโโโโโโโโโโโโโโ
|
| 456 |
with gr.Column(scale=1):
|
| 457 |
video_output = gr.Video(
|
| 458 |
label="Generated Video", autoplay=True, interactive=False
|
|
@@ -467,7 +448,6 @@ with gr.Blocks(title="wan2.2-i2v-fast") as demo:
|
|
| 467 |
"Click download to save the upscaled image.*"
|
| 468 |
)
|
| 469 |
|
| 470 |
-
# Create card slots dynamically
|
| 471 |
card_groups = [] # list of (group, slider, download_btn)
|
| 472 |
slider_components = []
|
| 473 |
download_components = []
|
|
@@ -490,7 +470,6 @@ with gr.Blocks(title="wan2.2-i2v-fast") as demo:
|
|
| 490 |
download_components.append(download_btn)
|
| 491 |
group_components.append(card_group)
|
| 492 |
|
| 493 |
-
# โโโ Wire up inputs/outputs โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 494 |
ui_inputs = [
|
| 495 |
input_image_component, prompt_input, steps_slider,
|
| 496 |
negative_prompt_input, duration_seconds_input,
|
|
@@ -498,7 +477,6 @@ with gr.Blocks(title="wan2.2-i2v-fast") as demo:
|
|
| 498 |
seed_input, randomize_seed_checkbox,
|
| 499 |
]
|
| 500 |
|
| 501 |
-
# Build output list: video, seed, then (slider, download, group_visibility) ร MAX_CARDS
|
| 502 |
ui_outputs = [video_output, seed_input]
|
| 503 |
for i in range(MAX_CARDS):
|
| 504 |
ui_outputs.append(slider_components[i])
|
|
@@ -511,21 +489,20 @@ with gr.Blocks(title="wan2.2-i2v-fast") as demo:
|
|
| 511 |
outputs=ui_outputs,
|
| 512 |
)
|
| 513 |
|
| 514 |
-
# โโโ Examples โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 515 |
gr.Examples(
|
| 516 |
examples=[
|
| 517 |
[
|
| 518 |
-
"wan_i2v_input.JPG",
|
| 519 |
"POV selfie video, white cat with sunglasses standing on surfboard, relaxed smile, tropical beach behind (clear water, green hills, blue sky with clouds). Surfboard tips, cat falls into ocean, camera plunges underwater with bubbles and sunlight beams. Brief underwater view of cat's face, then cat resurfaces, still filming selfie, playful summer vacation mood.",
|
| 520 |
4,
|
| 521 |
],
|
| 522 |
[
|
| 523 |
-
"wan22_input_2.jpg",
|
| 524 |
"A sleek lunar vehicle glides into view from left to right, kicking up moon dust as astronauts in white spacesuits hop aboard with characteristic lunar bouncing movements. In the distant background, a VTOL craft descends straight down and lands silently on the surface. Throughout the entire scene, ethereal aurora borealis ribbons dance across the star-filled sky, casting shimmering curtains of green, blue, and purple light that bathe the lunar landscape in an otherworldly, magical glow.",
|
| 525 |
4,
|
| 526 |
],
|
| 527 |
[
|
| 528 |
-
"kill_bill.jpeg",
|
| 529 |
"Uma Thurman's character, Beatrix Kiddo, holds her razor-sharp katana blade steady in the cinematic lighting. Suddenly, the polished steel begins to soften and distort, like heated metal starting to lose its structural integrity. The blade's perfect edge slowly warps and droops, molten steel beginning to flow downward in silvery rivulets while maintaining its metallic sheen. The transformation starts subtly at first - a slight bend in the blade - then accelerates as the metal becomes increasingly fluid. The camera holds steady on her face as her piercing eyes gradually narrow, not with lethal focus, but with confusion and growing alarm as she watches her weapon dissolve before her eyes. Her breathing quickens slightly as she witnesses this impossible transformation. The melting intensifies, the katana's perfect form becoming increasingly abstract, dripping like liquid mercury from her grip. Molten droplets fall to the ground with soft metallic impacts. Her expression shifts from calm readiness to bewilderment and concern as her legendary instrument of vengeance literally liquefies in her hands, leaving her defenseless and disoriented.",
|
| 530 |
6,
|
| 531 |
],
|
|
|
|
|
|
|
| 1 |
import spaces
|
| 2 |
import torch
|
| 3 |
from diffusers.pipelines.wan.pipeline_wan_i2v import WanImageToVideoPipeline
|
|
|
|
| 22 |
|
| 23 |
import aoti
|
| 24 |
|
|
|
|
|
|
|
| 25 |
MODEL_ID = "Wan-AI/Wan2.2-I2V-A14B-Diffusers"
|
| 26 |
|
| 27 |
MAX_DIM = 832
|
|
|
|
| 40 |
|
| 41 |
device = "cuda"
|
| 42 |
|
|
|
|
| 43 |
pipe = WanImageToVideoPipeline.from_pretrained(
|
| 44 |
MODEL_ID,
|
| 45 |
transformer=WanTransformer3DModel.from_pretrained(
|
|
|
|
| 87 |
repo_id='cbensimon/WanTransformer3DModel-sm120-cu130-raa',
|
| 88 |
)
|
| 89 |
|
|
|
|
| 90 |
print("Loading FLUX.2 Klein 4B model...")
|
| 91 |
klein_pipe = Flux2KleinPipeline.from_pretrained(
|
| 92 |
"black-forest-labs/FLUX.2-klein-4B",
|
|
|
|
| 94 |
).to(device)
|
| 95 |
print("FLUX.2 Klein 4B loaded successfully.")
|
| 96 |
|
|
|
|
|
|
|
| 97 |
default_prompt_i2v = "make this image come alive, cinematic motion, smooth animation"
|
| 98 |
default_negative_prompt = "่ฒ่ฐ่ณไธฝ, ่ฟๆ, ้ๆ, ็ป่ๆจก็ณไธๆธ
, ๅญๅน, ้ฃๆ ผ, ไฝๅ, ็ปไฝ, ็ป้ข, ้ๆญข, ๆดไฝๅ็ฐ, ๆๅทฎ่ดจ้, ไฝ่ดจ้, JPEGๅ็ผฉๆฎ็, ไธ้็, ๆฎ็ผบ็, ๅคไฝ็ๆๆ, ็ปๅพไธๅฅฝ็ๆ้จ, ็ปๅพไธๅฅฝ็่ธ้จ, ็ธๅฝข็, ๆฏๅฎน็, ๅฝขๆ็ธๅฝข็่ขไฝ, ๆๆ่ๅ, ้ๆญขไธๅจ็็ป้ข, ๆไนฑ็่ๆฏ, ไธๆก่
ฟ, ่ๆฏไบบๅพๅค, ๅ็่ตฐ"
|
| 99 |
|
|
|
|
|
|
|
| 100 |
def resize_image(image: Image.Image) -> Image.Image:
|
| 101 |
"""
|
| 102 |
Resizes an image to fit within the model's constraints, preserving aspect ratio as much as possible.
|
|
|
|
| 210 |
return result
|
| 211 |
|
| 212 |
|
|
|
|
| 213 |
def get_duration(
|
| 214 |
input_image,
|
| 215 |
prompt,
|
|
|
|
| 275 |
return video_path, current_seed
|
| 276 |
|
| 277 |
|
|
|
|
| 278 |
def generate_and_upscale(
|
| 279 |
input_image,
|
| 280 |
prompt,
|
|
|
|
| 306 |
if not frames:
|
| 307 |
return video_path, current_seed, []
|
| 308 |
|
|
|
|
| 309 |
upscaled_pairs = []
|
| 310 |
for i, frame in enumerate(frames):
|
| 311 |
progress(i / len(frames), desc=f"Upscaling frame {i+1}/{len(frames)}...")
|
|
|
|
| 336 |
- list of ImageSlider pairs for up to MAX_CARDS cards
|
| 337 |
- list of upscaled image paths for download buttons
|
| 338 |
"""
|
| 339 |
+
MAX_CARDS = 10
|
| 340 |
|
| 341 |
video_path, current_seed, upscaled_pairs = generate_and_upscale(
|
| 342 |
input_image, prompt, steps, negative_prompt,
|
|
|
|
| 344 |
seed, randomize_seed, progress,
|
| 345 |
)
|
| 346 |
|
|
|
|
| 347 |
slider_outputs = []
|
| 348 |
download_outputs = []
|
| 349 |
visibility_outputs = []
|
|
|
|
| 360 |
slider_outputs.append(None)
|
| 361 |
download_outputs.append(None)
|
| 362 |
visibility_outputs.append(gr.update(visible=False))
|
| 363 |
+
|
|
|
|
| 364 |
results = [video_path, current_seed]
|
| 365 |
for i in range(MAX_CARDS):
|
| 366 |
results.append(slider_outputs[i])
|
|
|
|
| 369 |
|
| 370 |
return results
|
| 371 |
|
|
|
|
|
|
|
|
|
|
| 372 |
css = '''
|
| 373 |
.upscale-card {
|
| 374 |
border: 1px solid var(--border-color-primary);
|
|
|
|
| 397 |
)
|
| 398 |
|
| 399 |
with gr.Row():
|
|
|
|
| 400 |
with gr.Column(scale=1):
|
| 401 |
input_image_component = gr.Image(type="pil", label="Input Image", height=300)
|
| 402 |
prompt_input = gr.Textbox(
|
|
|
|
| 434 |
|
| 435 |
generate_button = gr.Button("Generate Video & Upscale Frames", variant="primary")
|
| 436 |
|
|
|
|
| 437 |
with gr.Column(scale=1):
|
| 438 |
video_output = gr.Video(
|
| 439 |
label="Generated Video", autoplay=True, interactive=False
|
|
|
|
| 448 |
"Click download to save the upscaled image.*"
|
| 449 |
)
|
| 450 |
|
|
|
|
| 451 |
card_groups = [] # list of (group, slider, download_btn)
|
| 452 |
slider_components = []
|
| 453 |
download_components = []
|
|
|
|
| 470 |
download_components.append(download_btn)
|
| 471 |
group_components.append(card_group)
|
| 472 |
|
|
|
|
| 473 |
ui_inputs = [
|
| 474 |
input_image_component, prompt_input, steps_slider,
|
| 475 |
negative_prompt_input, duration_seconds_input,
|
|
|
|
| 477 |
seed_input, randomize_seed_checkbox,
|
| 478 |
]
|
| 479 |
|
|
|
|
| 480 |
ui_outputs = [video_output, seed_input]
|
| 481 |
for i in range(MAX_CARDS):
|
| 482 |
ui_outputs.append(slider_components[i])
|
|
|
|
| 489 |
outputs=ui_outputs,
|
| 490 |
)
|
| 491 |
|
|
|
|
| 492 |
gr.Examples(
|
| 493 |
examples=[
|
| 494 |
[
|
| 495 |
+
"example-file/wan_i2v_input.JPG",
|
| 496 |
"POV selfie video, white cat with sunglasses standing on surfboard, relaxed smile, tropical beach behind (clear water, green hills, blue sky with clouds). Surfboard tips, cat falls into ocean, camera plunges underwater with bubbles and sunlight beams. Brief underwater view of cat's face, then cat resurfaces, still filming selfie, playful summer vacation mood.",
|
| 497 |
4,
|
| 498 |
],
|
| 499 |
[
|
| 500 |
+
"example-file/wan22_input_2.jpg",
|
| 501 |
"A sleek lunar vehicle glides into view from left to right, kicking up moon dust as astronauts in white spacesuits hop aboard with characteristic lunar bouncing movements. In the distant background, a VTOL craft descends straight down and lands silently on the surface. Throughout the entire scene, ethereal aurora borealis ribbons dance across the star-filled sky, casting shimmering curtains of green, blue, and purple light that bathe the lunar landscape in an otherworldly, magical glow.",
|
| 502 |
4,
|
| 503 |
],
|
| 504 |
[
|
| 505 |
+
"example-file/kill_bill.jpeg",
|
| 506 |
"Uma Thurman's character, Beatrix Kiddo, holds her razor-sharp katana blade steady in the cinematic lighting. Suddenly, the polished steel begins to soften and distort, like heated metal starting to lose its structural integrity. The blade's perfect edge slowly warps and droops, molten steel beginning to flow downward in silvery rivulets while maintaining its metallic sheen. The transformation starts subtly at first - a slight bend in the blade - then accelerates as the metal becomes increasingly fluid. The camera holds steady on her face as her piercing eyes gradually narrow, not with lethal focus, but with confusion and growing alarm as she watches her weapon dissolve before her eyes. Her breathing quickens slightly as she witnesses this impossible transformation. The melting intensifies, the katana's perfect form becoming increasingly abstract, dripping like liquid mercury from her grip. Molten droplets fall to the ground with soft metallic impacts. Her expression shifts from calm readiness to bewilderment and concern as her legendary instrument of vengeance literally liquefies in her hands, leaving her defenseless and disoriented.",
|
| 507 |
6,
|
| 508 |
],
|