BonanDing commited on
Commit
8904839
·
1 Parent(s): 7aed17d

Fail fast for DeMemWM interactive path

Browse files
algorithms/dememwm/df_video.py CHANGED
@@ -1164,137 +1164,7 @@ class DeMemWMMinecraft(DiffusionForcingBase):
1164
  @torch.no_grad()
1165
  def interactive(self, first_frame, new_actions, first_pose, device,
1166
  memory_latent_frames, memory_actions, memory_poses, memory_c2w, memory_frame_idx):
1167
-
1168
- memory_condition_length = self.memory_condition_length
1169
-
1170
- if memory_latent_frames is None:
1171
- first_frame = torch.from_numpy(first_frame)
1172
- new_actions = torch.from_numpy(new_actions)
1173
- first_pose = torch.from_numpy(first_pose)
1174
- first_frame_encode = self.encode(first_frame[None, None].to(device))
1175
- memory_latent_frames = first_frame_encode.cpu()
1176
- memory_actions = new_actions[None, None].to(device)
1177
- memory_poses = first_pose[None, None].to(device)
1178
- new_c2w_mat = euler_to_camera_to_world_matrix(first_pose)
1179
- memory_c2w = new_c2w_mat[None, None].to(device)
1180
- memory_frame_idx = torch.tensor([[0]]).to(device)
1181
- return first_frame.cpu().numpy(), memory_latent_frames.cpu().numpy(), memory_actions.cpu().numpy(), memory_poses.cpu().numpy(), memory_c2w.cpu().numpy(), memory_frame_idx.cpu().numpy()
1182
- else:
1183
- memory_latent_frames = torch.from_numpy(memory_latent_frames)
1184
- memory_actions = torch.from_numpy(memory_actions).to(device)
1185
- memory_poses = torch.from_numpy(memory_poses).to(device)
1186
- memory_c2w = torch.from_numpy(memory_c2w).to(device)
1187
- memory_frame_idx = torch.from_numpy(memory_frame_idx).to(device)
1188
- new_actions = new_actions.to(device)
1189
-
1190
- curr_frame = 0
1191
- batch_size = 1
1192
- horizon = self.next_frame_length
1193
- n_frames = curr_frame + horizon
1194
- # context
1195
- n_context_frames = len(memory_latent_frames)
1196
- xs_pred = memory_latent_frames[:n_context_frames].clone()
1197
- curr_frame += n_context_frames
1198
-
1199
- pbar = tqdm(total=n_frames, initial=curr_frame, desc="Sampling")
1200
-
1201
- new_pose_condition_list = []
1202
- last_frame = xs_pred[-1].clone()
1203
- last_pose_condition = memory_poses[-1].clone()
1204
- curr_actions = new_actions.clone()
1205
- for hi in range(len(new_actions)):
1206
- last_pose_condition[:,3:] = last_pose_condition[:,3:] // 15
1207
- new_pose_condition_offset = self.pose_prediction_model(last_frame.to(device), curr_actions[None, hi], last_pose_condition)
1208
- new_pose_condition_offset[:,3:] = torch.round(new_pose_condition_offset[:,3:])
1209
- new_pose_condition = last_pose_condition + new_pose_condition_offset
1210
- new_pose_condition[:,3:] = new_pose_condition[:,3:] * 15
1211
- new_pose_condition[:,3:] %= 360
1212
- last_pose_condition = new_pose_condition.clone()
1213
- new_pose_condition_list.append(new_pose_condition[None])
1214
- new_pose_condition_list = torch.cat(new_pose_condition_list, 0)
1215
-
1216
- ai = 0
1217
- while ai < len(new_actions):
1218
- next_horizon = min(horizon, len(new_actions) - ai)
1219
- last_frame = xs_pred[-1].clone()
1220
- curr_actions = new_actions[ai:ai+next_horizon].clone()
1221
-
1222
- new_pose_condition = new_pose_condition_list[ai:ai+next_horizon].clone()
1223
-
1224
- new_c2w_mat = euler_to_camera_to_world_matrix(new_pose_condition)
1225
- memory_poses = torch.cat([memory_poses, new_pose_condition])
1226
- memory_actions = torch.cat([memory_actions, curr_actions[:, None]])
1227
- memory_c2w = torch.cat([memory_c2w, new_c2w_mat])
1228
- new_indices = memory_frame_idx[-1,0] + torch.arange(next_horizon, device=memory_frame_idx.device) + 1
1229
-
1230
- memory_frame_idx = torch.cat([memory_frame_idx, new_indices[:, None]])
1231
-
1232
- conditions = memory_actions.clone()
1233
- pose_conditions = memory_poses.clone()
1234
- c2w_mat = memory_c2w .clone()
1235
- frame_idx = memory_frame_idx.clone()
1236
-
1237
- # generation on frame
1238
- scheduling_matrix = self._generate_scheduling_matrix(next_horizon)
1239
- chunk = torch.randn((next_horizon, batch_size, *xs_pred.shape[2:])).to(xs_pred.device)
1240
- chunk = torch.clamp(chunk, -self.clip_noise, self.clip_noise)
1241
-
1242
- xs_pred = torch.cat([xs_pred, chunk], 0)
1243
-
1244
- # sliding window: only input the last n_tokens frames
1245
- start_frame = max(0, curr_frame - self.n_tokens)
1246
-
1247
- pbar.set_postfix(
1248
- {
1249
- "start": start_frame,
1250
- "end": curr_frame + next_horizon,
1251
- }
1252
- )
1253
-
1254
- # Handle condition similarity logic
1255
- if memory_condition_length:
1256
- random_idx = self._generate_condition_indices(
1257
- curr_frame, memory_condition_length, xs_pred, pose_conditions, frame_idx, next_horizon
1258
- )
1259
-
1260
- # random_idx = np.unique(random_idx)[:, None]
1261
- # memory_condition_length = len(random_idx)
1262
- xs_pred = torch.cat([xs_pred, xs_pred[random_idx[:, range(xs_pred.shape[1])], range(xs_pred.shape[1])].clone()], 0)
1263
-
1264
- # Prepare input conditions and pose conditions
1265
- input_condition, input_pose_condition, frame_idx_list = self._prepare_conditions(
1266
- start_frame, curr_frame, next_horizon, conditions, pose_conditions, c2w_mat, frame_idx, random_idx,
1267
- image_width=first_frame.shape[-1], image_height=first_frame.shape[-2]
1268
- )
1269
-
1270
- # Perform sampling for each step in the scheduling matrix
1271
- for m in range(scheduling_matrix.shape[0] - 1):
1272
- from_noise_levels, to_noise_levels = self._prepare_noise_levels(
1273
- scheduling_matrix, m, curr_frame, batch_size, memory_condition_length
1274
- )
1275
-
1276
- xs_pred[start_frame:] = self.diffusion_model.sample_step(
1277
- xs_pred[start_frame:].to(input_condition.device),
1278
- input_condition,
1279
- input_pose_condition,
1280
- from_noise_levels[start_frame:],
1281
- to_noise_levels[start_frame:],
1282
- current_frame=curr_frame,
1283
- mode="validation",
1284
- reference_length=memory_condition_length,
1285
- frame_idx=frame_idx_list
1286
- ).cpu()
1287
-
1288
-
1289
- if memory_condition_length:
1290
- xs_pred = xs_pred[:-memory_condition_length]
1291
-
1292
- curr_frame += next_horizon
1293
- pbar.update(next_horizon)
1294
- ai += next_horizon
1295
-
1296
- memory_latent_frames = torch.cat([memory_latent_frames, xs_pred[n_context_frames:]])
1297
- xs_pred = self.decode(xs_pred[n_context_frames:].to(device)).cpu()
1298
-
1299
- return xs_pred.cpu().numpy(), memory_latent_frames.cpu().numpy(), memory_actions.cpu().numpy(), \
1300
- memory_poses.cpu().numpy(), memory_c2w.cpu().numpy(), memory_frame_idx.cpu().numpy()
 
1164
  @torch.no_grad()
1165
  def interactive(self, first_frame, new_actions, first_pose, device,
1166
  memory_latent_frames, memory_actions, memory_poses, memory_c2w, memory_frame_idx):
1167
+ raise NotImplementedError(
1168
+ "DeMemWM interactive generation is unsupported until it uses the packed "
1169
+ "[target][anchor][dynamic][revisit] frame-memory API."
1170
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tests/test_dememwm_latent_dataset.py CHANGED
@@ -596,6 +596,12 @@ class DeMemWMLatentDatasetTests(unittest.TestCase):
596
  self.assertEqual(calls[2]["kwargs"]["frame_memory_masks"]["revisit"].tolist(), [[True]])
597
  self.assertAlmostEqual(float(loss), 1.0 / 3.0)
598
 
 
 
 
 
 
 
599
  def test_dataset_returns_target_anchor_dynamic_revisit_contract(self):
600
  with tempfile.TemporaryDirectory() as tmp:
601
  root = Path(tmp)
 
596
  self.assertEqual(calls[2]["kwargs"]["frame_memory_masks"]["revisit"].tolist(), [[True]])
597
  self.assertAlmostEqual(float(loss), 1.0 / 3.0)
598
 
599
+ def test_interactive_generation_fails_until_packed_memory_path_exists(self):
600
+ from algorithms.dememwm.df_video import DeMemWMMinecraft
601
+
602
+ with self.assertRaisesRegex(NotImplementedError, "packed .* frame-memory API"):
603
+ DeMemWMMinecraft.interactive(object(), None, None, None, None, None, None, None, None, None)
604
+
605
  def test_dataset_returns_target_anchor_dynamic_revisit_contract(self):
606
  with tempfile.TemporaryDirectory() as tmp:
607
  root = Path(tmp)