jspr commited on
Commit
cf648ca
·
verified ·
1 Parent(s): 302675f

Remove closed-loop classes (CerebellarGate, LossPredictor, EmotionGate) from forward_model.py

Browse files
Files changed (1) hide show
  1. forward_model.py +2 -87
forward_model.py CHANGED
@@ -1,12 +1,7 @@
1
- """Forward models (cerebellum analog) for predicting transformer activations.
2
 
3
  ForwardModel: per-position MLP. Structurally blind to cross-position effects.
4
- TransformerForwardModel: small transformer. Capacity-bottlenecked, not
5
- position-blind — the residual captures computational novelty, not attention's
6
- existence. Architecture mirrors the cerebellar circuit:
7
- - Causal attention with compressed projections (pontine relay)
8
- - MLP expansion (granule cell combinatorial coding)
9
- - Linear readout (Purkinje cell)
10
  """
11
 
12
  import math
@@ -82,86 +77,6 @@ class ForwardBlock(nn.Module):
82
  return x
83
 
84
 
85
- class CerebellarGate(nn.Module):
86
- """Learned gated projection for injecting forward model predictions.
87
-
88
- Zero-initialized so the injection starts at exactly zero.
89
- The projection learns to transform the forward model's prediction
90
- into a useful signal for the main model's residual stream (thalamic
91
- relay analog). Injection magnitude grows from zero as training
92
- discovers useful structure.
93
- """
94
-
95
- def __init__(self, d_model: int):
96
- super().__init__()
97
- self.projection = nn.Linear(d_model, d_model)
98
- nn.init.zeros_(self.projection.weight)
99
- nn.init.zeros_(self.projection.bias)
100
- print(f"CerebellarGate: {sum(p.numel() for p in self.parameters())/1e3:.1f}K "
101
- f"parameters (d_model={d_model})")
102
-
103
- def forward(self, fwd_pred):
104
- return self.projection(fwd_pred)
105
-
106
- def injection_norm(self):
107
- return self.projection.weight.norm().item()
108
-
109
-
110
- class LossPredictor(nn.Module):
111
- """Predicts per-token loss from early-layer activations (emotion analog).
112
-
113
- Returns both a low-dimensional embedding (for injection via EmotionGate)
114
- and a scalar loss prediction (for training via MSE against actual CE).
115
- When embed_dim=1, the embedding IS the scalar prediction.
116
- When embed_dim>1, a linear head maps the embedding to a scalar for training,
117
- but the full embedding is what gets injected.
118
- """
119
-
120
- def __init__(self, d_model: int, embed_dim: int = 1, hidden: int = 128):
121
- super().__init__()
122
- self.embed_dim = embed_dim
123
- self.encoder = nn.Sequential(
124
- nn.LayerNorm(d_model),
125
- nn.Linear(d_model, hidden),
126
- nn.GELU(),
127
- nn.Linear(hidden, embed_dim),
128
- )
129
- self.head = nn.Linear(embed_dim, 1) if embed_dim > 1 else None
130
- n_params = sum(p.numel() for p in self.parameters())
131
- print(f"LossPredictor: {n_params/1e3:.1f}K parameters "
132
- f"(d_model={d_model}, embed_dim={embed_dim}, hidden={hidden})")
133
-
134
- def forward(self, x):
135
- embed = self.encoder(x) # (B, T, embed_dim)
136
- if self.head is not None:
137
- loss_pred = self.head(embed).squeeze(-1) # (B, T)
138
- else:
139
- loss_pred = embed.squeeze(-1) # (B, T)
140
- return embed, loss_pred
141
-
142
-
143
- class EmotionGate(nn.Module):
144
- """Learned projection for injecting evaluative signals into the residual stream.
145
-
146
- Zero-initialized like CerebellarGate. Projects from a low-dimensional
147
- evaluative embedding to full residual stream dimensionality.
148
- """
149
-
150
- def __init__(self, embed_dim: int, d_model: int):
151
- super().__init__()
152
- self.projection = nn.Linear(embed_dim, d_model)
153
- nn.init.zeros_(self.projection.weight)
154
- nn.init.zeros_(self.projection.bias)
155
- print(f"EmotionGate: {sum(p.numel() for p in self.parameters())/1e3:.1f}K "
156
- f"parameters (embed_dim={embed_dim}, d_model={d_model})")
157
-
158
- def forward(self, embed):
159
- return self.projection(embed)
160
-
161
- def injection_norm(self):
162
- return self.projection.weight.norm().item()
163
-
164
-
165
  class TransformerForwardModel(nn.Module):
166
  def __init__(self, d_model: int, d_head: int = 64, n_head: int = 1,
167
  n_layer: int = 1, mlp_mult: float = 2, block_size: int = 128,
 
1
+ """Forward models for predicting transformer activations.
2
 
3
  ForwardModel: per-position MLP. Structurally blind to cross-position effects.
4
+ TransformerForwardModel: small transformer with capacity bottleneck.
 
 
 
 
 
5
  """
6
 
7
  import math
 
77
  return x
78
 
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  class TransformerForwardModel(nn.Module):
81
  def __init__(self, d_model: int, d_head: int = 64, n_head: int = 1,
82
  n_layer: int = 1, mlp_mult: float = 2, block_size: int = 128,