Yuanshi commited on
Commit
ab20f51
·
1 Parent(s): 0b31b45

interface update

Browse files
Files changed (2) hide show
  1. .gitignore +3 -1
  2. app.py +263 -82
.gitignore CHANGED
@@ -1,2 +1,4 @@
1
  **/__pycache__/
2
- *.pyc
 
 
 
1
  **/__pycache__/
2
+ *.pyc
3
+ .vscode
4
+ *.mp4
app.py CHANGED
@@ -1,97 +1,278 @@
 
 
 
 
1
  import gradio as gr
2
  import spaces
3
- import torch
4
- import os
5
 
6
- # ==========================================
7
- # 1. 核心处理函数 (骨架)
8
- # ==========================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  @spaces.GPU
10
- def run_stylization(input_video_path, prompt, noise_scale, shift_gamma, steps, guidance_scale, seed):
11
- """
12
- 这里是实际推理逻辑的占位符。
13
- """
 
 
 
 
 
 
14
  if not input_video_path:
15
  return None
16
-
 
 
17
  print("========== Inference Start ==========")
18
  print(f"Video Path: {input_video_path}")
19
  print(f"Prompt: {prompt}")
20
- print(f"Params: Noise={noise_scale}, Gamma={shift_gamma}, Steps={steps}, CFG={guidance_scale}, Seed={seed}")
 
 
 
 
 
 
21
 
22
- # [Prototype Logic] 直接返回输入视频用于演示
23
  return input_video_path
24
 
25
- # ==========================================
26
- # 2. 界面布局 (Gradio Blocks)
27
- # ==========================================
28
-
29
- # 移除 CSS 参数以修复 TypeError
30
- with gr.Blocks() as demo:
31
- with gr.Column(elem_id="col-container"):
32
- gr.Markdown("# 🎥 ViBT Video Stylization Interface")
33
- gr.Markdown("上传视频并设置风格化参数。")
34
-
35
- with gr.Row():
36
- # --- 左侧:输入与设置 ---
37
- with gr.Column():
38
- # 视频输入
39
- input_video = gr.Video(label="Source Video", sources=["upload"])
40
-
41
- # 提示词
42
- prompt_input = gr.Textbox(
43
- label="Style Prompt",
44
- placeholder="e.g., Van Gogh style, cyberpunk city...",
45
- value="Oil painting style, vivid colors"
46
- )
47
-
48
- # 高级参数折叠区
49
- with gr.Accordion("Advanced Settings", open=True):
50
- with gr.Row():
51
- noise_scale = gr.Slider(
52
- label="Noise Scale", minimum=0.0, maximum=2.0, step=0.1, value=1.0,
53
- info="Controls how much noise is added."
54
- )
55
- shift_gamma = gr.Slider(
56
- label="Shift Gamma", minimum=1.0, maximum=10.0, step=0.5, value=5.0,
57
- info="Scheduler parameter."
58
- )
59
-
60
- with gr.Row():
61
- num_steps = gr.Slider(
62
- label="Inference Steps", minimum=10, maximum=50, step=1, value=28,
63
- info="More steps = higher quality but slower."
64
- )
65
- guidance_scale = gr.Slider(
66
- label="Guidance Scale (CFG)", minimum=1.0, maximum=20.0, step=0.5, value=1.5,
67
- info="How closely to follow the prompt."
68
- )
69
-
70
- seed = gr.Number(label="Seed", value=42, precision=0)
71
-
72
- # 提交按钮
73
- run_btn = gr.Button("Generate Video", variant="primary")
74
-
75
- # --- 右侧:结果输出 ---
76
- with gr.Column():
77
- output_video = gr.Video(label="Stylized Result", interactive=False)
78
-
79
- # ==========================================
80
- # 3. 事件绑定
81
- # ==========================================
82
- run_btn.click(
83
- fn=run_stylization,
84
- inputs=[
85
- input_video,
86
- prompt_input,
87
- noise_scale,
88
- shift_gamma,
89
- num_steps,
90
- guidance_scale,
91
- seed
92
- ],
93
- outputs=[output_video]
94
  )
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  if __name__ == "__main__":
97
- demo.launch()
 
1
+ import functools
2
+ from dataclasses import dataclass
3
+ import random
4
+
5
  import gradio as gr
6
  import spaces
 
 
7
 
8
+
9
+ @dataclass(frozen=True)
10
+ class SliderConfig:
11
+ label: str
12
+ minimum: float
13
+ maximum: float
14
+ step: float
15
+ value: float
16
+ info: str
17
+
18
+
19
+ @dataclass(frozen=True)
20
+ class PresetConfig:
21
+ shift_gamma: float
22
+ steps: int
23
+ guidance_scale: float
24
+
25
+
26
+ GAMMA_SLIDER = SliderConfig(
27
+ label="Shift Gamma",
28
+ minimum=1.0,
29
+ maximum=10.0,
30
+ step=0.5,
31
+ value=5.0,
32
+ info="Scheduler adjustment parameter."
33
+ )
34
+
35
+ STEP_SLIDER = SliderConfig(
36
+ label="Inference Steps",
37
+ minimum=10,
38
+ maximum=50,
39
+ step=1,
40
+ value=28,
41
+ info="More steps improve quality but take longer."
42
+ )
43
+
44
+ GUIDANCE_SLIDER = SliderConfig(
45
+ label="Guidance Scale (CFG)",
46
+ minimum=1.0,
47
+ maximum=20.0,
48
+ step=0.5,
49
+ value=1.5,
50
+ info="Controls adherence to the text prompt."
51
+ )
52
+
53
+
54
+ STYLE_CHOICES = [
55
+ "Oil painting style, vivid colors",
56
+ "Neon cyberpunk, futuristic city",
57
+ "Minimalist sketch, soft shading",
58
+ "Anime aesthetic, bold lines",
59
+ ]
60
+
61
+
62
+ EXAMPLE_INPUTS = [
63
+ ["assets/video_00000000.mp4", "Oil painting style, vivid colors"],
64
+ ["assets/video_00000007.mp4", "Neon cyberpunk, futuristic city"],
65
+ ["assets/video_00000107.mp4", "Minimalist sketch, soft shading"],
66
+ ]
67
+
68
+
69
+ PRESET_MODES = {
70
+ "Fast": PresetConfig(shift_gamma=5.0, steps=10, guidance_scale=1.),
71
+ "Balanced": PresetConfig(shift_gamma=5.0, steps=10, guidance_scale=1.5),
72
+ "Quality": PresetConfig(shift_gamma=5.0, steps=20, guidance_scale=1.5),
73
+ }
74
+
75
+
76
+ def _create_slider(config: SliderConfig) -> gr.Slider:
77
+ """Helper to keep slider creation consistent."""
78
+ return gr.Slider(
79
+ label=config.label,
80
+ minimum=config.minimum,
81
+ maximum=config.maximum,
82
+ step=config.step,
83
+ value=config.value,
84
+ info=config.info,
85
+ )
86
+
87
+
88
  @spaces.GPU
89
+ def run_stylization(
90
+ input_video_path,
91
+ prompt,
92
+ shift_gamma,
93
+ steps,
94
+ guidance_scale,
95
+ seed,
96
+ randomize_seed,
97
+ ):
98
+ """Placeholder stylization pipeline that echoes the input video."""
99
  if not input_video_path:
100
  return None
101
+
102
+ resolved_seed = _resolve_seed(seed, randomize_seed)
103
+
104
  print("========== Inference Start ==========")
105
  print(f"Video Path: {input_video_path}")
106
  print(f"Prompt: {prompt}")
107
+ print(
108
+ "Params: "
109
+ f"Gamma={shift_gamma}, "
110
+ f"Steps={steps}, "
111
+ f"CFG={guidance_scale}, "
112
+ f"Seed={resolved_seed}"
113
+ )
114
 
 
115
  return input_video_path
116
 
117
+
118
+ def _resolve_seed(seed_value, randomize):
119
+ """Return an integer seed, generating a random one when requested or missing."""
120
+ if randomize or seed_value in (None, ""):
121
+ return random.randint(0, 2**31 - 1)
122
+ return int(seed_value)
123
+
124
+
125
+ def run_with_preset(input_video_path, prompt, seed, randomize_seed, preset_key):
126
+ """Wrap stylization with predefined presets for quick generation."""
127
+ preset = PRESET_MODES[preset_key]
128
+ return run_stylization(
129
+ input_video_path=input_video_path,
130
+ prompt=prompt,
131
+ shift_gamma=preset.shift_gamma,
132
+ steps=preset.steps,
133
+ guidance_scale=preset.guidance_scale,
134
+ seed=seed,
135
+ randomize_seed=randomize_seed,
136
+ )
137
+
138
+
139
+ def _bind_preset_button(button, preset_key, inputs, output, extra_kwargs=None):
140
+ extra_kwargs = extra_kwargs or {}
141
+ button.click(
142
+ fn=functools.partial(run_with_preset, preset_key=preset_key, **extra_kwargs),
143
+ inputs=inputs,
144
+ outputs=[output],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  )
146
 
147
+
148
+ def build_demo() -> gr.Blocks:
149
+ """Create the Gradio interface for video stylization."""
150
+ with gr.Blocks() as demo:
151
+ with gr.Column(elem_id="col-container"):
152
+ gr.HTML(
153
+ """
154
+ <style>
155
+ #col-container { max-width: 1200px; margin: 0 auto; }
156
+ </style>
157
+ """
158
+ )
159
+ gr.Markdown(
160
+ """
161
+ # 🎥 ViBT: Vision Bridge Transformer at Scale
162
+ <div style="text-align: center; display: flex; justify-content: left; gap: 5px;">
163
+ <a href="https://arxiv.org/abs/2411.15098"><img src="https://img.shields.io/badge/ariXv-Paper-A42C25.svg" alt="arXiv"></a>
164
+ <a href="https://huggingface.co/spaces/Yuanshi/OminiControl"><img src="https://img.shields.io/badge/🤗OminiControl-Demo-ffbd45.svg" alt="HuggingFace"></a>
165
+ <a href="https://github.com/Yuanshi9815/OminiControl"><img src="https://img.shields.io/badge/GitHub-Code-blue.svg?logo=github&" alt="GitHub"></a>
166
+ </div>
167
+ """
168
+ )
169
+
170
+ with gr.Row():
171
+ with gr.Column():
172
+ input_video = gr.Video(label="Source Video", sources=["upload"])
173
+ with gr.Column():
174
+ output_video = gr.Video(label="Stylized Result", interactive=False)
175
+
176
+ with gr.Row():
177
+ with gr.Column(scale=1) as control_col:
178
+ with gr.Tabs():
179
+ with gr.Tab("Quick Generate"):
180
+ prompt_quick = gr.Dropdown(
181
+ label="Style Instruction",
182
+ choices=STYLE_CHOICES,
183
+ value=STYLE_CHOICES[0],
184
+ allow_custom_value=False,
185
+ )
186
+
187
+ with gr.Row():
188
+ fast_btn = gr.Button("⚡ Fast Generate", variant="primary")
189
+ balanced_btn = gr.Button("🎯 Balanced Generate", variant="primary")
190
+ quality_btn = gr.Button("🌟 Quality Generate", variant="primary")
191
+
192
+ _bind_preset_button(
193
+ button=fast_btn,
194
+ preset_key="Fast",
195
+ inputs=[
196
+ input_video,
197
+ prompt_quick,
198
+ ],
199
+ output=output_video,
200
+ extra_kwargs={"seed": None, "randomize_seed": True},
201
+ )
202
+ _bind_preset_button(
203
+ button=balanced_btn,
204
+ preset_key="Balanced",
205
+ inputs=[
206
+ input_video,
207
+ prompt_quick,
208
+ ],
209
+ output=output_video,
210
+ extra_kwargs={"seed": None, "randomize_seed": True},
211
+ )
212
+ _bind_preset_button(
213
+ button=quality_btn,
214
+ preset_key="Quality",
215
+ inputs=[
216
+ input_video,
217
+ prompt_quick,
218
+ ],
219
+ output=output_video,
220
+ extra_kwargs={"seed": None, "randomize_seed": True},
221
+ )
222
+
223
+ with gr.Tab("Advanced Settings"):
224
+ prompt_adv = gr.Dropdown(
225
+ label="Style Instruction",
226
+ choices=STYLE_CHOICES,
227
+ value=STYLE_CHOICES[0],
228
+ allow_custom_value=True,
229
+ )
230
+ with gr.Row():
231
+ shift_gamma = _create_slider(GAMMA_SLIDER)
232
+ guidance_scale = _create_slider(GUIDANCE_SLIDER)
233
+
234
+ with gr.Row():
235
+ num_steps = _create_slider(STEP_SLIDER)
236
+ randomize_seed_adv = gr.Checkbox(
237
+ label="Randomize Seed",
238
+ value=False,
239
+ info="Checked = new random seed each run. Uncheck to provide your own seed.",
240
+ )
241
+
242
+ seed_adv = gr.Number(
243
+ label="Seed (used when Randomize is off)",
244
+ value=42,
245
+ precision=0,
246
+ )
247
+
248
+ run_btn = gr.Button("Generate", variant="primary")
249
+
250
+ run_btn.click(
251
+ fn=run_stylization,
252
+ inputs=[
253
+ input_video,
254
+ prompt_adv,
255
+ shift_gamma,
256
+ num_steps,
257
+ guidance_scale,
258
+ seed_adv,
259
+ randomize_seed_adv,
260
+ ],
261
+ outputs=[output_video],
262
+ )
263
+
264
+ with gr.Column(scale=1):
265
+ gr.Examples(
266
+ examples=EXAMPLE_INPUTS,
267
+ inputs=[input_video, prompt_quick, prompt_adv],
268
+ label="Example inputs",
269
+ )
270
+
271
+ return demo
272
+
273
+
274
+ demo = build_demo()
275
+
276
+
277
  if __name__ == "__main__":
278
+ demo.launch()