research spec
03 — Real Hidden-State Extraction at Layer L
- File
03-layer-l-hidden-extraction.md- Size
- 12.4 KB
- SHA-256
ebbeebeda1ecdee7…
03 — Real Hidden-State Extraction at Layer L
Feed the cortex the residual where semantic intent actually forms, not the final-layer mean-pool it metabolizes today.
Status: REFUTED (2026-07-01, S1.4) | Thesis anchor: experiments.txt §1 (correction-gated SSM cortex), §3 (neural hippocampus) | Goal anchor: GOALS.md Goal 2 (hidden-state extraction at layer L) | Depends on / relates to: 04-context-scoped-attractors (consumer), 05-metabolism-loop-closure (consumer), 02-kv-slot-fact-injection (sibling Goal 1, blocked), 01-correction-to-competence-benchmark (eval substrate)
Outcome (2026-07-01): REFUTED. S1.4 HF layer-L probe (
../experiments_logs/2026-07-01_s1_4_hf_layer_probe.md) measured warm_sep_silhouette on two architectures: Qwen2.5-0.5B-Instruct (gap −0.083, threshold +0.10) and LFM2.5-1.2B-Instruct (gap +0.058, threshold +0.10). Mid-layer hiddens do NOT cluster by concept better than the final layer on either model. This confirms lane_03's refutation on a substrate that can see every layer — the mid-layer assumption is a model property, not a llama.cpp keyhole.Campaign note (2026-07-11): Campaign 0d48130 attempted to re-run Exp03 on colab but was infrastructure-blocked — repeated HF snapshot transfers failed before execution; no metrics or ASI scores emitted. This is not a scientific null or refutation; the authoritative pre-campaign verdict remains S1.4 above. Evidence:
../experiments_logs/2026-07-11_campaign_0d48130.md.
Problem
The cortex's only window into the LM is a depth-final, position-averaged summary, and that is almost certainly the wrong signal.
CortexAgent.perceive()feedscortex.observe()the output ofdriver.peek_embedding(utterance, last_token_only=False)(src/oczy/experiments/cortex_agent.py:354), which is the final-layer, MEAN-pooled embedding produced byllama_cppcreate_embedding(src/oczy/lm/cvec_driver.py:514-572, pooling type MEAN). The docstring on that call (cortex_agent.py:350-353) explicitly marks it "Goal 2 staging."peek_layerdoes not exist.cvec_driver.py:519-520states: "Layer-L intermediate extraction is not supported here yet (binding limitation tracked under Goal 2)." GOALS.md "Goal 2 — Hidden-state extraction at layer L" is unimplemented.- The Goal-2 rationale in GOALS.md is the gap: "Real cortex metabolism needs the residual at a layer that actually carries semantic intent — empirically layers in the middle to upper third," not the embedding/final summary the cortex sees now.
- The cortex subsystem brief records this as an unanswered open question: "Is the final-layer mean-pooled embedding rich enough for meaningful steering, or does Goal 2 (layer-L peek) materially change the proj_hidden → warm_state signal?" No experiment has measured it.
- We cannot answer it with the current metrics. Every recent run reports
code_qa_accuracy=1.0(runs #79, #80, #82, #84, #85, #95, #101), and wherever a recall path succeeds it pins straight to ceiling —domain_co_recall1/1 (real driver, run #95) and prefix-driven exactco_recall1/1 (run #101); mock-driver exactco_recallis 0/0 (run #85) only because the hash embeddings carry no semantics. None of these discriminate architecture variants. A new, non-saturating representational metric is required to tell whether layer-L input changes the cortex at all.
Grounded layer facts (these correct the stale n_layers=28 in CLAUDE.md KEY FACTS — and the matching "28-layer transformer" phrasing in GOALS.md's own Goal-2 rationale): the actual checkpoint config at ~/.cache/huggingface/hub/models--LiquidAI--LFM2.5-1.2B-Instruct/snapshots/<rev>/config.json is model_type=lfm2, hidden_size=2048, num_hidden_layers=16, vocab_size=65536, with layer_types placing full_attention blocks at config indices [2, 5, 8, 10, 12, 14] (the other 10 blocks are conv). The GGUF driver's llama_n_layer also reports 16 (brief), matching HF — so "layer L" ranges over 16 blocks, and the 6 attention blocks are the most plausible carriers of routed semantic intent.
Hypothesis
- H1 (depth/position matter). A cortex fed the residual at a mid/upper attention block (HF
hidden_statesindex ~9 or ~13) yieldswarm_statevectors that are more semantically separable — paraphrases cluster, distinct concepts separate — than the same cortex fed layer-0 embeddings or the current final-layer mean-pool, by a cosine-silhouette margin ≥ 0.10. - H2 (structure is semantic, not a Hebbian artifact).
proj_hiddentrained withKVCortex.train_step(Hebbian,plastic-cortex/src/plastic_cortex/kv_cortex.py:499-524) on real layer-L hiddens aligns its row-subspace with the top-PCA subspace of those hiddens at ≥ 2× chance and ≥ 2× a column-shuffled-hidden control — i.e., the learned projector reflects the real hidden manifold, not self-amplified noise.
Falsifier. If layer-L silhouette ≤ final-mean-pool silhouette, or if warm_state trajectories for layer-L vs layer-0 stay cosine ≥ 0.98 over an identical utterance stream (the input source is irrelevant), then Goal 2 buys the cortex nothing measurable and the production swap is killed.
Why now / what unblocks it
transformers==5.12.1is installed and ships anlfm2module (Lfm2ForCausalLMis importable), and the full-precision HF checkpoint is already cached locally (models--LiquidAI--LFM2.5-1.2B-Instruct). So the brief's named "twin eval with activation capture" path is a one-callfrom_pretrained(..., output_hidden_states=True)forward — no binding fork, no network.- The validation needs no steering/articulation, so it sidesteps the blocked KV-slot path (Goal 1 / sibling 02) and the saturated benchmark entirely: it only exercises
cortex.observeinput →warm_stateandproj_hidden, both pure-numpy (kv_cortex.py:173-225, 499-524). - A binding-side fallback exists if the twin is too heavy:
llama_context_default_paramsexposescb_eval/cb_eval_user_data(the ggml backend eval callback — verified present inllama_cpp0.3.31), the brief's "binding hook" path, runnable on the already-loaded Q4 context.
Approach (ties to §1, §3)
- Implement
peek_layer(prompt, layer_idx, pooling)on an HF twin driver returning ad_embd=2048float32 vector: tokenize → forward withoutput_hidden_states=True→ selecthidden_states[layer_idx]→ pool (last-token default; mean optional). This is the cortex's real input window (§1). - Drive the existing
KVCortex.observe()/train_step()unchanged; vary only the peek-source layer (matched-pair single-variable, the repo standard). - Measure (a) representational separability of
warm_stateand (b) structural alignment ofproj_hidden— §1 (does the SSM cortex metabolize real intent?) and §3 (do the resulting hidden traces have hippocampus-worthy structure?). - Parity-check the twin against the GGUF final embedding so we know it is the same network (control).
- Defer the production wiring — swapping
cortex_agent.py:354peek_embedding→peek_layer(L)— behind passing acceptance. That swap is what unblocks 04 (context-scoped attractors need rich, separable cortex state) and 05 (metabolism loop needs real intent in, not a position-mean).
Success criteria (discriminating, non-saturating)
These deliberately avoid code_qa_accuracy/co_recall, which already sit at 1.0 wherever they apply.
warm_sep_silhouette(headline). Cosine-silhouette ofwarm_statevectors over a labeled paraphrase/distinct battery. Pass:silhouette(L_mid) − silhouette(L0) ≥ 0.10andsilhouette(L_mid) − silhouette(final-mean-pool) ≥ 0.10. Cannot saturate: within-group paraphrase variance is non-zero, so silhouette < 1 by construction.warm_traj_cos_L_vs_L0. Mean per-step cosine between layer-L and layer-0warm_stateover an identical 16-utterance stream. Pass: ≤ 0.80 (trajectories visibly diverge — operationalizes GOALS.md done-when #2, today only a qualitative claim).projh_align_ratio. PCA-subspace alignment of Hebbian-trainedproj_hidden: real-trained ÷ shuffle-trained. Pass: ≥ 2.0 and real alignment ≥ 2× chance (k/d_embd). Operationalizes GOALS.md done-when #3 ("non-trivial structure, not random") with a number.twin_gguf_final_cos(parity control). Cosine betweenpeek_layer(HF, final)andpeek_embedding(GGUF, final mean-pool). Pass ≥ 0.85, else the twin is not trusted as the same model and the other numbers are void.
Kill criteria. (a) silhouette(L_mid) ≤ silhouette(final-mean-pool) → depth/position no better than the current input; do not swap the production path. (b) warm_traj_cos_L_vs_L0 ≥ 0.98 → input source irrelevant. (c) projh_align_ratio < 1.2 → proj_hidden "structure" is a Hebbian artifact, satisfying done-when #3 only trivially.
Risks & open questions
- Memory. Full-precision LFM2-1.2B in fp32 ≈ 4.7 GB; the host ran the Q4 GGUF at ~1.6 GB RSS. Mitigation: load the twin in bf16/fp16 (~2.4 GB) and run the validation with only the HF twin (no GGUF needed). If still tight, use the
cb_evalPath-B on the Q4 context. - Quantization/tokenization mismatch. HF fp twin vs GGUF Q4 may diverge; if
twin_gguf_final_cos < 0.85(different chat template/special tokens or quant drift), prefer thecb_evalextraction so layer-L hiddens come from the exact model the cortex steers. - conv vs attention blocks. Which of the 16 blocks is richest for the cortex is unknown — swept across L0, a mid attention block, an upper attention block, and final. The 6 attention indices [2,5,8,10,12,14] are the prior, not a certainty.
- tanh saturation.
observeappliestanh(proj_hidden @ h); if real layer-L hiddens have larger norm than the embedding, the projection may saturate and collapse separability. Monitored viawarm_norm; if saturated, note and scale. d_cortexsensitivity. Defaultd_cortex=128; stressors/curriculum used_cortex=4. Separability may depend on capacity — swept as a secondary axis.- Out of scope. Whether better
warm_stateseparability translates into better steering/recall is not tested here — that belongs to 04 and 05, which consume this driver.
Prior evidence
cortex_agent.py:350-354— perceive() usespeek_embedding(last_token_only=False)(final-layer mean-pool) and labels it "Goal 2 staging."cvec_driver.py:514-572—peek_embeddingis final-layer only viacreate_embedding(MEAN pooling);peek_layerunimplemented (docstring 519-520).- GOALS.md "Goal 2" — done-when:
peek_layer(prompt, layer_idx)returns d_embd; cortex on real layer-L hiddens shows visibly differentwarm_statetrajectories vs layer-0; pickledproj_hiddentrained on real hiddens shows non-trivial structure. (The rationale text still says "28-layer transformer"; the checkpoint is 16 layers — see Problem.) kv_cortex.py:173-225—observe:warm = (1−plasticity)·warm + plasticity·tanh(proj_hidden @ h);kv_cortex.py:499-524—train_stepHebbian onproj_hidden, lr default 0.001, per-row L2 renorm.- HF config (
models--LiquidAI--LFM2.5-1.2B-Instruct/.../config.json) —lfm2, hidden_size 2048, num_hidden_layers 16, full_attention at config indices [2,5,8,10,12,14], vocab 65536; corrects CLAUDE.md/GOALS.mdn_layers=28. llama_cpp0.3.31 —llama_context_default_paramsexposescb_eval/cb_eval_user_data(binding-hook fallback); GGUFllama_n_layer= 16 (brief), matching HF.
Tracked fix-up (out of scope of this proposal but discovered while grounding it)
KVCortexConfig.n_layers defaults to 28 at plastic-cortex/src/plastic_cortex/kv_cortex.py:57, and the docstring at :50 claims "Defaults match LFM2.5-1.2B-Instruct: d_embd 2048, n_layers 28." That is wrong — LFM2.5-1.2B has num_hidden_layers=16 (HF + GGUF, verified above). The mismatch is silent because proj_c is (n_layers, d_embd, d_cortex); the extra 12 rows go unprojected under the current per-layer cvec emission path, but anyone wiring a real L into peek_layer would index past the model's depth. Action: before implementing project 03, patch kv_cortex.py:57 (and the :50 docstring) to n_layers=16, or pass KVCortexConfig(n_layers=16) explicitly at every construction site (run_curriculum.py:38-43, real-driver stressors) until the default is fixed.
- Saturated-metric context: runs #79/#80/#82/#84/#85/#95/#101 all report
code_qa_accuracy=1.0, withdomain_co_recall1/1 (run #95) and prefix exactco_recall1/1 (run #101) at ceiling — motivation for a new representational metric.