How LLMs Are Implemented, Algorithmically
Pull apart a decoder-only large model and you find only five modules: attention, normalization, positional encoding, the feed-forward network, plus the prefill / decode scheduling that strings them into a two-phase inference loop. This structure has barely changed from the 2017 Transformer [1] to today, and every “new architecture” is a local replacement inside one of these five modules. This piece gives each module its own chapter, writes out its core formulas, and then uses two real, current models — the latest Qwen3.5 [24] and DeepSeek-V4 [25] — to see what choices each one makes across these modules.
The whole piece uses one consistent set of symbols:
| Symbol | Meaning |
|---|---|
| batch size | |
| sequence (prompt) length | |
| number of layers | |
| hidden dim (the model’s main dimension) | |
| vocabulary size | |
| number of Q heads | |
| number of KV heads | |
| per-head dim | |
| FFN intermediate dim |
Tensor shapes follow PyTorch convention, written as [B, ..., H]; weight matrices follow the “input dim × output dim” convention, written as .
Attention — Q/K/V · Scaled Dot-Product · MHA/MQA/GQA/MLA
Attention is the only module in a Transformer that lets different tokens exchange information; every other module operates on each token independently. It first projects each token’s hidden state into three copies — query, key, and value:
- — the normalized input
- — Q projection; — K, V projections
- , , then reshaped to expose the head dimension
Scaled Dot-Product Attention
Within a single head, attention is just “use the similarity between Q and all Ks as weights to average over V”:
- — the similarity matrix for each pair
- — the scaling factor, keeping the inner products from growing so large that softmax is pushed into a saturated region with near-zero gradients
- — the causal mask, with the upper triangle set to (position can only see positions )
- softmax normalizes along the K dimension into attention weights, which are then weighted-summed with back to
Multi-Head attention replicates this operation times, each in its own -dimensional subspace, then concatenates and projects back to :
Different heads learn different attention patterns (near-neighbor, syntactic, coreference, …), which is where attention’s expressiveness comes from.
Four variants: touching only the K, V side
At inference, is used once and discarded, but the , of every historical position must be kept for later tokens — this is the KV Cache. It grows linearly with the sequence and is the main pressure on long-context memory and decode bandwidth. The difference among the four attention variants lies entirely in “how many independent sets of K, V there are, and whether K, V are low-rank compressed”; the Q side is always independent heads.
MHA (Multi-Head Attention, the original): every Q head gets its own independent set of K, V, for sets total. Most expressive, and the largest cache.
MQA (Multi-Query Attention) [2]: all Q heads share the same single set of K, V, leaving just 1 set:
The cache shrinks to , times smaller than MHA, but expressiveness is limited and large models applying it directly tend to lose accuracy.
GQA (Grouped-Query Attention) [3]: split the Q heads into groups sharing K, V within each group — a continuous interpolation between MHA and MQA:
degenerates to MHA, to MQA. The kernel only computes sets of K, V and broadcasts along the group dimension when computing scores, without actually replicating tensors. This is the current default for dense and most MoE models (Llama 3, Qwen3, Mistral).
MLA (Multi-head Latent Attention) [4]: GQA only scales the cache linearly with head count; MLA instead compresses K and V jointly into a low-rank latent vector , then routes RoPE through a separate, shared, small branch. In four steps:
Content branch — K and V share one down-projection, and only the latent vector enters the cache:
The Q side is also low-rank (saving memory during training):
Decoupled RoPE branch — on the K side, only one shared -dim vector is computed, used by all heads:
Concatenate and compute attention (the content part and the RoPE part concatenated along the head dimension):
The key point: MLA actually caches only and , for numbers in total. At inference, the associativity of matrices folds the up-projection into :
This way the K content part never has to be reconstructed; attention is computed directly on the cached latent vectors. But RoPE’s rotation angle depends on the absolute position and cannot be folded into fixed weights — once it is applied on the reconstructed K, the folding breaks. So the positional signal must be split into an independent -dim shallow branch.
KV dimension comparison
| Variant | per-token cache (per layer, fp16) | representative models | |
|---|---|---|---|
| MHA | GPT-2/3, Llama 1/2 7B | ||
| MQA | PaLM, Falcon | ||
| GQA | grouped | Llama 3, Qwen3, Mistral | |
| MLA | low-rank compressed | DeepSeek V2/V3 |
In one line: MHA → MQA/GQA saves params, FLOPs, and cache all at once; MLA adds a few projection stages, trading params/FLOPs for cache — shrinking the per-token cache from the KB range down to ~1 KB.
Linear attention and hybrid stacking
All four variants above are still softmax attention: in sequence length, with a cache that grows linearly. Linear attention replaces softmax with an associative feature map , rewriting attention as a recurrence over a “state matrix”, dropping the complexity to and compressing the KV Cache into a state of fixed size, independent of sequence length:
- — the state accumulated up to step , equivalent to “compressing” all historical KV into one matrix
- each decode step only updates and reads once, no longer slowing down as the cache grows
Naive linear attention cannot remember long-range details (the state only grows and cannot be precisely rewritten). Gated DeltaNet [26] adds two things to the recurrence: a gated decay (borrowed from Mamba2, letting the state forget quickly) and a delta rule ( controls precise rewriting of a specific key rather than pure accumulation):
In practice no one uses pure linear attention on its own: it is good at handling long sequences but weak at precise retrieval. The mainstream approach is hybrid stacking — most layers use linear attention to cut cost, and every few layers a full-attention layer is inserted to restore retrieval capability. The Qwen3.5 chapter below is exactly this “3 linear + 1 full” ratio.
Sparsification and compression: letting each query see only part of the KV
Full softmax lets every query see all historical KV; to save cache and FLOPs in ultra-long contexts, there are two orthogonal routes:
Compression — aggregate the KV of consecutive tokens into 1 “compressed entry” in advance, so attention runs over compressed entries and the effective sequence length shrinks to :
Sparse selection — no compression, but for each query pick only the most relevant top- historical entries to attend to, skipping the rest. DeepSeek’s approach is a lightweight lightning indexer that first computes a set of cheap index scores per query, then takes the top-:
The two routes stack: compress first, then do top- sparse selection over the compressed entries — that is DeepSeek-V4’s CSA below; push the compression rate to the max, drop sparse selection, and keep dense attention over the compressed entries — that is its HCA. Add a sliding-window branch for local detail and a set of attention sinks that let each head’s attention weights not sum to 1, and you have V4’s hybrid attention.
Normalization — LayerNorm vs RMSNorm · pre-norm
Normalization stabilizes the numerical scale of each layer’s input so that deep networks stay trainable. Standard LayerNorm does zero-mean, unit-variance over the feature dimension, then applies an affine transform:
- — learnable scale / shift
- — small constant to avoid division by zero (typically )
- — element-wise multiplication
RMSNorm [5] (the mainstream choice for Llama / Qwen / DeepSeek) drops the mean-centering and the bias, using only root-mean-square scaling:
The denominator is the root mean square of , hence the name. It drops the mean and also drops , roughly halving both compute and parameters, and empirically this is almost lossless for quality.
Placement: pre-norm, not post-norm. The original Transformer was post-norm (norm after the residual addition), which tends to be gradient-unstable at depth; modern models all use pre-norm — the norm sits inside the residual branch, and the trunk jumps straight across:
Pre-norm makes the residual trunk a “highway” undisturbed by the norm, allowing stable training even at hundreds of layers.
Beyond the residual: hyper-connections. Pre-norm adds each layer’s output back to a single residual trunk. Hyper-Connections [27] widen this trunk into parallel residual streams, mixing between layers with learnable (and input-dependent) coefficient matrices :
This relaxes the “fixed depth order + single residual” constraint, easing the tug-of-war between vanishing gradients and representation collapse. DeepSeek-V4’s mHC further constrains the residual mapping to the manifold of doubly stochastic matrices (spectral norm , non-expansive mapping) in exchange for numerical stability when stacking deep — see the DeepSeek chapter below.
Positional encoding — absolute position → RoPE → length extrapolation
Attention itself is order-insensitive (shuffle the tokens and the result is unchanged), so positional information must be injected explicitly. The original Transformer used absolute positional encoding: build a sinusoidal vector for each position and add it to the embedding. The downsides are that it only encodes absolute position and extrapolates poorly to lengths never seen in training.
RoPE (Rotary Positional Embedding) [6] takes a different tack: instead of adding a vector, it lets position act on Q and K as a rotation, so the inner product automatically retains only relative position. It slices each head’s dimensions into two-dimensional subspaces and, at position , multiplies the -th coordinate pair by a 2D rotation matrix:
- — the token’s absolute position; — the 2D-subspace index
- — the angular velocity of the -th subspace, with the frequency-decay base (Llama takes , Qwen3 takes )
Why does rotation encode relative position? Denote the whole -dim rotation as the block-diagonal matrix ; it is orthogonal and satisfies , hence:
When attention computes , the score for each pair depends only on the difference — absolute position is canceled in the inner product, leaving relative position. The frequency spectrum gives the subspaces angular velocities from fast to slow: has period about tokens handling near-neighbors, has period tens of thousands of tokens handling long range. RoPE acts only on Q and K, not on V.
Length extrapolation. Training only ever sees ; once inference length exceeds this, the low-frequency subspaces enter the out-of-distribution region and attention degrades. The common fixes all modify :
- Position Interpolation: , compressing all frequencies by the same ratio — simple, but it sacrifices high-frequency precision.
- NTK-aware: scale only the low frequencies while preserving the high ones, equivalent to enlarging .
- YaRN [7]: handle frequency bands separately — high frequencies unchanged, low frequencies scaled à la PI, with a smooth transition in between, plus a temperature correction to offset the attention-entropy drift. The long-context extension of Llama 3.1 and Qwen3 both use it.
Activation functions and the FFN — GELU · SwiGLU · GeGLU · MoE
After attention comes the per-token feed-forward network (FFN), responsible for nonlinear transformation and knowledge storage. The classic FFN first projects up, applies an activation, then projects down:
The activation is an element-wise scalar nonlinearity. The mainstream choices:
- is the standard-normal CDF; GELU [9] is used in GPT-2/3 and BERT
- SiLU (a.k.a. Swish) has a shape close to GELU but simpler, and is the gating activation of the Llama / PaLM line
Gated FFN: the GLU family
The real engineering inflection point is switching the activation from “wrapped on the projection” to “wrapped on the gate”. The GLU family [8] uses two independent up-projections, one as gate and one as value, multiplied element-wise:
Whichever you pick names the variant: is GeGLU (T5 v1.1), is the most common SwiGLU (PaLM, Llama, Qwen, DeepSeek):
SwiGLU has one more projection than the classic FFN (three matrices vs two), and to keep the parameter budget aligned, implementations usually set the intermediate dim to .
Mixture-of-Experts (MoE)
In a dense FFN, every token passes through the same pair of weights, paying for all parameters and all FLOPs. MoE [10] replicates the FFN into “experts”, with each token selecting only the top- to compute — total parameters scale linearly while the per-token activated parameters and FLOPs stay almost unchanged, trading capacity for knowledge, not for compute:
- — the router, mapping the hidden state to the logits of experts
- — the selected top- expert set; is the normalized combine weight
- each is usually just a SwiGLU, with only the weights not shared
A naive router will “collapse” onto a few hot experts, requiring load balancing. GShard/Switch use an auxiliary loss ( the routing fraction, the average probability) as a soft constraint; DeepSeek instead uses an auxiliary-loss-free scheme [12]: maintain a bias per expert, base TopK on , raise it for underused experts and lower it for overused ones — affecting only selection, without polluting the gradient. These two pieces (fine-grained MoE, loss-free balancing) are central to the DeepSeek chapter below.
Prefill and Decoding — GEMM vs GEMV · compute vs bandwidth
Autoregressive inference splits into two phases with sharply different dimensions and bottlenecks.
Prefill: ingest all prompt tokens at once, run through every layer in parallel, and produce the first output token plus the full KV Cache. The main tensor shape is , all matrix multiplications are matrix × matrix (GEMM), arithmetic intensity is high, and it is compute-bound, much like a single training forward pass.
Decoding: each step feeds only the 1 token generated last step, reads all historical K, V from the cache, and computes the next token. The main shape is , matrix multiplication degenerates to matrix × vector (GEMV), most time is spent moving weights from memory into the compute units, and it is memory-bandwidth-bound.
| Position | Prefill | Decode (per step) |
|---|---|---|
| input_ids | ||
| Q | ||
| K/V (from cache) | ||
| attention scores | ||
| operation type | GEMM (mat × mat) | GEMV (mat × vec) |
| bottleneck | compute | memory bandwidth |
KV Cache shape and growth
Each layer caches a pair of tensors that keep growing as generation proceeds:
The per-token, per-layer cache size (fp16, GQA) is . With that is 4 KB/layer; a 32-layer, 4096-token request is about 512 MB — under long contexts this is the main memory occupant, and the battleground for all cache optimizations like MLA, KV quantization, and PagedAttention.
The physical ceiling on throughput
Every decode step must scan the entire model’s weights once. With parameter count in fp16, the weight bytes are about , so the decode throughput ceiling for a single request ():
An 8B model has about 16 GB of fp16 weights; on an H100 @ 3 TB/s, moving the weights alone for one token takes about ms — the physical floor for single-request decode, almost independent of compute. The breakthrough is continuous batching: pack requests into one big GEMV so the same weights are shared by requests, multiplying arithmetic intensity by and raising throughput near-linearly until compute or attention bandwidth hits the wall first.
In computational complexity, having a KV Cache or not differs by three orders of magnitude. With the cache, the total for generating tokens:
The first term is the per-token linear layers (constant per decode step), the second is attention (growing linearly with the cache). Without the cache it would be , recomputing all history each step. “The longer you generate, the slower it gets” comes precisely from growing in the second term. In practice FlashAttention [13] (fusing softmax and matmul into one kernel, cutting memory from to ), PagedAttention [14] (paged cache management, eliminating fragmentation), and speculative decoding [15] (a small model drafts, the large model verifies at once) all do local surgery on this same skeleton without changing the formulas.
Case study: Qwen — Qwen3.5-397B-A17B
Qwen3.5 [24] (released 2026, a flagship natively multimodal model) is Alibaba’s latest open-source generation, with flagship Qwen3.5-397B-A17B (397B total parameters, ~17B activated per token). Compared with the previous Qwen3, it switches the attention backbone: no longer uniformly full attention, but a hybrid stack of linear attention (Gated DeltaNet) and full attention. Broken down into the five modules (language backbone only):
| Module | Qwen3.5’s choice |
|---|---|
| Attention | hybrid: every 4 layers = 3 Gated DeltaNet (linear attention) + 1 gated full attention (GQA) |
| Normalization | RMSNorm, pre-norm, |
| Positional encoding | RoPE (), native context |
| Activation / FFN | SwiGLU |
| Sparsity | fine-grained MoE, 512 routed experts, top-10 + 1 shared expert |
Key architecture numbers (from the official config): 60 layers, hidden ; full-attention layers with , , head_dim (decoupled from hidden); linear-attention layers with 16 key heads, 64 value heads, head dim , conv kernel width ; expert intermediate dim , vocabulary (byte-level BPE, expanded from Qwen3’s ~150k to ~250k).
Three module-level highlights:
- Hybrid attention: 3 of every 4 layers use Gated DeltaNet — an state recurrence whose cache is a fixed-size state matrix, absorbing the cost of long sequences; every 4th layer inserts full attention to restore precise retrieval. The full-sequence attention cost thus grows near-linearly rather than quadratically. See the earlier “Linear attention and hybrid stacking” section for the formulas.
- Gated attention: the full-attention layer’s output passes through a per-channel sigmoid gate , suppressing attention sinks and massive activations to stabilize large-model training.
- Fine-grained MoE + shared expert: each token selects 10 of 512 routed experts, plus 1 shared expert that every token passes through — compared with Qwen3’s “no shared expert”, Qwen3.5 shifts to a DeepSeek-style shared-expert configuration.
In one line: Qwen3.5 = “linear/full hybrid attention + gated attention + RoPE + SwiGLU + fine-grained MoE (with sharing)”, pushing the cost of long context down on the attention side.
Case study: DeepSeek — DeepSeek-V4-Pro / Flash
DeepSeek-V4 [25] (April 2026, preview) gives two MoE models: V4-Pro (1.6T total / 49B activated) and V4-Flash (284B / 13B activated), both natively supporting a 1-million-token context. Compared with V3 [18] / V3.2 [19], it keeps DeepSeekMoE and MTP but switches to new designs in attention and residuals.
Hybrid attention: CSA + HCA (replacing MLA). V3’s signature was MLA (compressing K, V into low-rank latent vectors); V4 goes further, dropping MLA and instead twisting the “compression” and “sparsity” routes (the earlier “Sparsification and compression” section) into two interleavable attention layer types:
- CSA (Compressed Sparse Attention): first compress every tokens’ KV into 1 entry, then use the lightning indexer to select only the top- compressed entries per query for attention (Pro , Flash ) — compression × sparsity stacked.
- HCA (Heavily Compressed Attention): push the compression rate to (far above CSA), but no longer sparse-select, keeping dense attention over the compressed entries.
The core attention uses shared-KV MQA (compressed entries serve as both K and V), the Q side goes through low-rank compression (: Pro , Flash ), plus an sliding-window branch for local dependencies and a set of learnable attention sinks that let each head’s attention weights not sum to 1. RoPE acts only on the last 64 dims of each vector. KV storage uses mixed precision: BF16 for the RoPE dims, FP8 for the rest, cutting the cache nearly in half again. The result: at 1M context V4-Pro needs only ~27% of V3.2’s per-token FLOPs and 10% of its KV cache, and Flash drops further to ~10% FLOPs and 7% KV cache; relative to a BF16 GQA (head_dim 128) baseline, KV cache is squeezed to about 2%.
DeepSeekMoE (fine-grained + shared experts) [11] follows V3’s approach with tweaked configuration: MoE now fills every Transformer layer (no more dense FFNs), the first 3 MoE layers switch to hash routing (assigning experts by a fixed hash of the token id); the routing scoring function changes from V3’s sigmoid to ; load balancing still uses the auxiliary-loss-free bias method [12], plus a weak sequence-level balancing loss. Pro has 1 shared + 384 routed experts per layer (intermediate dim ), Flash has 1 shared + 256 routed experts (intermediate dim ), both activating 6 routed experts per token.
Two more modules:
- mHC (Manifold-Constrained Hyper-Connections): widen the single residual trunk into parallel residual streams, and constrain the residual-mixing matrix to the manifold of doubly stochastic matrices (spectral norm , non-expansive), trading for numerical stability when stacking deep. See the earlier “Beyond the residual” passage for the principle.
- MTP (Multi-Token Prediction): a depth-1 shallow module predicts the “token after next”, giving the backbone a denser supervision signal during training and serving directly as a speculative-decoding draft at inference to boost throughput — same as V3.
Architecture numbers: V4-Pro has 61 layers, hidden ; V4-Flash has 43 layers, hidden ; vocabulary ; both trained in FP8, with post-training FP4 quantization of the MoE expert weights and indexer QK. Placing the three models side by side: Qwen3.5 takes “linear/full hybrid attention + fine-grained MoE”, DeepSeek-V4 takes “compression+sparsity hybrid attention (CSA/HCA) + fine-grained MoE + mHC + MTP” — the same skeleton, different trade-offs.
Summary — five modules, one skeleton
Decoder-only LLM inference is, at bottom, the combination of five modules: attention (who sees whom), normalization (stabilizing values), positional encoding (encoding order), FFN/MoE (storing knowledge), and prefill/decode (scheduling). Each module has one main formula, and the variants just swap in a replacement at one spot — GQA/MLA changes the attention KV structure, RMSNorm changes normalization, RoPE/YaRN changes positional encoding, SwiGLU/MoE changes the FFN. Once you understand these five formulas, the difference between Qwen3.5 and DeepSeek-V4 is nothing but a different selection table on the same skeleton; and any inference-optimization paper you read afterward can be located to whichever module it touches.
References — papers · technical reports
- Vaswani et al. Attention Is All You Need (NeurIPS 2017). arxiv.org/abs/1706.03762
- Shazeer. Fast Transformer Decoding: One Write-Head is All You Need (2019) — MQA. arxiv.org/abs/1911.02150
- Ainslie et al. GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints (EMNLP 2023). arxiv.org/abs/2305.13245
- DeepSeek-AI. DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model (2024) — first introduces MLA. arxiv.org/abs/2405.04434
- Zhang & Sennrich. Root Mean Square Layer Normalization (NeurIPS 2019) — RMSNorm. arxiv.org/abs/1910.07467
- Su et al. RoFormer: Enhanced Transformer with Rotary Position Embedding (2021) — RoPE. arxiv.org/abs/2104.09864
- Peng et al. YaRN: Efficient Context Window Extension of Large Language Models (2023). arxiv.org/abs/2309.00071
- Shazeer. GLU Variants Improve Transformer (2020) — SwiGLU / GeGLU. arxiv.org/abs/2002.05202
- Hendrycks & Gimpel. Gaussian Error Linear Units (GELUs) (2016). arxiv.org/abs/1606.08415
- Shazeer et al. Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer (ICLR 2017). arxiv.org/abs/1701.06538
- DeepSeek-AI. DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models (2024) — fine-grained + shared experts. arxiv.org/abs/2401.06066
- Wang et al. Auxiliary-Loss-Free Load Balancing Strategy for Mixture-of-Experts (2024). arxiv.org/abs/2408.15664
- Dao et al. FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness (NeurIPS 2022). arxiv.org/abs/2205.14135
- Kwon et al. Efficient Memory Management for Large Language Model Serving with PagedAttention (SOSP 2023) — vLLM. arxiv.org/abs/2309.06180
- Leviathan et al. Fast Inference from Transformers via Speculative Decoding (ICML 2023). arxiv.org/abs/2211.17192
- Qwen Team. Qwen3 Technical Report (2025). arxiv.org/abs/2505.09388
- Qwen Team. Qwen2.5 Technical Report (2024). arxiv.org/abs/2412.15115
- DeepSeek-AI. DeepSeek-V3 Technical Report (2024) — MLA + MoE + MTP + FP8. arxiv.org/abs/2412.19437
- DeepSeek-AI. DeepSeek-V3.2-Exp: Boosting Long-Context Efficiency with DeepSeek Sparse Attention (2025). github.com/deepseek-ai/DeepSeek-V3.2-Exp
- Meta AI. The Llama 3 Herd of Models (2024). arxiv.org/abs/2407.21783
- Jiang et al. Mixtral of Experts (Mistral AI, 2024). arxiv.org/abs/2401.04088
- Fedus et al. Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity (JMLR 2022). arxiv.org/abs/2101.03961
- Adam Casson. Transformer Inference Arithmetic — back-of-envelope inference FLOPs / KV cache. kipp.ly
- Qwen Team. Qwen3.5-Omni Technical Report (2026) — Gated DeltaNet + gated full-attention hybrid. arxiv.org/abs/2604.15804
- DeepSeek-AI. DeepSeek-V4: Towards Highly Efficient Million-Token Context Intelligence (2026) — CSA/HCA + mHC. arxiv.org/abs/2606.19348
- Yang et al. Gated Delta Networks: Improving Mamba2 with Delta Rule (ICLR 2025). arxiv.org/abs/2412.06464
- Zhu et al. Hyper-Connections (ICLR 2025, ByteDance). arxiv.org/abs/2409.19606