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 |
-
|
| 1169 |
-
|
| 1170 |
-
|
| 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)
|