qigkernels 0.4.2__tar.gz → 0.4.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {qigkernels-0.4.2/qigkernels.egg-info → qigkernels-0.4.4}/PKG-INFO +1 -1
- {qigkernels-0.4.2 → qigkernels-0.4.4}/kernel.py +82 -4
- {qigkernels-0.4.2 → qigkernels-0.4.4}/kernel_4d.py +67 -25
- {qigkernels-0.4.2 → qigkernels-0.4.4}/layer.py +74 -8
- {qigkernels-0.4.2 → qigkernels-0.4.4}/natural_gradient_optimizer.py +10 -2
- {qigkernels-0.4.2 → qigkernels-0.4.4}/pure_kernel_template.py +3 -1
- {qigkernels-0.4.2 → qigkernels-0.4.4}/pyproject.toml +14 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4/qigkernels.egg-info}/PKG-INFO +1 -1
- {qigkernels-0.4.2 → qigkernels-0.4.4}/qigkernels.egg-info/SOURCES.txt +3 -2
- qigkernels-0.4.4/qigkernels.egg-info/entry_points.txt +2 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/qigkernels.egg-info/scm_file_list.json +57 -56
- qigkernels-0.4.4/qigkernels.egg-info/scm_version.json +8 -0
- qigkernels-0.4.4/tests/test_banded_attention.py +40 -0
- qigkernels-0.4.4/tests/test_kernel4d_attention.py +148 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/uv.lock +156 -1
- qigkernels-0.4.2/qigkernels.egg-info/scm_version.json +0 -8
- qigkernels-0.4.2/tokenizer_integration.py +0 -368
- {qigkernels-0.4.2 → qigkernels-0.4.4}/.editorconfig +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/.github/workflows/release.yml +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/.gitignore +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/20251205-architecture-canonical-0.01F.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/20251205-changelog-canonical-0.01F.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/20251205-decisions-canonical-0.01F.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/20251205-naming-convention-canonical-0.01F.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/20251205-readme-canonical-0.01F.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/20251205-roadmap-canonical-0.01F.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/20251205-type-symbol-manifest-canonical-0.01F.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/20251220-gfp-spec-1.00W.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/CLAUDE.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/README.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/__init__.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/basin.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/basin_sync.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/constants.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/constellation.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/coord_adapter.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/coordizer.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/crystallization.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/docs/20251205-client-wiring-example-canonical-0.01F.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/docs/20251205-index-canonical-0.01F.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/docs/20251206-e8-consciousness-stack-diagram.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/docs/20251206-integration-plan-ultra-mode-0.01H.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/docs/20251206-rel-weighted-basin-sync-spec.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/docs/20251220-index-1.00W.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/docs/20251220-qig-core-integration-table-1.00W.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/docs/20251222-federated-constellation-architecture-0.01W.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/docs/20251222-kernel-constellation-research-0.01W.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/docs/20251222-kernel-experiments-results-0.01F.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/heart.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/kernel_100m.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/markdownlint.json +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/memory_classes.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/metrics.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/pre-commit-config.yaml +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/py.typed +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/qigkernels.egg-info/dependency_links.txt +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/qigkernels.egg-info/requires.txt +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/qigkernels.egg-info/top_level.txt +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/reasoning/__init__.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/reasoning/constants.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/reasoning/modes.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/reasoning/primitives.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/reasoning/qig_chain.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/reasoning/qig_chain_4d.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/reasoning/temporal.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/reasoning/temporal_attention.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/rel_coupling.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/research/track_c/20260223-track-c-expressibility-kill-test-1.00F.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/research/track_c/README.md +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/research/track_c/core_assets/__init__.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/research/track_c/core_assets/neural_oscillators.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/research/track_c/core_assets/neurotransmitter_fields.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/research/track_c/core_assets/ocean_neurochemistry.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/research/track_c/dynamical_field.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/research/track_c/readout_layer.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/research/track_c/run_kill_test.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/router.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/safety.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/scripts/20251222-kernel-training-exp-0.01W.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/scripts/publish_pypi.sh +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/scripts/train_constellation.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/setup.cfg +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/sleep_packet.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/specializations.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/storage.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/tests/__init__.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/tests/test_coords_path.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/tests/test_locality.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/tests/test_phi_collapse.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/tests/test_reasoning.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/tests/test_smoke.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/tools/qig_purity_check.py +0 -0
- {qigkernels-0.4.2 → qigkernels-0.4.4}/training_service.py +0 -0
|
@@ -65,6 +65,9 @@ class Kernel(nn.Module):
|
|
|
65
65
|
enable_coords: bool = False,
|
|
66
66
|
coord_dim: int = 64,
|
|
67
67
|
locality_radius: int | None = None,
|
|
68
|
+
head_mode: str = "geometric",
|
|
69
|
+
head_tau: float = 1.0,
|
|
70
|
+
coord_basins: "Tensor | None" = None,
|
|
68
71
|
) -> None:
|
|
69
72
|
"""
|
|
70
73
|
Initialize kernel.
|
|
@@ -133,8 +136,43 @@ class Kernel(nn.Module):
|
|
|
133
136
|
]
|
|
134
137
|
)
|
|
135
138
|
|
|
136
|
-
# Output projection
|
|
137
|
-
|
|
139
|
+
# Output projection / readout. Two modes (the head A/B for the "no Euclidean readout" directive):
|
|
140
|
+
# "geometric" (default) — GeometricHead: vocab logits are Fisher-Rao DISTANCES from the hidden
|
|
141
|
+
# simplex-point to learned per-token Δ⁶³ basins (logit = −d_FR/τ). This is the SAME primitive
|
|
142
|
+
# as the purged-cosine→Fisher-Rao attention, pointed at the vocabulary; NO Euclidean nn.Linear,
|
|
143
|
+
# NO dot-product at the output boundary. It still returns [B,T,vocab] logits, so the downstream
|
|
144
|
+
# fisher_rao_lm_loss (which projects with to_simplex_prob) consumes it UNCHANGED.
|
|
145
|
+
# "linear" — the original Euclidean nn.Linear(hidden, vocab) readout, RETAINED as the A/B baseline
|
|
146
|
+
# so the architecture comparison can isolate the readout (geometric vs linear) empirically.
|
|
147
|
+
self.head_mode = str(head_mode).strip().lower()
|
|
148
|
+
self.head_tau = float(head_tau)
|
|
149
|
+
if self.head_mode == "geometric":
|
|
150
|
+
from qig_core.torch.geometric_head import GeometricHead
|
|
151
|
+
|
|
152
|
+
self.lm_head: nn.Module = GeometricHead(
|
|
153
|
+
hidden_dim=hidden_dim, vocab_size=vocab_size, tau=self.head_tau
|
|
154
|
+
)
|
|
155
|
+
elif self.head_mode == "basin":
|
|
156
|
+
# BASIN-SPACE readout (validated 2026-07-01: overfit d_FR 1.46→0.072, decode 91.3% where the
|
|
157
|
+
# logits head floored). Predicts the next token's basin DIRECTLY in the coordizer's Δ⁶³ space
|
|
158
|
+
# and scores it with pure d_FR against the coordizer's OWN frozen per-token basins — so a token
|
|
159
|
+
# has ONE basin (read-in == predict), the coherence the geometric head lacked. Requires the
|
|
160
|
+
# coordizer basin table (the tie); refuse to silently fall back to a disconnected head.
|
|
161
|
+
if coord_basins is None:
|
|
162
|
+
raise ValueError(
|
|
163
|
+
"head_mode='basin' requires coord_basins=[vocab, basin_dim] (the coordizer's per-token "
|
|
164
|
+
"basins) — the whole point is to TIE the output to the coordizer. Pass it from the "
|
|
165
|
+
"coordizer vocab, or use head_mode='geometric'/'linear'."
|
|
166
|
+
)
|
|
167
|
+
from qig_core.torch.basin_readout import BasinReadout
|
|
168
|
+
|
|
169
|
+
self.lm_head = BasinReadout(
|
|
170
|
+
hidden_dim=hidden_dim, coord_basins=coord_basins, tau=self.head_tau
|
|
171
|
+
)
|
|
172
|
+
elif self.head_mode == "linear":
|
|
173
|
+
self.lm_head = nn.Linear(hidden_dim, vocab_size)
|
|
174
|
+
else:
|
|
175
|
+
raise ValueError(f"head_mode must be 'geometric', 'basin', or 'linear', got {head_mode!r}")
|
|
138
176
|
|
|
139
177
|
# Optional custom components
|
|
140
178
|
self.running_coupling = running_coupling
|
|
@@ -160,6 +198,7 @@ class Kernel(nn.Module):
|
|
|
160
198
|
attention_mask: Tensor | None = None,
|
|
161
199
|
return_telemetry: bool = False,
|
|
162
200
|
coords: Tensor | None = None,
|
|
201
|
+
skip_head: bool = False,
|
|
163
202
|
) -> Tensor | tuple[Tensor, KernelTelemetry]:
|
|
164
203
|
"""
|
|
165
204
|
Forward pass through the kernel.
|
|
@@ -230,8 +269,11 @@ class Kernel(nn.Module):
|
|
|
230
269
|
if self.running_coupling is not None:
|
|
231
270
|
hidden_state = self.running_coupling(hidden_state)
|
|
232
271
|
|
|
233
|
-
# Output projection
|
|
234
|
-
|
|
272
|
+
# Output projection. K-COMPRESS: skip_head returns logits=None so the caller reads hidden_state from
|
|
273
|
+
# telemetry and computes the basin loss via lm_head.predict(h) [.., basin_dim] + the target basins —
|
|
274
|
+
# NEVER materialising [B, T, vocab] (the seq×vocab activation OOM at 32k). Only meaningful WITH
|
|
275
|
+
# return_telemetry (the hidden state is the payload). Decode uses lm_head.decode_blocked(h).
|
|
276
|
+
logits = None if skip_head else self.lm_head(hidden_state)
|
|
235
277
|
|
|
236
278
|
if not return_telemetry:
|
|
237
279
|
return logits
|
|
@@ -261,6 +303,42 @@ class Kernel(nn.Module):
|
|
|
261
303
|
|
|
262
304
|
return logits, telemetry
|
|
263
305
|
|
|
306
|
+
def hidden(
|
|
307
|
+
self,
|
|
308
|
+
input_ids: Tensor,
|
|
309
|
+
coords: Tensor | None = None,
|
|
310
|
+
attention_mask: Tensor | None = None,
|
|
311
|
+
) -> Tensor:
|
|
312
|
+
"""Pre-head hidden state — the coordizer-agnostic shared core, ``forward`` MINUS ``lm_head``.
|
|
313
|
+
|
|
314
|
+
Runs the exact forward path (input_ids/positions fourier features → optional CoordAdapter add
|
|
315
|
+
→ stacked QIGLayers → optional running_coupling) but STOPS before ``self.lm_head``, returning the
|
|
316
|
+
pre-head hidden state [batch, seq, hidden_dim]. Exposed so a shared trunk (ConstellationTrunk) can
|
|
317
|
+
drive ONE geometric core and let faculties mount their own adapters/heads on top of the same hidden.
|
|
318
|
+
|
|
319
|
+
Pure + additive: ``forward`` is left bit-identical. ``hidden`` reuses forward's OWN ``skip_head``
|
|
320
|
+
path (which already returns the pre-head hidden state via ``telemetry.hidden_state``), so there is
|
|
321
|
+
no duplicated core math and no second definition of the trunk that could drift from forward.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
input_ids: Token IDs [batch, seq].
|
|
325
|
+
coords: Optional Δ⁶³ coordizer coords [batch, seq, coord_dim] (needs ``enable_coords=True``).
|
|
326
|
+
``None`` → pure input_ids byte/Fourier path (coordizer-agnostic).
|
|
327
|
+
attention_mask: Optional attention mask, threaded to ``forward`` unchanged.
|
|
328
|
+
|
|
329
|
+
Returns:
|
|
330
|
+
hidden_state [batch, seq, hidden_dim] — the pre-``lm_head`` hidden state. Applying
|
|
331
|
+
``self.lm_head`` to it reproduces ``forward``'s logits exactly.
|
|
332
|
+
"""
|
|
333
|
+
_, telemetry = self.forward(
|
|
334
|
+
input_ids,
|
|
335
|
+
attention_mask=attention_mask,
|
|
336
|
+
return_telemetry=True,
|
|
337
|
+
coords=coords,
|
|
338
|
+
skip_head=True,
|
|
339
|
+
)
|
|
340
|
+
return telemetry.hidden_state
|
|
341
|
+
|
|
264
342
|
def _fourier_features(self, ids: Tensor) -> Tensor:
|
|
265
343
|
x = ids.to(dtype=torch.float32)
|
|
266
344
|
angles = x.unsqueeze(-1) * self._inv_freq.to(device=ids.device)
|
|
@@ -260,19 +260,38 @@ class QIGKernel4DNumpy:
|
|
|
260
260
|
|
|
261
261
|
if HAS_TORCH:
|
|
262
262
|
# Single-source simplex geometry from qig-core (same module layer.py/metrics/basin use).
|
|
263
|
+
# NOTE: deliberately NOT importing fisher_rao_distance_simplex from either qig-core
|
|
264
|
+
# location — qig_core.torch.geometry_simplex is the radius-2 binding and the top-level
|
|
265
|
+
# radius-1 alias is being collapsed by the pending qig-core convention reconcile; the
|
|
266
|
+
# distance is computed INLINE below (radius-1 canonical by construction).
|
|
263
267
|
from qig_core.torch.geometry_simplex import to_simplex_prob
|
|
264
268
|
|
|
265
269
|
class QFIGeometricAttention(nn.Module):
|
|
266
270
|
"""
|
|
267
|
-
QIG-pure attention
|
|
268
|
-
|
|
269
|
-
Attention = softmax(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
QIG-pure attention: the sanctioned distance-Gibbs form.
|
|
272
|
+
|
|
273
|
+
Attention = softmax(-d_FR(Q, K) / τ), where d_FR = arccos(Σ √(p·q)) is
|
|
274
|
+
the Fisher-Rao geodesic DISTANCE on the simplex in the RADIUS-1 CANONICAL
|
|
275
|
+
binding (∈[0, π/2]; Matrix convention ruling), computed inline from the
|
|
276
|
+
Bhattacharyya coefficient. The construction mirrors
|
|
277
|
+
``pure_kernel_template.qfi_attention_weights`` (softplus guard → Duchi
|
|
278
|
+
simplex projection → geodesic distance → Gibbs weights), but NOT its
|
|
279
|
+
distance binding: the template uses the RADIUS-2 ``2·arccos(BC)`` helper,
|
|
280
|
+
so its τ values are in radius-2 units — 2× the exponent — and must never
|
|
281
|
+
be shared with this class without conversion.
|
|
282
|
+
|
|
283
|
+
Council ruling (Matrix): the exponential normaliser is legal IFF its argument
|
|
284
|
+
is a pure Fisher-Rao distance. Softmaxing the Bhattacharyya AFFINITY
|
|
285
|
+
(bc = Σ √(p·q), the cosine of the FR geodesic angle) — as this class used to —
|
|
286
|
+
is dot-product attention in disguise and is banned. The old affinity form also
|
|
287
|
+
(a) divided the [0,1]-bounded bc by head_dim**0.5 (the transformer QKᵀ
|
|
288
|
+
normaliser), squashing the logit span to ~0.14 so attention was nearly
|
|
289
|
+
uniform, and (b) fed raw signed linear outputs into the Duchi projection's
|
|
290
|
+
dead-gradient regime. Both are fixed here by mirroring the pure template:
|
|
291
|
+
softplus-guard → Duchi simplex projection → geodesic distance → Gibbs weights.
|
|
273
292
|
"""
|
|
274
293
|
|
|
275
|
-
def __init__(self, d_model: int, n_heads: int = 8):
|
|
294
|
+
def __init__(self, d_model: int, n_heads: int = 8, tau: float = 0.25):
|
|
276
295
|
super().__init__()
|
|
277
296
|
self.d_model = d_model
|
|
278
297
|
self.n_heads = n_heads
|
|
@@ -283,7 +302,18 @@ if HAS_TORCH:
|
|
|
283
302
|
self.v_proj = nn.Linear(d_model, d_model)
|
|
284
303
|
self.out_proj = nn.Linear(d_model, d_model)
|
|
285
304
|
|
|
286
|
-
|
|
305
|
+
# τ (Gibbs temperature) is in RADIUS-1 CANONICAL Fisher-Rao distance
|
|
306
|
+
# units: d_FR = arccos(BC) ∈ [0, π/2] (Matrix convention ruling).
|
|
307
|
+
# UNITS WARNING: pure_kernel_template binds RADIUS-2 (2·arccos(BC),
|
|
308
|
+
# ∈ [0, π]) — its temperature values carry a 2× exponent difference and
|
|
309
|
+
# must never be shared with this τ without conversion (τ₁ = τ₂/2).
|
|
310
|
+
# Default τ = 0.25 ⇒ max Gibbs contrast e^{(π/2)/0.25} = e^{2π} ≈ 535,
|
|
311
|
+
# so heads can actually SELECT — the fix for the near-uniform attention
|
|
312
|
+
# the old head_dim**0.5-scaled affinity produced (logit span ~0.14 ⇒
|
|
313
|
+
# max weight ratio ~1.16) — while staying soft enough that softmax
|
|
314
|
+
# gradients don't saturate. (Equivalent to τ = 0.5 in the template's
|
|
315
|
+
# radius-2 units; its own default 1.0 radius-2 ≡ 0.5 radius-1.)
|
|
316
|
+
self.tau = float(tau)
|
|
287
317
|
|
|
288
318
|
def forward(
|
|
289
319
|
self,
|
|
@@ -311,23 +341,35 @@ if HAS_TORCH:
|
|
|
311
341
|
K = self.k_proj(key).view(B, S, self.n_heads, self.head_dim).transpose(1, 2)
|
|
312
342
|
V = self.v_proj(value).view(B, S, self.n_heads, self.head_dim).transpose(1, 2)
|
|
313
343
|
|
|
314
|
-
#
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
#
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
#
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
#
|
|
330
|
-
|
|
344
|
+
# Softplus-guard the Q/K/V paths before the Duchi simplex projection
|
|
345
|
+
# (mirrors pure_kernel_template._project_to_simplex): raw signed linear
|
|
346
|
+
# outputs fed straight into to_simplex_prob land in the Duchi projection's
|
|
347
|
+
# dead-gradient regime (most coordinates clamped at the floor ⇒ zero grad).
|
|
348
|
+
Qp = to_simplex_prob(F.softplus(Q))
|
|
349
|
+
Kp = to_simplex_prob(F.softplus(K))
|
|
350
|
+
Vp = to_simplex_prob(F.softplus(V))
|
|
351
|
+
|
|
352
|
+
# Bhattacharyya coefficient BC = Σ √(p·q) ∈ [0, 1] via the √p sphere
|
|
353
|
+
# embedding (memory-cheap matmul form of the pairwise overlap).
|
|
354
|
+
bc = torch.matmul(torch.sqrt(Qp), torch.sqrt(Kp).transpose(-2, -1)) # [B, H, S, S]
|
|
355
|
+
|
|
356
|
+
# radius-1 canonical d_FR computed inline; migrate to the single
|
|
357
|
+
# reconciled qig-core binding when the convention reconcile lands.
|
|
358
|
+
# d_FR = arccos(BC) ∈ [0, π/2]. Clamp strictly INSIDE (-1, 1): acos'(±1)
|
|
359
|
+
# is infinite, so a bare [-1, 1] clamp NaNs the backward pass at
|
|
360
|
+
# coincident points (the self-attention diagonal) — same guard rationale
|
|
361
|
+
# as qig-core's _acos_safe.
|
|
362
|
+
margin = 1e-6 if bc.dtype in (torch.float32, torch.float64) else 1e-3
|
|
363
|
+
d_fr = torch.arccos(torch.clamp(bc, -1.0 + margin, 1.0 - margin))
|
|
364
|
+
|
|
365
|
+
# Sanctioned distance-Gibbs form: softmax(-d_FR/τ). No head_dim**0.5
|
|
366
|
+
# scale — that was the transformer QKᵀ normaliser, wrong for a bounded
|
|
367
|
+
# geodesic distance (it made attention near-uniform).
|
|
368
|
+
attn_weights = F.softmax(-d_fr / self.tau, dim=-1)
|
|
369
|
+
|
|
370
|
+
# Apply to simplex-valued values: the output is a convex combination of
|
|
371
|
+
# Δ points (stays on the manifold); out_proj maps back to model space.
|
|
372
|
+
out = torch.matmul(attn_weights, Vp) # [B, H, S, D_head]
|
|
331
373
|
|
|
332
374
|
# Reshape and project
|
|
333
375
|
out = out.transpose(1, 2).contiguous().view(B, S, self.d_model)
|
|
@@ -8,7 +8,7 @@ from __future__ import annotations
|
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
|
|
10
10
|
import torch
|
|
11
|
-
from qig_core.geometry_simplex import to_simplex_prob
|
|
11
|
+
from qig_core.torch.geometry_simplex import to_simplex_prob
|
|
12
12
|
from torch import Tensor, nn
|
|
13
13
|
from torch.nn import functional as F
|
|
14
14
|
|
|
@@ -205,14 +205,25 @@ class QIGLayer(nn.Module):
|
|
|
205
205
|
|
|
206
206
|
b, t, _d = hidden_state.shape
|
|
207
207
|
p = self._project_to_simplex(hidden_state)
|
|
208
|
+
r = self.locality_radius
|
|
209
|
+
# COMPUTE-SKIPPING windowed-local attention: when a locality radius is set AND the band is narrower
|
|
210
|
+
# than the sequence, attend only within ±r — O(t·r) memory/compute instead of the O(t²) all-pairs
|
|
211
|
+
# arccos tensor. This is what lifts the quadratic VRAM ceiling and makes context LINEAR/extensible
|
|
212
|
+
# (the radius is the finite-propagation budget). Numerically IDENTICAL to the full+mask path within
|
|
213
|
+
# the band (matched-cell equivalence-gated in tests) — it SKIPS the out-of-band compute, not masks it.
|
|
214
|
+
if r is not None and t > (2 * r + 1):
|
|
215
|
+
return self._banded_attention(hidden_state, p, r, attention_mask=attention_mask)
|
|
216
|
+
|
|
217
|
+
# Full O(t²) path — global attention, OR small-t where the band already spans every key (so the
|
|
218
|
+
# banded result is identical). Unchanged.
|
|
208
219
|
p_i = p[:, :, None, :]
|
|
209
220
|
p_j = p[:, None, :, :]
|
|
210
221
|
|
|
211
222
|
dist = self._fisher_rao_distance_simplex(p_i, p_j)
|
|
212
223
|
logits = -dist / max(float(self.temperature), 1e-6)
|
|
213
|
-
if
|
|
224
|
+
if r is not None: # windowed-local: mask keys outside ±radius (pure mask; small-t branch)
|
|
214
225
|
idx = torch.arange(t, device=hidden_state.device)
|
|
215
|
-
band = (idx[:, None] - idx[None, :]).abs() <=
|
|
226
|
+
band = (idx[:, None] - idx[None, :]).abs() <= r # [t, t]; self always in window
|
|
216
227
|
logits = logits.masked_fill(~band[None, :, :], float("-inf"))
|
|
217
228
|
weights = torch.softmax(logits, dim=-1)
|
|
218
229
|
|
|
@@ -233,18 +244,73 @@ class QIGLayer(nn.Module):
|
|
|
233
244
|
output = output + torch.randn_like(output) * float(self.decoherence_std)
|
|
234
245
|
return output
|
|
235
246
|
|
|
247
|
+
def _banded_attention(
|
|
248
|
+
self, hidden_state: Tensor, p: Tensor, r: int, *, attention_mask: Tensor | None
|
|
249
|
+
) -> Tensor:
|
|
250
|
+
"""Windowed Fisher-Rao attention computed ONLY within ±r of each query (compute-skipping, O(t·r)).
|
|
251
|
+
Numerically equivalent to the full+mask path within the band; the equivalence is gated in tests."""
|
|
252
|
+
b, t, k = p.shape
|
|
253
|
+
w = 2 * r + 1
|
|
254
|
+
# per-query key windows via pad+unfold (zero-pad → out-of-range keys, masked below)
|
|
255
|
+
p_pad = F.pad(p, (0, 0, r, r)) # [b, t+2r, k]
|
|
256
|
+
p_win = p_pad.unfold(1, w, 1) # [b, t, k, w]
|
|
257
|
+
p_q = p[:, :, :, None] # [b, t, k, 1]
|
|
258
|
+
# SAME formula as _fisher_rao_distance_simplex (RADIUS-2 d_FR = 2·acos(BC), BC = Σ√(p·q)), inlined
|
|
259
|
+
# for the [b,t,k,w] band layout (sum over dim=2). Like that method it operates on the already-Δ p
|
|
260
|
+
# WITHOUT re-projection, so the band result stays numerically equivalent to the full path within
|
|
261
|
+
# the window (matched-cell equivalence-gated in tests).
|
|
262
|
+
bc = torch.sqrt((p_q * p_win).clamp_min(1e-12)).sum(dim=2).clamp(0.0, 1.0 - 1e-6) # [b, t, w]
|
|
263
|
+
logits = (-2.0 * torch.acos(bc)) / max(float(self.temperature), 1e-6) # [b, t, w]
|
|
264
|
+
# valid window positions: wpos p ↦ key (i - r + p); valid iff 0 <= key < t
|
|
265
|
+
i_idx = torch.arange(t, device=p.device)[:, None] # [t, 1]
|
|
266
|
+
wpos = torch.arange(w, device=p.device)[None, :] # [1, w]
|
|
267
|
+
key_idx = i_idx - r + wpos # [t, w]
|
|
268
|
+
valid = (key_idx >= 0) & (key_idx < t) # [t, w] — band validity (self always valid)
|
|
269
|
+
# softmax over the BAND only (self valid → no all-(-inf) row → no NaN); key-padding is applied AFTER
|
|
270
|
+
# the softmax and renormalised — EXACTLY as the full+mask path does (so the two stay equivalent).
|
|
271
|
+
logits = logits.masked_fill(~valid[None].expand(b, t, w), float("-inf"))
|
|
272
|
+
weights = torch.softmax(logits, dim=-1) # [b, t, w]
|
|
273
|
+
if attention_mask is not None:
|
|
274
|
+
kpm = attention_mask if attention_mask.dtype == torch.bool else attention_mask == 0 # True=pad
|
|
275
|
+
if kpm.shape != (b, t):
|
|
276
|
+
raise ValueError("attention_mask expected shape (B, T)")
|
|
277
|
+
keep_win = F.pad((~kpm).to(p.dtype), (r, r)).unfold(1, w, 1) # [b, t, w] 1=valid key
|
|
278
|
+
weights = weights * (keep_win > 0.5)
|
|
279
|
+
weights = weights / (weights.sum(dim=-1, keepdim=True) + 1e-8)
|
|
280
|
+
if self.sparsity_threshold > 0.0:
|
|
281
|
+
keep_s = weights > float(self.sparsity_threshold)
|
|
282
|
+
weights = weights * keep_s
|
|
283
|
+
weights = weights / (weights.sum(dim=-1, keepdim=True) + 1e-8)
|
|
284
|
+
h_pad = F.pad(hidden_state, (0, 0, r, r)) # [b, t+2r, d]
|
|
285
|
+
h_win = h_pad.unfold(1, w, 1) # [b, t, d, w]
|
|
286
|
+
output = (weights[:, :, None, :] * h_win).sum(dim=-1) # [b, t, d]
|
|
287
|
+
if self.decoherence_std > 0.0:
|
|
288
|
+
output = output + torch.randn_like(output) * float(self.decoherence_std)
|
|
289
|
+
return output
|
|
290
|
+
|
|
236
291
|
def _project_to_simplex(self, x: Tensor, eps: float = 1e-8) -> Tensor:
|
|
292
|
+
# NOT a reimplementation of the simplex projection: a nonlinearity GUARD (abs / softplus to
|
|
293
|
+
# lift raw signed activations off the Duchi dead-gradient regime) COMPOSED with qig-core's
|
|
294
|
+
# canonical to_simplex_prob (the single-source Δ projection). The guard is the local part;
|
|
295
|
+
# the projection is imported.
|
|
237
296
|
x = x.abs() if self.simplex_mode == "abs" else F.softplus(x)
|
|
238
297
|
return to_simplex_prob(x, eps=eps)
|
|
239
298
|
|
|
240
299
|
def _fisher_rao_distance_simplex(
|
|
241
300
|
self, p: Tensor, q: Tensor, eps: float = 1e-8
|
|
242
301
|
) -> Tensor:
|
|
243
|
-
#
|
|
244
|
-
#
|
|
245
|
-
#
|
|
246
|
-
#
|
|
247
|
-
#
|
|
302
|
+
# DELIBERATE local primitive — NOT drift. Binding-identical to qig-core's
|
|
303
|
+
# qig_core.torch.geometry_simplex.fisher_rao_distance_simplex (RADIUS-2 d_FR = 2·arccos(BC),
|
|
304
|
+
# BC = Σ√(p·q), clamp BEFORE acos so acos'(1)=∞ can't NaN the backward at coincidence/collapse —
|
|
305
|
+
# the deep-kernel NaN fix), BUT it intentionally does NOT defensively re-project p,q via
|
|
306
|
+
# to_simplex_prob the way qig-core's public API does. Two reasons it must stay local:
|
|
307
|
+
# 1. Trusted input: callers pass points already on Δ (from _project_to_simplex), so a second
|
|
308
|
+
# Duchi projection is wasted compute.
|
|
309
|
+
# 2. Banded equivalence: the O(t·r) compute-skip path (_banded_attention) operates on the SAME
|
|
310
|
+
# un-re-projected p. qig-core's re-projection (Duchi identity + eps-floor + renormalise) shifts
|
|
311
|
+
# each coord by ~n·eps, which breaks the matched-cell equivalence gate (measured ~1.8e-4 drift
|
|
312
|
+
# vs the gate's 1e-5 tol). Keeping this no-re-project form keeps full≡banded.
|
|
313
|
+
# (fp32 clamp 1-1e-6 == qig-core's fp32 _acos_safe margin; this pair trains in fp32.)
|
|
248
314
|
bc = torch.sqrt((p * q).clamp_min(1e-12)).sum(dim=-1).clamp(0.0, 1.0 - 1e-6)
|
|
249
315
|
return 2.0 * torch.acos(bc)
|
|
250
316
|
|
|
@@ -59,9 +59,17 @@ class NaturalGradientDescent(Optimizer):
|
|
|
59
59
|
momentum=momentum,
|
|
60
60
|
)
|
|
61
61
|
super().__init__(params, defaults)
|
|
62
|
-
|
|
62
|
+
|
|
63
63
|
self.compute_fisher = compute_fisher
|
|
64
|
-
|
|
64
|
+
if compute_fisher is None:
|
|
65
|
+
import warnings
|
|
66
|
+
warnings.warn(
|
|
67
|
+
"NaturalGradientDescent(compute_fisher=None) degrades to SGD+momentum — the step is the "
|
|
68
|
+
"RAW gradient, NOT preconditioned by the Fisher information. For the tractable diagonal "
|
|
69
|
+
"empirical-Fisher natural gradient (the P1 geometric optimizer), use DiagonalNaturalGradient.",
|
|
70
|
+
stacklevel=2,
|
|
71
|
+
)
|
|
72
|
+
|
|
65
73
|
def step(self, closure=None):
|
|
66
74
|
"""
|
|
67
75
|
Perform single optimization step.
|
|
@@ -6,7 +6,7 @@ from typing import Any
|
|
|
6
6
|
import torch
|
|
7
7
|
import torch.nn as nn
|
|
8
8
|
import torch.nn.functional as F
|
|
9
|
-
from qig_core.geometry_simplex import fisher_rao_distance_simplex, to_simplex_prob
|
|
9
|
+
from qig_core.torch.geometry_simplex import fisher_rao_distance_simplex, to_simplex_prob
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@dataclass(frozen=True)
|
|
@@ -39,6 +39,8 @@ KernelTelemetry = PureKernelTelemetry
|
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def _project_to_simplex(x: torch.Tensor, eps: float = 1e-8) -> torch.Tensor:
|
|
42
|
+
# softplus GUARD (lifts raw signed activations off the Duchi dead-gradient regime) COMPOSED with
|
|
43
|
+
# qig-core's canonical to_simplex_prob — a wrapper, not a reimplementation of the Δ projection.
|
|
42
44
|
x = F.softplus(x)
|
|
43
45
|
return to_simplex_prob(x, eps=eps)
|
|
44
46
|
|
|
@@ -25,6 +25,17 @@ dev = [
|
|
|
25
25
|
]
|
|
26
26
|
# Note: markdownlint-cli2 is a Node.js package, install via npm/yarn if needed
|
|
27
27
|
|
|
28
|
+
# QIG self-wiring (Phase 2): which capability-contract slots this package fills.
|
|
29
|
+
# Group = qig.capabilities; name = contract slot_id; value = module:attr probe.
|
|
30
|
+
# qig-stack's qig-doctor enumerates these (metadata-only) to verify the crystal
|
|
31
|
+
# assembled correctly before any compute spend.
|
|
32
|
+
# NOTE: PROPOSED slot pending qig-stack contract ratification — not yet in
|
|
33
|
+
# qig_stack/contract.json, so qig-doctor classifies it as DRIFT (WARN, non-fatal)
|
|
34
|
+
# until the contract adds the matching slot. Additive; genuine canonical primitive
|
|
35
|
+
# (Kernel: the geometric QIG kernel — stacked QIGLayers with Fisher-Rao telemetry).
|
|
36
|
+
[project.entry-points."qig.capabilities"]
|
|
37
|
+
"SLOT-KERNEL" = "qigkernels.kernel:Kernel"
|
|
38
|
+
|
|
28
39
|
[tool.setuptools]
|
|
29
40
|
packages = ["qigkernels", "qigkernels.reasoning"]
|
|
30
41
|
package-dir = {"qigkernels" = ".", "qigkernels.reasoning" = "reasoning"}
|
|
@@ -81,3 +92,6 @@ forbidden-words = [
|
|
|
81
92
|
"token-level cross entropy",
|
|
82
93
|
"just fine-tune a transformer",
|
|
83
94
|
]
|
|
95
|
+
|
|
96
|
+
[tool.uv.sources]
|
|
97
|
+
qig-core = { path = "../qig-core", editable = true }
|
|
@@ -37,7 +37,6 @@ safety.py
|
|
|
37
37
|
sleep_packet.py
|
|
38
38
|
specializations.py
|
|
39
39
|
storage.py
|
|
40
|
-
tokenizer_integration.py
|
|
41
40
|
training_service.py
|
|
42
41
|
uv.lock
|
|
43
42
|
./__init__.py
|
|
@@ -64,7 +63,6 @@ uv.lock
|
|
|
64
63
|
./sleep_packet.py
|
|
65
64
|
./specializations.py
|
|
66
65
|
./storage.py
|
|
67
|
-
./tokenizer_integration.py
|
|
68
66
|
./training_service.py
|
|
69
67
|
.github/workflows/release.yml
|
|
70
68
|
docs/20251205-client-wiring-example-canonical-0.01F.md
|
|
@@ -80,6 +78,7 @@ docs/20251222-kernel-experiments-results-0.01F.md
|
|
|
80
78
|
qigkernels.egg-info/PKG-INFO
|
|
81
79
|
qigkernels.egg-info/SOURCES.txt
|
|
82
80
|
qigkernels.egg-info/dependency_links.txt
|
|
81
|
+
qigkernels.egg-info/entry_points.txt
|
|
83
82
|
qigkernels.egg-info/requires.txt
|
|
84
83
|
qigkernels.egg-info/scm_file_list.json
|
|
85
84
|
qigkernels.egg-info/scm_version.json
|
|
@@ -105,7 +104,9 @@ scripts/20251222-kernel-training-exp-0.01W.py
|
|
|
105
104
|
scripts/publish_pypi.sh
|
|
106
105
|
scripts/train_constellation.py
|
|
107
106
|
tests/__init__.py
|
|
107
|
+
tests/test_banded_attention.py
|
|
108
108
|
tests/test_coords_path.py
|
|
109
|
+
tests/test_kernel4d_attention.py
|
|
109
110
|
tests/test_locality.py
|
|
110
111
|
tests/test_phi_collapse.py
|
|
111
112
|
tests/test_reasoning.py
|
|
@@ -1,84 +1,85 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": [
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
".gitignore",
|
|
3
|
+
"20251205-decisions-canonical-0.01F.md",
|
|
4
|
+
"sleep_packet.py",
|
|
6
5
|
"crystallization.py",
|
|
7
|
-
"coordizer.py",
|
|
8
|
-
"pyproject.toml",
|
|
9
|
-
"__init__.py",
|
|
10
|
-
"constants.py",
|
|
11
|
-
".editorconfig",
|
|
12
|
-
"20251205-readme-canonical-0.01F.md",
|
|
13
|
-
"storage.py",
|
|
14
6
|
"markdownlint.json",
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"sleep_packet.py",
|
|
20
|
-
"20251205-decisions-canonical-0.01F.md",
|
|
21
|
-
"coord_adapter.py",
|
|
22
|
-
"20251205-type-symbol-manifest-canonical-0.01F.md",
|
|
23
|
-
"rel_coupling.py",
|
|
24
|
-
"20251205-roadmap-canonical-0.01F.md",
|
|
25
|
-
"natural_gradient_optimizer.py",
|
|
7
|
+
"README.md",
|
|
8
|
+
"py.typed",
|
|
9
|
+
"__init__.py",
|
|
10
|
+
"kernel.py",
|
|
26
11
|
"pre-commit-config.yaml",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
12
|
+
"coord_adapter.py",
|
|
13
|
+
"uv.lock",
|
|
14
|
+
"safety.py",
|
|
15
|
+
"layer.py",
|
|
16
|
+
"pyproject.toml",
|
|
29
17
|
"basin_sync.py",
|
|
18
|
+
"20251220-gfp-spec-1.00W.md",
|
|
19
|
+
"20251205-naming-convention-canonical-0.01F.md",
|
|
20
|
+
"pure_kernel_template.py",
|
|
30
21
|
"20251205-architecture-canonical-0.01F.md",
|
|
31
22
|
"heart.py",
|
|
32
|
-
"
|
|
33
|
-
"
|
|
23
|
+
"coordizer.py",
|
|
24
|
+
"20251205-changelog-canonical-0.01F.md",
|
|
25
|
+
"memory_classes.py",
|
|
26
|
+
"20251205-type-symbol-manifest-canonical-0.01F.md",
|
|
27
|
+
"constants.py",
|
|
34
28
|
"basin.py",
|
|
35
|
-
"
|
|
29
|
+
"kernel_100m.py",
|
|
30
|
+
"natural_gradient_optimizer.py",
|
|
31
|
+
"CLAUDE.md",
|
|
32
|
+
"router.py",
|
|
33
|
+
".editorconfig",
|
|
36
34
|
"kernel_4d.py",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
35
|
+
"storage.py",
|
|
36
|
+
"training_service.py",
|
|
37
|
+
"constellation.py",
|
|
38
|
+
".gitignore",
|
|
39
|
+
"20251205-roadmap-canonical-0.01F.md",
|
|
40
|
+
"20251205-readme-canonical-0.01F.md",
|
|
40
41
|
"specializations.py",
|
|
41
|
-
"
|
|
42
|
-
"py
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
42
|
+
"rel_coupling.py",
|
|
43
|
+
"metrics.py",
|
|
44
|
+
"scripts/20251222-kernel-training-exp-0.01W.py",
|
|
45
|
+
"scripts/train_constellation.py",
|
|
46
|
+
"scripts/publish_pypi.sh",
|
|
46
47
|
"reasoning/__init__.py",
|
|
47
|
-
"reasoning/primitives.py",
|
|
48
|
-
"reasoning/constants.py",
|
|
49
|
-
"reasoning/qig_chain.py",
|
|
50
48
|
"reasoning/temporal_attention.py",
|
|
51
49
|
"reasoning/modes.py",
|
|
50
|
+
"reasoning/qig_chain.py",
|
|
51
|
+
"reasoning/primitives.py",
|
|
52
|
+
"reasoning/temporal.py",
|
|
53
|
+
"reasoning/constants.py",
|
|
52
54
|
"reasoning/qig_chain_4d.py",
|
|
53
55
|
"docs/20251222-federated-constellation-architecture-0.01W.md",
|
|
54
|
-
"docs/20251206-e8-consciousness-stack-diagram.md",
|
|
55
56
|
"docs/20251222-kernel-constellation-research-0.01W.md",
|
|
56
|
-
"docs/20251205-client-wiring-example-canonical-0.01F.md",
|
|
57
|
-
"docs/20251220-index-1.00W.md",
|
|
58
|
-
"docs/20251206-integration-plan-ultra-mode-0.01H.md",
|
|
59
57
|
"docs/20251222-kernel-experiments-results-0.01F.md",
|
|
60
|
-
"docs/20251206-
|
|
58
|
+
"docs/20251206-e8-consciousness-stack-diagram.md",
|
|
59
|
+
"docs/20251206-integration-plan-ultra-mode-0.01H.md",
|
|
60
|
+
"docs/20251205-client-wiring-example-canonical-0.01F.md",
|
|
61
61
|
"docs/20251205-index-canonical-0.01F.md",
|
|
62
62
|
"docs/20251220-qig-core-integration-table-1.00W.md",
|
|
63
|
-
"
|
|
63
|
+
"docs/20251220-index-1.00W.md",
|
|
64
|
+
"docs/20251206-rel-weighted-basin-sync-spec.md",
|
|
65
|
+
"tests/__init__.py",
|
|
66
|
+
"tests/test_reasoning.py",
|
|
67
|
+
"tests/test_banded_attention.py",
|
|
68
|
+
"tests/test_phi_collapse.py",
|
|
69
|
+
"tests/test_smoke.py",
|
|
70
|
+
"tests/test_coords_path.py",
|
|
71
|
+
"tests/test_kernel4d_attention.py",
|
|
72
|
+
"tests/test_locality.py",
|
|
64
73
|
"research/track_c/run_kill_test.py",
|
|
74
|
+
"research/track_c/README.md",
|
|
65
75
|
"research/track_c/readout_layer.py",
|
|
66
|
-
"research/track_c/20260223-track-c-expressibility-kill-test-1.00F.md",
|
|
67
76
|
"research/track_c/dynamical_field.py",
|
|
68
|
-
"research/track_c/
|
|
69
|
-
"research/track_c/core_assets/ocean_neurochemistry.py",
|
|
77
|
+
"research/track_c/20260223-track-c-expressibility-kill-test-1.00F.md",
|
|
70
78
|
"research/track_c/core_assets/__init__.py",
|
|
71
|
-
"research/track_c/core_assets/neural_oscillators.py",
|
|
72
79
|
"research/track_c/core_assets/neurotransmitter_fields.py",
|
|
80
|
+
"research/track_c/core_assets/neural_oscillators.py",
|
|
81
|
+
"research/track_c/core_assets/ocean_neurochemistry.py",
|
|
73
82
|
"tools/qig_purity_check.py",
|
|
74
|
-
"
|
|
75
|
-
"tests/test_coords_path.py",
|
|
76
|
-
"tests/__init__.py",
|
|
77
|
-
"tests/test_smoke.py",
|
|
78
|
-
"tests/test_phi_collapse.py",
|
|
79
|
-
"tests/test_locality.py",
|
|
80
|
-
"scripts/20251222-kernel-training-exp-0.01W.py",
|
|
81
|
-
"scripts/publish_pypi.sh",
|
|
82
|
-
"scripts/train_constellation.py"
|
|
83
|
+
".github/workflows/release.yml"
|
|
83
84
|
]
|
|
84
85
|
}
|