StackNobel commited on
Commit
f7abb67
·
verified ·
1 Parent(s): db87e13

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -36
app.py CHANGED
@@ -135,8 +135,6 @@ def interpolate_bits(frames_np, multiplier=2, scale=1.0):
135
 
136
  # Handle input shape
137
  if isinstance(frames_np, list):
138
- # Convert list of arrays to one big array for easier shape handling if needed,
139
- # but here we just grab dims from first frame
140
  T = len(frames_np)
141
  H, W, C = frames_np[0].shape
142
  else:
@@ -144,7 +142,6 @@ def interpolate_bits(frames_np, multiplier=2, scale=1.0):
144
 
145
  # 1. No Interpolation Case
146
  if multiplier < 2:
147
- # Just convert 4D array to list of 3D arrays
148
  if isinstance(frames_np, np.ndarray):
149
  return list(frames_np)
150
  return frames_np
@@ -159,19 +156,14 @@ def interpolate_bits(frames_np, multiplier=2, scale=1.0):
159
 
160
  # Helper: Numpy (H, W, C) Float -> Tensor (1, C, H, W) Half
161
  def to_tensor(frame_np):
162
- # frame_np is float32 0-1
163
  t = torch.from_numpy(frame_np).to(device)
164
- # HWC -> CHW
165
  t = t.permute(2, 0, 1).unsqueeze(0)
166
  return F.pad(t, padding).half()
167
 
168
  # Helper: Tensor (1, C, H, W) Half -> Numpy (H, W, C) Float
169
  def from_tensor(tensor):
170
- # Crop padding
171
  t = tensor[0, :, :H, :W]
172
- # CHW -> HWC
173
  t = t.permute(1, 2, 0)
174
- # Keep as float32, range 0-1
175
  return t.float().cpu().numpy()
176
 
177
  def make_inference(I0, I1, n):
@@ -194,25 +186,17 @@ def interpolate_bits(frames_np, multiplier=2, scale=1.0):
194
  output_frames =[]
195
 
196
  # Process Frames
197
- # Load first frame into GPU
198
  I1 = to_tensor(frames_np[0])
199
-
200
  total_steps = T - 1
201
 
202
  with tqdm(total=total_steps, desc="Interpolating", unit="frame") as pbar:
203
-
204
  for i in range(total_steps):
205
  I0 = I1
206
- # Add original frame to output
207
  output_frames.append(from_tensor(I0))
208
 
209
- # Load next frame
210
  I1 = to_tensor(frames_np[i+1])
211
-
212
- # Generate intermediate frames
213
  mid_tensors = make_inference(I0, I1, n_interp)
214
 
215
- # Append intermediate frames
216
  for mid in mid_tensors:
217
  output_frames.append(from_tensor(mid))
218
 
@@ -220,7 +204,6 @@ def interpolate_bits(frames_np, multiplier=2, scale=1.0):
220
  pbar.update(50)
221
  pbar.update(total_steps % 50)
222
 
223
- # Add the very last frame
224
  output_frames.append(from_tensor(I1))
225
 
226
  # Cleanup
@@ -264,21 +247,10 @@ pipe = WanImageToVideoPipeline.from_pretrained(
264
  ).to('cuda')
265
  original_scheduler = copy.deepcopy(pipe.scheduler)
266
 
267
- # if os.path.exists(CACHE_DIR):
268
- # shutil.rmtree(CACHE_DIR)
269
- # print("Deleted Hugging Face cache.")
270
- # else:
271
- # print("No hub cache found.")
272
-
273
  quantize_(pipe.text_encoder, Int8WeightOnlyConfig())
274
  quantize_(pipe.transformer, Float8DynamicActivationFloat8WeightConfig())
275
  quantize_(pipe.transformer_2, Float8DynamicActivationFloat8WeightConfig())
276
 
277
- # aoti.aoti_blocks_load(pipe.transformer, 'zerogpu-aoti/Wan2', variant='fp8da')
278
- # aoti.aoti_blocks_load(pipe.transformer_2, 'zerogpu-aoti/Wan2', variant='fp8da')
279
-
280
- # pipe.vae.enable_slicing()
281
- # pipe.vae.enable_tiling()
282
 
283
  default_prompt_i2v = "make this image come alive, cinematic motion, smooth animation"
284
  default_negative_prompt = "色调艳丽, 过曝, 静态, 细节模糊不清, 字幕, 风格, 作品, 画作, 画面, 静止, 整体发灰, 最差质量, 低质量, JPEG压缩残留, 丑陋的, 残缺的, 多余的手指, 画得不好的手部, 画得不好的脸部, 畸形的, 毁容的, 形态畸形的肢体, 手指融合, 静止不动的画面, 杂乱的背景, 三条腿, 背景人很多, 倒着走"
@@ -382,7 +354,6 @@ def get_inference_duration(
382
  return total_time
383
 
384
 
385
-
386
  @spaces.GPU(duration=get_inference_duration, size='xlarge')
387
  def run_inference(
388
  resized_image,
@@ -431,7 +402,7 @@ def run_inference(
431
  output_type="np"
432
  )
433
 
434
- raw_frames_np = result.frames[0] # Returns (T, H, W, C) float32
435
  pipe.scheduler = original_scheduler
436
 
437
  frame_factor = frame_multiplier // FIXED_FPS
@@ -568,17 +539,55 @@ with gr.Blocks(theme=gr.themes.Soft(), css=CSS, delete_cache=(3600, 3700)) as de
568
  generate_button = gr.Button("Generate Video", variant="primary")
569
 
570
  with gr.Column():
571
- # ASSIGNED elem_id="generated-video" so JS can find it
572
  video_output = gr.Video(label="Generated Video", autoplay=True, sources=["upload"], show_download_button=True, show_share_button=True, interactive=False, elem_id="generated-video")
573
 
574
- # --- Frame Grabbing UI ---
575
  with gr.Row():
576
  grab_frame_btn = gr.Button("📸 Use Current Frame as Input", variant="secondary")
577
  timestamp_box = gr.Number(value=0, label="Timestamp", visible=True, elem_id="hidden-timestamp")
578
- # -------------------------
579
 
580
  file_output = gr.File(label="Download Video")
581
 
582
- ui_inputs =[
583
- input_image_component, last_image_component, prompt_input, steps_slider,
584
- neg
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
  # Handle input shape
137
  if isinstance(frames_np, list):
 
 
138
  T = len(frames_np)
139
  H, W, C = frames_np[0].shape
140
  else:
 
142
 
143
  # 1. No Interpolation Case
144
  if multiplier < 2:
 
145
  if isinstance(frames_np, np.ndarray):
146
  return list(frames_np)
147
  return frames_np
 
156
 
157
  # Helper: Numpy (H, W, C) Float -> Tensor (1, C, H, W) Half
158
  def to_tensor(frame_np):
 
159
  t = torch.from_numpy(frame_np).to(device)
 
160
  t = t.permute(2, 0, 1).unsqueeze(0)
161
  return F.pad(t, padding).half()
162
 
163
  # Helper: Tensor (1, C, H, W) Half -> Numpy (H, W, C) Float
164
  def from_tensor(tensor):
 
165
  t = tensor[0, :, :H, :W]
 
166
  t = t.permute(1, 2, 0)
 
167
  return t.float().cpu().numpy()
168
 
169
  def make_inference(I0, I1, n):
 
186
  output_frames =[]
187
 
188
  # Process Frames
 
189
  I1 = to_tensor(frames_np[0])
 
190
  total_steps = T - 1
191
 
192
  with tqdm(total=total_steps, desc="Interpolating", unit="frame") as pbar:
 
193
  for i in range(total_steps):
194
  I0 = I1
 
195
  output_frames.append(from_tensor(I0))
196
 
 
197
  I1 = to_tensor(frames_np[i+1])
 
 
198
  mid_tensors = make_inference(I0, I1, n_interp)
199
 
 
200
  for mid in mid_tensors:
201
  output_frames.append(from_tensor(mid))
202
 
 
204
  pbar.update(50)
205
  pbar.update(total_steps % 50)
206
 
 
207
  output_frames.append(from_tensor(I1))
208
 
209
  # Cleanup
 
247
  ).to('cuda')
248
  original_scheduler = copy.deepcopy(pipe.scheduler)
249
 
 
 
 
 
 
 
250
  quantize_(pipe.text_encoder, Int8WeightOnlyConfig())
251
  quantize_(pipe.transformer, Float8DynamicActivationFloat8WeightConfig())
252
  quantize_(pipe.transformer_2, Float8DynamicActivationFloat8WeightConfig())
253
 
 
 
 
 
 
254
 
255
  default_prompt_i2v = "make this image come alive, cinematic motion, smooth animation"
256
  default_negative_prompt = "色调艳丽, 过曝, 静态, 细节模糊不清, 字幕, 风格, 作品, 画作, 画面, 静止, 整体发灰, 最差质量, 低质量, JPEG压缩残留, 丑陋的, 残缺的, 多余的手指, 画得不好的手部, 画得不好的脸部, 畸形的, 毁容的, 形态畸形的肢体, 手指融合, 静止不动的画面, 杂乱的背景, 三条腿, 背景人很多, 倒着走"
 
354
  return total_time
355
 
356
 
 
357
  @spaces.GPU(duration=get_inference_duration, size='xlarge')
358
  def run_inference(
359
  resized_image,
 
402
  output_type="np"
403
  )
404
 
405
+ raw_frames_np = result.frames[0]
406
  pipe.scheduler = original_scheduler
407
 
408
  frame_factor = frame_multiplier // FIXED_FPS
 
539
  generate_button = gr.Button("Generate Video", variant="primary")
540
 
541
  with gr.Column():
 
542
  video_output = gr.Video(label="Generated Video", autoplay=True, sources=["upload"], show_download_button=True, show_share_button=True, interactive=False, elem_id="generated-video")
543
 
 
544
  with gr.Row():
545
  grab_frame_btn = gr.Button("📸 Use Current Frame as Input", variant="secondary")
546
  timestamp_box = gr.Number(value=0, label="Timestamp", visible=True, elem_id="hidden-timestamp")
 
547
 
548
  file_output = gr.File(label="Download Video")
549
 
550
+ ui_inputs = [
551
+ input_image_component,
552
+ last_image_component,
553
+ prompt_input,
554
+ steps_slider,
555
+ negative_prompt_input,
556
+ duration_seconds_input,
557
+ guidance_scale_input,
558
+ guidance_scale_2_input,
559
+ seed_input,
560
+ randomize_seed_checkbox,
561
+ quality_slider,
562
+ scheduler_dropdown,
563
+ flow_shift_slider,
564
+ frame_multi,
565
+ play_result_video,
566
+ safe_mode_checkbox
567
+ ]
568
+
569
+ generate_button.click(
570
+ fn=generate_video,
571
+ inputs=ui_inputs,
572
+ outputs=[video_output, file_output, seed_input]
573
+ )
574
+
575
+ grab_frame_btn.click(
576
+ fn=None,
577
+ inputs=None,
578
+ outputs=[timestamp_box],
579
+ js=get_timestamp_js
580
+ )
581
+
582
+ timestamp_box.change(
583
+ fn=extract_frame,
584
+ inputs=[video_output, timestamp_box],
585
+ outputs=[input_image_component]
586
+ )
587
+
588
+ if __name__ == "__main__":
589
+ demo.queue().launch(
590
+ mcp_server=True,
591
+ ssr_mode=False,
592
+ show_error=True,
593
+ )