Test the operator, its derivatives, and its scaling separately
Build deterministic reference cases, meaningful error metrics, metamorphic checks, and mechanism-aware complexity experiments.
On this page
The question for today
What you’ll understand
- Separate a kernel mismatch from an intentional operator approximation.
- Apply absolute-plus-relative tolerance and local gradient checks.
- Test masking, head mapping, permutation, and complexity assumptions.
An efficient attention implementation can fail in several different ways: it can compute the wrong mask, accumulate gradients incorrectly, introduce excessive numerical error, or execute the intended operator more slowly than expected. One large random comparison does not distinguish those mechanisms. Build a test suite around the mathematical contract, then add numerical and complexity evidence. Exact tiled kernels should match the same dense operator within precision-aware tolerances; sparse and alternative-kernel methods need a matching reference first, followed by a separate comparison with whatever dense behavior or task quality they aim to approximate.
Make the reference harder to fool
Use small cases that can be calculated by hand before comparing larger tensors against a higher-precision implementation. Uniform logits test the allowed-key average directly. A single dominant score tests stable normalization, while a masked dominant score tests whether exclusion happens before the maximum and denominator. Distinct sequences and heads reveal accidental broadcasting that identical random distributions can hide. Fix dropout to zero for deterministic tests, then validate dropout behavior separately.
Choose elementwise absolute-plus-relative tolerances based on dtype, accumulation, shape, and the reference’s accuracy. Relative error alone is unstable near a zero reference value, while a large absolute tolerance can hide meaningful errors in small outputs. Record maximum and aggregate errors, inspect failing coordinates, and verify finiteness. A tolerance is not permission to ignore systematic mask or head-mapping differences whose values happen to fit under one loose threshold.
Check invariants and gradients
Softmax is invariant to adding a common finite constant to all allowed logits in a row. Consistently permuting keys, values, and mask columns preserves a noncausal row’s output. These transformations make useful metamorphic tests, provided positional biases and causal relations are transformed consistently rather than accidentally changed. For GQA, compare a shared-KV implementation with a reference that explicitly repeats K and V according to the documented grouping, including the summed backward gradients.
Finite differences on a tiny smooth case help detect a missing scale or denominator term in backward. Use a central difference at a step that balances truncation and floating-point cancellation, and avoid crossing a discontinuous mask or routing change. A successful spot check does not prove the whole gradient tensor, so combine it with reference gradients for varied shapes, ragged boundaries, empty-row extensions, and the same logical dropout realization when replay is part of the contract.
Complexity needs controlled experiments
Sweep sequence length while holding head width, feature width, batch, pattern width, dtype, and mask family fixed as appropriate. Dense attention retains quadratic leading pair work even when tiled saved state is linear. A bounded window has linear logical pairs, while a window that grows with N does not. A feature-map method’s linear claim similarly assumes a controlled feature width. Report the actual parameter values beside any fitted scaling curve.
Measure peak memory after isolating allocations and distinguish allocated from reserved pools where the tooling permits. Measure time with synchronized device timing or an equivalent documented method; asynchronous launch return time is not kernel completion time. Include kernel selection and fallback behavior, because the same high-level call can select different backends across shapes. A scaling test should explain a mechanism and identify its boundaries, not turn a few timing samples into an unsupported asymptotic proof.
Work it through
Tolerance near zero and a small gradient check
A reference output is (0,2) and a tested output is (0.0002,2.002). Use absolute tolerance a=0.001 and relative tolerance r=0.001. Separately test L(t)=1+2σ(t), the output of two-logit attention with values (1,3), at t=0 and h=0.001.
Absolute errors are 0.0002 and 0.002. Their allowed bounds are 0.001+0.001×0=0.001 and 0.001+0.001×2=0.003, so both coordinates pass. A pure relative-error test is undefined or misleading at the zero reference coordinate.
For the scalar attention case, L(0)=2 and the analytic derivative is 2σ(0)(1−σ(0))=0.5. This derivative includes the normalization coupling between the two logits.
The central difference uses [L(0.001)−L(−0.001)]/0.002≈0.4999999583, agreeing closely with 0.5. Replacing the tested zero-coordinate output by 0.002 would fail its 0.001 bound despite the other coordinate still passing.
The example combines a precision-aware output check with a local derivative check. Neither substitutes for testing mask, layout, and shared-head semantics across the supported domain.
The living notebook
Explore the model
Interactive lab · root-finding
An explicit error bound is different from a plausible value
Reset, set Target c to 2 and Initial upper bound U to 3. Predict after one Step that the bracket is [0,1.5], midpoint 0.75, and maximum endpoint distance 0.75. Reset, set c to 1 and U to 2; predict exact midpoint root 1 and zero bound after Step. Refinements cap at 50. This bisection model certifies one quadratic root bracket, not attention error or gradient correctness.
- Midpoint after 0 refinements
- 1.5
- Bracket error bound
- 1.5
- Computed residual · x² − c
- 0.25
Bisection of x² − c on [0,U], capped at 50 iterations for floating-point resolution. The error bound is the maximum distance from the displayed midpoint to either bracket endpoint (half the width in exact arithmetic). Compensated square evaluation preserves the bracket when ordinary multiplication rounds a residual to zero. A truly exact endpoint or midpoint collapses the bracket. This is one monotone quadratic, not a general root solver. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forA stated bound has assumptions and a defined target; visual closeness alone is not a correctness criterion.
Pause & reason
Check your understanding
Your turn
Try it yourself
For zero logits and scalar values (2,4), a mask allows only the first key. Compute the correct output and the output if the mask is ignored. Would increasing floating-point tolerance repair this discrepancy?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Uniform probabilities apply only over allowed keys.
Compare with the solution
The correct allowed set contains one key, so its probability is 1 and output is 2. Ignoring the mask gives probabilities (1/2,1/2) and output 3. The difference of 1 is a semantic mask error, not a rounding effect. A looser tolerance might hide the failure numerically but cannot make the two operators equivalent.
Keep the idea
Take it with you
- Use a reference with the same mask, layout, scale, and head semantics.
- Check outputs, gradients, and invariants with precision-aware metrics.
- Scaling claims require fixed parameters and measured backend behavior.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.