Skip to the content.

Bug Zoo is TorchLean’s collection of small case studies for semantic bugs that can pass ordinary runtime checks. These examples focus on cases where code still returns tensors, losses, or tokens, but the returned value no longer satisfies the intended contract.

Bug Zoo shows the motivation for TorchLean in miniature: many ML failures are not type errors or crashes, but silent changes in meaning.

Each card starts with a bug pattern, then isolates the small mathematical contract that would have made the intended behavior explicit. Some cards make a mistake unrepresentable in the checked fragment. Others turn the mistake into a theorem obligation or a runtime agreement that has to be named.

A Few Case Studies

Attention mask Bug Zoo case study Attention Masks Checks that masked future positions receive exactly zero attention weight under the stated causal mask semantics. KV cache and RoPE Bug Zoo case study KV Cache and RoPE Makes the cache-position contract explicit so incremental decoding agrees with the intended full-sequence computation. Tokenizer boundary Bug Zoo case study Tokenizer Boundaries Separates byte/token assumptions from model assumptions, so text preprocessing cannot silently change the checked claim. Normalization state Bug Zoo case study Normalization State Tracks which statistics are training state, inference state, or explicit inputs rather than treating normalization as a black box. Batch invariance Bug Zoo case study Batch Invariance States when processing one sample alone should agree with processing it as part of a batch. Float and autograd boundaries Bug Zoo case study Float and Autograd Boundaries Shows how runtime Float32 and reverse-mode claims are connected through named assumptions and proof statements.

How To Read The Zoo

Each Bug Zoo file is small enough to read directly. Read the whole chain: the bug family, the bad pattern, the TorchLean object that names the intended behavior, and the theorem or checker condition that makes the contract explicit.

Build the whole set:

lake build NN.Examples.BugZoo.All

For the cases that also have runnable checker commands, use:

lake exe verify -- camera-box3d-cert
lake exe verify -- all

The Lean files are the primary artifacts:

Source file Bug family Contract exposed
AttentionMask.lean Causal masks, mask polarity, finite sentinels standing in for $-\infty$ Future positions receive exactly zero attention weight under hard-mask semantics.
KVCache.lean Shifted or malformed key/value caches in autoregressive decoding The appended key/value vector is exactly the final cache entry.
RoPEPosition.lean Off-by-one or mismatched rotary/absolute positions Appending a token assigns the next sequence position.
TokenizerBoundary.lean Vocabulary-size and special-token mismatches Imported token ids inhabit Fin vocabSize.
BatchInvariance.lean Dynamic batching changing per-sample outputs Selecting one row from a batched reference run equals evaluating that row alone.
NormalizationState.lean BatchNorm formula/state mistakes Epsilon placement and eval-time running statistics are explicit objects.
LayerNormDegenerateAxis.lean One-feature LayerNorm corner cases The output is the bias, with zero input and scale-gradient contribution.
ConstantNormalizationSlice.lean Cancellation in normalization kernels on constant slices Affine normalization returns the bias and contributes zero scale gradient.
IgnoredLabelLoss.lean All-ignored cross-entropy reductions Ignored labels and the empty-reduction policy are named.
AutogradDomain.lean Masking after undefined division The safe graph records epsilon-protected division before masking.
StableLoss.lean Numerically unstable losses and domain-sensitive ops Logit losses use the stable log-softmax path.
ShapeAndBroadcast.lean Missing axes and silent broadcasts Dimension changes are explicit terms with shape evidence.
CompilerBoundary.lean Optimized graphs silently changing semantics Backend acceptance is a preservation obligation over ops, shapes, dtypes, weights, and buffers.
FloatBoundary.lean Real-valued reasoning applied to Float32 runs Runtime Float32 claims pass through a named IEEE-style bridge assumption.
Geometry3DProjection.lean Camera convention, depth, layout, and projection-box errors The checker recomputes projection, positive depth, and 2D box enclosure.

What “A Checked Claim” Looks Like Here

Each case study should end in a precise statement.

Here is the attention-mask claim in one line: under the hard-mask semantics, strict-future keys get exactly zero attention weight.

theorem trueInfinityMask_future_attention_weight_zero :
  Spec.get2 (Spec.hardMaskedSoftmaxSpec scores (Spec.causalMask n)) i j = 0

And here is the Float32 boundary claim: runtime arithmetic rewrites to the explicit IEEE32Exec model only under a named assumption.

theorem runtimeFloat32_add_rewrites_to_ieee32
    [RuntimeFloat32FiniteMatchesIEEE32Exec] (a b : _root_.Float32)
    (ha : Float32.isFinite a = true) (hb : Float32.isFinite b = true)
    (hr : Float32.isFinite (Float32.add a b) = true) :
    toIEEE32Exec (Float32.add a b) = IEEE32Exec.add (toIEEE32Exec a) (toIEEE32Exec b)

Those are the statement shapes Bug Zoo makes routine.