Assemble and Test a Transformer Block
A transformer block is not a bag of famous layers. It is an ordered tensor contract whose mask, normalization placement, residual routes, parameter identity, and numeric behavior must agree.
- Authorship
- InterviewsVector
- Published / updated
- 2026-08-25 / 2026-08-25
- Review status
- Artifact tests passing · primary sources recorded
Original InterviewsVector material. Code examples are covered by repository tests and primary references are recorded. No named human reviewer is claimed.
The decision in one pass
For a pre-layer-normalized decoder block, normalize the current residual stream, compute masked self-attention, project it back to the hidden width, and add the first residual. Normalize that result, apply a position-wise MLP, and add the second residual. Every transformation preserves the [batch, sequence, hidden] outer shape, while attention temporarily exposes head and source-position dimensions. A causal mask forbids keys to the right of each query; a padding mask forbids declared padding keys and requires a separate decision for padded query outputs. Validate concrete immutable input and weight records, bind model and architecture revisions, use stable softmax and bounded arithmetic, and test prefix invariance. A tiny dependency-free block can teach these contracts, but it is not numerically or operationally equivalent to a fused production kernel.
Why this matters
Most transformer failures are local contract violations with global symptoms: an inverted mask leaks future tokens, a normalization move changes optimization, a projection silently swaps dimensions, or a padded row reaches the loss. A block-level contract turns those mistakes into reproducible failures before a full training run spends them into a checkpoint.
You will be able to
- Trace attention, residual, normalization, and MLP paths in their exact execution order.
- Derive the shapes and causal visibility set for every query position.
- Distinguish a padding-key rule from the policy for padded query outputs.
- Build an immutable content-addressed block input and parameter record.
- Stress stable softmax, normalization, masking, dimensions, and numeric limits.
- State why an inspectable toy block is not a production-kernel equivalence claim.
Your Vector Loop for this lab
- 01
Model
Draw one declared decoder block with its residual stream, pre-normalization sites, mask semantics, and tensor axes.
- 02
Derive
Derive scaled attention, prefix visibility, normalization statistics, and both residual additions at fixed dimensions.
- 03
Build
Capture concrete immutable parameters and inputs, then execute a bounded dependency-free teaching block.
- 04
Stress
Invert masks, alter future tokens, corrupt dimensions, move normalization, inject padding, forge identities, and attack numeric bounds.
- 05
Operate
Record model, architecture, weight, input, mask, precision, and kernel identities beside block-level replay evidence.
- 06
Defend
Explain which block invariants passed and why they do not prove training quality, fused-kernel parity, or production throughput.
Start with one ordered block contract
The residual stream has a declared hidden width d and sequence length T. Attention consumes normalized rows, constructs queries, keys, and values, routes visible values, and returns d features per position. The MLP transforms each position independently and also returns d features. Residual addition is legal only because both branches return the same outer shape and semantics.
| Boundary | Teaching shape | Invariant |
|---|---|---|
| residual input | [T, d] | ordered positions in one model revision |
| Q, K, V | [T, d] | projection identity and hidden width agree |
| attention scores | [T, T] | masked source positions cannot contribute |
| attention output | [T, d] | projected back before residual addition |
| MLP output | [T, d] | position-wise transform returns residual width |
Derive attention and masking as routing
A = softmax((QKᵀ / √d) + M); Z = AV
The additive mask M contributes a forbidden value before softmax in common kernels. The artifact instead enumerates only permitted keys, which makes causal and padding visibility explicit without manufacturing a finite stand-in for negative infinity.
- 01Normalize before the branchFor a pre-norm contract, calculate per-row mean and variance, apply the declared epsilon, gain, and bias, then project Q, K, and V.
- 02Construct the visible setQuery i may use non-padding keys j where j ≤ i. A future token must not affect any earlier output.
- 03Apply stable softmaxSubtract the largest visible score before exponentiation and use an accurate sum for the denominator.
- 04Close the residual pathProject the routed value to d features, validate numeric bounds, and add it to the exact input row.
Keep normalization, residuals, and the MLP distinct
Y = X + Attn(LN₁(X)); O = Y + MLP(LN₂(Y))
This equation names a pre-norm block. A post-norm block has a different graph and training behavior; moving LN is an architecture change, not formatting.
The position-wise MLP shares parameters across positions but does not mix positions. Attention mixes permitted positions; the MLP transforms features within each position. Residual addition preserves a direct path around each learned branch. Dropout, multiple heads, bias terms, rotary position operations, gated activations, and fused kernels are deliberately outside this minimal executable surface and must be named when added.
| Change | Contract consequence | Required replay |
|---|---|---|
| pre-norm to post-norm | different graph | optimization and gradient-path tests |
| causal to bidirectional mask | different information boundary | future-perturbation and task tests |
| ReLU to gated MLP | different parameters and activation | shape, numeric, and checkpoint tests |
| reference to fused kernel | different implementation | tolerance, precision, and performance tests |
Build a content-addressed teaching block
1def audit_transformer_block(2 contract: TransformerBlockContract,3 weights: TransformerBlockWeights,4 evidence: TransformerBlockInput,5) -> TransformerBlockReport:6 """Validate scope and run one bounded pre-norm causal block."""Expected output
example=illustrative_only
contract_version=transformer-block-v1
contract_content_id=transformer-contract@sha256:1e518b5f80e3143f2e5ec1ff73c93c007852c676206ed833cda980c23eddbeec
weights_content_id=transformer-weights@sha256:3741140d92a7d319759d7ce417b486c01ea20c8cd4d9bd2cd5355b999e0896d5
input_content_id=transformer-input@sha256:4f7c85be333eba606a98d3bb4bcdd24ccaef020d0b9c077256ba9184919fcac4
shape=3x2
mask=causal-plus-padding
norm=pre-layer-norm
status=PASS
claim=TEACHING_BLOCK_NOT_PRODUCTION_KERNELVerify: python3 -m unittest discover courses/ai-engineering/reference-impl/transformer_block
The excerpt is literal artifact source. The public boundary requires concrete frozen dataclasses, revalidates input and parameter tuples, checks model and contract scope, recomputes weight and evidence digests, caps dimensions and parameter count, rejects booleans and non-finite or sub-resolution values, and bounds every derived output. Its stable softmax subtracts the maximum visible score and its sums use math.fsum.
Stress the boundaries that shape tests miss
- 01Perturb the futureChange a later token sharply and require earlier outputs to remain unchanged under causal masking.
- 02Forge the scopeReuse values under a stale model version, architecture digest, weight content ID, or input digest and require refusal.
- 03Attack paddingReject a non-contiguous padding suffix and verify the declared padded-query output behavior instead of leaving it implicit.
- 04Attack arithmeticInject bool, NaN, infinity, subnormal inputs, excessive magnitudes, unsafe epsilon, and derived overflow.
- 05Attack representationPass mutable lists, duck types, ragged rows, and constructor-bypassed records at the public boundary.
Operate block changes as architecture releases
| Evidence | What it detects | What remains separate |
|---|---|---|
| prefix invariance | causal future leakage | downstream quality |
| mask coverage | padding/visibility mistakes | tokenizer correctness |
| activation and residual bounds | local numeric failure | full-run convergence |
| reference/fused comparison | implementation drift | serving capacity |
| content identities | stale or mixed revisions | model governance approval |
Release a block change with old/new checkpoint replays, fixed token batches, attention-mask probes, forward tolerances by precision, local VJP or gradient checks, training smoke tests, and end-to-end task evaluation. Keep compiler, kernel, device, precision, seed, and framework versions with the evidence. A fast fused path should have a readable reference oracle even when production never runs the oracle.
Defend only the claim the block proves
A passing report supports this narrow statement: one concrete pre-norm, single-head, causal teaching block accepted its declared immutable inputs and weights, preserved the expected shape, and completed bounded binary64 arithmetic. It does not prove mathematical equivalence to every transformer, production-kernel parity, correct gradients, training convergence, or model quality.
Operate at three altitudes
Production lens
- — Validate causal and padding-mask semantics at every kernel or framework boundary.
- — Compare fused and reference outputs under explicit precision-specific tolerances and fixed inputs.
- — Track activation, residual, attention-score, and gradient distributions by layer and sequence slice.
- — Bind checkpoints, architecture configuration, kernels, compiler, precision, and device revision in replay evidence.
Staff lens
- — Treat normalization placement, mask semantics, and residual topology as versioned architecture decisions.
- — Require a readable oracle and prefix-invariance tests before accepting a new optimized attention path.
- — Separate correctness, numerical parity, training behavior, throughput, and model quality into different gates.
Interview defense
Walk through a decoder transformer block and explain how you would test it.
I would name the exact pre-norm or post-norm graph, then trace [batch, sequence, hidden] through Q/K/V projections, causal and padding masks, stable softmax, value routing, output projection, the first residual, the position-wise MLP, and the second residual. I would test shapes, future-token prefix invariance, padding behavior, residual identity cases, stable-softmax extremes, local gradients, immutable model and weight scope, and reference-versus-fused parity. A tiny reference validates contracts; it does not claim production-kernel equivalence or model quality.
Expect the interviewer to press on
- — How would an inverted boolean mask present?
- — Why does changing pre-norm to post-norm require more than a unit test update?
- — What does FlashAttention change, and what mathematical result should remain?
Misconceptions to remove
“If all tensor shapes match, the block is correct.”
Mask direction, position semantics, model identity, normalization placement, and residual ordering can all be wrong while shapes agree.
“A causal mask is just an optimization hint.”
It is an information boundary. Future leakage changes the function and can invalidate training or evaluation.
“A pure-Python block proves a fused GPU kernel is correct.”
It can serve as a bounded oracle; parity still needs explicit precision, tolerance, shape, device, and kernel-version evidence.
Check your model
1. What perturbation directly tests whether a decoder block leaks future information?
Change only tokens after a prefix boundary and assert that every output inside the earlier prefix remains unchanged under deterministic execution.
2. Why must an attention output projection return the hidden width before residual addition?
The residual branch and stream must share both shape and feature semantics; otherwise the addition is undefined or silently changes the representation contract.
3. What does subtracting the maximum score before softmax protect?
It avoids exponentiating large positive values while preserving the normalized distribution, though input and derived numeric bounds still need validation.
Prove the mechanism
Extend the reference block with two attention heads while preserving causal prefix invariance, immutable parameter identities, stable softmax, and exact output-shape tests. Document the new parameter count and all new failure cases.
Add a production constraint
Implement a post-norm variant as a separately versioned contract, then compare forward evidence and local vector-Jacobian products without claiming that either layout is universally superior.
Artifact: Minimal transformer block
courses/ai-engineering/reference-impl/transformer_block/transformer_block_contract.py
Download reference implementationPrimary references and next links
References
- 1. Attention Is All You Need
Vaswani et al.. Primary transformer paper for attention, masking, residual, normalization, and feed-forward structure.
- 2. Layer Normalization
Ba, Kiros, and Hinton. Primary paper for per-example normalization with learned gain and bias.
- 3. MultiheadAttention
PyTorch documentation. Official shape and attention-mask semantics reference.
Continue through the graph
- Position, Context, and Extrapolation →
Connect block routing to positional mechanisms and context bounds.
- Backpropagation as Local Contracts →
Add local derivative and gradient checks to the forward contract.
Glossary: transformer block · causal mask · padding mask · pre-layer normalization · residual stream · stable softmax