BonanDing commited on
Commit
b9efa38
·
1 Parent(s): efb241a

Add DeMemWM model acceptance checks

Browse files
algorithms/dememwm/models/dit.py CHANGED
@@ -400,6 +400,7 @@ class SpatioTemporalDiTBlock(nn.Module):
400
  frame_memory_geometry,
401
  )
402
  elif self.use_memory_attention:
 
403
  r_shift_msa, r_scale_msa, r_gate_msa, r_shift_mlp, r_scale_mlp, r_gate_mlp = self.r_adaLN_modulation(c).chunk(6, dim=-1)
404
 
405
  if pose_cond is not None:
@@ -443,12 +444,12 @@ class SpatioTemporalDiTBlock(nn.Module):
443
  else:
444
  # pose_cond *= 0
445
  x = x + gate(self.r_attn(modulate(self.r_norm1(x+pose_cond[:,:,None, None]), r_shift_msa, r_scale_msa),
446
- current_frame=current_frame, timestep=timestep,
447
- is_last_block=is_last_block,
448
  reference_length=reference_length), r_gate_msa)
449
  else:
450
- x = x + gate(self.r_attn(modulate(self.r_norm1(x), r_shift_msa, r_scale_msa), current_frame=current_frame, timestep=timestep,
451
- is_last_block=is_last_block), r_gate_msa)
 
 
452
 
453
  x = x + gate(self.r_mlp(modulate(self.r_norm2(x), r_shift_mlp, r_scale_mlp)), r_gate_mlp)
454
 
 
400
  frame_memory_geometry,
401
  )
402
  elif self.use_memory_attention:
403
+ reference_length = self.reference_length if reference_length is None else reference_length
404
  r_shift_msa, r_scale_msa, r_gate_msa, r_shift_mlp, r_scale_mlp, r_gate_mlp = self.r_adaLN_modulation(c).chunk(6, dim=-1)
405
 
406
  if pose_cond is not None:
 
444
  else:
445
  # pose_cond *= 0
446
  x = x + gate(self.r_attn(modulate(self.r_norm1(x+pose_cond[:,:,None, None]), r_shift_msa, r_scale_msa),
 
 
447
  reference_length=reference_length), r_gate_msa)
448
  else:
449
+ x = x + gate(self.r_attn(
450
+ modulate(self.r_norm1(x), r_shift_msa, r_scale_msa),
451
+ reference_length=reference_length,
452
+ ), r_gate_msa)
453
 
454
  x = x + gate(self.r_mlp(modulate(self.r_norm2(x), r_shift_mlp, r_scale_mlp)), r_gate_mlp)
455
 
tests/test_dememwm_diffusion.py CHANGED
@@ -106,6 +106,31 @@ class DeMemWMDiffusionTargetOnlyTests(unittest.TestCase):
106
  self.assertEqual(tuple(x_pred.shape), tuple(x.shape))
107
  self.assertEqual(tuple(loss.shape), tuple(x.shape))
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  def test_frame_memory_pose_is_batch_first_and_separate_from_pose_cond(self):
110
  torch.manual_seed(0)
111
  diffusion = _make_diffusion(output_frames=2)
@@ -198,6 +223,19 @@ class DeMemWMDiffusionTargetOnlyTests(unittest.TestCase):
198
  self.assertEqual(diffusion.model.calls[0]["x_shape"], (1, 5, 1, 1, 1))
199
  self.assertEqual(tuple(ddim.shape), (2, 1, 1, 1, 1))
200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
 
202
  if __name__ == "__main__":
203
  unittest.main()
 
106
  self.assertEqual(tuple(x_pred.shape), tuple(x.shape))
107
  self.assertEqual(tuple(loss.shape), tuple(x.shape))
108
 
109
+ def test_padded_frame_memory_masks_keep_target_prediction_and_loss_shapes(self):
110
+ torch.manual_seed(0)
111
+ diffusion = _make_diffusion(output_frames=2)
112
+ x, action_cond, noise_levels, segments = _packed_inputs()
113
+ masks = {
114
+ "target": torch.ones((1, 2), dtype=torch.bool),
115
+ "anchor": torch.ones((1, 1), dtype=torch.bool),
116
+ "dynamic": torch.zeros((1, 1), dtype=torch.bool),
117
+ "revisit": torch.ones((1, 1), dtype=torch.bool),
118
+ }
119
+
120
+ x_pred, loss = diffusion(
121
+ x,
122
+ action_cond,
123
+ None,
124
+ noise_levels=noise_levels,
125
+ reference_length=0,
126
+ frame_memory_segments=segments,
127
+ frame_memory_masks=masks,
128
+ )
129
+
130
+ self.assertIs(diffusion.model.calls[0]["kwargs"]["frame_memory_masks"], masks)
131
+ self.assertEqual(tuple(x_pred.shape), (2, 1, 1, 1, 1))
132
+ self.assertEqual(tuple(loss.shape), (2, 1, 1, 1, 1))
133
+
134
  def test_frame_memory_pose_is_batch_first_and_separate_from_pose_cond(self):
135
  torch.manual_seed(0)
136
  diffusion = _make_diffusion(output_frames=2)
 
223
  self.assertEqual(diffusion.model.calls[0]["x_shape"], (1, 5, 1, 1, 1))
224
  self.assertEqual(tuple(ddim.shape), (2, 1, 1, 1, 1))
225
 
226
+ diffusion = _make_diffusion(output_frames=2)
227
+ sample = diffusion.sample_step(
228
+ x,
229
+ action_cond,
230
+ None,
231
+ curr_noise_level=torch.tensor([[3], [2], [0], [0], [0]], dtype=torch.long),
232
+ next_noise_level=torch.tensor([[2], [1], [0], [0], [0]], dtype=torch.long),
233
+ reference_length=0,
234
+ frame_memory_segments=segments,
235
+ )
236
+ self.assertEqual(diffusion.model.calls[0]["x_shape"], (1, 5, 1, 1, 1))
237
+ self.assertEqual(tuple(sample.shape), (2, 1, 1, 1, 1))
238
+
239
 
240
  if __name__ == "__main__":
241
  unittest.main()
tests/test_dememwm_temporal_attention.py CHANGED
@@ -61,6 +61,19 @@ class DeMemWMTemporalAttentionTests(unittest.TestCase):
61
  expected = torch.tensor([10.0, 15.0, 20.0, 100.0, 1.0, 3.0, 200.0])
62
  self.assertTrue(torch.allclose(out.flatten(), expected))
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  def test_block_threads_frame_memory_metadata_to_temporal_attention(self):
65
  class ZeroAttention(nn.Module):
66
  def forward(self, x):
@@ -135,6 +148,52 @@ class DeMemWMTemporalAttentionTests(unittest.TestCase):
135
  self.assertIs(spy.calls[0]["frame_memory_segments"], segments)
136
  self.assertIs(spy.calls[0]["frame_memory_masks"], masks)
137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  def test_dit_builds_geometry_cache_once_and_threads_to_reference_attention(self):
139
  class ZeroAttention(nn.Module):
140
  def forward(self, x):
 
61
  expected = torch.tensor([10.0, 15.0, 20.0, 100.0, 1.0, 3.0, 200.0])
62
  self.assertTrue(torch.allclose(out.flatten(), expected))
63
 
64
+ def test_frame_memory_temporal_targets_do_not_depend_on_appended_memory(self):
65
+ attn = _averaging_temporal_attention()
66
+ segments = {"target": 3, "anchor": 1, "dynamic": 2, "revisit": 1}
67
+ x = torch.tensor([10.0, 20.0, 30.0, 100.0, 1.0, 3.0, 200.0]).view(1, 7, 1, 1, 1)
68
+ changed_memory = torch.tensor([10.0, 20.0, 30.0, -500.0, 700.0, 900.0, -300.0]).view(1, 7, 1, 1, 1)
69
+
70
+ out = attn(x, frame_memory_segments=segments)
71
+ changed_out = attn(changed_memory, frame_memory_segments=segments)
72
+
73
+ expected_target = torch.tensor([10.0, 15.0, 20.0]).view(1, 3, 1, 1, 1)
74
+ self.assertTrue(torch.allclose(out[:, :3], expected_target))
75
+ self.assertTrue(torch.allclose(out[:, :3], changed_out[:, :3]))
76
+
77
  def test_block_threads_frame_memory_metadata_to_temporal_attention(self):
78
  class ZeroAttention(nn.Module):
79
  def forward(self, x):
 
148
  self.assertIs(spy.calls[0]["frame_memory_segments"], segments)
149
  self.assertIs(spy.calls[0]["frame_memory_masks"], masks)
150
 
151
+ def test_dit_baseline_and_packed_frame_memory_output_lengths_with_real_blocks(self):
152
+ torch.manual_seed(0)
153
+ model = DiT(
154
+ input_h=2,
155
+ input_w=2,
156
+ patch_size=1,
157
+ in_channels=1,
158
+ hidden_size=8,
159
+ depth=1,
160
+ num_heads=1,
161
+ mlp_ratio=1.0,
162
+ action_cond_dim=3,
163
+ pose_cond_dim=0,
164
+ reference_length=1,
165
+ use_memory_attention=True,
166
+ )
167
+ model.eval()
168
+
169
+ x = torch.randn((1, 3, 1, 2, 2))
170
+ t = torch.zeros((1, 3), dtype=torch.long)
171
+ action_cond = torch.zeros((1, 3, 3))
172
+ with torch.no_grad():
173
+ baseline = model(x, t, action_cond, reference_length=1)
174
+ self.assertEqual(tuple(baseline.shape), (1, 3, 1, 2, 2))
175
+
176
+ packed = torch.randn((1, 5, 1, 2, 2))
177
+ packed_t = torch.zeros((1, 5), dtype=torch.long)
178
+ packed_action = torch.zeros((1, 5, 3))
179
+ segments = {"target": 2, "anchor": 1, "dynamic": 1, "revisit": 1}
180
+ masks = {
181
+ "target": torch.ones((1, 2), dtype=torch.bool),
182
+ "anchor": torch.ones((1, 1), dtype=torch.bool),
183
+ "dynamic": torch.zeros((1, 1), dtype=torch.bool),
184
+ "revisit": torch.ones((1, 1), dtype=torch.bool),
185
+ }
186
+ with torch.no_grad():
187
+ packed_out = model(
188
+ packed,
189
+ packed_t,
190
+ packed_action,
191
+ reference_length=1,
192
+ frame_memory_segments=segments,
193
+ frame_memory_masks=masks,
194
+ )
195
+ self.assertEqual(tuple(packed_out.shape), (1, 2, 1, 2, 2))
196
+
197
  def test_dit_builds_geometry_cache_once_and_threads_to_reference_attention(self):
198
  class ZeroAttention(nn.Module):
199
  def forward(self, x):