Upload overlay/subsystems/sdr_semantic.py with huggingface_hub
Browse files
overlay/subsystems/sdr_semantic.py
CHANGED
|
@@ -265,7 +265,42 @@ class SemanticFoldingSDR(nn.Module):
|
|
| 265 |
self.delta_u = nn.Parameter(torch.randn(vocab_size, delta_rank) * 1e-4)
|
| 266 |
self.delta_v = nn.Parameter(torch.randn(delta_rank, n_bits) * 1e-4)
|
| 267 |
|
| 268 |
-
# ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 269 |
# invalidates torch.compile guards on every maybe_som_update call.
|
| 270 |
# Persisted manually via state_dict hooks for checkpointing.
|
| 271 |
self._som_step: int = 0
|
|
|
|
| 265 |
self.delta_u = nn.Parameter(torch.randn(vocab_size, delta_rank) * 1e-4)
|
| 266 |
self.delta_v = nn.Parameter(torch.randn(delta_rank, n_bits) * 1e-4)
|
| 267 |
|
| 268 |
+
# ------------------------------------------------------------------
|
| 269 |
+
# Contrastive retina parameter (Retina-D).
|
| 270 |
+
#
|
| 271 |
+
# Audit 2026-05-09 issue #21: this parameter was previously named
|
| 272 |
+
# `retina_logits`, which UNCONDITIONALLY SHADOWED the learnable-mode
|
| 273 |
+
# binary retina logits assigned above (also named `retina_logits`,
|
| 274 |
+
# shape [V, n_bits]). The shadow silently broke binary_only(),
|
| 275 |
+
# binary_softplus_topk(), and the symmetric-difference debug paths
|
| 276 |
+
# in learnable mode — they all index `retina_logits[token_ids]` and
|
| 277 |
+
# expected n_bits columns but were getting contrastive_rank columns.
|
| 278 |
+
#
|
| 279 |
+
# Renamed to `retina_contrastive` to remove the shadow. The
|
| 280 |
+
# contrastive_loss() and contrastive-retina debug code paths in this
|
| 281 |
+
# module are updated to use the new name; the optimizer group in
|
| 282 |
+
# hydra/model.py is updated to bind to `retina_contrastive`.
|
| 283 |
+
#
|
| 284 |
+
# retina_contrastive: [V, contrastive_rank] — a compact learned
|
| 285 |
+
# embedding for each vocabulary token. Cosine similarity on these
|
| 286 |
+
# logits is the contrastive signal. Using a low-rank projection
|
| 287 |
+
# (contrastive_rank << n_bits) keeps the similarity computation
|
| 288 |
+
# cheap: O(V_unique * contrastive_rank) vs O(V * n_bits).
|
| 289 |
+
#
|
| 290 |
+
# Initialised with unit-norm rows so cosine similarities start near
|
| 291 |
+
# zero (random ~1/sqrt(contrastive_rank)) rather than being uniformly
|
| 292 |
+
# positive from a raw randn init. This avoids a cold-start
|
| 293 |
+
# degenerate state where all pairs look similar and the loss
|
| 294 |
+
# provides no gradient direction.
|
| 295 |
+
# ------------------------------------------------------------------
|
| 296 |
+
self.retina_contrastive = None
|
| 297 |
+
if contrastive_rank > 0:
|
| 298 |
+
_logit_init = torch.randn(vocab_size, contrastive_rank)
|
| 299 |
+
# Normalise rows to unit length so cosine starts meaningful
|
| 300 |
+
_logit_init = _logit_init / (_logit_init.norm(dim=-1, keepdim=True) + 1e-8)
|
| 301 |
+
self.retina_contrastive = nn.Parameter(_logit_init * 0.1)
|
| 302 |
+
|
| 303 |
+
# Step counter as plain Python int — avoids GPU buffer mutation that
|
| 304 |
# invalidates torch.compile guards on every maybe_som_update call.
|
| 305 |
# Persisted manually via state_dict hooks for checkpointing.
|
| 306 |
self._som_step: int = 0
|