LayerNorm #
Pointwise analytic correctness for a LayerNorm graph.
This is spec-level over ℝ. It is the proof-tape counterpart of the runtime/spec LayerNorm in
Spec.layerNorm: a seqLen × embedDim tensor is normalized across the last axis, the row-wise
normalizer is broadcast back over each token, and affine parameters gamma/beta are broadcast
over the sequence dimension. The runtime API and typed graph path both route through that spec
definition; this file proves the corresponding reverse-mode graph rule.
Because the proof graph uses the differentiable scalar nodes sqrt (max x 0) and inv, the main
theorem is pointwise (GraphFDerivCorrectAt). The _of_domain variants take the two domain
assumptions (positive var + ε, nonzero std) at the execution point; the main statements take
only 0 < ε, since the row variance is a mean of squares and therefore nonnegative
(LayerNormEval.varEps_pos_of_eps_pos, LayerNormEval.std_ne_zero_of_eps_pos). Away from the
clamp kink and zero denominator, backprop is the adjoint of the Fréchet derivative. The executable
Spec.layerNorm additionally clamps the raw variance before adding epsilon as a numerical guard;
over exact real variance this is the same contract on the positive branch used by the proof.
The last section connects the graph to the spec. outputCLM_evalVec_layerNormGraph shows that the
output block of the graph evaluation is tensorToVec (Spec.layerNorm X gamma beta) for the packed
inputs, so hasFDerivAt_specLayerNormVec and backpropVec_single_eq_adjoint_specLayerNorm state
differentiability and the adjoint rule for the spec function itself. The adjointness of
Spec.layerNormJvp and Spec.layerNormBackward is proved in
NN.Proofs.Autograd.Tape.Ops.Norm.LayerNormAdjoint. The companion LayerNormFDeriv module
identifies that JVP with the actual derivative and proves that the primitive backward rule
returns the same cotangents as this graph.
PyTorch correspondence / citations #
- Conceptually corresponds to
torch.nn.LayerNorm(without batching/running stats): normalize along the last dimension, then apply affine parameters(gamma,beta). https://pytorch.org/docs/stable/generated/torch.nn.LayerNorm.html
Pointwise proof that layerNormGraph satisfies GraphFDerivCorrectAt, from explicit domain
assumptions.
The hypotheses hVarEpsPos and hStdNe0 ensure that sqrt and inv are differentiable at the
execution point. layerNormGraphFderivCorrectAt discharges both from 0 < ε.
Instances For
Pointwise end-to-end result from explicit domain assumptions: backprop equals (fderiv eval)†
for layerNormGraph.
The hypotheses hVarEpsPos and hStdNe0 are the domain assumptions needed for differentiability
of sqrt (after clamp) and inv at the actual execution point.
Pointwise end-to-end result: backprop equals (fderiv eval)† for layerNormGraph whenever
0 < ε.
LayerNorm inputs inside an arbitrary tape context.
This is the model-level interface we use once LayerNorm is no longer the root graph. For example,
in a post-norm Transformer block, x is the residual stream produced by an earlier SSA node, while
gamma and beta are carried parameters in the surrounding context.
Sequence/residual matrix normalized across its last axis.
Affine scale vector.
Affine shift vector.
Instances For
LayerNorm as one reusable pointwise node over arbitrary context indices.
Internally this node runs the already-proved detailed LayerNorm graph. Its JVP is defined as the Fréchet derivative of that composed map at the current point, and its VJP is the adjoint of that derivative. This is exactly the block-level abstraction needed for large model proofs: the detailed LayerNorm proof remains in this file, while Transformer/GPT/ViT proofs can treat LayerNorm as a single pointwise node with explicit domain assumptions.
Instances For
Pointwise derivative certificate for wholeNode.
Only 0 < ε is needed: the row variance computed inside the packed LayerNorm graph is a mean of
squares, so var + ε is positive and the clamped standard deviation is nonzero at every point.
Instances For
The graph computes Spec.layerNorm #
The packed context [X, gamma, beta] determines three spec tensors. Evaluating the LayerNorm graph
on it and reading the output block gives exactly tensorToVec (Spec.layerNorm X gamma beta).
Consequently the spec function is differentiable wherever the graph is, with the graph's backprop
as the adjoint of its derivative.
The input matrix of a packed LayerNorm context, as a spec tensor.
Instances For
The scale vector of a packed LayerNorm context, as a spec tensor.
Instances For
The shift vector of a packed LayerNorm context, as a spec tensor.
Instances For
Pack three spec tensors into a LayerNorm context vector.
Instances For
The centered block.
Forward bridge: the output block of the LayerNorm graph is Spec.layerNorm of the packed
inputs.
The spec LayerNorm map is the output projection of the graph evaluation.
Spec.layerNorm is differentiable in [X, gamma, beta] for 0 < ε, with derivative the
output projection of the graph derivative.
Spec.layerNorm is differentiable in [X, gamma, beta] for 0 < ε.
The adjoint of the output projection injects a cotangent into the output block.
Reverse-mode bridge: backprop of the LayerNorm graph seeded on the output block is the adjoint
derivative of Spec.layerNorm in [X, gamma, beta].
Packed tensors #
The input block of a packed context.
The scale block of a packed context.
The shift block of a packed context.
Packing and unpacking round-trip on the input matrix.
Packing and unpacking round-trip on the scale vector.
Packing and unpacking round-trip on the shift vector.
Forward bridge in tensor form: evaluating the LayerNorm graph on packed spec tensors and
reading the output block gives Spec.layerNorm.