Back to blog
ResearchModels

The Hadamard MLP for Channel Mixing for Almost No Parameters

Needle replaces the transformer's feed-forward layer with three Kronecker-factored mixes that start as the Walsh-Hadamard transform and learn from there. 25.6K parameters per layer instead of 4.7M, and a fifth of the compute per token.

HN

Henry Ndubuaku

||13 min read

A transformer block has two parts. Attention mixes information across tokens, and the feed-forward layer mixes the channels within a token, the 768 numbers that describe it. The feed-forward layers hold most of the parameters in a transformer, and on a small device every parameter has to be read from memory for every token. Needle replaces the feed-forward layer with a Hadamard MLP, a mixer with 25.6K parameters per layer instead of 4.7M. Below is the construction and what it costs.

The cost of a feed-forward layer

A token is a vector x∈Rdx \in \mathbb{R}^{d} with d=768d = 768. The standard feed-forward layer is two matrices with a nonlinearity between them:

FFN(x)=W2 σ(W1x),W1∈R4d×d, W2∈Rd×4d.\mathrm{FFN}(x) = W_2\, \sigma(W_1 x), \qquad W_1 \in \mathbb{R}^{4d \times d},\ W_2 \in \mathbb{R}^{d \times 4d}.

It stores 2⋅768⋅3072≈4.7M2 \cdot 768 \cdot 3072 \approx 4.7\text{M} numbers per layer, and it spends 4.7M4.7\text{M} multiply-adds on every token.

On a GPU the multiply-adds are the cost. On a phone, a watch or a microcontroller, the cost is moving the weights. Every weight travels from memory into the processor for every token, and memory is slow. A token is not done until the last weight has arrived.

what one token has to read, per layereach cell is 26K weights · the token cannot finish until the last cell is readdense feed-forward, d = 768, hidden 4d4.7M weights · 4.7M multiply-addsHadamard MLP25.6K weights · 0.21M multiply-addsevery weight is fetched from memory for every token, and on a small device the fetch takes longer than the arithmetic
The cost that matters on a small device. Every weight a layer touches has to be fetched for every token. The dense layer is 180 cells wide at this scale; the Hadamard MLP is one.

Our attention-only study measured what this layer contributes. Its parameter count matters. Its exact shape matters much less. What the block needs is a mixer that connects every channel to every other, plus a nonlinearity, with as few stored numbers as possible.

A mixer with no weights

The Walsh-Hadamard matrix connects every channel to every other and stores nothing. One rule defines it at every size:

H1=[1],H2n=12[HnHnHn−Hn].H_1 = [1], \qquad H_{2n} = \frac{1}{\sqrt{2}} \begin{bmatrix} H_n & H_n \\ H_n & -H_n \end{bmatrix}.

Tile the matrix four times, flip the sign of the bottom-right copy, scale by 1/21/\sqrt{2}.

H1 · 1 × 1H₁ = [1]H₂ₙ = 1/√2 · [ Hₙ Hₙ ][ Hₙ −Hₙ ]+1/√n−1/√nevery row is orthogonal to every otherH H = I · nothing to store · n log₂ n adds
The Walsh-Hadamard matrix. Each step tiles the last matrix four times and flips the sign of one quarter. The rule is the whole definition, so the matrix costs no memory at any size.

Three properties make it a good mixer.

  1. Every entry is +1/n+1/\sqrt{n} or −1/n-1/\sqrt{n}. Nothing is stored; the rule is the matrix.
  2. It is orthogonal, HH⊤=IH H^{\top} = I. It rotates a vector without stretching it, so values do not grow or vanish as they pass through.
  3. Applying it is cheap. The fast transform below does it in log⁡2n\log_2 n stages. Each stage pairs channels and replaces the pair (a,b)(a, b) by (a+b,a−b)/2(a+b, a-b)/\sqrt{2}, which is nlog⁡2nn \log_2 n additions in total.
Eight channels, three butterfly stages, every channel talks to every otherxstage 1stage 2H₈ xx0x1x2x3x4x5x6x7+1−1
The Walsh-Hadamard transform. Each stage pairs channels a fixed distance apart and replaces them by their sum and difference, so n channels are fully mixed in n log₂ n additions with no weights at all. Needle's MLP starts from this transform and learns away from it.

After the last stage every output depends on every input. Needle 2 used this transform as its mixer, with a learned scale on each channel before and after it. Needle 3 keeps the idea and makes the rotation itself learnable, at the same cost. The tool for that is the Kronecker product, in the form of a Monarch matrix.

Folding a vector into a tile

Pad the 768 channels to n=1024n = 1024 and write them as a 32×3232 \times 32 tile ZZ, one row after another. Take two small matrices A,B∈R32×32A, B \in \mathbb{R}^{32 \times 32}. Mix the rows of the tile with AA and the columns with BB:

Z  ↦  A⊤Z B.Z \;\mapsto\; A^{\top} Z\, B.

Flatten the tile back into a vector. The result is the same as multiplying the vector by one 1024×10241024 \times 1024 matrix, the Kronecker product A⊗BA \otimes B:

(A⊗B) vec(Z)=vec ⁣(A⊤Z B).(A \otimes B)\, \mathrm{vec}(Z) = \mathrm{vec}\!\left(A^{\top} Z\, B\right).

1 · reshapethe 1,024-channel vector becomes a 32 × 32 tile Zz ∈ ℝ¹⁰²⁴Z · 32 × 32 (shown 8 × 8)Aᵀ · 32 × 32B · 32 × 32both start as the32-point Walsh matrixand are learned from there(A ⊗ B) z = vec(Aᵀ Z B) · 2 · 32 · 32 · 32 = 65,536 multiply-adds · 2,048 parameters
One Monarch stage. A 1,024 × 1,024 mixing matrix is replaced by the Kronecker product of two 32 × 32 matrices, which is applied by folding the token into a tile and multiplying its rows, then its columns. The engine runs each stage this way, in registers.

A dense 1024×10241024 \times 1024 matrix stores 1,048,5761{,}048{,}576 numbers and costs as many multiply-adds. The two factors store 2⋅322=2,0482 \cdot 32^2 = 2{,}048 numbers and cost 2⋅323=65,5362 \cdot 32^3 = 65{,}536 multiply-adds. That is 512 times fewer parameters and 16 times less work.

The Walsh matrix is itself a Kronecker product, H1024=H32⊗H32H_{1024} = H_{32} \otimes H_{32}. So A=B=H32A = B = H_{32} at initialisation makes the stage an exact Hadamard transform on the first step of training, and every later step is free to move AA and BB.

Why one stage is not enough

One stage mixes each channel with its own row and its own column of the tile. Two channels in different rows and different columns never meet. Of the 1,024 channels, one stage lets a channel reach 2⋅32−1=632 \cdot 32 - 1 = 63.

The fix is a fixed shuffle between stages. After the first stage, a random permutation Π\Pi moves the 63 reached channels to new places in the tile. The second stage spreads each of them along its new row and column, and after that every channel has a path to every other.

one channelwhere can channel z₈ send its value?Z · 32 × 32 (shown 6 × 6)reachedstage 1 row + column 2·32 − 1 = 63shuffle same 63, new placesstage 2 rows + columns all 1,024one Kronecker stage is not a mixertwo stages with a shuffle between them areNeedle uses three, the third for capacity
Why the permutations are there. A Kronecker stage only mixes along rows and columns of the tile. A fixed shuffle between two stages gives every channel a path to every other, the same trick that turns butterflies into a full transform.

A product of block-structured matrices with permutations between them is a Monarch matrix, the same idea as learned butterfly factorisations. Two stages give full reach. Needle uses three, because the third stage adds capacity, and each stage is still two small matrix products.

The whole layer

Ms=As⊗BsM_s = A_s \otimes B_s are the three mixes, Π1,Π2\Pi_1, \Pi_2 the fixed shuffles, D1…D4D_1 \dots D_4 learned per-channel scales, bb a bias, and silu(u)=u⋅sigmoid(u)\mathrm{silu}(u) = u \cdot \mathrm{sigmoid}(u) the nonlinearity:

y=D4 M3 D3 Π2 M2 silu ⁣(D2 c(x)⊙Π1 M1 D1 x+b).y = D_4\, M_3\, D_3\, \Pi_2\, M_2\, \mathrm{silu}\!\big(D_2\, c(x) \odot \Pi_1\, M_1\, D_1\, x + b\big).

Reading from the inside out: scale, mix, shuffle, scale, nonlinearity, mix, shuffle, scale, mix, scale. The middle scale D2D_2 is multiplied by a gain c(x)c(x) that depends on the token:

c(x)=1+softmax(xV) U,V∈R768×8, U∈R8×1024.c(x) = 1 + \mathrm{softmax}(x V)\, U, \qquad V \in \mathbb{R}^{768 \times 8},\ U \in \mathbb{R}^{8 \times 1024}.

The token is projected to 8 numbers, softmax turns them into weights over 8 patterns, and each pattern is a vector of channel gains. UU starts at zero, so c(x)=1c(x) = 1 at initialisation. The gain costs 14K multiply-adds and gives each token some control over how its own channels are scaled, which a wide dense layer gets from its width. D4D_4 starts at 0.02, so a new layer writes gently into the residual stream, the same convention as the attention output.

The whole MLP, left to rightx is padded from 768 to 1,024 channels on the way in and cut back on the way outD₁diagonal gainA₁ ⊗ B₁mix · Walsh initΠ₁fixed shuffleD₂ ⊙ c(x)silu(· + b)the only nonlinearityA₂ ⊗ B₂mixΠ₂fixed shuffleD₃diagonal gainA₃ ⊗ B₃mixD₄write gain · init 0.02c(x) = 1 + softmax(x V) U · rank 8 · identity at initparameters per layer ≈ 25.6K · a dense 4d feed-forward at this width is 4.7M
Three Kronecker mixes, two fixed permutations between them, four learned diagonals, one bias, one activation and a rank-8 gain that lets the input modulate its own channel scaling. Everything mixes; almost nothing is stored.

The parameter count per layer:

piececount
three Kronecker stages, 3×2×3223 \times 2 \times 32^26,144
four diagonal scales and a bias, 5×10245 \times 10245,120
gain, VV: 768×8768 \times 86,144
gain, UU: 8×10248 \times 10248,192
total25,600

Per token, the three mixes cost 3×65,5363 \times 65{,}536 multiply-adds, the scales about 5K and the gain 14K, roughly 0.21M0.21\text{M} in total.

The cost, compared

Parameters per layerlog scaledense 4d feed-forward4.7MHadamard MLP25.6KMultiply-adds per token, per layerlog scaledense 4d feed-forward4.7MHadamard MLP0.21MWhole model, MFLOPs per tokenlinearsame-shape transformer, dense FFN296Needle3-20L-121M100
At d = 768 with a 4d hidden width, a dense feed-forward layer holds 4.7M parameters and spends 4.7M multiply-adds per token; the Hadamard MLP holds 25.6K and spends about 0.21M. Across the 20-layer model that is the difference between 296 and 100 MFLOPs per token, with attention and the engram unchanged.

Per layer the Hadamard MLP is 180 times smaller than the dense layer and 22 times cheaper to run. Over the 20 blocks of Needle 3 the difference is 94M parameters, which would take the model from 121M to 215M, and 196 MFLOPs per token, which would take it from 100 to 296.

A dense feed-forward layer is also where a transformer stores facts. Needle stores them in the engram, a conditional memory of hashed n-gram tables that holds 70.8M of its 121M parameters. A table is read by gather: a few rows per token, selected by hashing the last few tokens, with no arithmetic. So the parameter budget went from a matrix that every token reads in full to a memory that is only touched where it is needed.

Results

The question is what the swap loses. We trained the same 12-layer, d=640d = 640 decoder on 800M tokens of Nemotron QA text on 8 H100s, once per mixer, with the same optimiser, schedule and seed, and changed only the feed-forward block. At this width a dense 4d4d feed-forward layer is 3.28M parameters and the Hadamard MLP is 24K; at Needle 3's d=768d = 768 the same two numbers are 4.7M and 25.6K. Validation cross-entropy is in nats per token. The removed columns are for the whole model, since that is what a device stores, and the change column is against the dense GELU row.

mixer, same model shapemixer per layermodelremovedMACs removedvalidation CEloss change
dense FFN, GELU, hidden 4d4d3.28M61.6M2.281
dense FFN, SwiGLU3.32M62.1M0%0%2.422+6.2%
Hadamard MLP24K22.6M63%40%2.695+18.1%
Kronecker stages without the gain11K22.4M64%40%2.695+18.1%
Monarch, normal init65K23.1M62%41%2.699+18.3%
low-rank FFN, same size24K22.6M63%42%2.930+28.5%

What we lose relative to what we remove: per layer the mixer goes from 3.28M parameters to 24K, 99.3% of it; the whole model gives up 63% of its parameters and 40% of its multiply-adds, because the embeddings and attention stay, and pays 18% more loss on general QA text. A low-rank feed-forward layer that removes the same 63% pays 28%. Monarch without the Walsh start pays the same as the Hadamard MLP. SwiGLU removes nothing and pays 6%. The token-dependent gain costs nothing and gains nothing measurable here; across three seeds the Hadamard MLP and the same stages without the gain differ by 0.0%, 1.0% and 1.4% of the loss, in alternating directions.

Removing one piece at a time, at a shorter 573-step screen on an 8-layer, d=512d = 512 model where the dense layer scores 5.29:

ablationvalidation CEloss change
full Hadamard MLP5.84
one Kronecker stage instead of three5.95+1.9%
normal initialisation instead of Walsh5.95+1.9%
no permutations between stages5.90+1.0%
rotation fixed at Walsh, only scales learn5.86+0.3%
no diagonal scales5.45−6.8%

Removing the diagonal scales is the one change that helps at 573 steps and hurts at the full 3,000, where it costs 2.3% of the loss, 2.756 against 2.695.

The 18% is the price on text where the feed-forward layer's storage role matters, the same query-token deficit the attention-only study measured. On tool-shaped data, where the answer is in the context, the price was not where the loss lived, and the engram carries the facts. All rows in the table are one seed; the Hadamard MLP and the gain-free stages were run at two more seeds, which is where the three paired differences come from.

On the device

Each Kronecker stage runs as the two 32×3232 \times 32 products of the diagram, on a tile that fits in vector registers. A layer's mixer is a few hundred fused multiply-adds per lane with no weight matrix to fetch. The three factor pairs, the scales and the gain are a little over a hundred kilobytes per layer at full precision, and much less in the shipped 2-bit archive, so the mixer stays in cache for the whole session. Decode on a Raspberry Pi 5 runs at 400 to 4,000 tokens per second across the depth ladder, and the Hadamard MLP is a large part of that.

What it gives up

  • A dense layer can represent any linear map on its hidden width. Three Kronecker mixes with shuffles cannot represent all of them.
  • The rank-8 gain is a small substitute for the token-dependence a wide hidden layer has.
  • On the reasoning-dense, tool-shaped data Needle trains on, the block's job is to route and transform what is already in context. That expressivity was not where the loss lived, and the engram took the storage role.
  • Whether the same trade holds for knowledge-heavy general text at larger scale is open, and it is the same question the attention-only study left open.
  • Within Needle's regime the numbers above are the argument: a 121M model that beats models ten times its size on mobile tool calls, at a third of the compute a transformer of its shape would spend.

References

  1. Vaswani et al., Attention Is All You Need, 2017.
  2. Walsh, A Closed Set of Normal Orthogonal Functions, American Journal of Mathematics, 1923.
  3. Fino and Algazi, Unified Matrix Treatment of the Fast Walsh-Hadamard Transform, IEEE Transactions on Computers, 1976.
  4. Dao et al., Monarch: Expressive Structured Matrices for Efficient and Accurate Training, 2022.
  5. Dao et al., Learning Fast Algorithms for Linear Transforms Using Butterfly Factorizations, 2019.
  6. Hendrycks and Gimpel, Gaussian Error Linear Units, 2016.
  7. Cheng et al., Conditional Memory via Scalable Lookup: A New Axis of Sparsity for Large Language Models, 2026.
  8. Ndubuaku et al., A Controlled Study of Attention-Only Transformers, 2026.