Massive activation at layer 21, and three follow-ups on loop depth + LoopSplit

#20
by an0nya - opened

Hi again, thanks for the thorough answers on #16, and for fixing the config docstring so quickly.

Since that thread I've been probing the released weights layer by layer, and I found something in layer 21 that we can't find documented anywhere. Sharing the measurement in full below in case it's useful, then three follow-up questions.

(ML details and modeling code interpreted with the help of Claude - the probes are mine, the mechanistic reading is a joint effort, and I'd rather say so than imply I read activation statistics unassisted.)

A massive activation / attention sink at layer 21, built in pass 1 and cleared in pass 2

Single forward passes, three unrelated prompts, no generation. loop0's layer 21 writes an enormous activation into a single channel, dim 2279:

L20 → L21 (pass 1)
L2 norm 379 → 3616
max abs 119 → 3584
kurtosis 33 → 2963

It is the same dimension on every prompt (magnitudes 3584 / 4224 / 3968), with secondary sinks at 2373, 1777 and 369. The other 3071 dimensions combined carry an L2 of only ~479 - so layer 21 barely changes the content of the stream, it bolts a ~10x spike on top of it. The following RMSNorm then crushes the stream to a post-norm L2 of 20.4 / 20.8 / 21.7 and pins dim 2279 at −9.8 to three significant figures regardless of prompt - a fixed, content-independent bias handed to pass 2.

The part we found most striking: the same weights do the opposite job in the two passes. loop0-L21 builds the sink (119 → 3584). loop1-L21 clears it (348 → 58, kurtosis 1318 → 17) - which is what Nanbeige4.1's final layer L31 also does (288 → 121, kurtosis 1429 → 170), i.e. ordinary final-layer behaviour. So pass 2 uses those weights conventionally and pass 1 repurposes them to construct a sink.

Relatedly, the two passes run in visibly different activation regimes. 4.1 sits at kurtosis 600–1400 throughout its stack. 4.2's pass 1 drops to kurtosis 9.0 / 5.2 / 5.0 at layers 17–19 (near-Gaussian, essentially outlier-free) before the spike at 21. Pass 2 rebuilds outliers normally (500–1300).

The overall pattern matches the massive-activation / implicit-attention-sink signature described by Sun et al. (2024); we matched it by signature rather than verifying against their exact numbers.

Caveats: this is the 8-bit MLX conversion (MercuriusDream/Nanbeige4.2-3B-mlx-8bit), three prompts, last-token position. The effect is far too large to be a quantization artifact, but the exact magnitudes are worth confirming on BF16 before anyone leans on them, and we'd happily be corrected if you see different numbers internally.

Q1. Is the pass-1 sink construction designed, emergent, or known?

Given that the same weights clear a sink in pass 2 and build one in pass 1, I'm curious whether this showed up in your own analysis, and whether the ~21-magnitude post-norm handoff between passes is something the training objective pins deliberately, or just where it settled. If it's crucial for the loop, that seems like a notable property of the architecture that isn't in the report.

Q2. Did the from-scratch 3-loop ablation show normal length control?

You mentioned the 1 / 2 / 3-loop from-scratch runs. The report's section 3.2.2 list of pre-RLHF behaviors: repetitive reasoning, cyclic reflection, delayed termination, and the length-control RL in section 3.2.3 are the parts of the paper I've found most useful. At a fixed 3 loops, trained that way, did termination and length behave normally, or did the extra pass interact with length control at all? I'm asking because it separates two very different explanations for what I see when depth is changed after training, and only you can answer it.

Q3. LoopSplit - which layers loop, and how were they chosen?

You said some layers aren't looped while others are looped two or more times. Is the split hand-designed, learned, or selected by an ablation? And is it roughly contiguous (e.g. an inner block) or scattered?

I ask because I've been measuring per-layer sensitivity on 4.2 and get a fairly clean picture: layers 0, 1 and 21 look structurally untouchable while the middle band tolerates a lot of structural change. If LoopSplit's chosen layers land in a similar place, that seems like a useful independent convergence; if they don't, I'd rather know my map is wrong.


For context on why I'm asking, and to set expectations: I'm fully aware that running the model past num_loops=2 is well outside what it was trained for, and I'm not expecting any of this to produce something that rivals a model you designed and trained deliberately. I'm extending loops on the released weights mostly because it's a fun thing to poke at, and because the ways it breaks are interesting in their own right - the failure modes seem to say something about what the architecture is doing, which is really what I'm after.

All of it is inference-time, without any retraining (yet (hopefully not, due to my hardware limitations)). I have results but I'm still verifying them against a baseline error I found in my own harness, so I'd rather not quote numbers I might have to retract. Happy to share properly once they're solid, here or wherever is most useful to you.

Thanks again for releasing such a cool model, and for being so willing to discuss it openly.

Nanbeige LLM Lab org

Hi, thanks for the careful probing.

To answer your questions together:

On the layer-21 phenomenon (Q1): Nothing about it is hand-designed. During training we only optimize the loss on the second pass; the first pass's loss is tracked purely as a monitoring signal, never optimized toward. So it isn't something we specifically studied, it is emergent. Since our next generation, Nanbeige4.5, already moves to LoopSplit, which differs substantially from the Nanbeige4.2 scheme, we have not done further probing on the 4.2 architecture.

On the 3-loop ablation (Q2): Our 1/2/3-loop comparison was pre-training only, with no post-training.

On LoopSplit (Q3): The split came from experiments. The outer layers (front and back) are not looped, while a contiguous middle block is looped multiple times. At the same FLOPs as Nanbeige4.2, this gives a clear performance advantage. For the implementation details, you can refer to the LoopSplit-related modeling code we have already released ahead of time in Nanbeige4.2.

Thanks again for the interest! 🤝

Sign up or log in to comment