Spaces:
Sleeping
Sleeping
File size: 3,351 Bytes
559617d fca9e42 559617d 60f0957 559617d fca9e42 559617d ac9a9f2 fca9e42 ac9a9f2 fca9e42 ac9a9f2 fca9e42 ac9a9f2 fca9e42 ac9a9f2 fca9e42 ac9a9f2 fca9e42 559617d 60f0957 fca9e42 ac9a9f2 559617d ac9a9f2 559617d 60f0957 559617d ac9a9f2 60f0957 559617d 60f0957 fca9e42 559617d 60f0957 559617d 60f0957 fca9e42 559617d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import spaces
import torch
import gc
import os
import gradio as gr
from diffusers import WanPipeline
from diffusers.utils import export_to_video
from huggingface_hub import snapshot_download
import tempfile
import time
# ============================================================
# DOWNLOAD model to DISK only at startup (near-zero RAM usage)
# This runs during container startup = NO time limit
# ============================================================
print("π₯ Pre-caching model files to disk (no RAM used)...")
start = time.time()
model_path = snapshot_download(
"Wan-AI/Wan2.1-T2V-1.3B-Diffusers",
token=os.environ.get("HF_TOKEN"),
allow_patterns=["*.safetensors", "*.json", "*.txt", "*.model"],
ignore_patterns=["*.bin", "*.onnx", "*.msgpack"],
)
gc.collect()
print(f"β
Files cached to disk in {time.time()-start:.0f}s")
print(f"π Path: {model_path}")
# Model loaded lazily inside GPU function
pipe = None
@spaces.GPU(duration=240)
def generate_video(prompt, negative_prompt, num_frames, height, width, num_inference_steps, guidance_scale):
global pipe
if pipe is None:
print("π¦ Loading to GPU from local disk cache...")
load_start = time.time()
pipe = WanPipeline.from_pretrained(
model_path,
torch_dtype=torch.float16,
low_cpu_mem_usage=True,
)
pipe.to("cuda")
pipe.vae.enable_tiling()
gc.collect()
print(f"β
On GPU in {time.time()-load_start:.0f}s")
start = time.time()
with torch.inference_mode():
result = pipe(
prompt=prompt,
negative_prompt=negative_prompt,
num_frames=int(num_frames),
height=int(height),
width=int(width),
num_inference_steps=int(num_inference_steps),
guidance_scale=float(guidance_scale),
).frames[0]
print(f"β
Generated in {time.time()-start:.1f}s")
output_path = tempfile.mktemp(suffix=".mp4")
export_to_video(result, output_path, fps=16)
gc.collect(); torch.cuda.empty_cache()
return output_path
with gr.Blocks(title="Shotarch Video Gen", theme=gr.themes.Soft()) as demo:
gr.Markdown("# π¬ Shotarch Video Generator\n### Wan2.1-1.3B on ZeroGPU")
with gr.Row():
with gr.Column():
prompt = gr.Textbox(label="Prompt", lines=3, placeholder="Describe your video...")
negative = gr.Textbox(label="Negative Prompt", lines=2, value="Bright tones, overexposed, static, blurred details, worst quality, low quality, ugly, deformed, still picture")
with gr.Row():
width = gr.Slider(480, 1280, value=1280, step=16, label="Width")
height = gr.Slider(320, 720, value=720, step=16, label="Height")
with gr.Row():
num_frames = gr.Slider(17, 81, value=81, step=4, label="Frames (81=5sec)")
steps = gr.Slider(10, 50, value=25, step=1, label="Steps")
guidance = gr.Slider(1.0, 15.0, value=5.0, step=0.5, label="Guidance Scale")
btn = gr.Button("π¬ Generate Video", variant="primary")
with gr.Column():
output = gr.Video(label="Generated Video")
btn.click(fn=generate_video, inputs=[prompt, negative, num_frames, height, width, steps, guidance], outputs=output)
demo.launch()
|