Documentation

LeanMlir.Proofs.Nets.ViT.ViTChainClose

ViT — the attention-block cotangent chain #

TokenParamGrad.lean certifies each ViT param output for any cotangent dy at that site's output. This file defines the cotangent the actual backward chain delivers at each site — the ViT analogue of ConvNeXtChainClose — and the step ties (ViTStepTie, ViTStepTieGB) feed those cotangents to those bridges at the real forward. The definitions are per example; everything in a ViT is per-example separable, so the batched tie lifts them with batchMapAux.

The chain composes the rendered backward denotations — exactly the render's backward tokens: per-token dense input-VJP (denseRowBack's denotation rowDenseBackFlat = rowwise dX = W·dy), the GELU mask at either form (dy ⊙ gf.scalarDeriv at the saved pre-GELU), the rowwise scalar-LN input-VJP (lnRowBack's denotation rowLNBackFlat = rowwise bnGradInput), the row-softmax backward (softmaxRowBack's denotation rowSoftmaxBackFlat, recomputing the weights from the saved pre-softmax scores), and the SDPA matmuls spelled with the forward matmulF/transposeF on cotangents (matMulFlat/transposeFlat):

block: bout = h + fc2(gelu(fc1(LN₂ h))), h = x + Wo·SDPA(Wq·LN₁x, Wk·LN₁x, Wv·LN₁x)

The MLP residual passes dyOut straight to the fc2 output AND down the LN₂ branch (the cotangent at h is dyOut + LN₂-back(…)); the attention residual likewise (the block input's is cotH + LN₁-back(…)). The new wrinkle vs all prior nets is the three-way fan-in at LN₁'s output — the Q/K/V dense-backs all read from LN₁ x, so their three cotangents SUM (vitCotLn1), the biPath fan-in at width 3.

The substantive new ties (vitCotD{Q,K,V}_eq_sdpaBack{Q,K,V}): at the pinned saved activations (pre-softmax scores = the scaled Q·Kᵀ, post-softmax weights = sdpaWeights), the matmul-spelled chain segments ARE the proven closed forms sdpaBack{Q,K,V} (Attention.lean) — dP = dO·Vᵀ → softmax-back → ·1/√d → dQ = dS·K / dK = dSᵀ·Q / dV = Pᵀ·dO, flattened. So the rendered attention backward is pinned to the audited SDPA backward suite.

noncomputable def Proofs.vitCotM1 (gf : GeluForm) {Np1 D mlpDim : ℕ} (Wfc2 : Mat mlpDim D) (m1 : Vec (Np1 * mlpDim)) (dyOut : Vec (Np1 * D)) :
Vec (Np1 * mlpDim)

Cotangent at the fc1 output (pre-GELU): the GELU mask at the saved pre-activation m1 (geluBack's denotation).

Equations
Instances For
    theorem Proofs.vitCotM1_apply {gf : GeluForm} {Np1 D mlpDim : ℕ} (Wfc2 : Mat mlpDim D) (m1 : Vec (Np1 * mlpDim)) (dyOut : Vec (Np1 * D)) (i : Fin (Np1 * mlpDim)) :
    vitCotM1 gf Wfc2 m1 dyOut i = StableHLO.rowDenseBackFlat Np1 mlpDim D Wfc2 dyOut i * gf.scalarDeriv (m1 i)

    vitCotM1 with its private fc2 back unfolded: fc2's per-token input-VJP, then the GELU mask.

    noncomputable def Proofs.vitCotLn2 (gf : GeluForm) {Np1 D mlpDim : ℕ} (Wfc1 : Mat D mlpDim) (Wfc2 : Mat mlpDim D) (m1 : Vec (Np1 * mlpDim)) (dyOut : Vec (Np1 * D)) :
    Vec (Np1 * D)

    Cotangent at the LN₂ output (= the fc1 input): fc1's per-token input-VJP.

    Equations
    Instances For
      noncomputable def Proofs.vitCotDP {Np1 D : ℕ} (v dAtt : Vec (Np1 * D)) :
      Vec (Np1 * Np1)

      dP = dAtt·Vᵀ — the rendered matmulF/transposeF on the cotangent against the saved v.

      Equations
      Instances For
        noncomputable def Proofs.vitCotDS {Np1 D : ℕ} (ss : Vec (Np1 * Np1)) (v dAtt : Vec (Np1 * D)) :
        Vec (Np1 * Np1)

        dS — softmaxRowBack's denotation at the saved pre-softmax scaled scores ss.

        Equations
        Instances For
          noncomputable def Proofs.vitCotDQ {Np1 D : ℕ} (d : ℕ) (ss : Vec (Np1 * Np1)) (k v dAtt : Vec (Np1 * D)) :
          Vec (Np1 * D)

          dQ = (1/√d · dS)·K against the saved k.

          Equations
          Instances For
            noncomputable def Proofs.vitCotDK {Np1 D : ℕ} (d : ℕ) (ss : Vec (Np1 * Np1)) (q v dAtt : Vec (Np1 * D)) :
            Vec (Np1 * D)

            dK = (1/√d · dS)ᵀ·Q against the saved q.

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For
              noncomputable def Proofs.vitCotDV {Np1 D : ℕ} (p : Vec (Np1 * Np1)) (dAtt : Vec (Np1 * D)) :
              Vec (Np1 * D)

              dV = Pᵀ·dAtt against the saved post-softmax weights p.

              Equations
              Instances For
                noncomputable def Proofs.vitCotLn1 {Np1 D : ℕ} (Wq Wk Wv : Mat D D) (dQ dK dV : Vec (Np1 * D)) :
                Vec (Np1 * D)

                The three-way fan-in at LN₁'s output: the Q/K/V dense-backs all read from LN₁ x, so their cotangents SUM — the biPath fan-in at width 3, the new structural wrinkle vs every prior net.

                Equations
                Instances For
                  noncomputable def Proofs.vitCotFl (N D nClasses : ℕ) (Wcls : Mat D nClasses) (dy : Vec nClasses) :
                  Vec ((N + 1) * D)

                  Cotangent at the final-LN output: classifier-back (dotOut's denotation Mat.mulVec Wcls) scattered to row 0 (clsPadF's denotation clsPadFlat).

                  Equations
                  Instances For
                    theorem Proofs.vitCotDP_eq_sdpaDWeights (Np1 d : ℕ) (V dOut : Mat Np1 d) :

                    dP-segment tie: the rendered matmulF(dOut, transposeF V) is the proven sdpaDWeights V dOut = dOut·Vᵀ, flattened.

                    theorem Proofs.vitCotDV_eq_sdpaBackV (Np1 d : ℕ) (Q K V dOut : Mat Np1 d) :
                    vitCotDV (sdpaWeights Np1 d Q K).flatten dOut.flatten = (sdpaBackV Np1 d Q K V dOut).flatten

                    dV tie: at the saved post-softmax weights (sdpaWeights Q K), the rendered matmulF(transposeF P, dOut) IS the proven sdpaBackV = weightsᵀ·dOut.

                    theorem Proofs.vitCotDS_eq_sdpaDScaled (Np1 d : ℕ) (Q K V dOut : Mat Np1 d) :
                    vitCotDS (Mat.flatten fun (i j : Fin Np1) => sdpaScale d * Q.mul K.transpose i j) V.flatten dOut.flatten = (sdpaDScaled Np1 d Q K V dOut).flatten

                    dS-segment tie: softmaxRowBack's denotation, recomputing the weights from the saved pre-softmax scaled scores, applied to the flattened sdpaDWeights, IS the proven sdpaDScaled (the per-row pᵢ⊙(dwᵢ − ⟨pᵢ,dwᵢ⟩) closed form).

                    theorem Proofs.vitCotDQ_eq_sdpaBackQ (Np1 d : ℕ) (Q K V dOut : Mat Np1 d) :
                    vitCotDQ d (Mat.flatten fun (i j : Fin Np1) => sdpaScale d * Q.mul K.transpose i j) K.flatten V.flatten dOut.flatten = (sdpaBackQ Np1 d Q K V dOut).flatten

                    dQ tie: at the saved activations, the rendered matmulF(scaleF(softmaxRowBack(matmulF(dOut, transposeF V))), K) IS the proven sdpaBackQ = (1/√d · softmax-back(dOut·Vᵀ))·K.

                    theorem Proofs.vitCotDK_eq_sdpaBackK (Np1 d : ℕ) (Q K V dOut : Mat Np1 d) :
                    vitCotDK d (Mat.flatten fun (i j : Fin Np1) => sdpaScale d * Q.mul K.transpose i j) Q.flatten V.flatten dOut.flatten = (sdpaBackK Np1 d Q K V dOut).flatten

                    dK tie: likewise the rendered transposed chain IS the proven sdpaBackK = (1/√d · softmax-back(dOut·Vᵀ))ᵀ·Q.