Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
@@ -34,12 +34,12 @@ class VideoGenerationConfig:
|
|
34 |
lora_filename: str = "Wan21_CausVid_14B_T2V_lora_rank32.safetensors"
|
35 |
mod_value: int = 32
|
36 |
default_height: int = 512
|
37 |
-
default_width: int =
|
38 |
max_area: float = 480.0 * 832.0
|
39 |
slider_min_h: int = 128
|
40 |
-
slider_max_h: int =
|
41 |
slider_min_w: int = 128
|
42 |
-
slider_max_w: int =
|
43 |
fixed_fps: int = 24
|
44 |
min_frames: int = 8
|
45 |
max_frames: int = 81
|
@@ -163,7 +163,10 @@ class ModelManager:
|
|
163 |
self._pipe.fuse_lora()
|
164 |
|
165 |
# GPU μ΅μ ν μ€μ
|
166 |
-
if
|
|
|
|
|
|
|
167 |
self._pipe.enable_model_cpu_offload()
|
168 |
else:
|
169 |
self._pipe.to("cuda")
|
@@ -216,16 +219,29 @@ class VideoGenerator:
|
|
216 |
return self.config.default_height, self.config.default_width
|
217 |
|
218 |
aspect_ratio = orig_h / orig_w
|
219 |
-
|
220 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
|
222 |
calc_h = max(self.config.mod_value, (calc_h // self.config.mod_value) * self.config.mod_value)
|
223 |
calc_w = max(self.config.mod_value, (calc_w // self.config.mod_value) * self.config.mod_value)
|
224 |
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
229 |
|
230 |
return new_h, new_w
|
231 |
|
@@ -254,8 +270,12 @@ class VideoGenerator:
|
|
254 |
if hasattr(spaces, 'GPU'): # Spaces νκ²½ 체ν¬
|
255 |
if duration > 2.5: # Zero GPUμμλ 2.5μ΄λ‘ μ ν
|
256 |
return False, "β±οΈ In Zero GPU environment, duration is limited to 2.5s for stability"
|
257 |
-
|
258 |
-
|
|
|
|
|
|
|
|
|
259 |
|
260 |
# GPU λ©λͺ¨λ¦¬ 체ν¬
|
261 |
if torch.cuda.is_available():
|
@@ -312,11 +332,11 @@ def get_duration(input_image, prompt, height, width, negative_prompt,
|
|
312 |
elif duration_seconds > 1.5:
|
313 |
base_duration += 10
|
314 |
|
315 |
-
# ν΄μλλ³ μΆκ° μκ°
|
316 |
pixels = height * width
|
317 |
-
if pixels > 400000: #
|
318 |
base_duration += 20
|
319 |
-
elif pixels > 250000: #
|
320 |
base_duration += 10
|
321 |
|
322 |
# Zero GPU νκ²½μμλ μ΅λ 90μ΄λ‘ μ ν
|
@@ -339,7 +359,7 @@ def generate_video(input_image, prompt, height, width,
|
|
339 |
|
340 |
# Zero GPU νκ²½μμ μΆκ° κ²μ¦
|
341 |
if hasattr(spaces, 'GPU'):
|
342 |
-
logger.info(f"Zero GPU environment detected. Duration: {duration_seconds}s, Resolution: {height}x{width}")
|
343 |
|
344 |
# μ
λ ₯ κ²μ¦
|
345 |
is_valid, error_msg = video_generator.validate_inputs(
|
@@ -584,7 +604,7 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
|
|
584 |
<div class="header">
|
585 |
<h1>π¬ AI Video Magic Studio</h1>
|
586 |
<p>Transform your images into captivating videos with Wan 2.1 + CausVid LoRA</p>
|
587 |
-
<div class="gpu-status">π₯οΈ GPU Optimized</div>
|
588 |
</div>
|
589 |
""")
|
590 |
|
@@ -594,7 +614,8 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
|
|
594 |
<strong>π‘ Zero GPU Performance Tips:</strong>
|
595 |
<ul style="margin: 5px 0; padding-left: 20px;">
|
596 |
<li>Maximum duration: 2.5 seconds (limited by Zero GPU)</li>
|
597 |
-
<li>
|
|
|
598 |
<li>Use 4-6 steps for optimal speed/quality balance</li>
|
599 |
<li>Wait between generations to avoid queue errors</li>
|
600 |
</ul>
|
@@ -654,14 +675,14 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
|
|
654 |
maximum=config.slider_max_h,
|
655 |
step=config.mod_value,
|
656 |
value=config.default_height,
|
657 |
-
label="π Height (
|
658 |
)
|
659 |
width_slider = gr.Slider(
|
660 |
minimum=config.slider_min_w,
|
661 |
maximum=config.slider_max_w,
|
662 |
step=config.mod_value,
|
663 |
value=config.default_width,
|
664 |
-
label="π Width (
|
665 |
)
|
666 |
|
667 |
steps_slider = gr.Slider(
|
@@ -705,7 +726,7 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
|
|
705 |
gr.Examples(
|
706 |
examples=[
|
707 |
["peng.png", "a penguin playfully dancing in the snow, Antarctica", 512, 512],
|
708 |
-
["forg.jpg", "the frog jumps around",
|
709 |
],
|
710 |
inputs=[input_image, prompt_input, height_slider, width_slider],
|
711 |
outputs=[video_output, seed],
|
@@ -747,4 +768,4 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
|
|
747 |
)
|
748 |
|
749 |
if __name__ == "__main__":
|
750 |
-
demo.queue(max_size=1).launch() #
|
|
|
34 |
lora_filename: str = "Wan21_CausVid_14B_T2V_lora_rank32.safetensors"
|
35 |
mod_value: int = 32
|
36 |
default_height: int = 512
|
37 |
+
default_width: int = 512 # Zero GPU νκ²½μ μν΄ κΈ°λ³Έκ° μμ
|
38 |
max_area: float = 480.0 * 832.0
|
39 |
slider_min_h: int = 128
|
40 |
+
slider_max_h: int = 832 # Zero GPU νκ²½μ μν΄ μμ
|
41 |
slider_min_w: int = 128
|
42 |
+
slider_max_w: int = 832 # Zero GPU νκ²½μ μν΄ μμ
|
43 |
fixed_fps: int = 24
|
44 |
min_frames: int = 8
|
45 |
max_frames: int = 81
|
|
|
163 |
self._pipe.fuse_lora()
|
164 |
|
165 |
# GPU μ΅μ ν μ€μ
|
166 |
+
if hasattr(spaces, 'GPU'): # Zero GPU νκ²½
|
167 |
+
self._pipe.enable_model_cpu_offload()
|
168 |
+
logger.info("CPU offload enabled for Zero GPU")
|
169 |
+
elif config.enable_model_cpu_offload:
|
170 |
self._pipe.enable_model_cpu_offload()
|
171 |
else:
|
172 |
self._pipe.to("cuda")
|
|
|
219 |
return self.config.default_height, self.config.default_width
|
220 |
|
221 |
aspect_ratio = orig_h / orig_w
|
222 |
+
|
223 |
+
# Zero GPU νκ²½μμλ λ μμ max_area μ¬μ©
|
224 |
+
if hasattr(spaces, 'GPU'):
|
225 |
+
max_area = 640.0 * 640.0 # 409,600 pixels
|
226 |
+
else:
|
227 |
+
max_area = self.config.max_area
|
228 |
+
|
229 |
+
calc_h = round(np.sqrt(max_area * aspect_ratio))
|
230 |
+
calc_w = round(np.sqrt(max_area / aspect_ratio))
|
231 |
|
232 |
calc_h = max(self.config.mod_value, (calc_h // self.config.mod_value) * self.config.mod_value)
|
233 |
calc_w = max(self.config.mod_value, (calc_w // self.config.mod_value) * self.config.mod_value)
|
234 |
|
235 |
+
# Zero GPU νκ²½μμ μΆκ° μ ν
|
236 |
+
if hasattr(spaces, 'GPU'):
|
237 |
+
max_dim = 832
|
238 |
+
new_h = int(np.clip(calc_h, self.config.slider_min_h, min(max_dim, self.config.slider_max_h)))
|
239 |
+
new_w = int(np.clip(calc_w, self.config.slider_min_w, min(max_dim, self.config.slider_max_w)))
|
240 |
+
else:
|
241 |
+
new_h = int(np.clip(calc_h, self.config.slider_min_h,
|
242 |
+
(self.config.slider_max_h // self.config.mod_value) * self.config.mod_value))
|
243 |
+
new_w = int(np.clip(calc_w, self.config.slider_min_w,
|
244 |
+
(self.config.slider_max_w // self.config.mod_value) * self.config.mod_value))
|
245 |
|
246 |
return new_h, new_w
|
247 |
|
|
|
270 |
if hasattr(spaces, 'GPU'): # Spaces νκ²½ 체ν¬
|
271 |
if duration > 2.5: # Zero GPUμμλ 2.5μ΄λ‘ μ ν
|
272 |
return False, "β±οΈ In Zero GPU environment, duration is limited to 2.5s for stability"
|
273 |
+
# ν½μ
μ κΈ°λ° μ ν (640x640 = 409,600 ν½μ
)
|
274 |
+
max_pixels = 640 * 640
|
275 |
+
if height * width > max_pixels:
|
276 |
+
return False, f"π In Zero GPU environment, total pixels limited to {max_pixels:,} (e.g., 640Γ640, 512Γ832)"
|
277 |
+
if height > 832 or width > 832: # ν λ³μ μ΅λ κΈΈμ΄
|
278 |
+
return False, "π In Zero GPU environment, maximum dimension is 832 pixels"
|
279 |
|
280 |
# GPU λ©λͺ¨λ¦¬ 체ν¬
|
281 |
if torch.cuda.is_available():
|
|
|
332 |
elif duration_seconds > 1.5:
|
333 |
base_duration += 10
|
334 |
|
335 |
+
# ν΄μλλ³ μΆκ° μκ° (ν½μ
μ κΈ°λ°)
|
336 |
pixels = height * width
|
337 |
+
if pixels > 400000: # 640x640 κ·Όμ²
|
338 |
base_duration += 20
|
339 |
+
elif pixels > 250000: # 512x512 κ·Όμ²
|
340 |
base_duration += 10
|
341 |
|
342 |
# Zero GPU νκ²½μμλ μ΅λ 90μ΄λ‘ μ ν
|
|
|
359 |
|
360 |
# Zero GPU νκ²½μμ μΆκ° κ²μ¦
|
361 |
if hasattr(spaces, 'GPU'):
|
362 |
+
logger.info(f"Zero GPU environment detected. Duration: {duration_seconds}s, Resolution: {height}x{width}, Pixels: {height*width:,}")
|
363 |
|
364 |
# μ
λ ₯ κ²μ¦
|
365 |
is_valid, error_msg = video_generator.validate_inputs(
|
|
|
604 |
<div class="header">
|
605 |
<h1>π¬ AI Video Magic Studio</h1>
|
606 |
<p>Transform your images into captivating videos with Wan 2.1 + CausVid LoRA</p>
|
607 |
+
<div class="gpu-status">π₯οΈ Zero GPU Optimized</div>
|
608 |
</div>
|
609 |
""")
|
610 |
|
|
|
614 |
<strong>π‘ Zero GPU Performance Tips:</strong>
|
615 |
<ul style="margin: 5px 0; padding-left: 20px;">
|
616 |
<li>Maximum duration: 2.5 seconds (limited by Zero GPU)</li>
|
617 |
+
<li>Maximum total pixels: 409,600 (e.g., 640Γ640, 512Γ832, 448Γ896)</li>
|
618 |
+
<li>Maximum single dimension: 832 pixels</li>
|
619 |
<li>Use 4-6 steps for optimal speed/quality balance</li>
|
620 |
<li>Wait between generations to avoid queue errors</li>
|
621 |
</ul>
|
|
|
675 |
maximum=config.slider_max_h,
|
676 |
step=config.mod_value,
|
677 |
value=config.default_height,
|
678 |
+
label="π Height (max 832px in Zero GPU)"
|
679 |
)
|
680 |
width_slider = gr.Slider(
|
681 |
minimum=config.slider_min_w,
|
682 |
maximum=config.slider_max_w,
|
683 |
step=config.mod_value,
|
684 |
value=config.default_width,
|
685 |
+
label="π Width (max 832px in Zero GPU)"
|
686 |
)
|
687 |
|
688 |
steps_slider = gr.Slider(
|
|
|
726 |
gr.Examples(
|
727 |
examples=[
|
728 |
["peng.png", "a penguin playfully dancing in the snow, Antarctica", 512, 512],
|
729 |
+
["forg.jpg", "the frog jumps around", 576, 320], # 16:9 aspect ratio within limits
|
730 |
],
|
731 |
inputs=[input_image, prompt_input, height_slider, width_slider],
|
732 |
outputs=[video_output, seed],
|
|
|
768 |
)
|
769 |
|
770 |
if __name__ == "__main__":
|
771 |
+
demo.queue(max_size=1, concurrency_count=1).launch() # λ μ격ν λμμ± μ μ΄
|