lhallee commited on
Commit
2b0f1cd
·
verified ·
1 Parent(s): 629d173

Upload vb_layers_pair_averaging.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. vb_layers_pair_averaging.py +135 -135
vb_layers_pair_averaging.py CHANGED
@@ -1,135 +1,135 @@
1
- import torch
2
- from torch import Tensor, nn
3
-
4
- from . import vb_layers_initialize as init
5
-
6
-
7
- class PairWeightedAveraging(nn.Module):
8
- """Pair weighted averaging layer."""
9
-
10
- def __init__(
11
- self,
12
- c_m: int,
13
- c_z: int,
14
- c_h: int,
15
- num_heads: int,
16
- inf: float = 1e6,
17
- ) -> None:
18
- """Initialize the pair weighted averaging layer.
19
-
20
- Parameters
21
- ----------
22
- c_m: int
23
- The dimension of the input sequence.
24
- c_z: int
25
- The dimension of the input pairwise tensor.
26
- c_h: int
27
- The dimension of the hidden.
28
- num_heads: int
29
- The number of heads.
30
- inf: float
31
- The value to use for masking, default 1e6.
32
-
33
- """
34
- super().__init__()
35
- self.c_m = c_m
36
- self.c_z = c_z
37
- self.c_h = c_h
38
- self.num_heads = num_heads
39
- self.inf = inf
40
-
41
- self.norm_m = nn.LayerNorm(c_m)
42
- self.norm_z = nn.LayerNorm(c_z)
43
-
44
- self.proj_m = nn.Linear(c_m, c_h * num_heads, bias=False)
45
- self.proj_g = nn.Linear(c_m, c_h * num_heads, bias=False)
46
- self.proj_z = nn.Linear(c_z, num_heads, bias=False)
47
- self.proj_o = nn.Linear(c_h * num_heads, c_m, bias=False)
48
- init.final_init_(self.proj_o.weight)
49
-
50
- def forward(
51
- self, m: Tensor, z: Tensor, mask: Tensor, chunk_heads: False = bool
52
- ) -> Tensor:
53
- """Forward pass.
54
-
55
- Parameters
56
- ----------
57
- m : torch.Tensor
58
- The input sequence tensor (B, S, N, D)
59
- z : torch.Tensor
60
- The input pairwise tensor (B, N, N, D)
61
- mask : torch.Tensor
62
- The pairwise mask tensor (B, N, N)
63
-
64
- Returns
65
- -------
66
- torch.Tensor
67
- The output sequence tensor (B, S, N, D)
68
-
69
- """
70
- # Compute layer norms
71
- m = self.norm_m(m)
72
- z = self.norm_z(z)
73
-
74
- if chunk_heads and not self.training:
75
- # Compute heads sequentially
76
- o_chunks = []
77
- for head_idx in range(self.num_heads):
78
- sliced_weight_proj_m = self.proj_m.weight[
79
- head_idx * self.c_h : (head_idx + 1) * self.c_h, :
80
- ]
81
- sliced_weight_proj_g = self.proj_g.weight[
82
- head_idx * self.c_h : (head_idx + 1) * self.c_h, :
83
- ]
84
- sliced_weight_proj_z = self.proj_z.weight[head_idx : (head_idx + 1), :]
85
- sliced_weight_proj_o = self.proj_o.weight[
86
- :, head_idx * self.c_h : (head_idx + 1) * self.c_h
87
- ]
88
-
89
- # Project input tensors
90
- v: Tensor = m @ sliced_weight_proj_m.T
91
- v = v.reshape(*v.shape[:3], 1, self.c_h)
92
- v = v.permute(0, 3, 1, 2, 4)
93
-
94
- # Compute weights
95
- b: Tensor = z @ sliced_weight_proj_z.T
96
- b = b.permute(0, 3, 1, 2)
97
- b = b + (1 - mask[:, None]) * -self.inf
98
- w = torch.softmax(b, dim=-1)
99
-
100
- # Compute gating
101
- g: Tensor = m @ sliced_weight_proj_g.T
102
- g = g.sigmoid()
103
-
104
- # Compute output
105
- o = torch.einsum("bhij,bhsjd->bhsid", w, v)
106
- o = o.permute(0, 2, 3, 1, 4)
107
- o = o.reshape(*o.shape[:3], 1 * self.c_h)
108
- o_chunks = g * o
109
- if head_idx == 0:
110
- o_out = o_chunks @ sliced_weight_proj_o.T
111
- else:
112
- o_out += o_chunks @ sliced_weight_proj_o.T
113
- return o_out
114
- else:
115
- # Project input tensors
116
- v: Tensor = self.proj_m(m)
117
- v = v.reshape(*v.shape[:3], self.num_heads, self.c_h)
118
- v = v.permute(0, 3, 1, 2, 4)
119
-
120
- # Compute weights
121
- b: Tensor = self.proj_z(z)
122
- b = b.permute(0, 3, 1, 2)
123
- b = b + (1 - mask[:, None]) * -self.inf
124
- w = torch.softmax(b, dim=-1)
125
-
126
- # Compute gating
127
- g: Tensor = self.proj_g(m)
128
- g = g.sigmoid()
129
-
130
- # Compute output
131
- o = torch.einsum("bhij,bhsjd->bhsid", w, v)
132
- o = o.permute(0, 2, 3, 1, 4)
133
- o = o.reshape(*o.shape[:3], self.num_heads * self.c_h)
134
- o = self.proj_o(g * o)
135
- return o
 
1
+ import torch
2
+ from torch import Tensor, nn
3
+
4
+ from . import vb_layers_initialize as init
5
+
6
+
7
+ class PairWeightedAveraging(nn.Module):
8
+ """Pair weighted averaging layer."""
9
+
10
+ def __init__(
11
+ self,
12
+ c_m: int,
13
+ c_z: int,
14
+ c_h: int,
15
+ num_heads: int,
16
+ inf: float = 1e6,
17
+ ) -> None:
18
+ """Initialize the pair weighted averaging layer.
19
+
20
+ Parameters
21
+ ----------
22
+ c_m: int
23
+ The dimension of the input sequence.
24
+ c_z: int
25
+ The dimension of the input pairwise tensor.
26
+ c_h: int
27
+ The dimension of the hidden.
28
+ num_heads: int
29
+ The number of heads.
30
+ inf: float
31
+ The value to use for masking, default 1e6.
32
+
33
+ """
34
+ super().__init__()
35
+ self.c_m = c_m
36
+ self.c_z = c_z
37
+ self.c_h = c_h
38
+ self.num_heads = num_heads
39
+ self.inf = inf
40
+
41
+ self.norm_m = nn.LayerNorm(c_m)
42
+ self.norm_z = nn.LayerNorm(c_z)
43
+
44
+ self.proj_m = nn.Linear(c_m, c_h * num_heads, bias=False)
45
+ self.proj_g = nn.Linear(c_m, c_h * num_heads, bias=False)
46
+ self.proj_z = nn.Linear(c_z, num_heads, bias=False)
47
+ self.proj_o = nn.Linear(c_h * num_heads, c_m, bias=False)
48
+ init.final_init_(self.proj_o.weight)
49
+
50
+ def forward(
51
+ self, m: Tensor, z: Tensor, mask: Tensor, chunk_heads: False = bool
52
+ ) -> Tensor:
53
+ """Forward pass.
54
+
55
+ Parameters
56
+ ----------
57
+ m : torch.Tensor
58
+ The input sequence tensor (B, S, N, D)
59
+ z : torch.Tensor
60
+ The input pairwise tensor (B, N, N, D)
61
+ mask : torch.Tensor
62
+ The pairwise mask tensor (B, N, N)
63
+
64
+ Returns
65
+ -------
66
+ torch.Tensor
67
+ The output sequence tensor (B, S, N, D)
68
+
69
+ """
70
+ # Compute layer norms
71
+ m = self.norm_m(m)
72
+ z = self.norm_z(z)
73
+
74
+ if chunk_heads and not self.training:
75
+ # Compute heads sequentially
76
+ o_chunks = []
77
+ for head_idx in range(self.num_heads):
78
+ sliced_weight_proj_m = self.proj_m.weight[
79
+ head_idx * self.c_h : (head_idx + 1) * self.c_h, :
80
+ ]
81
+ sliced_weight_proj_g = self.proj_g.weight[
82
+ head_idx * self.c_h : (head_idx + 1) * self.c_h, :
83
+ ]
84
+ sliced_weight_proj_z = self.proj_z.weight[head_idx : (head_idx + 1), :]
85
+ sliced_weight_proj_o = self.proj_o.weight[
86
+ :, head_idx * self.c_h : (head_idx + 1) * self.c_h
87
+ ]
88
+
89
+ # Project input tensors
90
+ v: Tensor = m @ sliced_weight_proj_m.T
91
+ v = v.reshape(*v.shape[:3], 1, self.c_h)
92
+ v = v.permute(0, 3, 1, 2, 4)
93
+
94
+ # Compute weights
95
+ b: Tensor = z @ sliced_weight_proj_z.T
96
+ b = b.permute(0, 3, 1, 2)
97
+ b = b + (1 - mask[:, None]) * -self.inf
98
+ w = torch.softmax(b, dim=-1)
99
+
100
+ # Compute gating
101
+ g: Tensor = m @ sliced_weight_proj_g.T
102
+ g = g.sigmoid()
103
+
104
+ # Compute output
105
+ o = torch.einsum("bhij,bhsjd->bhsid", w, v)
106
+ o = o.permute(0, 2, 3, 1, 4)
107
+ o = o.reshape(*o.shape[:3], 1 * self.c_h)
108
+ o_chunks = g * o
109
+ if head_idx == 0:
110
+ o_out = o_chunks @ sliced_weight_proj_o.T
111
+ else:
112
+ o_out += o_chunks @ sliced_weight_proj_o.T
113
+ return o_out
114
+ else:
115
+ # Project input tensors
116
+ v: Tensor = self.proj_m(m)
117
+ v = v.reshape(*v.shape[:3], self.num_heads, self.c_h)
118
+ v = v.permute(0, 3, 1, 2, 4)
119
+
120
+ # Compute weights
121
+ b: Tensor = self.proj_z(z)
122
+ b = b.permute(0, 3, 1, 2)
123
+ b = b + (1 - mask[:, None]) * -self.inf
124
+ w = torch.softmax(b, dim=-1)
125
+
126
+ # Compute gating
127
+ g: Tensor = self.proj_g(m)
128
+ g = g.sigmoid()
129
+
130
+ # Compute output
131
+ o = torch.einsum("bhij,bhsjd->bhsid", w, v)
132
+ o = o.permute(0, 2, 3, 1, 4)
133
+ o = o.reshape(*o.shape[:3], self.num_heads * self.c_h)
134
+ o = self.proj_o(g * o)
135
+ return o