Documentation

LeanMlir.Proofs.Nets.ResNet.ResNet50SyncStepTieB

ResNet-50's data-parallel step at SYNCHRONISED BatchNorm IS the single-device step at R·N #

ResNet50StepTieB threads a loss cotangent g down the batch-BN bottleneck backward chain on ONE device and ties every parameter gradient node to the certified per-op gradient at the cotangent that chain delivers. This is its data-parallel twin, for the render ResNet50RenderB emits at replicas > 1: R replicas at batch N, every BatchNorm synchronised (bnFwdSite / bnBackSite / bnGammaSite), every parameter gradient all-reduced by its mean. The capstone r50_net_syncTiedB says that, for every one of the 161 parameters,

mean over the R replicas of replica r's gradient node, replica cotangent gs r
  = the single-device gradient node at the global batch R·N, loss cotangent G

whenever each replica's loss cotangent is R × its shard of the global one (∀ r, gs r = batchShard r (R • G)) — the gradient node r50_net_tiedB at N := R·N ties to the certified per-op gradient. The right-hand side is the existing single-device chain at N := R·N, so the spec has not moved.

The loss cotangent is a binder, as it is in r50_net_tiedB. ResNet-50 ships both losses, so the capstone takes the scaled-shard relation between the replicas' cotangents and the global one as its hypothesis, and two corollaries discharge it, one per loss:

  1. Sharding — each replica's backward chain, handed its shard of a global cotangent, computes the shard of the global chain. Every non-BN link (relu mask, the 1×1 and 3×3 conv input-VJPs, the strided 3×3 and strided 1×1 input-VJPs, the stem pool's scatter, the head) is a per-example map; the BN link is bnSyncInB, whose shard lemma bnSyncInB_shard is P2 on the graph. In the strided block bn₁ runs at the INPUT grid 2h × 2w (v1.5: the stride is on the 3×3), so that site's statistics reduce over N·(2h)·(2w) per replica.
  2. The collectives — the mean over replicas of each replica's gradient node is 1/R of the global node at the global cotangent (DataParallel.Sync's P4 lemmas and ResNet-34's strided and dense ones). The γ node is the sync one, bnSyncGammaGradB, reading the forward's all-reduced statistics.
  3. Homogeneity — the single-device chain is linear in its cotangent (*_smul below for the three bottleneck forms, ResNet-34's for the links they are built from).
  4. The divisor — the R the hypothesis carries cancels the collective's 1/R.

The index seam #

The chain runs at N·(c·h·w), the BN nodes at N·(c·(h·w)); the replica BN link bnSyncInB is the den of the emitted nodes over .operand leaves at reassocB (ResNet-34's), and reassocB_shard commutes the relabelling with sharding.

What is NOT claimed #

The replicas' saved forward activations enter as the shards of the single-device forward's (batchShard r (r50Pre_k (R*N) q w X)); that the sync forward graph computes exactly those is StableHLO.resnet50FwdGraphSyncFull_shard, the forward half. No stochastic depth (drop-path): the chain is the drop-free one, as r50_net_tiedB's is. The nodes are at either precision: bf16 selects the conv weight collectives' kind on both sides (ConvWSyncAt bf16 / ConvStridedWSyncAt bf16, Foundation.GradNodesBAt), true being the bf16 DP artifacts' (resnet50in160_lambaccdp4x128wxclipbcebf16, …), read at the identity rounding (Bf16Erasure, as ResNet34SyncStepTieB). The render has no conv-bias gradient ops, so there are none here. That the replicas' inputs are the shards of one batch is the driver's. The gradient accumulator and the optimizers run after the collective, so this is per micro-step. The lowerer's all_reduce is trusted as every other op's lowering is.

theorem Proofs.ResNet50SyncTieB.r50IdCotIn_smul (N h w : ℕ) {mid oc : ℕ} (p : R50IdW mid oc) (xin : Vec (N * (oc * h * w))) :
theorem Proofs.ResNet50SyncTieB.r50ProjCotIn_smul (N h w : ℕ) {ic mid oc : ℕ} (p : R50ProjW ic mid oc) (xin : Vec (N * (ic * h * w))) :
theorem Proofs.ResNet50SyncTieB.r50DownCotIn_smul (N h w : ℕ) {ic mid oc : ℕ} (p : R50ProjW ic mid oc) (xin : Vec (N * (ic * (2 * h) * (2 * w)))) :
noncomputable def Proofs.ResNet50SyncTieB.r50IdSyncCotIn (R : ℕ) (hR : 0 < R) (N h w : ℕ) {mid oc : ℕ} (p : R50IdW mid oc) (XIN : Vec (R * N * (oc * h * w))) (dys : Fin R → Vec (N * (oc * h * w))) (r : Fin R) :
Vec (N * (oc * h * w))

The replica's block-INPUT cotangent: the residual fan-in, body plus identity skip.

Equations
  • One or more equations did not get rendered due to their size.
Instances For
    theorem Proofs.ResNet50SyncTieB.r50IdSyncCotIn_shard (R : ℕ) (hR : 0 < R) (N h w : ℕ) {mid oc : ℕ} (hN : 0 < N) (hh : 0 < h) (hw : 0 < w) (p : R50IdW mid oc) (XIN : Vec (R * N * (oc * h * w))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) (hdys : ∀ (r : Fin R), dys r = batchShard R N (oc * h * w) DY r) (r : Fin R) :
    r50IdSyncCotIn R hR N h w p XIN dys r = batchShard R N (oc * h * w) (ResNet50TieB.r50IdCotIn (R * N) h w p XIN DY) r
    noncomputable def Proofs.ResNet50SyncTieB.r50ProjSyncCotIn (R : ℕ) (hR : 0 < R) (N h w : ℕ) {ic mid oc : ℕ} (p : R50ProjW ic mid oc) (XIN : Vec (R * N * (ic * h * w))) (dys : Fin R → Vec (N * (oc * h * w))) (r : Fin R) :
    Vec (N * (ic * h * w))

    The replica's block-INPUT cotangent: both branches' input-VJPs, as the render adds them.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      theorem Proofs.ResNet50SyncTieB.r50ProjSyncCotIn_shard (R : ℕ) (hR : 0 < R) (N h w : ℕ) {ic mid oc : ℕ} (hN : 0 < N) (hh : 0 < h) (hw : 0 < w) (p : R50ProjW ic mid oc) (XIN : Vec (R * N * (ic * h * w))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) (hdys : ∀ (r : Fin R), dys r = batchShard R N (oc * h * w) DY r) (r : Fin R) :
      r50ProjSyncCotIn R hR N h w p XIN dys r = batchShard R N (ic * h * w) (ResNet50TieB.r50ProjCotIn (R * N) h w p XIN DY) r
      noncomputable def Proofs.ResNet50SyncTieB.r50DownSyncCotIn (R : ℕ) (hR : 0 < R) (N h w : ℕ) {ic mid oc : ℕ} (p : R50ProjW ic mid oc) (XIN : Vec (R * N * (ic * (2 * h) * (2 * w)))) (dys : Fin R → Vec (N * (oc * h * w))) (r : Fin R) :
      Vec (N * (ic * (2 * h) * (2 * w)))

      The replica's block-INPUT cotangent: conv₁'s input-VJP plus the strided skip's.

      Equations
      • One or more equations did not get rendered due to their size.
      Instances For
        theorem Proofs.ResNet50SyncTieB.r50DownSyncCotIn_shard (R : ℕ) (hR : 0 < R) (N h w : ℕ) {ic mid oc : ℕ} (hN : 0 < N) (hh : 0 < h) (hw : 0 < w) (p : R50ProjW ic mid oc) (XIN : Vec (R * N * (ic * (2 * h) * (2 * w)))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) (hdys : ∀ (r : Fin R), dys r = batchShard R N (oc * h * w) DY r) (r : Fin R) :
        r50DownSyncCotIn R hR N h w p XIN dys r = batchShard R N (ic * (2 * h) * (2 * w)) (ResNet50TieB.r50DownCotIn (R * N) h w p XIN DY) r
        def Proofs.ResNet50SyncTieB.r50IdSyncTiedB (R : ℕ) (hR : 0 < R) (N h w : ℕ) {mid oc : ℕ} (pfx xN cotN vN epsStr : String) (p : R50IdW mid oc) (bf16 : Bool) (XIN : Vec (R * N * (oc * h * w))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) :

        Identity bottleneck, DP-tied. Its nine emitted parameter collectives — the three conv weights and the three BatchNorms' γ and β — each equal the single-device node at the global batch, at the single-device chain cotangents driven by DY, when the replicas' block-output cotangents are R × its shards. Each BN's γ/β reads the cotangent at THAT BN's output (N1, N2, A), each conv the one at the conv's output (C1, C2, C3) — r50IdTiedB's wiring.

        Equations
        • One or more equations did not get rendered due to their size.
        Instances For
          theorem Proofs.ResNet50SyncTieB.r50IdSyncCotIn_scaled (R : ℕ) (hR : 0 < R) (N h w : ℕ) {mid oc : ℕ} (hN : 0 < N) (hh : 0 < h) (hw : 0 < w) (p : R50IdW mid oc) (XIN : Vec (R * N * (oc * h * w))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) (hdys : ∀ (r : Fin R), dys r = batchShard R N (oc * h * w) (fun (i : Fin (R * N * (oc * h * w))) => ↑R * DY i) r) (r : Fin R) :
          r50IdSyncCotIn R hR N h w p XIN dys r = batchShard R N (oc * h * w) (fun (i : Fin (R * N * (oc * h * w))) => ↑R * ResNet50TieB.r50IdCotIn (R * N) h w p XIN DY i) r

          The scaled-shard invariant, carried through one identity bottleneck: replicas at R × the shards of DY produce block-input cotangents at R × the shards of the single-device one.

          theorem Proofs.ResNet50SyncTieB.r50_idblock_syncTiedB (R : ℕ) (hR : 0 < R) (N h w : ℕ) {mid oc : ℕ} (hN : 0 < N) (hh : 0 < h) (hw : 0 < w) (pfx xN cotN vN epsStr : String) (p : R50IdW mid oc) (bf16 : Bool) (XIN : Vec (R * N * (oc * h * w))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) (hdys : ∀ (r : Fin R), dys r = batchShard R N (oc * h * w) (fun (i : Fin (R * N * (oc * h * w))) => ↑R * DY i) r) :
          r50IdSyncTiedB R hR N h w pfx xN cotN vN epsStr p bf16 XIN dys DY
          def Proofs.ResNet50SyncTieB.r50ProjSyncTiedB (R : ℕ) (hR : 0 < R) (N h w : ℕ) {ic mid oc : ℕ} (pfx xN cotN vN epsStr : String) (p : R50ProjW ic mid oc) (bf16 : Bool) (XIN : Vec (R * N * (ic * h * w))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) :

          Stride-1 projection bottleneck, DP-tied — stage 1 block 0, twelve collectives: the identity bottleneck's nine plus the stride-1 1×1 skip's weight (an ORDINARY ConvWSync) and its BatchNorm's γ and β, which read A, the post-relu cotangent.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            theorem Proofs.ResNet50SyncTieB.r50ProjSyncCotIn_scaled (R : ℕ) (hR : 0 < R) (N h w : ℕ) {ic mid oc : ℕ} (hN : 0 < N) (hh : 0 < h) (hw : 0 < w) (p : R50ProjW ic mid oc) (XIN : Vec (R * N * (ic * h * w))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) (hdys : ∀ (r : Fin R), dys r = batchShard R N (oc * h * w) (fun (i : Fin (R * N * (oc * h * w))) => ↑R * DY i) r) (r : Fin R) :
            r50ProjSyncCotIn R hR N h w p XIN dys r = batchShard R N (ic * h * w) (fun (i : Fin (R * N * (ic * h * w))) => ↑R * ResNet50TieB.r50ProjCotIn (R * N) h w p XIN DY i) r
            theorem Proofs.ResNet50SyncTieB.r50_projblock_syncTiedB (R : ℕ) (hR : 0 < R) (N h w : ℕ) {ic mid oc : ℕ} (hN : 0 < N) (hh : 0 < h) (hw : 0 < w) (pfx xN cotN vN epsStr : String) (p : R50ProjW ic mid oc) (bf16 : Bool) (XIN : Vec (R * N * (ic * h * w))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) (hdys : ∀ (r : Fin R), dys r = batchShard R N (oc * h * w) (fun (i : Fin (R * N * (oc * h * w))) => ↑R * DY i) r) :
            r50ProjSyncTiedB R hR N h w pfx xN cotN vN epsStr p bf16 XIN dys DY
            def Proofs.ResNet50SyncTieB.r50DownSyncTiedB (R : ℕ) (hR : 0 < R) (N h w : ℕ) {ic mid oc : ℕ} (pfx xN cotN vN epsStr : String) (p : R50ProjW ic mid oc) (bf16 : Bool) (XIN : Vec (R * N * (ic * (2 * h) * (2 * w)))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) :

            Strided projection bottleneck, DP-tied — stages 2/3/4 block 0, twelve collectives. v1.5: W₁ is an ordinary ConvWSync at the INPUT grid 2h × 2w and bn₁'s γ/β reduce there; only W₂ (the 3×3) and Wp (the 1×1 skip) are ConvStridedWSync.

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For
              theorem Proofs.ResNet50SyncTieB.r50DownSyncCotIn_scaled (R : ℕ) (hR : 0 < R) (N h w : ℕ) {ic mid oc : ℕ} (hN : 0 < N) (hh : 0 < h) (hw : 0 < w) (p : R50ProjW ic mid oc) (XIN : Vec (R * N * (ic * (2 * h) * (2 * w)))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) (hdys : ∀ (r : Fin R), dys r = batchShard R N (oc * h * w) (fun (i : Fin (R * N * (oc * h * w))) => ↑R * DY i) r) (r : Fin R) :
              r50DownSyncCotIn R hR N h w p XIN dys r = batchShard R N (ic * (2 * h) * (2 * w)) (fun (i : Fin (R * N * (ic * (2 * h) * (2 * w)))) => ↑R * ResNet50TieB.r50DownCotIn (R * N) h w p XIN DY i) r
              theorem Proofs.ResNet50SyncTieB.r50_downblock_syncTiedB (R : ℕ) (hR : 0 < R) (N h w : ℕ) {ic mid oc : ℕ} (hN : 0 < N) (hh : 0 < h) (hw : 0 < w) (pfx xN cotN vN epsStr : String) (p : R50ProjW ic mid oc) (bf16 : Bool) (XIN : Vec (R * N * (ic * (2 * h) * (2 * w)))) (dys : Fin R → Vec (N * (oc * h * w))) (DY : Vec (R * N * (oc * h * w))) (hdys : ∀ (r : Fin R), dys r = batchShard R N (oc * h * w) (fun (i : Fin (R * N * (oc * h * w))) => ↑R * DY i) r) :
              r50DownSyncTiedB R hR N h w pfx xN cotN vN epsStr p bf16 XIN dys DY
              def Proofs.ResNet50SyncTieB.r50NetSyncTiedB (R : ℕ) (hR : 0 < R) (N q : ℕ) {nCls : ℕ} (xN cotN vN epsStr : String) (w : R50BWeights nCls) (bf16 : Bool) (X : Vec (R * N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (G : Vec (R * N * nCls)) (gs : Fin R → Vec (N * nCls)) :

              Every all-reduced parameter gradient of the sync-BN data-parallel ResNet-50 step, tied — the statement r50_net_syncTiedB proves, named so the per-loss corollaries can state it at their cotangents.

              The single-device chain is r50_net_tiedB's (its dy_k) at the global batch R·N, driven by the global loss cotangent G. The replica chain is each replica's own: the head backward on its shard of the trunk's output at its own cotangent gs r, then sixteen bottleneck backwards, every BatchNorm the sync backward. The conjuncts are the 161 collectives the render emits — stem 3, twelve identity bottlenecks × 9, four projection bottlenecks × 12, dense 2 — each equal to the single-device gradient node at N := R·N.

              Equations
              • One or more equations did not get rendered due to their size.
              Instances For
                theorem Proofs.ResNet50SyncTieB.r50_net_syncTiedB (R : ℕ) (hR : 0 < R) (N : ℕ) (hN : 0 < N) (q : ℕ) (hq : 0 < q) {nCls : ℕ} (xN cotN vN epsStr : String) (w : R50BWeights nCls) (bf16 : Bool) (X : Vec (R * N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (G : Vec (R * N * nCls)) (gs : Fin R → Vec (N * nCls)) (hgs : ∀ (r : Fin R), gs r = batchShard R N nCls (fun (i : Fin (R * N * nCls)) => ↑R * G i) r) :
                r50NetSyncTiedB R hR N q xN cotN vN epsStr w bf16 X G gs

                The synchronised-BN data-parallel ResNet-50 step IS the single-device step at the global batch. R replicas at batch N, each running the render's sync-BN backward chain from its own loss cotangent gs r; every parameter's all-reduced mean gradient — the 161 the render emits — equals the single-device batch-BN gradient node at batch R·N, at the cotangent r50_net_tiedB's chain delivers there from G, whenever each replica's cotangent is R × its shard of G.

                The hypothesis hgs is the divisor step, left open because r50_net_tiedB leaves the loss open: a replica divides its loss by its own batch and the global step by R × that, so a replica's cotangent is R × its shard of the global one — for the label-smoothed CE (r50_net_syncTiedB_smoothedCE) and for BCE-with-logits (r50_net_syncTiedB_bce) alike.

                The right-hand chain is r50_net_tiedB's at N := R·N, g := G, whose nodes that capstone ties to the certified per-op gradient at the chain cotangent — so this and it together say each all-reduced gradient equals the single-device node at the global batch. N, q are binders, so one statement covers the 224-px (q = 7) and 160-px (q = 5) artifacts; 0 < q makes every BatchNorm's reduction width nonzero.

                theorem Proofs.ResNet50SyncTieB.replicaBceLossCot_eq (R N nCls : ℕ) (hR : 0 < R) (bk : ℝ) (bStr logN ohN : String) (Z : Vec (R * N * nCls)) (T : Vec (R * N * (1 * nCls))) (r : Fin R) :
                BackLinks.unrowB N nCls (StableHLO.den (bceLossCotGraph N nCls bk bStr logN ohN (BackLinks.rowB N nCls (batchShard R N nCls Z r)) (batchShard R N (1 * nCls) T r))) = batchShard R N nCls (fun (i : Fin (R * N * nCls)) => ↑R * BackLinks.unrowB (R * N) nCls (StableHLO.den (bceLossCotGraph (R * N) nCls (↑R * bk) bStr logN ohN (BackLinks.rowB (R * N) nCls Z) T)) i) r

                The BCE divisor step — SyncKit.replicaLossCot_eq's peer for BCE-with-logits. Replica r's three-op chain divides by bk, the single-device one at the global batch by R·bk; at the replica's shard of the logits and targets, the replica's cotangent is R × its shard of the global one. σ(z) − t is per example, so only the divisor differs.

                theorem Proofs.ResNet50SyncTieB.r50_net_syncTiedB_smoothedCE (R : ℕ) (hR : 0 < R) (N : ℕ) (hN : 0 < N) (q : ℕ) (hq : 0 < q) {nCls : ℕ} (xN cotN vN epsStr aStr negAK bStr logN ohN : String) (α B : ℝ) (w : R50BWeights nCls) (bf16 : Bool) (X : Vec (R * N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (T : Vec (R * N * (1 * nCls))) :
                r50NetSyncTiedB R hR N q xN cotN vN epsStr w bf16 X (BackLinks.unrowB (R * N) nCls (StableHLO.den (smoothedLossCotGraph (R * N) nCls α (↑R * B) aStr negAK bStr logN ohN (BackLinks.rowB (R * N) nCls (resnet50ForwardBFull (R * N) q w X)) T))) fun (r : Fin R) => BackLinks.unrowB N nCls (StableHLO.den (smoothedLossCotGraph N nCls α B aStr negAK bStr logN ohN (BackLinks.rowB N nCls (batchShard R N nCls (resnet50ForwardBFull (R * N) q w X) r)) (batchShard R N (1 * nCls) T r)))

                The sync-BN DP step at the label-smoothed loss — every bce := false DP artifact. Replicas divide by B, the global step by R·B; replicaLossCot_eq discharges hgs.

                theorem Proofs.ResNet50SyncTieB.r50_net_syncTiedB_bce (R : ℕ) (hR : 0 < R) (N : ℕ) (hN : 0 < N) (q : ℕ) (hq : 0 < q) {nCls : ℕ} (xN cotN vN epsStr bStr logN ohN : String) (w : R50BWeights nCls) (bf16 : Bool) (X : Vec (R * N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (T : Vec (R * N * (1 * nCls))) :
                r50NetSyncTiedB R hR N q xN cotN vN epsStr w bf16 X (BackLinks.unrowB (R * N) nCls (StableHLO.den (bceLossCotGraph (R * N) nCls (↑(R * N) * ↑nCls) bStr logN ohN (BackLinks.rowB (R * N) nCls (resnet50ForwardBFull (R * N) q w X)) T))) fun (r : Fin R) => BackLinks.unrowB N nCls (StableHLO.den (bceLossCotGraph N nCls (↑N * ↑nCls) bStr logN ohN (BackLinks.rowB N nCls (batchShard R N nCls (resnet50ForwardBFull (R * N) q w X) r)) (batchShard R N (1 * nCls) T r)))

                The sync-BN DP step at BCE-with-logits, at the COMMITTED divisors — every bce := true DP artifact, including resnet50in160_lambaccdp8x64wxclipbce (per micro-step). A replica's chain divides by N·K (its own batch × the class count, what the render bakes at B := N); the single-device step at the global batch by (R·N)·K — r50_lossCot_is_bce_grad's divisor at N := R·N. replicaBceLossCot_eq discharges hgs once (R·N)·K = R·(N·K).