H2 AttnRes Kernel Lab
Kernel engineering note · v0.2.0

Making Attention Residuals kernel-efficient.

Inside Hydra-2P: a numerically faithful, two-phase fused forward and backward design that reorganizes depth-wise attention around data lifetime—not approximation.

hydra_2p.forward
Q pseudo-queries [S, D]
V completed blocks [N, M, D]
↓
PHASE 1 · RMSNorm + score + online softmax + value accumulation
onumerator
mrow max
ℓdenominator
↓ + live partial
PHASE 2 · exact shared-maximum merge → output
July 18, 202612 minute readPyTorch · Triton · CUDA
Open source · MIT

Residual connections are the quiet infrastructure of deep networks. They keep gradients moving, but they also make a surprisingly strong routing decision: every earlier update is accumulated with the same fixed weight. Attention Residuals turn that fixed depth-wise sum into learned retrieval. The architecture is elegant. Making it cheap at kernel level is the systems problem tackled by AttnRes Kernel Lab.

The central idea

Hydra-2P does not approximate AttnRes. It separates immutable block history from the live partial state, fuses each phase around its natural lifetime, and reconstructs softmax weights during backward.

01 · Context

A residual stream is already a depth router.

A standard PreNorm residual stack updates its state as hl = hl−1 + fl−1(hl−1). Unroll the recurrence and each layer receives the embedding plus every earlier layer output with a coefficient of one. This is useful for optimization, but rigid as information routing.

hl = h1 + Σl−1i=1 fi(hi)
Standard residuals: every prior contribution receives a fixed unit weight.

That fixed aggregation can let hidden-state magnitude grow with depth and can dilute any one layer's relative contribution. The sequence axis escaped a similar fixed recurrence by adopting attention. The Kimi Team's Attention Residuals report asks the natural question: why not give the depth axis learned, content-dependent routing too?

02 · Architecture

Attention Residuals make depth selective.

AttnRes replaces uniform addition with a softmax-weighted sum over previous representations. Each layer owns a learned pseudo-query wl. Earlier layer or block outputs serve as both values and normalized routing keys.

αi→l = softmaxi(wl⊤ RMSNorm(vi))
hl = Σi αi→l · vi
Keys are RMS-normalized for routing. Values remain unnormalized.

Full AttnRes attends over every preceding layer output. Block AttnRes compresses layers into a modest number of completed block summaries. Inside a block, each layer also sees the partial sum produced so far. This bounds persistent history while retaining content-dependent cross-depth access.

SOURCE 01

Completed blocks

Immutable representations shared by every pseudo-query in the current execution block.

SOURCE 02

Live partial

The current block's sequentially evolving sum, absent for the first layer and unique thereafter.

03 · Systems view

The equation is small. The eager graph is not.

A readable PyTorch implementation stacks values, materializes RMS-normalized keys, computes depth logits, writes probabilities, and launches separate reductions and elementwise operations. Backpropagation retains or reconstructs many of those intermediates. Depth is much smaller than sequence length—but at large token counts, moving an extra tensor across HBM is still real work.

Property
Materializing graph
Hydra-2P
Normalized keys
Written to memory
Register-local
Depth logits
Materialized
Streamed
Softmax probabilities
Saved/materialized
Never stored
Live partial merge
Full softmax replay
O(1) row statistics
Backward policy
Saved graph state
Depth-score recompute

The optimization target is therefore not a new approximation. It is a better schedule: batch what is shared, defer what is sequential, and keep stable-softmax state minimal.

04 · Hydra-2P

Two phases, aligned with data lifetime.

Hydra-2P treats completed history and the partial block as two softmax partitions. The first can be computed early and in parallel for all layer queries. The second arrives sequentially and can be merged exactly.

Forward dataflow · one program per layer-token row
INPUT
Q + completed VLoad each query once. Stream N completed block values.
→
PHASE 1
Shared-history sweepFuse RMSNorm, scores, online softmax, and value numerator.
→
PHASE 2
Live-state mergeScore the partial and join partitions under one maximum.
no K tensorno logits tensorno probability tensorFP32 row state

Phase 1: sweep shared history once

For each `(layer, token)` row, the Triton kernel loads the pseudo-query and walks the completed blocks. Each value is normalized in registers to form a key, dotted with the query, and immediately folded into an online-softmax accumulator.

m′ = max(m, x)
ℓ′ = em−m′ℓ + ex−m′
o′ = em−m′o + ex−m′v
Each source updates only a maximum, denominator, and unnormalized value numerator.

The phase emits three sufficient statistics per row: numerator o, maximum m, and denominator ℓ. It never writes the normalized key or source probability.

Phase 2: merge the live partial exactly

When a layer's partial-block value becomes available, Phase 2 normalizes and scores that singleton source. Let `(o₁, m₁, ℓ₁)` describe completed history and `(o₂, m₂, ℓ₂)` describe the partial. A common maximum makes their merge stable and exact:

m = max(m₁, m₂)
h = (em₁−mo₁ + em₂−mo₂) / (em₁−mℓ₁ + em₂−mℓ₂)
The result is algebraically identical to one softmax over all valid sources.

The `has_partial` mask handles the first layer in a block without a sentinel contaminating the denominator. Disabled partials contribute exactly zero mass.

05 · Numerical contract

Fusion is useful only if the math survives it.

The implementation keeps routing and reduction state in FP32 for FP16 and BF16 inputs. RMS variance, dot-product logits, maxima, denominators, numerators, outputs, and gradient accumulation all use FP32 internally before results are cast to the requested dtype.

INVARIANT 01

Values stay raw

RMSNorm is applied only to the keys used for routing. The weighted values preserve the AttnRes equation.

INVARIANT 02

One effective softmax

Both partitions share a final maximum and denominator. The split changes schedule, not weights.

INVARIANT 03

Stable exponentials

Every exponential is shifted by a running or final row maximum before evaluation.

INVARIANT 04

Explicit masking

An absent partial contributes neither value mass nor normalization mass.

This contract is backed by a materializing reference implementation and tests comparing both forward values and manually derived gradients.

06 · Gradient path

Save statistics. Recompute probabilities.

Saving a depth-attention probability tensor would undermine much of the forward fusion. Hydra-2P instead saves the output and final row `(max, denominator)`. During backward, each source score is recomputed and its weight reconstructed.

aj = exp(xj − m) / ℓ
dxj = aj · ⟨dh, vj − h⟩
The softmax-value gradient collapses to one scalar per source.

From that scalar, the kernel computes the direct value gradient, the normalized-key gradient, the RMSNorm Jacobian, and the query contribution. Completed-block gradients and query gradients reduce through FP32 atomics; the partial gradient has single-writer ownership.

Recomputation wins when the thing being recomputed is small—and the tensor it replaces is expensive to move.

The current repository exposes four Triton kernels: two forward phases and two backward ownership paths. This is deliberately transparent research code: the readable PyTorch implementation carries the same manual gradient, while the Triton version makes memory ownership explicit.

07 · Self-evolution

The fastest tile is an empirical fact.

Kernel performance depends on hidden dimension, token count, depth, dtype, GPU architecture, register pressure, and occupancy. A single compile-time configuration is rarely ideal across the shape space.

The plan tuner evaluates valid hidden-dimension tiles and warp counts using the metric users actually care about: combined forward + backward latency. The winner is cached under a key containing GPU name, dtype, query shape, block shape, and partial shape.

python -m attnres_kernel.benchmark \
  --layers 8 \
  --blocks 8 \
  --tokens 4096 \
  --dim 128 \
  --tune

This makes the system “self-evolving” in a practical, bounded sense: it learns execution policy from measured hardware behavior while leaving the mathematical operator fixed.

08 · Evidence

Correctness is verified. GPU speed is a measurement task.

The `v0.2.0` suite covers Hydra-2P, recurrent KDA, KDA write traces, Cross-Axis Delta Routing, manual backward parity, exact partition merges, integrated-layer gradients, and CUDA backend hooks.

Release validation

v0.2.0
22 CPU tests passing
Forward parity verified
Manual gradients verified
Package build verified
CUDA parity requires GPU host
Target-GPU speedups not yet published

The development host did not expose an NVIDIA runtime, so the project does not manufacture a GPU speedup number. The benchmark is synchronized, measures median end-to-end forward + backward time, and records the selected plan. Credible results should report GPU model, PyTorch and Triton versions, dtype, full `S/N/M/D` shape, absolute timings, and speedup.

Scope of the current kernel family

Contiguous CUDA FP16/BF16/FP32 tensors, hidden dimensions up to 256, and first-order gradients. Large depth dimensions may benefit from a future split-reduction backward.

09 · Sequence × depth

KDA adds a second, complementary memory axis.

Hydra-2P routes across model depth. Kimi Delta Attention (KDA) routes across sequence time using a fixed-size recurrent matrix state. The repository now integrates both without pretending they are the same operation.

Dt = Diag(αt) St−1
et = βt(vt − kt⊤Dt)
St = Dt + ktet⊤;  ot = St⊤qt
Channel-wise decay controls forgetting; the delta rule writes only the current prediction error.

The new `KimiDeltaAttention` module follows the Kimi Linear parameterization: short causal convolutions and SiLU for Q/K/V, L2-normalized Q/K, low-rank channel decay, a head-wise β gate, head RMSNorm, and a gated output projection. Its portable recurrent state uses FP32 and is exactly streamable across sequence segments.

Integrated layer · orthogonal routing axes
DEPTH
Completed + partial blocksRepresentations produced by earlier model depth.
→
HYDRA-2P
Depth routingExact softmax chooses which residual blocks matter.
→
KDA
Time mixingFinite recurrent memory decays, reads, and writes by delta.
depth-wise softmaxsequence-wise recurrenceFP32 stateoptional FLA/FlashKDA

`KDAAttnResLayer` first uses Hydra-2P to construct the current layer input, normalizes it, applies KDA across tokens, and accumulates the KDA update into the live AttnRes block. The functional KDA API can dispatch to FLA—and therefore FlashKDA on compatible installations—while retaining the recurrent implementation as a correctness oracle.

Deliberate scope

The project integrates and tests KDA; it does not rebrand KDA as Hydra-2P or claim the official chunkwise algorithm. KDA originates in the Kimi Linear report, with production kernels maintained by FLA and MoonshotAI FlashKDA.

10 · Cross-axis routing

CADR routes what changed—and whether KDA found it novel.

Cross-Axis Delta Routing replaces cumulative depth values with residual deltas and adds a second normalized key derived from KDA's gated write error, write energy, and memory retention. The descriptor changes source selection but never enters the hidden value stream.

xs,i = (qds)⊤ RMSNorm(Δi) + λ(qws)⊤ RMSNorm(zi)
hs = Σi softmax(xs,i) · Δi
Residual deltas are keys and values. KDA write descriptors are auxiliary keys only.

The CADR implementation extends Hydra-2P's completed/live split to both key spaces. Two fused Triton forward kernels stream delta/descriptor pairs and merge the live source exactly. Two backward kernels reconstruct probabilities and differentiate the delta value path, both RMSNorm key paths, and both pseudo-query families.

DEPTH SIGNAL

Residual delta

Captures the actual transformation introduced by a layer or block instead of repeated cumulative history.

TIME SIGNAL

KDA write descriptor

Summarizes gated prediction error, write energy, and memory retention without routing the full recurrent state.

The new `CADRKDAAttnResLayer` closes the loop: CADR constructs the layer input, KDA mixes across tokens, and KDA emits the descriptor cached with the next residual delta. The architecture document contains the complete derivation, tensor contract, kernel ownership model, diagnostics, ablations, and novelty boundary.

11 · Start here

The repository is built to be read, tested, and changed.

The public API validates shapes and dispatches supported CUDA inputs to Triton, with a custom PyTorch fallback everywhere else. The full implementation is MIT licensed at github.com/manishklach/attnres-kernel-lab.

import torch
from attnres_kernel import attnres

S, N, B, T, D = 8, 8, 2, 2048, 128
q = torch.randn(S, D, device="cuda", dtype=torch.float16,
                requires_grad=True)
blocks = torch.randn(N, B, T, D, device="cuda",
                     dtype=torch.float16, requires_grad=True)
partials = torch.randn(S, B, T, D, device="cuda",
                       dtype=torch.float16, requires_grad=True)
has_partial = torch.tensor([False] + [True] * 7,
                           device="cuda")

output = attnres(q, blocks, partials, has_partial)
output.square().mean().backward()

For transformer integration, `prepare_inter_block` computes Phase 1 ahead of the sequential layer group, and `merge_partial` consumes each live state. `AttnResPlan` makes backend, tile, warp count, and epsilon explicit when experiments require reproducible dispatch.

Build on Hydra-2P

Read the kernels. Run the benchmark. Challenge the schedule.

The next useful evidence is a reproducible A100, H100, or Blackwell shape sweep—and the next useful kernel is a split-reduction backward for deeper source counts.