Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -13,6 +13,11 @@ import tempfile
|
|
| 13 |
from typing import Optional, Tuple, Any
|
| 14 |
from groq import Groq
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
# =========================================================
|
| 18 |
# API CONFIGURATION
|
|
@@ -36,7 +41,7 @@ pipe = WanPipeline.from_pretrained(
|
|
| 36 |
|
| 37 |
MAX_SEED = np.iinfo(np.int32).max
|
| 38 |
FIXED_FPS = 24
|
| 39 |
-
MIN_FRAMES =
|
| 40 |
MAX_FRAMES = 81
|
| 41 |
|
| 42 |
# =========================================================
|
|
@@ -70,7 +75,7 @@ Enhanced: "A fluffy orange tabby cat playfully batting at a dangling yarn ball,
|
|
| 70 |
def enhance_prompt(prompt: str) -> str:
|
| 71 |
"""Enhance the user prompt using Groq LLM API."""
|
| 72 |
if not GROQ_API_KEY:
|
| 73 |
-
return prompt
|
| 74 |
|
| 75 |
try:
|
| 76 |
client = Groq(api_key=GROQ_API_KEY)
|
|
@@ -110,8 +115,18 @@ def enhance_prompt(prompt: str) -> str:
|
|
| 110 |
# HELPER FUNCTIONS
|
| 111 |
# =========================================================
|
| 112 |
def get_num_frames(duration_seconds: float) -> int:
|
| 113 |
-
"""
|
| 114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
|
| 117 |
# =========================================================
|
|
@@ -146,8 +161,11 @@ def generate_video(
|
|
| 146 |
current_seed = random.randint(0, MAX_SEED) if randomize_seed else int(seed)
|
| 147 |
generator = torch.Generator(device=device).manual_seed(current_seed)
|
| 148 |
|
| 149 |
-
# Calculate frames
|
| 150 |
num_frames = get_num_frames(duration_seconds)
|
|
|
|
|
|
|
|
|
|
| 151 |
|
| 152 |
# Generate video
|
| 153 |
output_frames = pipe(
|
|
@@ -170,7 +188,7 @@ def generate_video(
|
|
| 170 |
info_log = f"""✅ VIDEO GENERATION COMPLETE!
|
| 171 |
{'=' * 50}
|
| 172 |
🎬 Video Info:
|
| 173 |
-
• Duration: {
|
| 174 |
• Total Frames: {num_frames}
|
| 175 |
• FPS: {FIXED_FPS}
|
| 176 |
• Resolution: {width} x {height}
|
|
@@ -590,10 +608,10 @@ with gr.Blocks() as demo:
|
|
| 590 |
|
| 591 |
duration_slider = gr.Slider(
|
| 592 |
label="⏱️ Duration (seconds)",
|
| 593 |
-
minimum=
|
| 594 |
-
maximum=
|
| 595 |
step=0.5,
|
| 596 |
-
value=
|
| 597 |
)
|
| 598 |
|
| 599 |
generate_btn = gr.Button(
|
|
|
|
| 13 |
from typing import Optional, Tuple, Any
|
| 14 |
from groq import Groq
|
| 15 |
|
| 16 |
+
# =========================================================
|
| 17 |
+
# CUDA BACKEND FIX
|
| 18 |
+
# =========================================================
|
| 19 |
+
# Fix for cusolver error
|
| 20 |
+
torch.backends.cuda.preferred_linalg_library("cusolver")
|
| 21 |
|
| 22 |
# =========================================================
|
| 23 |
# API CONFIGURATION
|
|
|
|
| 41 |
|
| 42 |
MAX_SEED = np.iinfo(np.int32).max
|
| 43 |
FIXED_FPS = 24
|
| 44 |
+
MIN_FRAMES = 9 # Must be (4k + 1) format: 9, 13, 17, 21, 25, ...
|
| 45 |
MAX_FRAMES = 81
|
| 46 |
|
| 47 |
# =========================================================
|
|
|
|
| 75 |
def enhance_prompt(prompt: str) -> str:
|
| 76 |
"""Enhance the user prompt using Groq LLM API."""
|
| 77 |
if not GROQ_API_KEY:
|
| 78 |
+
return prompt
|
| 79 |
|
| 80 |
try:
|
| 81 |
client = Groq(api_key=GROQ_API_KEY)
|
|
|
|
| 115 |
# HELPER FUNCTIONS
|
| 116 |
# =========================================================
|
| 117 |
def get_num_frames(duration_seconds: float) -> int:
|
| 118 |
+
"""
|
| 119 |
+
Calculate number of frames based on duration.
|
| 120 |
+
num_frames - 1 must be divisible by 4, so num_frames must be 4k + 1
|
| 121 |
+
Valid values: 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81
|
| 122 |
+
"""
|
| 123 |
+
raw_frames = int(duration_seconds * FIXED_FPS)
|
| 124 |
+
# Round to nearest valid frame count (4k + 1)
|
| 125 |
+
k = round((raw_frames - 1) / 4)
|
| 126 |
+
num_frames = 4 * k + 1
|
| 127 |
+
# Clamp to valid range
|
| 128 |
+
num_frames = max(MIN_FRAMES, min(MAX_FRAMES, num_frames))
|
| 129 |
+
return num_frames
|
| 130 |
|
| 131 |
|
| 132 |
# =========================================================
|
|
|
|
| 161 |
current_seed = random.randint(0, MAX_SEED) if randomize_seed else int(seed)
|
| 162 |
generator = torch.Generator(device=device).manual_seed(current_seed)
|
| 163 |
|
| 164 |
+
# Calculate frames (must be 4k + 1)
|
| 165 |
num_frames = get_num_frames(duration_seconds)
|
| 166 |
+
actual_duration = num_frames / FIXED_FPS
|
| 167 |
+
|
| 168 |
+
print(f"Generating video with {num_frames} frames ({actual_duration:.2f}s)")
|
| 169 |
|
| 170 |
# Generate video
|
| 171 |
output_frames = pipe(
|
|
|
|
| 188 |
info_log = f"""✅ VIDEO GENERATION COMPLETE!
|
| 189 |
{'=' * 50}
|
| 190 |
🎬 Video Info:
|
| 191 |
+
• Duration: {actual_duration:.2f} seconds
|
| 192 |
• Total Frames: {num_frames}
|
| 193 |
• FPS: {FIXED_FPS}
|
| 194 |
• Resolution: {width} x {height}
|
|
|
|
| 608 |
|
| 609 |
duration_slider = gr.Slider(
|
| 610 |
label="⏱️ Duration (seconds)",
|
| 611 |
+
minimum=0.5,
|
| 612 |
+
maximum=3.5,
|
| 613 |
step=0.5,
|
| 614 |
+
value=2.0
|
| 615 |
)
|
| 616 |
|
| 617 |
generate_btn = gr.Button(
|