xizaoqu commited on
Commit
3e832e9
·
1 Parent(s): 4610cb2

after multi-frame gen

Browse files
algorithms/worldmem/df_video.py CHANGED
@@ -350,6 +350,7 @@ class WorldMemMinecraft(DiffusionForcingBase):
350
  self.focal_length = cfg.focal_length
351
  self.log_video = cfg.log_video
352
  self.self_consistency_eval = getattr(cfg, "self_consistency_eval", False)
 
353
 
354
  super().__init__(cfg)
355
 
@@ -576,7 +577,7 @@ class WorldMemMinecraft(DiffusionForcingBase):
576
  x = rearrange(x, "(t b) c h w-> t b c h w", t=total_frames)
577
  return x
578
 
579
- def _generate_condition_indices(self, curr_frame, condition_similar_length, xs_pred, pose_conditions, frame_idx):
580
  """
581
  Generate indices for condition similarity based on the current frame and pose conditions.
582
  """
@@ -592,17 +593,26 @@ class WorldMemMinecraft(DiffusionForcingBase):
592
  points += pose_conditions[curr_frame, :, :3][None]
593
  fov_half_h = torch.tensor(105 / 2, device=pose_conditions.device)
594
  fov_half_v = torch.tensor(75 / 2, device=pose_conditions.device)
595
- in_fov1 = is_inside_fov_3d_hv(
596
- points, pose_conditions[curr_frame, :, :3],
597
- pose_conditions[curr_frame, :, -2], pose_conditions[curr_frame, :, -1],
598
- fov_half_h, fov_half_v
599
- )
 
 
 
 
 
 
 
 
600
 
601
  # Compute overlap ratios and select indices
602
  in_fov_list = torch.stack([
603
  is_inside_fov_3d_hv(points, pc[:, :3], pc[:, -2], pc[:, -1], fov_half_h, fov_half_v)
604
  for pc in pose_conditions[:curr_frame]
605
  ])
 
606
  random_idx = []
607
  for _ in range(condition_similar_length):
608
  overlap_ratio = ((in_fov1.bool() & in_fov_list).sum(1)) / in_fov1.sum()
@@ -806,8 +816,8 @@ class WorldMemMinecraft(DiffusionForcingBase):
806
  new_actions = new_actions.to(device)
807
 
808
  curr_frame = 0
809
- horizon = 1
810
  batch_size = 1
 
811
  n_frames = curr_frame + horizon
812
  # context
813
  n_context_frames = len(self_frames)
@@ -816,24 +826,47 @@ class WorldMemMinecraft(DiffusionForcingBase):
816
 
817
  pbar = tqdm(total=n_frames, initial=curr_frame, desc="Sampling")
818
 
819
-
820
- for ai in range(len(new_actions)):
821
-
822
- last_frame = xs_pred[-1].clone()
823
- curr_actions = new_actions[ai]
824
- last_pose_condition = self_poses[-1].clone()
825
  last_pose_condition[:,3:] = last_pose_condition[:,3:] // 15
826
- new_pose_condition_offset = self.pose_prediction_model(last_frame.to(device), curr_actions[None], last_pose_condition)
827
-
828
  new_pose_condition_offset[:,3:] = torch.round(new_pose_condition_offset[:,3:])
829
  new_pose_condition = last_pose_condition + new_pose_condition_offset
830
  new_pose_condition[:,3:] = new_pose_condition[:,3:] * 15
831
  new_pose_condition[:,3:] %= 360
832
- self_actions = torch.cat([self_actions, curr_actions[None, None]])
833
- self_poses = torch.cat([self_poses, new_pose_condition[None]])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
834
  new_c2w_mat = euler_to_camera_to_world_matrix(new_pose_condition)
835
- self_memory_c2w = torch.cat([self_memory_c2w, new_c2w_mat[None]])
836
- self_frame_idx = torch.cat([self_frame_idx, torch.tensor([[self_frame_idx[-1,0]+1]]).to(device)])
 
 
 
837
 
838
  conditions = self_actions.clone()
839
  pose_conditions = self_poses.clone()
@@ -841,26 +874,26 @@ class WorldMemMinecraft(DiffusionForcingBase):
841
  frame_idx = self_frame_idx.clone()
842
 
843
  # generation on frame
844
- scheduling_matrix = self._generate_scheduling_matrix(horizon)
845
- chunk = torch.randn((horizon, batch_size, *xs_pred.shape[2:])).to(xs_pred.device)
846
  chunk = torch.clamp(chunk, -self.clip_noise, self.clip_noise)
847
 
848
  xs_pred = torch.cat([xs_pred, chunk], 0)
849
 
850
  # sliding window: only input the last n_tokens frames
851
- start_frame = max(0, curr_frame + horizon - self.n_tokens)
852
 
853
  pbar.set_postfix(
854
  {
855
  "start": start_frame,
856
- "end": curr_frame + horizon,
857
  }
858
  )
859
 
860
  # Handle condition similarity logic
861
  if condition_similar_length:
862
  random_idx = self._generate_condition_indices(
863
- curr_frame, condition_similar_length, xs_pred, pose_conditions, frame_idx
864
  )
865
 
866
  # random_idx = np.unique(random_idx)[:, None]
@@ -869,10 +902,13 @@ class WorldMemMinecraft(DiffusionForcingBase):
869
 
870
  # Prepare input conditions and pose conditions
871
  input_condition, input_pose_condition, frame_idx_list = self._prepare_conditions(
872
- start_frame, curr_frame, horizon, conditions, pose_conditions, c2w_mat, frame_idx, random_idx,
873
  image_width=first_frame.shape[-1], image_height=first_frame.shape[-2]
874
  )
875
 
 
 
 
876
  # Perform sampling for each step in the scheduling matrix
877
  for m in range(scheduling_matrix.shape[0] - 1):
878
  from_noise_levels, to_noise_levels = self._prepare_noise_levels(
@@ -891,12 +927,14 @@ class WorldMemMinecraft(DiffusionForcingBase):
891
  frame_idx=frame_idx_list
892
  ).cpu()
893
 
894
-
 
895
  if condition_similar_length:
896
  xs_pred = xs_pred[:-condition_similar_length]
897
 
898
- curr_frame += horizon
899
- pbar.update(horizon)
 
900
 
901
  self_frames = torch.cat([self_frames, xs_pred[n_context_frames:]])
902
  xs_pred = self.decode(xs_pred[n_context_frames:].to(device)).cpu()
 
350
  self.focal_length = cfg.focal_length
351
  self.log_video = cfg.log_video
352
  self.self_consistency_eval = getattr(cfg, "self_consistency_eval", False)
353
+ self.next_frame_length = cfg.next_frame_length
354
 
355
  super().__init__(cfg)
356
 
 
577
  x = rearrange(x, "(t b) c h w-> t b c h w", t=total_frames)
578
  return x
579
 
580
+ def _generate_condition_indices(self, curr_frame, condition_similar_length, xs_pred, pose_conditions, frame_idx, horizon):
581
  """
582
  Generate indices for condition similarity based on the current frame and pose conditions.
583
  """
 
593
  points += pose_conditions[curr_frame, :, :3][None]
594
  fov_half_h = torch.tensor(105 / 2, device=pose_conditions.device)
595
  fov_half_v = torch.tensor(75 / 2, device=pose_conditions.device)
596
+
597
+ # in_fov1 = is_inside_fov_3d_hv(
598
+ # points, pose_conditions[curr_frame, :, :3],
599
+ # pose_conditions[curr_frame, :, -2], pose_conditions[curr_frame, :, -1],
600
+ # fov_half_h, fov_half_v
601
+ # )
602
+
603
+ in_fov1 = torch.stack([
604
+ is_inside_fov_3d_hv(points, pc[:, :3], pc[:, -2], pc[:, -1], fov_half_h, fov_half_v)
605
+ for pc in pose_conditions[curr_frame:curr_frame+horizon]
606
+ ])
607
+
608
+ in_fov1 = torch.sum(in_fov1, 0) > 0
609
 
610
  # Compute overlap ratios and select indices
611
  in_fov_list = torch.stack([
612
  is_inside_fov_3d_hv(points, pc[:, :3], pc[:, -2], pc[:, -1], fov_half_h, fov_half_v)
613
  for pc in pose_conditions[:curr_frame]
614
  ])
615
+
616
  random_idx = []
617
  for _ in range(condition_similar_length):
618
  overlap_ratio = ((in_fov1.bool() & in_fov_list).sum(1)) / in_fov1.sum()
 
816
  new_actions = new_actions.to(device)
817
 
818
  curr_frame = 0
 
819
  batch_size = 1
820
+ horizon = self.next_frame_length
821
  n_frames = curr_frame + horizon
822
  # context
823
  n_context_frames = len(self_frames)
 
826
 
827
  pbar = tqdm(total=n_frames, initial=curr_frame, desc="Sampling")
828
 
829
+ new_pose_condition_list = []
830
+ last_frame = xs_pred[-1].clone()
831
+ last_pose_condition = self_poses[-1].clone()
832
+ curr_actions = new_actions.clone()
833
+ for hi in range(len(new_actions)):
 
834
  last_pose_condition[:,3:] = last_pose_condition[:,3:] // 15
835
+ new_pose_condition_offset = self.pose_prediction_model(last_frame.to(device), curr_actions[None, hi], last_pose_condition)
 
836
  new_pose_condition_offset[:,3:] = torch.round(new_pose_condition_offset[:,3:])
837
  new_pose_condition = last_pose_condition + new_pose_condition_offset
838
  new_pose_condition[:,3:] = new_pose_condition[:,3:] * 15
839
  new_pose_condition[:,3:] %= 360
840
+ last_pose_condition = new_pose_condition.clone()
841
+ new_pose_condition_list.append(new_pose_condition[None])
842
+ new_pose_condition_list = torch.cat(new_pose_condition_list, 0)
843
+
844
+ ai = 0
845
+ while ai < len(new_actions):
846
+ next_horizon = min(horizon, len(new_actions) - ai)
847
+ last_frame = xs_pred[-1].clone()
848
+ curr_actions = new_actions[ai:ai+next_horizon].clone()
849
+
850
+ # last_pose_condition = self_poses[-1].clone()
851
+ # new_pose_condition_list = []
852
+ # for hi in range(next_horizon):
853
+ # last_pose_condition[:,3:] = last_pose_condition[:,3:] // 15
854
+ # new_pose_condition_offset = self.pose_prediction_model(last_frame.to(device), curr_actions[None, hi], last_pose_condition)
855
+ # new_pose_condition_offset[:,3:] = torch.round(new_pose_condition_offset[:,3:])
856
+ # new_pose_condition = last_pose_condition + new_pose_condition_offset
857
+ # new_pose_condition[:,3:] = new_pose_condition[:,3:] * 15
858
+ # new_pose_condition[:,3:] %= 360
859
+ # last_pose_condition = new_pose_condition.clone()
860
+ # new_pose_condition_list.append(new_pose_condition[None])
861
+ # new_pose_condition = torch.cat(new_pose_condition_list, 0)
862
+ new_pose_condition = new_pose_condition_list[ai:ai+next_horizon].clone()
863
+
864
  new_c2w_mat = euler_to_camera_to_world_matrix(new_pose_condition)
865
+ self_poses = torch.cat([self_poses, new_pose_condition])
866
+ self_actions = torch.cat([self_actions, curr_actions[:, None]])
867
+ self_memory_c2w = torch.cat([self_memory_c2w, new_c2w_mat])
868
+ new_indices = self_frame_idx[-1,0] + torch.arange(next_horizon, device=self_frame_idx.device)
869
+ self_frame_idx = torch.cat([self_frame_idx, new_indices[:, None]])
870
 
871
  conditions = self_actions.clone()
872
  pose_conditions = self_poses.clone()
 
874
  frame_idx = self_frame_idx.clone()
875
 
876
  # generation on frame
877
+ scheduling_matrix = self._generate_scheduling_matrix(next_horizon)
878
+ chunk = torch.randn((next_horizon, batch_size, *xs_pred.shape[2:])).to(xs_pred.device)
879
  chunk = torch.clamp(chunk, -self.clip_noise, self.clip_noise)
880
 
881
  xs_pred = torch.cat([xs_pred, chunk], 0)
882
 
883
  # sliding window: only input the last n_tokens frames
884
+ start_frame = max(0, curr_frame - self.n_tokens)
885
 
886
  pbar.set_postfix(
887
  {
888
  "start": start_frame,
889
+ "end": curr_frame + next_horizon,
890
  }
891
  )
892
 
893
  # Handle condition similarity logic
894
  if condition_similar_length:
895
  random_idx = self._generate_condition_indices(
896
+ curr_frame, condition_similar_length, xs_pred, pose_conditions, frame_idx, next_horizon
897
  )
898
 
899
  # random_idx = np.unique(random_idx)[:, None]
 
902
 
903
  # Prepare input conditions and pose conditions
904
  input_condition, input_pose_condition, frame_idx_list = self._prepare_conditions(
905
+ start_frame, curr_frame, next_horizon, conditions, pose_conditions, c2w_mat, frame_idx, random_idx,
906
  image_width=first_frame.shape[-1], image_height=first_frame.shape[-2]
907
  )
908
 
909
+ from time import time
910
+ start_time = time()
911
+
912
  # Perform sampling for each step in the scheduling matrix
913
  for m in range(scheduling_matrix.shape[0] - 1):
914
  from_noise_levels, to_noise_levels = self._prepare_noise_levels(
 
927
  frame_idx=frame_idx_list
928
  ).cpu()
929
 
930
+ end_time = time()
931
+ print(f"Time taken for {next_horizon} frames: {end_time - start_time:.2f} seconds")
932
  if condition_similar_length:
933
  xs_pred = xs_pred[:-condition_similar_length]
934
 
935
+ curr_frame += next_horizon
936
+ pbar.update(next_horizon)
937
+ ai += next_horizon
938
 
939
  self_frames = torch.cat([self_frames, xs_pred[n_context_frames:]])
940
  xs_pred = self.decode(xs_pred[n_context_frames:].to(device)).cpu()
app.py CHANGED
@@ -243,6 +243,12 @@ def set_memory_length(memory_length, sampling_memory_length_state):
243
  print("set memory length to", worldmem.condition_similar_length)
244
  return sampling_memory_length_state
245
 
 
 
 
 
 
 
246
  def generate(keys, input_history, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx):
247
  input_actions = parse_input_to_tensor(keys)
248
 
@@ -321,7 +327,8 @@ def reset(selected_image):
321
  self_actions=self_actions,
322
  self_poses=self_poses,
323
  self_memory_c2w=self_memory_c2w,
324
- self_frame_idx=self_frame_idx)
 
325
 
326
  return input_history, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx
327
 
@@ -329,7 +336,7 @@ def on_image_click(selected_image):
329
  input_history, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx = reset(selected_image)
330
  return input_history, selected_image, selected_image, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx
331
 
332
- def set_memory(examples_case, image_display, log_output, slider_denoising_step, slider_context_length, slider_memory_length):
333
  if examples_case == '1':
334
  data_bundle = np.load("assets/examples/case1.npz")
335
  input_history = data_bundle['input_history'].item()
@@ -511,11 +518,16 @@ with gr.Blocks(css=css) as demo:
511
  label="Memory Length",
512
  info="How many previous frames in memory window."
513
  )
514
-
 
 
 
 
515
 
516
  sampling_timesteps_state = gr.State(worldmem.sampling_timesteps)
517
  sampling_context_length_state = gr.State(worldmem.n_tokens)
518
  sampling_memory_length_state = gr.State(worldmem.condition_similar_length)
 
519
 
520
  memory_frames = gr.State(load_image_as_tensor(selected_image.value)[None].numpy())
521
  self_frames = gr.State()
@@ -545,11 +557,16 @@ with gr.Blocks(css=css) as demo:
545
 
546
  example_case.change(
547
  fn=set_memory,
548
- inputs=[example_case, image_output, log_output, slider_denoising_step, slider_context_length, slider_memory_length],
549
  outputs=[log_output, image_display, video_display, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx]
550
  )
551
 
552
- submit_button.click(generate, inputs=[input_box, log_output, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx], outputs=[image_display, video_display, log_output, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx])
 
 
 
 
 
553
  reset_btn.click(reset, inputs=[selected_image], outputs=[log_output, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx])
554
  image_display_1.select(lambda: on_image_click(SUNFLOWERS_IMAGE), outputs=[log_output, selected_image, image_display, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx])
555
  image_display_2.select(lambda: on_image_click(DESERT_IMAGE), outputs=[log_output, selected_image, image_display, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx])
@@ -561,5 +578,6 @@ with gr.Blocks(css=css) as demo:
561
  slider_denoising_step.change(fn=set_denoising_steps, inputs=[slider_denoising_step, sampling_timesteps_state], outputs=sampling_timesteps_state)
562
  slider_context_length.change(fn=set_context_length, inputs=[slider_context_length, sampling_context_length_state], outputs=sampling_context_length_state)
563
  slider_memory_length.change(fn=set_memory_length, inputs=[slider_memory_length, sampling_memory_length_state], outputs=sampling_memory_length_state)
 
564
 
565
  demo.launch()
 
243
  print("set memory length to", worldmem.condition_similar_length)
244
  return sampling_memory_length_state
245
 
246
+ def set_next_frame_length(next_frame_length, sampling_next_frame_length_state):
247
+ worldmem.next_frame_length = next_frame_length
248
+ sampling_next_frame_length_state = next_frame_length
249
+ print("set next frame length to", worldmem.next_frame_length)
250
+ return sampling_next_frame_length_state
251
+
252
  def generate(keys, input_history, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx):
253
  input_actions = parse_input_to_tensor(keys)
254
 
 
327
  self_actions=self_actions,
328
  self_poses=self_poses,
329
  self_memory_c2w=self_memory_c2w,
330
+ self_frame_idx=self_frame_idx,
331
+ )
332
 
333
  return input_history, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx
334
 
 
336
  input_history, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx = reset(selected_image)
337
  return input_history, selected_image, selected_image, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx
338
 
339
+ def set_memory(examples_case):
340
  if examples_case == '1':
341
  data_bundle = np.load("assets/examples/case1.npz")
342
  input_history = data_bundle['input_history'].item()
 
518
  label="Memory Length",
519
  info="How many previous frames in memory window."
520
  )
521
+ slider_next_frame_length = gr.Slider(
522
+ minimum=1, maximum=5, value=worldmem.next_frame_length, step=1,
523
+ label="Next Frame Length",
524
+ info="How many next frames to generate at once."
525
+ )
526
 
527
  sampling_timesteps_state = gr.State(worldmem.sampling_timesteps)
528
  sampling_context_length_state = gr.State(worldmem.n_tokens)
529
  sampling_memory_length_state = gr.State(worldmem.condition_similar_length)
530
+ sampling_next_frame_length_state = gr.State(worldmem.next_frame_length)
531
 
532
  memory_frames = gr.State(load_image_as_tensor(selected_image.value)[None].numpy())
533
  self_frames = gr.State()
 
557
 
558
  example_case.change(
559
  fn=set_memory,
560
+ inputs=[example_case],
561
  outputs=[log_output, image_display, video_display, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx]
562
  )
563
 
564
+ submit_button.click(generate, inputs=[input_box, log_output, memory_frames,
565
+ self_frames, self_actions, self_poses,
566
+ self_memory_c2w, self_frame_idx],
567
+ outputs=[image_display, video_display, log_output,
568
+ memory_frames, self_frames, self_actions, self_poses,
569
+ self_memory_c2w, self_frame_idx])
570
  reset_btn.click(reset, inputs=[selected_image], outputs=[log_output, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx])
571
  image_display_1.select(lambda: on_image_click(SUNFLOWERS_IMAGE), outputs=[log_output, selected_image, image_display, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx])
572
  image_display_2.select(lambda: on_image_click(DESERT_IMAGE), outputs=[log_output, selected_image, image_display, memory_frames, self_frames, self_actions, self_poses, self_memory_c2w, self_frame_idx])
 
578
  slider_denoising_step.change(fn=set_denoising_steps, inputs=[slider_denoising_step, sampling_timesteps_state], outputs=sampling_timesteps_state)
579
  slider_context_length.change(fn=set_context_length, inputs=[slider_context_length, sampling_context_length_state], outputs=sampling_context_length_state)
580
  slider_memory_length.change(fn=set_memory_length, inputs=[slider_memory_length, sampling_memory_length_state], outputs=sampling_memory_length_state)
581
+ slider_next_frame_length.change(fn=set_next_frame_length, inputs=[slider_next_frame_length, sampling_next_frame_length_state], outputs=sampling_next_frame_length_state)
582
 
583
  demo.launch()
configurations/huggingface.yaml CHANGED
@@ -48,11 +48,12 @@ frame_stack: 1
48
  uncertainty_scale: 1
49
  guidance_scale: 0.0
50
  chunk_size: 1 # -1 for full trajectory diffusion, number to specify diffusion chunk size
51
- scheduling_matrix: autoregressive
52
  noise_level: random_all
53
  causal: True
54
  x_shape: [3, 360, 640]
55
  context_frames: 1
56
- diffusion_path: /mnt/xiaozeqi/worldmem_github/diffusion_only_2025-04-04_4-56-27_epoch1step560000.ckpt
57
  vae_path: yslan/worldmem_checkpoints/vae_only.ckpt
58
  pose_predictor_path: yslan/worldmem_checkpoints/pose_prediction_model_only.ckpt
 
 
48
  uncertainty_scale: 1
49
  guidance_scale: 0.0
50
  chunk_size: 1 # -1 for full trajectory diffusion, number to specify diffusion chunk size
51
+ scheduling_matrix: full_sequence
52
  noise_level: random_all
53
  causal: True
54
  x_shape: [3, 360, 640]
55
  context_frames: 1
56
+ diffusion_path: /mnt/xiaozeqi/worldmem_github/diffusion_only_2025-04-06-16-24-11_epoch1step720000.ckpt
57
  vae_path: yslan/worldmem_checkpoints/vae_only.ckpt
58
  pose_predictor_path: yslan/worldmem_checkpoints/pose_prediction_model_only.ckpt
59
+ next_frame_length: 1