ArmanRV commited on
Commit
14da46e
·
verified ·
1 Parent(s): 471955c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -0
app.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import gradio as gr
4
+ import torch
5
+ from PIL import Image
6
+
7
+ from diffusers import StableVideoDiffusionPipeline
8
+ import imageio.v2 as imageio
9
+
10
+
11
+ # -------- paths --------
12
+ ROOT = "/data" if os.path.isdir("/data") else "/home/user"
13
+ MODEL_DIR = os.path.join(ROOT, "models", "svd-xt")
14
+ OUT_DIR = os.path.join(ROOT, "outputs")
15
+ os.makedirs(OUT_DIR, exist_ok=True)
16
+
17
+ pipe = None
18
+
19
+ def get_pipe():
20
+ global pipe
21
+ if pipe is not None:
22
+ return pipe
23
+
24
+ if not os.path.isdir(MODEL_DIR):
25
+ raise gr.Error(f"Model not found at {MODEL_DIR}. postBuild didn't download it.")
26
+
27
+ dtype = torch.float16 if torch.cuda.is_available() else torch.float32
28
+ pipe = StableVideoDiffusionPipeline.from_pretrained(
29
+ MODEL_DIR,
30
+ torch_dtype=dtype,
31
+ local_files_only=True, # <-- запрет докачки в рантайме
32
+ )
33
+
34
+ if torch.cuda.is_available():
35
+ pipe = pipe.to("cuda")
36
+ try:
37
+ pipe.enable_xformers_memory_efficient_attention()
38
+ except Exception:
39
+ pass
40
+
41
+ return pipe
42
+
43
+
44
+ def run(image: Image.Image, motion: int, fps: int, frames: int, steps: int, seed: int):
45
+ if image is None:
46
+ raise gr.Error("Upload an image first.")
47
+
48
+ if seed < 0:
49
+ seed = int(time.time()) % 10_000_000
50
+
51
+ generator = torch.Generator(device="cuda" if torch.cuda.is_available() else "cpu").manual_seed(int(seed))
52
+
53
+ pipe = get_pipe()
54
+
55
+ # SVD любит 1024 ширину по умолчанию, но лучше держать умеренно для VRAM
56
+ # Можно подстроить под фото, но начнём с безопасного.
57
+ img = image.convert("RGB")
58
+
59
+ # В diffusers для SVD параметры могут называться немного по-разному между версиями,
60
+ # но обычно работают: num_frames, fps, motion_bucket_id, num_inference_steps
61
+ out = pipe(
62
+ image=img,
63
+ num_frames=int(frames),
64
+ fps=int(fps),
65
+ motion_bucket_id=int(motion),
66
+ num_inference_steps=int(steps),
67
+ generator=generator,
68
+ )
69
+
70
+ video_frames = out.frames[0] # list[PIL]
71
+ out_path = os.path.join(OUT_DIR, f"svd_{int(time.time())}.mp4")
72
+ imageio.mimsave(out_path, video_frames, fps=int(fps))
73
+ return out_path
74
+
75
+
76
+ with gr.Blocks(title="SVD img2vid XT (local)") as demo:
77
+ gr.Markdown("## Stable Video Diffusion (img2vid-xt) — local in Space")
78
+
79
+ with gr.Row():
80
+ inp = gr.Image(type="pil", label="Input image")
81
+ out = gr.Video(label="Output video")
82
+
83
+ with gr.Accordion("Settings", open=False):
84
+ motion = gr.Slider(1, 255, value=127, step=1, label="motion_bucket_id (higher = more motion)")
85
+ fps = gr.Slider(6, 30, value=12, step=1, label="fps")
86
+ frames = gr.Slider(8, 30, value=14, step=1, label="num_frames")
87
+ steps = gr.Slider(10, 50, value=25, step=1, label="steps")
88
+ seed = gr.Number(value=-1, precision=0, label="seed (-1 random)")
89
+
90
+ btn = gr.Button("Generate", variant="primary")
91
+ btn.click(run, [inp, motion, fps, frames, steps, seed], out)
92
+
93
+ demo.queue().launch()