Skip to content

Commit 67fde75

Browse files
committed
Relax attend_to_offset value width
1 parent c71676f commit 67fde75

3 files changed

Lines changed: 41 additions & 13 deletions

File tree

tests/compile/forward/test_forward_compile.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,23 @@ def test_compile_attend_to_offset():
145145
)
146146

147147

148+
def test_compile_attend_to_offset_wide_value():
149+
"""attend_to_offset supports values wider than the position encoding."""
150+
pos = create_pos_encoding()
151+
v = create_input("v", 20)
152+
out = pos.attend_to_offset(v, delta_pos=-1)
153+
154+
n_pos = 5
155+
_verify(
156+
out,
157+
n_pos=n_pos,
158+
input_values={
159+
"v": torch.randn(n_pos, 20),
160+
},
161+
pos_encoding=pos,
162+
)
163+
164+
148165
def test_compile_map_to_table():
149166
"""map_to_table — table lookup via MLP (large d_hidden)."""
150167
x = create_input("x", 2)

tests/graph/test_pos_encoding.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,18 @@ def test_attend_to_offset():
3232
pos_encoding = PosEncoding(16)
3333
last_input = pos_encoding.attend_to_offset(value_input, delta_pos=-1)
3434
output = last_input.compute(n_pos=5, input_values={"value": input_values})
35-
assert torch.allclose(output[:, 1:], input_values[:, :-1])
35+
assert torch.allclose(output[0], input_values[0])
36+
assert torch.allclose(output[1:], input_values[:-1])
37+
38+
39+
def test_attend_to_offset_value_can_be_wider_than_position_encoding():
40+
input_values = torch.arange(5 * 20, dtype=torch.float32).reshape(5, 20)
41+
value_input = InputNode("value", 20, value_range=(-100.0, 100.0))
42+
pos_encoding = PosEncoding(16)
43+
last_input = pos_encoding.attend_to_offset(value_input, delta_pos=-1)
44+
output = last_input.compute(n_pos=5, input_values={"value": input_values})
45+
assert torch.allclose(output[0], input_values[0])
46+
assert torch.allclose(output[1:], input_values[:-1])
3647

3748

3849
def test_delta_matrix():

torchwright/graph/pos_encoding.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,30 +61,30 @@ def attend_to_offset(self, value: Node, delta_pos=-1) -> Node:
6161
# NOOP -- supporting this simplifies some use cases.
6262
return value
6363

64-
# We're applying the query/key to the position
65-
d_head = self.d_pos
66-
assert self.d_pos <= d_head
67-
assert len(value) <= d_head
64+
# Q/K match positions in positional-encoding space; V/O transports
65+
# the payload independently and may be wider than the position vector.
66+
d_qk = self.d_pos
67+
d_v = len(value)
6868

69-
# key_matrix shape (d_key_in, d_head)
69+
# key_matrix shape (d_key_in, d_qk)
7070
delta = get_pos_delta_matrix(delta_pos, self.d_pos)
7171
# The last sin/cos pair (columns d_pos-2, d_pos-1) contains the
7272
# raw position counter instead of a sinusoid. Zero it out so the
7373
# counter doesn't participate in the trig-identity attention.
7474
delta[self.d_pos - 2 :, :] = 0.0
7575
delta[:, self.d_pos - 2 :] = 0.0
76-
key_matrix = torch.zeros((len(self), d_head))
76+
key_matrix = torch.zeros((len(self), d_qk))
7777
key_matrix[:, : self.d_pos] = delta
7878

79-
# query_matrix shape (d_query_in, d_head)
80-
query_matrix = attention_hardness * torch.eye(len(self), d_head)
79+
# query_matrix shape (d_query_in, d_qk)
80+
query_matrix = attention_hardness * torch.eye(len(self), d_qk)
8181
query_matrix[self.d_pos - 2 :, :] = 0.0
8282

83-
# value_matrix shape (d_value_in, d_head)
84-
value_matrix = torch.eye(len(value), d_head)
83+
# value_matrix shape (d_value_in, d_v)
84+
value_matrix = torch.eye(d_v)
8585

86-
# output_matrix shape (d_head, d_output)
87-
output_matrix = torch.eye(d_head, len(value))
86+
# output_matrix shape (d_v, d_output)
87+
output_matrix = torch.eye(d_v)
8888

8989
return Attn(
9090
query_in=self,

0 commit comments

Comments
 (0)