Skip to content

Commit fe7915b

Browse files
Merge pull request #160 from arnor-sigurdsson/residual-flow-improvements
Residual flow improvements
2 parents 5036213 + 5625d4d commit fe7915b

13 files changed

Lines changed: 340 additions & 316 deletions

src/eir/models/fusion/fusion_default.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def __init__(
100100
self.input_projections[name] = nn.Sequential(
101101
nn.RMSNorm(normalized_shape=output_dim),
102102
nn.Linear(in_features=output_dim, out_features=self.fusion_dim),
103-
nn.GELU(),
103+
nn.RMSNorm(normalized_shape=self.fusion_dim),
104104
)
105105

106106
fusion_resblocks_kwargs = {

src/eir/models/input/array/models_locally_connected.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ def __init__(
241241
kernel_size=fc_0_kernel_size,
242242
bias=True,
243243
)
244-
self.act_0 = nn.GELU()
244+
self.norm_0 = nn.RMSNorm(normalized_shape=self.fc_0.out_features)
245245

246246
cutoff = dynamic_cutoff or self.model_config.cutoff
247247
assert isinstance(cutoff, int)
@@ -287,7 +287,7 @@ def forward(self, input: torch.Tensor) -> torch.Tensor:
287287
out = self.flatten_fn(x=input)
288288

289289
out = self.fc_0(out)
290-
out = self.act_0(out)
290+
out = self.norm_0(out)
291291
out = self.lcl_blocks(out)
292292

293293
return out
@@ -302,12 +302,10 @@ class ExpertBranch(nn.Module):
302302
def __init__(
303303
self,
304304
fc_0: LCL,
305-
act_0: nn.Module,
306305
lcl_blocks: nn.Sequential,
307306
):
308307
super().__init__()
309308
self.fc_0 = fc_0
310-
self.act_0 = act_0
311309
self.lcl_blocks = lcl_blocks
312310

313311
@property
@@ -318,7 +316,6 @@ def out_features(self) -> int:
318316

319317
def forward(self, x: torch.Tensor) -> torch.Tensor:
320318
x = self.fc_0(x)
321-
x = self.act_0(x)
322319
x = self.lcl_blocks(x)
323320
return x
324321

@@ -381,7 +378,6 @@ def __init__(
381378
kernel_size=expert_fc_0_kernel,
382379
bias=True,
383380
)
384-
act_0 = nn.GELU()
385381

386382
expert_kernel_width = _clamp_kernel_for_min_chunks(
387383
kernel_size=kernel_width,
@@ -407,7 +403,6 @@ def __init__(
407403

408404
branch = ExpertBranch(
409405
fc_0=fc_0,
410-
act_0=act_0,
411406
lcl_blocks=lcl_blocks,
412407
)
413408
self.expert_branches[name] = branch

src/eir/models/input/tabular/tabular.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,12 @@ def forward(self, input: torch.Tensor) -> torch.Tensor:
185185
output = self.layer(input)
186186
output = self.mlp_blocks(output)
187187

188-
if self.training and self.drop_prob > 0.0:
189-
mask = (torch.rand(1, device=output.device) >= self.drop_prob).float()
190-
output = output * mask
188+
if self.drop_prob > 0.0:
189+
if self.training:
190+
mask = (torch.rand(1, device=output.device) >= self.drop_prob).float()
191+
output = output * mask
192+
else:
193+
output = output * (1.0 - self.drop_prob)
191194

192195
return output
193196

src/eir/models/layers/cnn_layers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ def __init__(
194194
stochastic_depth_p: float = 0.0,
195195
conv_downsample_identity: bool = True,
196196
):
197+
"""
198+
TODO: Look into adding a dynamic addition of a norm under downsample identity
199+
(if dimensions are being changed in the downsample),
200+
similar to what we have e.g. in MLPResidualBlock currently.
201+
202+
"""
197203
super().__init__()
198204

199205
self.in_channels = in_channels

src/eir/models/layers/lcl_layers.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,26 +164,26 @@ def __init__(
164164

165165
self.out_features = self.fc_2.out_features
166166

167-
# generally seems to work better to always initialize to 1.0 in LCL blocks
168-
# in contrast to what we do in the standard MLP blocks
169-
self.ls = LayerScale(dim=self.out_features, init_values=1.0)
167+
self.ls = LayerScale(dim=self.out_features, init_values=1e-05)
170168

171-
if in_features == self.out_features:
172-
self.downsample_identity = lambda x: x
173-
else:
169+
self._norm_identity = full_preactivation or (in_features != self.out_features)
170+
self.downsample_identity: nn.Module
171+
if in_features != self.out_features:
174172
self.downsample_identity = LCL(
175173
in_features=self.in_features,
176174
out_feature_sets=1,
177175
bias=True,
178176
num_chunks=self.fc_2.out_features,
179177
)
178+
else:
179+
self.downsample_identity = nn.Identity()
180180

181181
self.stochastic_depth = StochasticDepth(p=stochastic_depth_p, mode="batch")
182182

183183
def forward(self, x: torch.Tensor) -> torch.Tensor:
184184
out = self.norm_1(x)
185185

186-
identity = out if self.full_preactivation else x
186+
identity = out if self._norm_identity else x
187187
identity = self.downsample_identity(identity)
188188

189189
out = self.fc_1(out)

src/eir/models/layers/mlp_layers.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,18 @@ def __init__(
7272
bias=False,
7373
)
7474

75+
self._norm_identity = full_preactivation or (in_features != out_features)
7576
self.downsample_identity: nn.Module
76-
if in_features == out_features:
77-
self.downsample_identity = nn.Identity()
78-
ls_init = 1e-05
79-
else:
77+
if in_features != out_features:
8078
self.downsample_identity = nn.Linear(
8179
in_features=in_features,
8280
out_features=out_features,
8381
bias=True,
8482
)
8583
ls_init = 1.0
84+
else:
85+
self.downsample_identity = nn.Identity()
86+
ls_init = 1e-05
8687

8788
self.ls = LayerScale(
8889
dim=out_features,
@@ -97,7 +98,7 @@ def __init__(
9798
def forward(self, x: torch.Tensor) -> torch.Tensor:
9899
out = self.norm_1(x)
99100

100-
identity = out if self.full_preactivation else x
101+
identity = out if self._norm_identity else x
101102
identity = self.downsample_identity(identity)
102103

103104
out = self.fc_1(out)

src/eir/models/layers/projection_layers.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ def get_lcl_projection_layer(
113113
out_feature_sets_candidates: Sequence[int] = tuple(range(1, 1024 + 1)),
114114
diff_tolerance: int = 0,
115115
kernel_width_divisible_by: int | None = None,
116+
full_preactivation: bool = False,
117+
dropout_p: float = 0.0,
116118
) -> LCLResidualBlock | LCL | None:
117119
layer_class: type[LCLResidualBlock] | type[LCL]
118120
match layer_type:
@@ -140,11 +142,17 @@ def get_lcl_projection_layer(
140142
return None
141143

142144
best_kernel_size, best_out_feature_sets = solution
143-
best_layer = layer_class(
144-
in_features=input_dimension,
145-
kernel_size=best_kernel_size,
146-
out_feature_sets=best_out_feature_sets,
147-
)
145+
146+
kwargs: dict = {
147+
"in_features": input_dimension,
148+
"kernel_size": best_kernel_size,
149+
"out_feature_sets": best_out_feature_sets,
150+
}
151+
if layer_type == "lcl_residual":
152+
kwargs["full_preactivation"] = full_preactivation
153+
kwargs["dropout_p"] = dropout_p
154+
155+
best_layer = layer_class(**kwargs)
148156

149157
return best_layer
150158

src/eir/models/output/tabular/shared_mlp_residual.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,18 @@ def _build_shared(self, input_dimension: int) -> None:
9898

9999
final_block = MLPResidualBlock(
100100
in_features=self.model_config.fc_task_dim,
101-
out_features=self.total_outputs,
101+
out_features=self.model_config.fc_task_dim,
102102
dropout_p=self.model_config.rb_do,
103103
stochastic_depth_p=self.model_config.stochastic_depth_p,
104104
full_preactivation=False,
105105
)
106106

107-
self.shared_branch = nn.Sequential(shared_branch_module, final_block)
107+
final_norm = nn.RMSNorm(self.model_config.fc_task_dim)
108+
final_proj = nn.Linear(self.model_config.fc_task_dim, self.total_outputs)
109+
110+
self.shared_branch = nn.Sequential(
111+
shared_branch_module, final_block, final_norm, final_proj
112+
)
108113

109114
def _build_expert(self, input_dimension: int, num_experts: int) -> None:
110115
self.input_identity = nn.Identity()
@@ -140,6 +145,8 @@ def _build_expert(self, input_dimension: int, num_experts: int) -> None:
140145
torch.zeros(num_targets, num_experts),
141146
)
142147

148+
self.expert_norm = nn.RMSNorm(expert_dim)
149+
143150
self.target_final_layers = nn.ModuleDict(
144151
{
145152
name: nn.Linear(in_features=expert_dim, out_features=size)
@@ -176,6 +183,7 @@ def _forward_expert(self, inputs: torch.Tensor) -> dict[str, torch.Tensor]:
176183
# Per-target weighted average of expert outputs:
177184
# (T, E) @ (B, E, D) -> (B, T, D)
178185
all_mixed = torch.matmul(gate_weights, stacked)
186+
all_mixed = self.expert_norm(all_mixed)
179187

180188
per_target = []
181189
for i, name in enumerate(self.target_names):

src/eir/models/tensor_broker/tensor_broker_fusion_layers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def __init__(
8989
self,
9090
input_shape: torch.Size,
9191
context_shape: torch.Size,
92-
gate_init_value: float = 0.01,
92+
gate_init_value: float = 1e-05,
9393
):
9494
super().__init__()
9595
self.input_shape = input_shape

src/eir/models/tensor_broker/tensor_broker_projection_layers.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,6 @@ def get_projection_layer(
8686

8787
mlp_input_target = target_dim
8888

89-
norm_layer = nn.RMSNorm(normalized_shape=input_dim)
90-
act_layer = nn.GELU()
91-
projection_layers.append(norm_layer)
92-
projection_layers.append(act_layer)
93-
9489
if projection_lcl_residual_blocks:
9590
cur_dim = input_dim
9691
while cur_dim // 4 > mlp_input_target:
@@ -101,6 +96,7 @@ def get_projection_layer(
10196
layer_type="lcl_residual",
10297
diff_tolerance=cur_dim // 100,
10398
kernel_width_divisible_by=kernel_width_divisible_by,
99+
dropout_p=0.1,
104100
)
105101
if block is not None:
106102
projection_layers.append(block)
@@ -116,6 +112,8 @@ def get_projection_layer(
116112
projection_layers.append(fallback)
117113
cur_dim = halve_target
118114
else:
115+
projection_layers.append(nn.RMSNorm(normalized_shape=input_dim))
116+
119117
try:
120118
lcl_projection_layer = get_1d_projection_layer(
121119
input_dimension=input_dim,
@@ -125,9 +123,6 @@ def get_projection_layer(
125123
kernel_width_divisible_by=kernel_width_divisible_by,
126124
)
127125
except ValueError:
128-
# Sometimes we cannot create are reasonable LCL projection
129-
# e.g. if target dim is much larger tha input dim so we have this
130-
# fallback
131126
lcl_projection_layer = get_1d_projection_layer(
132127
input_dimension=input_dim,
133128
target_dimension=mlp_input_target,
@@ -137,16 +132,17 @@ def get_projection_layer(
137132
)
138133

139134
projection_layers.append(lcl_projection_layer)
135+
projection_layers.append(nn.RMSNorm(normalized_shape=mlp_input_target))
140136
cur_dim = mlp_input_target
141137

142138
mlp_residual_block = MLPResidualBlock(
143139
in_features=cur_dim,
144140
out_features=target_dim,
145141
dropout_p=0.0,
146-
full_preactivation=True,
147142
stochastic_depth_p=0.0,
148143
)
149144
projection_layers.append(mlp_residual_block)
145+
150146
projected_shape = to_shape_no_batch
151147

152148
case "mlp_residual":
@@ -155,13 +151,18 @@ def get_projection_layer(
155151

156152
projection_layer = MLPResidualBlock(
157153
in_features=input_dim,
158-
out_features=target_dim,
154+
out_features=input_dim,
159155
dropout_p=0.0,
160-
full_preactivation=True,
161156
stochastic_depth_p=0.0,
162157
reduce_at_fc_1=False,
163158
)
164159
projection_layers.append(projection_layer)
160+
161+
projection_layers.append(nn.RMSNorm(normalized_shape=input_dim))
162+
projection_layers.append(
163+
nn.Linear(in_features=input_dim, out_features=target_dim)
164+
)
165+
165166
projected_shape = to_shape_no_batch
166167

167168
case "cnn":

0 commit comments

Comments
 (0)