The full [3,3,9,3] ConvNeXt-T step tie — the whole net tied through the real forward #
The whole-net thread for the ConvNeXt-T schedule (the batched MobileNetV2 peer is
MobileNetV2TieB.mnv2_net_tiedB). The folds (ConvNeXtFold and the MobileNetV2 / ResNet-34 / ViT
folds it imports) make every rendered param op den = certified ∀ cotangent; this file feeds each
consumer the forward activations of the convNextTrainStepText render and the loss-driven
backward-chain cotangent that net delivers, so the 18-block train step is den-composed
forward → loss → backward with no free activations and no symbolic cotangent. The statement is
per example, at one image and a hard label; the artifact runs a batch of 32, and that batch and
its mean lie outside this statement (the batched form is ConvNeXtStepTieGB.lean).
The net this is about #
verified_mlir/convnext_train_step.mlir, measured, not assumed:
| convention | this file | read from |
|---|---|---|
| depth / widths | [3,3,9,3], 96 → 192 → 384 → 768 | ConvNeXtRender.cnxTiny |
| stem | 4×4/s4 patchify conv then channel-LN | convNextFwdChain |
| normalisation | chanLNTensor3 (per-channel [c] affine, h·w statistics per example) at all 22 spatial sites: 1 stem + 18 block + 3 downsample | cnxLnFwdSite |
| head | GAP → vector-LN at one row (rowLNVecFlat 1 768) → dense | cnxHeadLnFwdSite |
| activation | GELU (smooth — no kink mask anywhere) | cnxFwdBlock |
| layer scale | per-channel Vec c, broadcast by chanIdx | layerScaleChF |
| padding | symmetric; ConvNeXt is a PyTorch-origin net and has no XLA-SAME site | — |
| params | 182 | allParams, and the artifact's 184 func args (%x + 182 + %onehot) |
The channel-LN specifics #
- channel-LN γ/β (
Vec c) at every spatial site, throughCnxFold.chanLn{Gamma,Beta}Sgd_den— the render re-emits the[h·w, c]transposes and runs ViT'sveclnGammaSgd/rowDenseBiasSgdon that view, so the op operands here arechanLNRowsof the saved LN input and of the chain cotangent, while the certified Jacobian ischanLNTensor3's in thec·h·wactivation layout (ChannelLN's permutation argument bridges the two). - the channel-LN input-VJP in the cotangent chain:
chanLNTensor3Back. It is the certified VJP —chanLNTensor3Back_eq_chanLN_vjp. - the stem LN:
psng/psnbttie at the stem-LN output cotangent, and the stem conv's own gradients see the LN input-VJP of it. - the head at the vector LN:
hng/hnbt : Vec 768throughSgdNode.veclnGammaSgd_den/rowDenseBiasSgd_den_lnbetaatN = 1. Stated at the literal 768 because1 * mdoes not reduce at a variablem— the render's own documented trap, in the proof this time. - the four even-kernel weight grads. The three downsample 2×2/s2 weights
are
convStridedWeightSgd(SgdNode.convStridedW_denis kernel-generic), and the stem 4×4/s4 weight isconvStride4WeightGrad, whosedenisflatConvStride4WeightGradHasVJP.
Coverage #
All 182 parameters are tied. 181 of them at the fused step θ − lr·(certified per-layer Jacobian · the chain cotangent), where each chain cotangent is the certified VJP backward of the
stages above it (CnxTieGB.cnxBlockCotInChAt_eq_vjp, cnxDownCotInChAt_eq_vjp,
cnxHeadDyXheadChN_eq_vjp); the stem weight psW at its gradient, because the render emits convStride4WeightGrad and wraps
it in hand-written sgd text (there is no fused convStride4WeightSgd op to be the den of). What
remains outside: the block backward is rendered hand-written, so the cotangent SSA ↔ chain-cot
correspondence is the per-op trust the whole suite carries; plus per-op pretty lexing; LN 0 < ε
smoothness; ℝ → Float32 — the boundary every prior fold carries.
ConvNeXt block — all 9 params tied (depthwise → channel-LN → expand → GELU → project → layer-scale → +skip) #
Forward: out = addV( layerScaleCh lg (conv₁ₓ₁ₚᵣ( gelu( conv₁ₓ₁ₑₓ( chanLN( dw₇ₓ₇(xin) ))))), xin ).
Backward from the block-output cotangent dyOut (the residual addV is the outermost op and there
is no post-add activation, so it passes dyOut straight to the layer-scale output): layer-scale-back
(cnxCotP) → project-conv-back → GELU mask (cnxCotE) → expand-conv-back (cnxCotN) → the
channel-LN input-VJP (chanLNTensor3Back) → depthwise-back. cnxCotP/cnxCotE/cnxCotN are
LN-form-agnostic and are reused verbatim from ConvNeXtChainClose.
ConvNeXt block, tied. All 9 params (depthwise 7×7 W+b, channel-LN γ/β at Vec c,
expand/project 1×1 conv W+b, per-channel layer-scale γ) denote
θ − lr·(certified per-layer Jacobian · cot) at the real block forward activations and the
chain cotangents driven by dyOut.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Downsample — channel-LN → 2×2/s2 conv (all 4 params tied) #
Forward: o = convˢ²(chanLN(xin)) (LN over the block-input grid 2h×2w with a Vec ci affine,
then a 2×2/s2 conv ci → co). No skip. Backward from dyOut: strided-conv-back (cotN') →
channel-LN-back. The strided weight is no longer a gap: convStridedWeightSgd is emitted at
2×2 since sWGradGeom split the odd/even padding cases, and SgdNode.convStridedW_den is
kernel-generic.
Downsample, tied. Channel-LN γ/β at the ci·(2h)·(2w) input grid, plus the strided conv's
weight and bias, at the real forward + the chain cotangents.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Stem — 4×4/s4 patchify conv → channel-LN (all 4 params) #
psng/psnbt tie at dyStem, the cotangent block 1 delivers at the stem-LN output; the conv's
own two parameters then see cotPatch, the LN input-VJP of it. The bias grad is a pure cotangent
reduce, so the render emits it as a stride-1 convBiasSgd at the OUTPUT resolution; the node
carries an input it never reads (stated at zero), and the clause is at the real stride-4 stem on
the image x through GradNodeB.pdiv_flatConvStride4_bias_eq_conv2d (any conv's bias Jacobian
is the channel indicator). The weight is the convStride4WeightGrad op, and it ties at the
gradient: its SGD wrap is hand-written text.
Stem, tied. Channel-LN γ/β, the conv bias, and the conv weight's gradient.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Head — GAP → vector-LN at one row → dense #
After GAP the tensor is a single [768] row, so "normalise each spatial row over its channels"
and "normalise the feature vector" are the same function at m = 1: the head is ViT's per-token
LN with one token, and cnxHeadLnFwdSite is cnxLnFwdSite with the two transposes deleted. Stated at
the LITERAL 768 — 1 * m does not reduce at a variable m (Nat.mul recurses on its second
argument), which is the annotation trap the render carries in its own comment.
Head LN + dense bias, tied. The head-LN γ/β (at the pooled row gap, cot = the dense-back
cotHn) and the dense bias (cot = the loss g) at the real forward.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The emitted loss-cotangent graph denotes the softmax-CE gradient at the logits.
Forward aliases — thread block inputs through the real forward #
The stem output: patchify conv then channel-LN.
Equations
- Proofs.CnxTie.cnxStemFwdO ε Wst bst psng psnbt x = Proofs.chanLNTensor3 c h w ε psng psnbt (Proofs.flatConvStride4 Wst bst x)
Instances For
Equations
- Proofs.CnxTie.cnxBlockFwdChO gf ε Wdw bdw ng nbt Wex bex Wpr bpr lg xin i = Proofs.CnxTie.cnxBlockBodyChO✝ gf ε Wdw bdw ng nbt Wex bex Wpr bpr lg xin i + xin i
Instances For
Equations
- Proofs.CnxTie.cnxDownFwdChO ε dng dnbt Wd bd xin = Proofs.flatConvStride2 Wd bd (Proofs.chanLNTensor3 ci (2 * h) (2 * w) ε dng dnbt xin)
Instances For
Backward cot-in constructors — thread block dyOuts (the residual fan-in) #
ConvNeXt block input cotangent: depthwise-back(cotD) + dyOut (the identity-skip fan-in),
with cotD through the channel-LN input-VJP.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Downsample input cotangent (at ci·(2h)·(2w)): the channel-LN input-VJP of the
strided-conv-back. No skip.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The cotangent at the last block output xhead (= s3b2's dyOut): gap-back(headLN-back( dense-back(g))). The head LN's input-VJP is the render's rowScaleF γ then lnRowBack at
γ = 1, which is rowLNVecFlatBack (rowLNBack_affine_eq).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Input-only *TiedAt wrappers — compute internals from a block's input #
Note: only cnxStemChTiedAt is @[irreducible]: without it the capstone's
refine ⟨cnx_stem_ch_tiedAt …, ?_, …⟩ times out in whnf, and moving it to its own goal does not
help. Every other definition in this section and the two above is a plain def.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The ties' weight records #
The whole-net ties share ONE ε across the stem, every block, downsample and head LN, so these
records carry no ε (unlike CnxBlockParamsCh, whose εn is per block). The dot-notation
wrappers below are abbrevs over the constructors above: a statement over a
record unfolds to exactly the unpacked one.
ConvNeXt-T as the ties bind it: patchify stem + its LN, the [3,3,9,3] blocks, three
downsamples, head LN + dense.
- sW : Kernel4 96 3 4 4
- sb : Vec 96
- sγ : Vec 96
- sβ : Vec 96
- b1 : CnxTieBlk 96 384
- b2 : CnxTieBlk 96 384
- b3 : CnxTieBlk 96 384
- d0 : CnxTieDown 96 192
- b4 : CnxTieBlk 192 768
- b5 : CnxTieBlk 192 768
- b6 : CnxTieBlk 192 768
- d1 : CnxTieDown 192 384
- b7 : CnxTieBlk 384 1536
- b8 : CnxTieBlk 384 1536
- b9 : CnxTieBlk 384 1536
- b10 : CnxTieBlk 384 1536
- b11 : CnxTieBlk 384 1536
- b12 : CnxTieBlk 384 1536
- b13 : CnxTieBlk 384 1536
- b14 : CnxTieBlk 384 1536
- b15 : CnxTieBlk 384 1536
- d2 : CnxTieDown 384 768
- b16 : CnxTieBlk 768 3072
- b17 : CnxTieBlk 768 3072
- b18 : CnxTieBlk 768 3072
- hG : Vec 768
- hT : Vec 768
- Wfc : Mat 768 nC
- bfc : Vec nC
Instances For
The block's forward (cnxBlockFwdChO).
Equations
Instances For
The block's input cotangent (cnxBlockCotInChAt).
Equations
Instances For
The downsample's input cotangent (cnxDownCotInChAt).
Instances For
The downsample's per-example tie (cnxDownChTiedAt).
Equations
Instances For
The same net as ConvNeXtFullT states it #
The records above are the render's shape: one shared ε, the eighteen blocks by name.
ConvNeXtFullT states ConvNeXt-T with an ε per record and Fin-indexed stages. These say the
two describe one function: block by block (rfl), and whole-net at toCh ε.
The FullT weights at the shared ε, which every LayerNorm (stem, blocks, downsamples, head)
takes.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The capstone's forward IS convNextForwardTCh. The chain cnx_net_tied_certified threads
(stem, eighteen blocks, three downsamples, GAP → LN → dense) is the FullT forward at
w.toCh ε, so convNextForwardTChHasVJP is a VJP of the function the ties are stated on.
The whole-net capstone — all 182 params through the REAL forward + composed cotangent #
The convNextTrainStepText forward threaded: block inputs are the forward prefixes
(cnxStemFwdO / cnxBlockFwdChO / cnxDownFwdChO), and the backward cotangents are composed
from the loss g = softmax(logits) − onehot down through dense (denseHasVJP) + the head LN +
GAP (globalAvgPoolFlatHasVJP) + every block's backward, with the residual fan-in + dyOut at
each of the eighteen identity-skip merges, the channel-LN-back at each of the three downsamples,
and the stem LN's own back before the patchify conv's gradients. Each stem / block / down / head
tie then holds at its real input + threaded cotangent. The whole [3,3,9,3]
182-parameter ConvNeXt-T train step is den-composed forward → loss → backward, no free
activations, no symbolic cotangent.
The whole [3,3,9,3] ConvNeXt-T train step, tied. Threading the real (channel-LN,
per-channel layer-scale) forward and the loss-driven backward cotangent chain (GELU masks, the
residual fan-in at every identity skip, the channel-LN-back at every downsample and at the
stem), the 18 ConvNeXt blocks, the 3 downsamples, the 4×4/s4 stem with its LN, the
GAP → LN → dense head, and the dense total-loss fold + loss-cotangent graph all denote
θ − lr·(certified per-layer Jacobian · the chain cotangent), each chain cotangent the
certified VJP backward of the stages above it (CnxTieGB.cnxBlockCotInChAt_eq_vjp,
cnxDownCotInChAt_eq_vjp, cnxHeadDyXheadChN_eq_vjp). All 182 parameters; psW at its gradient (its SGD wrap is
hand-written text). The statement is per example, at one image x and a hard label label;
the artifact's batch of 32 and its mean lie outside it (the batched form is
CnxTieGB.cnx_net_tiedGB).