BonanDing commited on
Commit
047d060
·
1 Parent(s): 894c19c

Make DeMemWM memory streams self-only

Browse files
.exp_artifact/dememwm_future_memory_selection_plan.md CHANGED
@@ -339,7 +339,7 @@ Allow noncausal DeMemWM dynamic events
339
 
340
  ## Substep 4: Make All Packed Memory Streams Diagonal/Self-Only
341
 
342
- Status: `[ ]`
343
 
344
  Goal:
345
 
 
339
 
340
  ## Substep 4: Make All Packed Memory Streams Diagonal/Self-Only
341
 
342
+ Status: `[x]`
343
 
344
  Goal:
345
 
algorithms/dememwm/models/attention.py CHANGED
@@ -68,11 +68,8 @@ class TemporalAxialAttention(nn.Module):
68
  segment_slice = slice(cursor, cursor + length)
69
  segment_slices[segment] = segment_slice
70
  if length > 0:
71
- if segment == "dynamic":
72
- allow[:, segment_slice, segment_slice] = True
73
- else:
74
- idx = torch.arange(cursor, cursor + length, device=device)
75
- allow[:, idx, idx] = True
76
  cursor += length
77
 
78
  if frame_memory_masks is not None:
 
68
  segment_slice = slice(cursor, cursor + length)
69
  segment_slices[segment] = segment_slice
70
  if length > 0:
71
+ idx = torch.arange(cursor, cursor + length, device=device)
72
+ allow[:, idx, idx] = True
 
 
 
73
  cursor += length
74
 
75
  if frame_memory_masks is not None:
tests/test_dememwm_temporal_attention.py CHANGED
@@ -40,6 +40,65 @@ class DeMemWMTemporalAttentionTests(unittest.TestCase):
40
  expected = torch.tensor([10.0, 15.0, 20.0, 100.0, 200.0])
41
  self.assertTrue(torch.allclose(out.flatten(), expected))
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  def test_frame_memory_segments_mask_temporal_streams(self):
44
  attn = _averaging_temporal_attention()
45
  x = torch.tensor([10.0, 20.0, 30.0, 100.0, 1.0, 3.0, 200.0]).view(1, 7, 1, 1, 1)
@@ -47,7 +106,7 @@ class DeMemWMTemporalAttentionTests(unittest.TestCase):
47
 
48
  out = attn(x, frame_memory_segments=segments)
49
 
50
- expected = torch.tensor([10.0, 15.0, 20.0, 100.0, 2.0, 2.0, 200.0])
51
  self.assertTrue(torch.allclose(out.flatten(), expected))
52
 
53
  masks = {
 
40
  expected = torch.tensor([10.0, 15.0, 20.0, 100.0, 200.0])
41
  self.assertTrue(torch.allclose(out.flatten(), expected))
42
 
43
+ def test_frame_memory_attention_bias_keeps_target_causal_and_streams_self_only(self):
44
+ attn = _averaging_temporal_attention()
45
+ segments = {"target": 3, "anchor": 2, "dynamic": 2, "revisit": 2}
46
+ total_frames = sum(segments.values())
47
+
48
+ bias = attn._frame_memory_attn_bias(
49
+ B=1,
50
+ T=total_frames,
51
+ H=1,
52
+ W=1,
53
+ dtype=torch.float32,
54
+ device=torch.device("cpu"),
55
+ frame_memory_segments=segments,
56
+ frame_memory_masks=None,
57
+ )[0, 0]
58
+ allow = torch.isfinite(bias)
59
+
60
+ target_expected = torch.tril(torch.ones((3, 3), dtype=torch.bool))
61
+ self.assertTrue(torch.equal(allow[:3, :3], target_expected))
62
+ self.assertFalse(allow[:3, 3:].any().item())
63
+
64
+ cursor = segments["target"]
65
+ for stream in ("anchor", "dynamic", "revisit"):
66
+ length = segments[stream]
67
+ rows = slice(cursor, cursor + length)
68
+ self.assertTrue(torch.equal(allow[rows, rows], torch.eye(length, dtype=torch.bool)))
69
+ self.assertFalse(allow[rows, :cursor].any().item())
70
+ self.assertFalse(allow[rows, cursor + length :].any().item())
71
+ cursor += length
72
+
73
+ def test_frame_memory_attention_bias_restores_invalid_memory_row_diagonal(self):
74
+ attn = _averaging_temporal_attention()
75
+ segments = {"target": 2, "anchor": 2, "dynamic": 2, "revisit": 2}
76
+ total_frames = sum(segments.values())
77
+ masks = {
78
+ "target": torch.ones((1, 2), dtype=torch.bool),
79
+ "anchor": torch.tensor([[False, True]]),
80
+ "dynamic": torch.tensor([[True, False]]),
81
+ "revisit": torch.tensor([[False, False]]),
82
+ }
83
+
84
+ bias = attn._frame_memory_attn_bias(
85
+ B=1,
86
+ T=total_frames,
87
+ H=1,
88
+ W=1,
89
+ dtype=torch.float32,
90
+ device=torch.device("cpu"),
91
+ frame_memory_segments=segments,
92
+ frame_memory_masks=masks,
93
+ )[0, 0]
94
+ allow = torch.isfinite(bias)
95
+
96
+ self.assertTrue(allow.any(dim=-1).all().item())
97
+ for row in (2, 5, 6, 7):
98
+ row_expected = torch.zeros(total_frames, dtype=torch.bool)
99
+ row_expected[row] = True
100
+ self.assertTrue(torch.equal(allow[row], row_expected))
101
+
102
  def test_frame_memory_segments_mask_temporal_streams(self):
103
  attn = _averaging_temporal_attention()
104
  x = torch.tensor([10.0, 20.0, 30.0, 100.0, 1.0, 3.0, 200.0]).view(1, 7, 1, 1, 1)
 
106
 
107
  out = attn(x, frame_memory_segments=segments)
108
 
109
+ expected = torch.tensor([10.0, 15.0, 20.0, 100.0, 1.0, 3.0, 200.0])
110
  self.assertTrue(torch.allclose(out.flatten(), expected))
111
 
112
  masks = {