Quantifying the Per-layer Contribution of LLMs
Setup设置
The baseline is the MuonH Qwen3 recipe of the Marin speedrun, from 130m to 1.2B. We add a next-token loss after every layer and judge each layer by its final training loss, plotted against the layer number. Figures that follow training put backbone compute 6ND on the x axis, where N counts the parameters of the layers up to that one, without the embedding and the heads, and D the training tokens so far. The final training loss is the mean over the last 50 steps, and training curves are 50-step running means. Each setup is trained once; nine runs of the 130m baseline that differ in seed or EMA but share the data order end within 0.004 nats of each other. Code
基线是 Marin speedrun 里的 MuonH Qwen3 配方,规模从 130m 到 1.2B。我们在每一层后面加一个预测下一个词的损失,用每层的最终训练损失来衡量,横轴是层号。随训练变化的图,横轴是骨干算力 6ND:N 是到这一层为止各层的参数量,不算 embedding 和头,D 是到当时为止的训练 token 数。最终训练损失是最后 50 步的平均值,训练曲线是 50 步的滑动平均。每种做法只训练一次;130m 基线跑过 9 次,种子或 EMA 不同、数据顺序相同,它们的最终损失相差不超过 0.004 nats。代码
--- baseline loss (simplified)+++ per-layer losses (simplified; the Code link has the real code) def loss_fn(model, tokens): targets = tokens[1:] x = model.embed(tokens[:-1])- for block in model.blocks:+ loss = 0.0+ for k, block in enumerate(model.blocks[:-1]): x = block(x)- return cross_entropy(model.head(model.norm(x)), targets)+ # probes: read the layer, but send no gradient into the model+ h = stop_gradient(x) if probe else x+ # every earlier layer has its own norm and output head, and predicts the next token+ logits = model.layer_heads[k](model.layer_norms[k](h))+ loss += cross_entropy(logits, targets)+ x = model.blocks[-1](x)+ # the usual loss at the last layer, at the same weight+ return loss + cross_entropy(model.head(model.norm(x)), targets)--- 基线损失(简化)+++ 逐层损失(简化;真实代码见“代码”链接) def loss_fn(model, tokens): targets = tokens[1:] x = model.embed(tokens[:-1])- for block in model.blocks:+ loss = 0.0+ for k, block in enumerate(model.blocks[:-1]): x = block(x)- return cross_entropy(model.head(model.norm(x)), targets)+ # 探针:读取这一层,但梯度不传回模型+ h = stop_gradient(x) if probe else x+ # 前面每一层都有自己的 norm 和输出头,也预测下一个词+ logits = model.layer_heads[k](model.layer_norms[k](h))+ loss += cross_entropy(logits, targets)+ x = model.blocks[-1](x)+ # 最后一层仍是原来的损失,权重相同+ return loss + cross_entropy(model.head(model.norm(x)), targets)
Experiments实验
Answered已有结论Passive and active: how much does each layer contribute?被动与主动:每一层贡献多少?
Read passively, the baseline's early layers predict far worse than ordinary models of the same depth and catch up only at the last layer. Trained actively with separate heads, every layer ends 0.07 to 0.17 nats above an ordinary model of its depth, closest in the middle layers, and the last layer ends worse than an ordinary 4-layer model.
被动读取时,基线模型的前几层远不如同深度的普通模型,到最后一层才追上。用独立头主动监督时,每一层都比同深度的普通模型高 0.07 到 0.17 nats,中间几层最接近;最后一层比普通的 4 层模型还差。
Every layer predicts through the model's output head, and every layer's loss trains that head.每一层都经过模型的输出头预测,每一层的损失都训练这个头。
Every layer predicts through the output head, but only the last layer's loss trains it.每一层都经过输出头预测,但只有最后一层的损失训练这个头。
Every layer predicts through a head of its own.每一层都用自己的头预测。
Every layer predicts through a head of its own, but no gradient flows back into the model; the heads share only the output head's gradient clipping. The model trains like the baseline.每一层都用自己的头预测,但梯度不传回模型,这些头只和输出头共用梯度裁剪。模型和基线训练得几乎一样。
An ordinary model with fewer layers, 1 to 5, trained on its own with only its output head; the 6-layer one is the baseline. Layer k is compared with the model of k layers.层数更少的普通模型,1 到 5 层,单独训练,只有自己的输出头;6 层的就是基线。第 k 层和 k 层的模型比较。
Answered已有结论Does a deeper network benefit from supervising its shallow layers?更深的网络能否从浅层监督中获益?
The 130m layer stacked 48 deep, every layer predicting through a head of its own.130m 的层堆到 48 层,每一层都用自己的头预测。
The same network with heads that take no gradient back. It trains like an ordinary 48-layer model, except that the probe heads share the output head's gradient clipping.同样的网络,头的梯度不回传。它像普通的 48 层模型一样训练,只是探针的头和输出头共用梯度裁剪。
Testing检验中Does the residual design change what each layer contributes?残差设计会不会改变每一层的贡献?
Normalize, transform, add back to the stream.先归一化,再变换,加回残差流。
A second normalization on the branch output before it is added: the baseline's own design.分支输出加回之前再归一化一次:基线自己的设计。
The normalized input is scaled by 1/√ℓ, more in deeper layers.归一化后的输入乘以 1/√ℓ,越深的层缩得越多。
No norm before the branch; the stream is scaled up by (2L)^¼ and normalized after the add.分支前不归一化;残差流乘以 (2L)^¼,相加后再归一化。
Norms before and after, with a residual gain equal to the number of sublayers.前后都归一化,残差增益等于子层数。
Four residual streams, mixed by learned weights, read into the branch and written back.四条残差流,由可学习的权重混合,读入分支再写回。
Hyper-connections with the stream mixing kept doubly stochastic.超连接,但流之间的混合矩阵保持双随机。
A layer's input is a learned softmax mix of every earlier output and the embedding.每层的输入是此前所有层输出和 embedding 的 softmax 加权混合。
The same mix over 8 block outputs and the running sum of the current block.同样的混合,只在 8 个块的输出和当前块的累加和上做。
Attention also reads the same token's keys and values from earlier layers.注意力还读取同一 token 在之前各层的 key 和 value。
Testing检验中Why does Hyper-Connections pay only half?为什么 Hyper-Connections 只付一半代价?
Testing检验中Why does supervising shallow layers hurt the final performance?为什么浅层监督会损害最终性能?
Every layer loss has weight 1 and its gradient reaches every layer below it.每个逐层损失的权重是 1,梯度传到它下面的每一层。
Each layer loss is weighted 0.2, so the five sum to the final loss's weight.每个逐层损失的权重是 0.2,五个加起来等于最终损失的权重。
A layer loss trains its head and its own layer; its gradient stops before reaching the layers below.逐层损失只训练它的头和它所在的那一层;梯度不再传到下面的层。
Layer losses weighted 0.2, each training only its own layer.逐层损失权重为 0.2,并且各自只训练自己那一层。
Answered已有结论Is the gap in the heads or in the features?差距在读出头,还是在特征?
In the features. Retraining the heads of either 300m model on its frozen backbone finds no better heads: the separate heads end slightly higher at every layer, the probes barely move, and the probes still read the early layers far worse than the separate heads. Undertrained heads do not explain the gap.
在特征。在冻结的骨干上重训两个 300m 模型的读出头,没有找到更好的头:独立头每一层都略微变高,探针几乎不变,探针读前几层仍然远不如独立头。读出头没训够解释不了这个差距。
Each finished 300m model keeps its backbone; only its heads train for 2,000 more steps.训练好的 300m 模型保留骨干网络,只让读出头再训练 2,000 步。
Answered已回答Does multi-token prediction change what each layer knows?多 token 预测会不会改变每一层知道的东西?
Testing检验中Does multi-token prediction help at larger sizes?多 token 预测在更大的模型上有帮助吗?
Testing检验中Why does AttnRes scramble what its layers hold?为什么 AttnRes 会打乱各层的信息?
Takeaways核心结论
Acknowledgements致谢
The author is pleased to acknowledge that the work reported on in this post was substantially performed using the Princeton Research Computing resources at Princeton University. Princeton Research Computing is a consortium of groups including the Princeton Institute for Computational Science and Engineering (PICSciE) and Research Computing at Princeton University.
本文报告的工作主要使用普林斯顿大学 Princeton Research Computing 的计算资源完成。Princeton Research Computing 是由普林斯顿计算科学与工程研究所(PICSciE)和普林斯顿大学 Research Computing 等团队组成的联合体。
Experiment record实验记录
Citation
@misc{chai2026perlayer,
title = {Quantifying the Per-layer Contribution of LLMs},
author = {Chai, Wenhao},
year = {2026},
howpublished = {Blog post},
url = {https://wenhaochai.com/exps/per-layer-contribution.html}
}