splat_attention v2: CausalSplatHUB (the AR-validated causal form), dtype-aware clamps (fp16 landmine defused), header carries the full causal record — binding surface, corrected supply law, optimizer + precision guidance, the open problem stated plainly
Browse files- splat_attention.py +92 -2
splat_attention.py
CHANGED
|
@@ -74,6 +74,38 @@
|
|
| 74 |
# Frozen-everything remains fine for INFERENCE-style play and the
|
| 75 |
# static properties above.
|
| 76 |
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
# Status: research prototype. Trained-at-scale results pending; treat
|
| 78 |
# every number above as what it is — a measurement on the stated probe.
|
| 79 |
# =========================================================================
|
|
@@ -179,7 +211,11 @@ class SplatAttention(nn.Module):
|
|
| 179 |
centers = frac * (L - 1)
|
| 180 |
g = torch.exp(-0.5 * ((pos.unsqueeze(0) - centers.unsqueeze(1))
|
| 181 |
/ sig) ** 2)
|
| 182 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
n_glob = int(round(self.M * self.global_frac))
|
| 184 |
if n_glob > 0:
|
| 185 |
g[:n_glob] = 1.0
|
|
@@ -229,10 +265,64 @@ class SplatAttention(nn.Module):
|
|
| 229 |
c0, Mc)
|
| 230 |
out = out.add_(part)
|
| 231 |
den = den.add_(dpart)
|
| 232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 233 |
return self.drop(self.w_o(out))
|
| 234 |
|
| 235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
def _demo():
|
| 237 |
torch.manual_seed(0)
|
| 238 |
dev = "cuda" if torch.cuda.is_available() else "cpu"
|
|
|
|
| 74 |
# Frozen-everything remains fine for INFERENCE-style play and the
|
| 75 |
# static properties above.
|
| 76 |
#
|
| 77 |
+
# CAUSAL / AR RECORD (2026-08-09/10, rank-controlled recall battery,
|
| 78 |
+
# clean protocol — see trainers/ for full replication):
|
| 79 |
+
# CausalSplatHUB (included below) is the causal prefix-sum form of the
|
| 80 |
+
# aleph read, measured against matched softmax attention on in-context
|
| 81 |
+
# key-value binding with dial-able demand (key rank R):
|
| 82 |
+
# low demand (R=4): near parity (.92 vs .96, shared data ceiling)
|
| 83 |
+
# moderate demand (R=16): .90 vs .99 — army extrapolates toward parity
|
| 84 |
+
# high demand (R=64): .84 vs .99 — army-SATURATED below parity.
|
| 85 |
+
# THE OPEN PROBLEM, stated plainly: at high binding demand the linear
|
| 86 |
+
# aleph read saturates below softmax parity and count does not close it.
|
| 87 |
+
# Something else is needed there — address dimensionality, per-depth
|
| 88 |
+
# allocation, and optimizer geometry are the live suspects.
|
| 89 |
+
# SUPPLY LAW (corrected): the army-size knee tracks the task's
|
| 90 |
+
# addressing DEMAND, but the constant is demand-dependent (4R at low
|
| 91 |
+
# demand, >=16R at moderate, saturating at high). Provision generously
|
| 92 |
+
# and measure CONSUMED address erank PER LAYER — late layers
|
| 93 |
+
# under-consume badly (uniform per-layer K wastes most of its supply).
|
| 94 |
+
# OPTIMIZER (measured, decisive): momentum-geometric optimizers
|
| 95 |
+
# (Muon-style orthogonalized momentum, plain SGD-momentum) beat Adam by
|
| 96 |
+
# ~.09 on this mechanism, and the mechanism is ~20x more
|
| 97 |
+
# optimizer-sensitive than softmax attention. Treat the optimizer as
|
| 98 |
+
# part of the architecture.
|
| 99 |
+
# PRECISION: train in fp32 or bf16 (bf16 measured >= fp32); do NOT
|
| 100 |
+
# train through fp8 (fails); fp8 e4m3 INFERENCE of trained weights is
|
| 101 |
+
# viable (~5% cost). All normalizer clamps in this file are dtype-aware
|
| 102 |
+
# because 1e-9-class constants flush to ZERO in fp16 (measured NaN at
|
| 103 |
+
# ~5% of sharp reads before the fix).
|
| 104 |
+
# REPLICATOR'S WARNING: evaluation-protocol faults can fake
|
| 105 |
+
# architecture plateaus (a window-truncation ceiling masqueraded as a
|
| 106 |
+
# softmax plateau at .936 for two days of this record). The trainers
|
| 107 |
+
# directory ships the corrected harness; use its clean gauges.
|
| 108 |
+
#
|
| 109 |
# Status: research prototype. Trained-at-scale results pending; treat
|
| 110 |
# every number above as what it is — a measurement on the stated probe.
|
| 111 |
# =========================================================================
|
|
|
|
| 211 |
centers = frac * (L - 1)
|
| 212 |
g = torch.exp(-0.5 * ((pos.unsqueeze(0) - centers.unsqueeze(1))
|
| 213 |
/ sig) ** 2)
|
| 214 |
+
if g.dtype in (torch.float32, torch.float64):
|
| 215 |
+
_cl = 1e-9
|
| 216 |
+
else: # half dtypes: 1e-9 flushes to 0 (landmine)
|
| 217 |
+
_cl = float(torch.finfo(g.dtype).tiny) * 8
|
| 218 |
+
g = g / g.sum(dim=0, keepdim=True).clamp(min=_cl)
|
| 219 |
n_glob = int(round(self.M * self.global_frac))
|
| 220 |
if n_glob > 0:
|
| 221 |
g[:n_glob] = 1.0
|
|
|
|
| 265 |
c0, Mc)
|
| 266 |
out = out.add_(part)
|
| 267 |
den = den.add_(dpart)
|
| 268 |
+
if den.dtype in (torch.float32, torch.float64):
|
| 269 |
+
_cl = 1e-9
|
| 270 |
+
else: # half dtypes: 1e-9 flushes to 0 (landmine)
|
| 271 |
+
_cl = float(torch.finfo(den.dtype).tiny) * 8
|
| 272 |
+
out = out / den.unsqueeze(-1).clamp_min(_cl)
|
| 273 |
return self.drop(self.w_o(out))
|
| 274 |
|
| 275 |
|
| 276 |
+
|
| 277 |
+
class CausalSplatHUB(nn.Module):
|
| 278 |
+
"""Causal (autoregressive) aleph linear attention — the AR-validated
|
| 279 |
+
form from the rank-controlled recall battery. Prefix-sum memories over
|
| 280 |
+
the 2K oriented halves of the address; no selection event; O(L*K*d).
|
| 281 |
+
|
| 282 |
+
Guidance from the measured record (see header): D should match the
|
| 283 |
+
content's intrinsic dimensionality; K should be provisioned to the
|
| 284 |
+
task's addressing demand (knee tracks demand, constant is
|
| 285 |
+
demand-dependent — measure consumed address erank per layer); train
|
| 286 |
+
with momentum-geometric optimizers; fp32/bf16 only."""
|
| 287 |
+
|
| 288 |
+
def __init__(self, d_model, K=64, D=16, tau=0.1):
|
| 289 |
+
super().__init__()
|
| 290 |
+
self.K, self.D, self.tau = K, D, tau
|
| 291 |
+
self.codebook = nn.Parameter(F.normalize(torch.randn(K, D), dim=-1))
|
| 292 |
+
self.q = nn.Linear(d_model, D, bias=False)
|
| 293 |
+
self.k = nn.Linear(d_model, D, bias=False)
|
| 294 |
+
self.v = nn.Linear(d_model, d_model, bias=False)
|
| 295 |
+
self.o = nn.Linear(d_model, d_model, bias=False)
|
| 296 |
+
for m in (self.q, self.k, self.v, self.o):
|
| 297 |
+
nn.init.orthogonal_(m.weight)
|
| 298 |
+
|
| 299 |
+
def _oriented(self, x):
|
| 300 |
+
A = F.normalize(self.codebook, dim=-1)
|
| 301 |
+
u = (F.normalize(x, dim=-1) @ A.T) / self.tau
|
| 302 |
+
m = u.abs().amax(dim=-1, keepdim=True)
|
| 303 |
+
ep, en = torch.exp(u - m), torch.exp(-u - m)
|
| 304 |
+
Z = (ep + en).sum(dim=-1, keepdim=True)
|
| 305 |
+
return ep / Z, en / Z
|
| 306 |
+
|
| 307 |
+
def forward(self, x):
|
| 308 |
+
qp, qn = self._oriented(self.q(x))
|
| 309 |
+
kp, kn = self._oriented(self.k(x))
|
| 310 |
+
v = self.v(x)
|
| 311 |
+
Sp = torch.cumsum(torch.einsum("blk,bld->blkd", kp, v), dim=1)
|
| 312 |
+
Sn = torch.cumsum(torch.einsum("blk,bld->blkd", kn, v), dim=1)
|
| 313 |
+
zp = torch.cumsum(kp, dim=1)
|
| 314 |
+
zn = torch.cumsum(kn, dim=1)
|
| 315 |
+
num = (torch.einsum("blk,blkd->bld", qp, Sp)
|
| 316 |
+
+ torch.einsum("blk,blkd->bld", qn, Sn))
|
| 317 |
+
den = ((qp * zp).sum(-1, keepdim=True)
|
| 318 |
+
+ (qn * zn).sum(-1, keepdim=True))
|
| 319 |
+
if den.dtype in (torch.float32, torch.float64):
|
| 320 |
+
cl = 1e-12
|
| 321 |
+
else: # half dtypes: small constants flush to 0
|
| 322 |
+
cl = float(torch.finfo(den.dtype).tiny) * 8
|
| 323 |
+
return self.o(num / den.clamp_min(cl))
|
| 324 |
+
|
| 325 |
+
|
| 326 |
def _demo():
|
| 327 |
torch.manual_seed(0)
|
| 328 |
dev = "cuda" if torch.cuda.is_available() else "cpu"
|