{"id":1040,"date":"2026-07-05T14:54:02","date_gmt":"2026-07-05T14:54:02","guid":{"rendered":"https:\/\/learnerbox.net\/blog\/?p=1040"},"modified":"2026-07-06T11:21:03","modified_gmt":"2026-07-06T11:21:03","slug":"how-large-language-models-work-part-3-the-transformer-block-and-architecture","status":"publish","type":"post","link":"https:\/\/learnerbox.net\/blog\/ai-theory\/how-large-language-models-work-part-3-the-transformer-block-and-architecture\/","title":{"rendered":"How Large Language Models Work \u2014 Part 3: The Transformer Block and Architecture"},"content":{"rendered":"\n<h6 class=\"wp-block-heading\">This is Part 3 of a five-part series on the internal mechanics of large language models. <a href=\"https:\/\/learnerbox.net\/blog\/ai-theory\/how-large-language-models-work-part-2-the-attention-mechanism\/#comments\">Part 2<\/a> derived scaled dot-product attention and the KV cache. Part 3 traces the complete transformer block consisting of feed-forward networks, layer normalisation, and residual streams; it examines the architectural differences between decoder-only and encoder-decoder models.<\/h6>\n\n\n\n<h4 class=\"wp-block-heading\">From Attention Output to Transformer Block<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">At the end of Part 2, self-attention had produced an output matrix <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>O<\/mi><mo>\u2208<\/mo><msup><mi mathvariant=\"double-struck\">R<\/mi><mrow><mi>n<\/mi><mo>\u00d7<\/mo><mi>d<\/mi><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">O \\in \\mathbb{R}^{n \\times d}<\/annotation><\/semantics><\/math> or one updated vector per token, now containing contextual information drawn from every other position in the sequence. But this is only the first half of a single transformer block. Before the signal moves to the next layer, it passes through three more components: a residual connection, layer normalisation, and a position-wise feed-forward network. Together with multi-head attention, these four elements constitute the repeating unit of every transformer-based LLM, stacked <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>N<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">N<\/annotation><\/semantics><\/math> times to form the full model.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Understanding each component precisely is important not just for implementation, but for diagnosing failure modes, interpreting mechanistic interpretability research, and making informed decisions about architectural variants when selecting or fine-tuning models.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Residual Connections<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The residual connection, introduced in ResNets for computer vision and adopted into transformers from the outset, is deceptively simple. Rather than passing the attention output <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>O<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">O<\/annotation><\/semantics><\/math> directly to the next component, the original input <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>X<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">X<\/annotation><\/semantics><\/math> is added back:<math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><msup><mi>X<\/mi><mo mathvariant=\"normal\" lspace=\"0em\" rspace=\"0em\">\u2032<\/mo><\/msup><mo>=<\/mo><mi>X<\/mi><mo>+<\/mo><mtext>MultiHead<\/mtext><mo stretchy=\"false\">(<\/mo><mi>X<\/mi><mo stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">X&#8217; = X + \\text{MultiHead}(X)<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This addition of the residual or skip connection has several important consequences.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, it solves the vanishing gradient problem for very deep networks. During backpropagation, gradients flow backward through the network. Without residual connections, multiplying many Jacobians together through <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>N<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">N<\/annotation><\/semantics><\/math>N sequential non-linear transformations causes gradient magnitudes to decay exponentially, making early layers extremely slow to learn. The residual path provides a direct gradient highway that bypasses each block, so that gradients can flow backward through the addition operation unchanged, regardless of how many layers separate the loss from the input.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Second, and more subtly, residual connections give the network an inductive bias toward learning <em>incremental<\/em> transformations. Rather than learning to reconstruct the full representation from scratch at each layer, each block learns only the <em>delta<\/em> or the correction to add to the existing representation. In mechanistic interpretability, researchers conceptualise the transformer as a <em>residual stream<\/em>: a <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>d<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">d<\/annotation><\/semantics><\/math>-dimensional vector that is progressively written to and read from by successive attention heads and feed-forward layers, each contributing small structured updates. This framing, developed extensively by Anthropic, EleutherAI, and Neel Nanda&#8217;s research group, has proven highly productive for understanding what specific components of large models actually compute.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Layer Normalisation<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Before and\/or after each sub-component, layer normalisation is applied. For a vector <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi mathvariant=\"bold\">x<\/mi><mo>\u2208<\/mo><msup><mi mathvariant=\"double-struck\">R<\/mi><mi>d<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">\\mathbf{x} \\in \\mathbb{R}^d<\/annotation><\/semantics><\/math>:<math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><mtext>LayerNorm<\/mtext><mo stretchy=\"false\">(<\/mo><mi mathvariant=\"bold\">x<\/mi><mo stretchy=\"false\">)<\/mo><mo>=<\/mo><mi>\u03b3<\/mi><mo>\u2299<\/mo><mfrac><mrow><mi mathvariant=\"bold\">x<\/mi><mo>\u2212<\/mo><mi>\u03bc<\/mi><\/mrow><mrow><mi>\u03c3<\/mi><mo>+<\/mo><mi>\u03f5<\/mi><\/mrow><\/mfrac><mo>+<\/mo><mi>\u03b2<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\text{LayerNorm}(\\mathbf{x}) = \\gamma \\odot \\frac{\\mathbf{x} &#8211; \\mu}{\\sigma + \\epsilon} + \\beta<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">where <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>\u03bc<\/mi><mo>=<\/mo><mfrac><mn>1<\/mn><mi>d<\/mi><\/mfrac><msub><mo>\u2211<\/mo><mi>i<\/mi><\/msub><msub><mi>x<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">\\mu = \\frac{1}{d}\\sum_i x_i<\/annotation><\/semantics><\/math> is the mean, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>\u03c3<\/mi><mo>=<\/mo><msqrt><mrow><mfrac><mn>1<\/mn><mi>d<\/mi><\/mfrac><msub><mo>\u2211<\/mo><mi>i<\/mi><\/msub><mo stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo>\u2212<\/mo><mi>\u03bc<\/mi><msup><mo stretchy=\"false\">)<\/mo><mn>2<\/mn><\/msup><\/mrow><\/msqrt><\/mrow><annotation encoding=\"application\/x-tex\">\\sigma = \\sqrt{\\frac{1}{d}\\sum_i (x_i &#8211; \\mu)^2}<\/annotation><\/semantics><\/math> is the standard deviation, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>\u03f5<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\epsilon<\/annotation><\/semantics><\/math> is a small constant for numerical stability, and <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>\u03b3<\/mi><mo separator=\"true\">,<\/mo><mi>\u03b2<\/mi><mo>\u2208<\/mo><msup><mi mathvariant=\"double-struck\">R<\/mi><mi>d<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">\\gamma, \\beta \\in \\mathbb{R}^d<\/annotation><\/semantics><\/math> are learned scale and shift parameters.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Layer normalisation stabilises training by preventing the internal covariate shift problem, which is the tendency for the distribution of a layer&#8217;s inputs to change as upstream parameters update, forcing each layer to continuously readapt. By normalising each token&#8217;s representation independently across the feature dimension (as opposed to batch normalisation, which normalises across the batch dimension), layer norm is compatible with variable-length sequences and works correctly with batch size 1, making it well-suited for autoregressive inference.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Two conventions exist for where layer norm is placed within the block:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Post-norm<\/strong> (original Transformer, &#8220;Attention Is All You Need&#8221;): LayerNorm is applied after the residual addition:<math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><msup><mi>X<\/mi><mo mathvariant=\"normal\" lspace=\"0em\" rspace=\"0em\">\u2032<\/mo><\/msup><mo>=<\/mo><mtext>LayerNorm<\/mtext><mo stretchy=\"false\">(<\/mo><mi>X<\/mi><mo>+<\/mo><mtext>MultiHead<\/mtext><mo stretchy=\"false\">(<\/mo><mi>X<\/mi><mo stretchy=\"false\">)<\/mo><mo stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">X&#8217; = \\text{LayerNorm}(X + \\text{MultiHead}(X))<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Pre-norm<\/strong> (GPT-2, GPT-3, most modern LLMs): LayerNorm is applied to the input before the sub-component:<math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><msup><mi>X<\/mi><mo mathvariant=\"normal\" lspace=\"0em\" rspace=\"0em\">\u2032<\/mo><\/msup><mo>=<\/mo><mi>X<\/mi><mo>+<\/mo><mtext>MultiHead<\/mtext><mo stretchy=\"false\">(<\/mo><mtext>LayerNorm<\/mtext><mo stretchy=\"false\">(<\/mo><mi>X<\/mi><mo stretchy=\"false\">)<\/mo><mo stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">X&#8217; = X + \\text{MultiHead}(\\text{LayerNorm}(X))<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pre-norm has become the dominant convention because it produces more stable training dynamics at large scale. Gradients flow more cleanly through the unmodified residual path, and the model is less sensitive to initialisation and learning rate choice. The architectural difference is subtle but has meaningful empirical consequences; models trained with post-norm often require careful learning rate warmup schedules that pre-norm models do not.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">The Feed-Forward Network<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">After the attention sub-layer (with its own residual connection and layer norm), each transformer block applies a position-wise feed-forward network (FFN). The term &#8220;position-wise&#8221; means the same two-layer MLP is applied independently to each token&#8217;s vector, and the FFN has no cross-token interactions, unlike attention.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The standard formulation:<math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><mtext>FFN<\/mtext><mo stretchy=\"false\">(<\/mo><mi mathvariant=\"bold\">x<\/mi><mo stretchy=\"false\">)<\/mo><mo>=<\/mo><msub><mi>W<\/mi><mn>2<\/mn><\/msub><mo>\u22c5<\/mo><mi>\u03c3<\/mi><mo stretchy=\"false\">(<\/mo><msub><mi>W<\/mi><mn>1<\/mn><\/msub><mi mathvariant=\"bold\">x<\/mi><mo>+<\/mo><msub><mi mathvariant=\"bold\">b<\/mi><mn>1<\/mn><\/msub><mo stretchy=\"false\">)<\/mo><mo>+<\/mo><msub><mi mathvariant=\"bold\">b<\/mi><mn>2<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">\\text{FFN}(\\mathbf{x}) = W_2 \\cdot \\sigma(W_1 \\mathbf{x} + \\mathbf{b}_1) + \\mathbf{b}_2<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">where <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>W<\/mi><mn>1<\/mn><\/msub><mo>\u2208<\/mo><msup><mi mathvariant=\"double-struck\">R<\/mi><mrow><msub><mi>d<\/mi><mtext>ff<\/mtext><\/msub><mo>\u00d7<\/mo><mi>d<\/mi><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">W_1 \\in \\mathbb{R}^{d_{\\text{ff}} \\times d}<\/annotation><\/semantics><\/math>, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>W<\/mi><mn>2<\/mn><\/msub><mo>\u2208<\/mo><msup><mi mathvariant=\"double-struck\">R<\/mi><mrow><mi>d<\/mi><mo>\u00d7<\/mo><msub><mi>d<\/mi><mtext>ff<\/mtext><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">W_2 \\in \\mathbb{R}^{d \\times d_{\\text{ff}}}<\/annotation><\/semantics><\/math>\u200b, and <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>d<\/mi><mtext>ff<\/mtext><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">d_{\\text{ff}}<\/annotation><\/semantics><\/math>\u200b is the intermediate dimension, typically <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mn>4<\/mn><mi>d<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">4d<\/annotation><\/semantics><\/math>. In GPT-3, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>d<\/mi><mo>=<\/mo><mn>12288<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">d = 12288<\/annotation><\/semantics><\/math> and <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>d<\/mi><mtext>ff<\/mtext><\/msub><mo>=<\/mo><mn>49152<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">d_{\\text{ff}} = 49152<\/annotation><\/semantics><\/math>, giving each FFN roughly <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mn>4<\/mn><mo>\u00d7<\/mo><msup><mn>12288<\/mn><mn>2<\/mn><\/msup><mo>\u2248<\/mo><mn>603<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">4 \\times 12288^2 \\approx 603<\/annotation><\/semantics><\/math> million parameters, more than the attention sub-layer at that layer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The activation function <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>\u03c3<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\sigma<\/annotation><\/semantics><\/math>\u03c3 has evolved across generations. The original transformer used ReLU. GPT-2 and GPT-3 used GeLU (<a href=\"https:\/\/arxiv.org\/abs\/1606.08415\" rel=\"noopener\">Gaussian Error Linear Unit<\/a>), which approximates ReLU with a smooth, non-zero gradient for slightly negative inputs:<math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><mtext>GeLU<\/mtext><mo stretchy=\"false\">(<\/mo><mi>x<\/mi><mo stretchy=\"false\">)<\/mo><mo>=<\/mo><mi>x<\/mi><mo>\u22c5<\/mo><mi mathvariant=\"normal\">\u03a6<\/mi><mo stretchy=\"false\">(<\/mo><mi>x<\/mi><mo stretchy=\"false\">)<\/mo><mo>\u2248<\/mo><mn>0.5<\/mn><mi>x<\/mi><mtext>\u2009\u2063<\/mtext><mrow><mo fence=\"true\">(<\/mo><mn>1<\/mn><mo>+<\/mo><mi>tanh<\/mi><mo>\u2061<\/mo><mtext>\u2009\u2063<\/mtext><mrow><mo fence=\"true\">(<\/mo><msqrt><mfrac><mn>2<\/mn><mi>\u03c0<\/mi><\/mfrac><\/msqrt><mrow><mo fence=\"true\">(<\/mo><mi>x<\/mi><mo>+<\/mo><mn>0.044715<\/mn><msup><mi>x<\/mi><mn>3<\/mn><\/msup><mo fence=\"true\">)<\/mo><\/mrow><mo fence=\"true\">)<\/mo><\/mrow><mo fence=\"true\">)<\/mo><\/mrow><\/mrow><annotation encoding=\"application\/x-tex\">\\text{GeLU}(x) = x \\cdot \\Phi(x) \\approx 0.5x\\!\\left(1 + \\tanh\\!\\left(\\sqrt{\\frac{2}{\\pi}}\\left(x + 0.044715x^3\\right)\\right)\\right)<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">where <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi mathvariant=\"normal\">\u03a6<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\Phi<\/annotation><\/semantics><\/math> is the standard normal CDF. More recent models use SwiGLU, a gated variant introduced by <a href=\"https:\/\/arxiv.org\/abs\/2002.05202\" rel=\"noopener\">Noam Shazeer in 2020<\/a> and adopted in PaLM, Llama, and most frontier models:<math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><mtext>SwiGLU<\/mtext><mo stretchy=\"false\">(<\/mo><mi mathvariant=\"bold\">x<\/mi><mo stretchy=\"false\">)<\/mo><mo>=<\/mo><mtext>SiLU<\/mtext><mo stretchy=\"false\">(<\/mo><msub><mi>W<\/mi><mn>1<\/mn><\/msub><mi mathvariant=\"bold\">x<\/mi><mo stretchy=\"false\">)<\/mo><mo>\u2299<\/mo><mo stretchy=\"false\">(<\/mo><msub><mi>W<\/mi><mn>3<\/mn><\/msub><mi mathvariant=\"bold\">x<\/mi><mo stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">\\text{SwiGLU}(\\mathbf{x}) = \\text{SiLU}(W_1 \\mathbf{x}) \\odot (W_3 \\mathbf{x})<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">where <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mtext>SiLU<\/mtext><mo stretchy=\"false\">(<\/mo><mi>x<\/mi><mo stretchy=\"false\">)<\/mo><mo>=<\/mo><mi>x<\/mi><mo>\u22c5<\/mo><mi>\u03c3<\/mi><mo stretchy=\"false\">(<\/mo><mi>x<\/mi><mo stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">\\text{SiLU}(x) = x \\cdot \\sigma(x)<\/annotation><\/semantics><\/math> is the Sigmoid Linear Unit and <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>W<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">W_3<\/annotation><\/semantics><\/math>\u200b is an additional learned gate projection. SwiGLU consistently outperforms GeLU on downstream benchmarks, though the underlying reason remains an active area of research. When using SwiGLU, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>d<\/mi><mtext>ff<\/mtext><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">d_{\\text{ff}}<\/annotation><\/semantics><\/math>\u200b is typically set to <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mfrac><mn>8<\/mn><mn>3<\/mn><\/mfrac><mi>d<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\frac{8}{3}d<\/annotation><\/semantics><\/math> rather than <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mn>4<\/mn><mi>d<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">4d<\/annotation><\/semantics><\/math> to keep parameter counts comparable across architectures.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What does the FFN actually learn? <a href=\"https:\/\/en.wikipedia.org\/wiki\/Mechanistic_interpretability\" rel=\"noopener\">Mechanistic interpretability work<\/a>, particularly from Anthropic and the <a href=\"https:\/\/dynalist.io\/d\/n2ZWtnoYHrU1s4vnFSAQ519J\" rel=\"noopener\">Neel Nanda group<\/a>, has provided strong evidence that FFN layers function as key-value memories. Each row of <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>W<\/mi><mn>1<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">W_1<\/annotation><\/semantics><\/math>\u200b acts as a pattern detector (a &#8220;key&#8221;), and the corresponding row of <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>W<\/mi><mn>2<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">W_2<\/annotation><\/semantics><\/math> stores an associated &#8220;value&#8221; that gets added to the residual stream when that pattern is detected. This explains why larger FFNs improve factual recall (they have more memory slots) and why deleting specific FFN neurons can surgically remove specific factual associations from a model&#8217;s behaviour.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">The Complete Transformer Block<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Assembling all components, the full pre-norm transformer block for a decoder-only model is:<math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><mi mathvariant=\"bold\">a<\/mi><mo>=<\/mo><mi mathvariant=\"bold\">x<\/mi><mo>+<\/mo><mtext>MultiHead<\/mtext><mo stretchy=\"false\">(<\/mo><mtext>LayerNorm<\/mtext><mo stretchy=\"false\">(<\/mo><mi mathvariant=\"bold\">x<\/mi><mo stretchy=\"false\">)<\/mo><mo stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">\\mathbf{a} = \\mathbf{x} + \\text{MultiHead}(\\text{LayerNorm}(\\mathbf{x}))<\/annotation><\/semantics><\/math> <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><msup><mi mathvariant=\"bold\">x<\/mi><mo mathvariant=\"normal\" lspace=\"0em\" rspace=\"0em\">\u2032<\/mo><\/msup><mo>=<\/mo><mi mathvariant=\"bold\">a<\/mi><mo>+<\/mo><mtext>FFN<\/mtext><mo stretchy=\"false\">(<\/mo><mtext>LayerNorm<\/mtext><mo stretchy=\"false\">(<\/mo><mi mathvariant=\"bold\">a<\/mi><mo stretchy=\"false\">)<\/mo><mo stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">\\mathbf{x}&#8217; = \\mathbf{a} + \\text{FFN}(\\text{LayerNorm}(\\mathbf{a}))<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This two-step computation, attention followed by FFN, each with its own pre-norm and residual, is repeated <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>N<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">N<\/annotation><\/semantics><\/math> times. In GPT-3, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>N<\/mi><mo>=<\/mo><mn>96<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">N = 96<\/annotation><\/semantics><\/math>. In Llama 3 70B, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>N<\/mi><mo>=<\/mo><mn>80<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">N = 80<\/annotation><\/semantics><\/math>. In a typical GPT-4-class model, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>N<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">N<\/annotation><\/semantics><\/math> is believed to be in the range of 96\u2013120 layers. Each repetition allows the model to build increasingly abstract representations. Early layers handle low-level syntactic patterns, while later layers encode semantic and factual content.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"994\" src=\"https:\/\/learnerbox.net\/blog\/wp-content\/uploads\/2026\/07\/transformer_block_structure-1024x994.png\" alt=\"\" class=\"wp-image-1042\" title=\"\" srcset=\"https:\/\/learnerbox.net\/blog\/wp-content\/uploads\/2026\/07\/transformer_block_structure-1024x994.png 1024w, https:\/\/learnerbox.net\/blog\/wp-content\/uploads\/2026\/07\/transformer_block_structure-300x291.png 300w, https:\/\/learnerbox.net\/blog\/wp-content\/uploads\/2026\/07\/transformer_block_structure-768x745.png 768w, https:\/\/learnerbox.net\/blog\/wp-content\/uploads\/2026\/07\/transformer_block_structure-1536x1491.png 1536w, https:\/\/learnerbox.net\/blog\/wp-content\/uploads\/2026\/07\/transformer_block_structure-2048x1988.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Decoder-Only vs Encoder-Decoder Architecture<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Two principal transformer architectures are in widespread use, differing in how they process input and generate output.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>Decoder-only models<\/em><\/strong> (GPT, Llama, Mistral, Gemma, Falcon) use a single stack of transformer blocks with causal (masked) self-attention. Every token can attend only to previous tokens. The entire input prompt and the generated output share the same context window and are processed by the same stack. At inference time, the model autoregressively generates one token at a time, each conditioned on all prior tokens. This architecture is dominant for general-purpose language models because it scales efficiently and the training objective of next-token prediction across the entire sequence is simple, scalable, and empirically powerful.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>Encoder-decoder models<\/em><\/strong> (T5, BART, mT5, the original Transformer for machine translation) use two distinct stacks. The encoder processes the full input with bidirectional attention. Every token can attend to every other token simultaneously, with no causal mask. The encoded representation is then passed to the decoder via a cross-attention mechanism: each decoder token&#8217;s query attends to the encoder&#8217;s key-value pairs in addition to previously generated decoder tokens. The cross-attention block takes the form:<math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><mtext>CrossAttn<\/mtext><mo stretchy=\"false\">(<\/mo><msub><mi>Q<\/mi><mtext>dec<\/mtext><\/msub><mo separator=\"true\">,<\/mo><mtext>&nbsp;<\/mtext><msub><mi>K<\/mi><mtext>enc<\/mtext><\/msub><mo separator=\"true\">,<\/mo><mtext>&nbsp;<\/mtext><msub><mi>V<\/mi><mtext>enc<\/mtext><\/msub><mo stretchy=\"false\">)<\/mo><mo>=<\/mo><mtext>softmax<\/mtext><mtext>\u2009\u2063<\/mtext><mrow><mo fence=\"true\">(<\/mo><mfrac><mrow><msub><mi>Q<\/mi><mtext>dec<\/mtext><\/msub><msubsup><mi>K<\/mi><mtext>enc<\/mtext><mi mathvariant=\"normal\">\u22a4<\/mi><\/msubsup><\/mrow><msqrt><msub><mi>d<\/mi><mi>k<\/mi><\/msub><\/msqrt><\/mfrac><mo fence=\"true\">)<\/mo><\/mrow><msub><mi>V<\/mi><mtext>enc<\/mtext><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">\\text{CrossAttn}(Q_{\\text{dec}},\\ K_{\\text{enc}},\\ V_{\\text{enc}}) = \\text{softmax}\\!\\left(\\frac{Q_{\\text{dec}} K_{\\text{enc}}^\\top}{\\sqrt{d_k}}\\right)V_{\\text{enc}}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This architecture was originally designed for sequence-to-sequence tasks such as translation, summarisation, or question answering, where the full input is available before generation begins. It has largely been supplanted by decoder-only models for general language tasks, primarily because the instruction-tuned decoder-only paradigm proved more flexible and scalable. However, encoder-decoder models retain advantages for tasks requiring deep understanding of a fixed input, such as structured prediction, constrained generation, and certain retrieval tasks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A hybrid, the encoder-only model (BERT, RoBERTa, DeBERTa), uses bidirectional attention with no autoregressive generation. It is optimised for discriminative tasks such as classification, named entity recognition, or semantic similarity, rather than generation, and remains widely used in production embedding pipelines and retrieval systems.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Depth, Width, and the Scaling Hypothesis<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The transformer block&#8217;s design raises a natural question: does it matter whether a model has more layers (depth) or larger hidden dimension (width)? Empirically, the two interact in complex ways, and the optimal allocation of a fixed parameter budget between depth and width is one of the central questions addressed by scaling law research, which is the subject of Part 4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What is clear from both theory and experiment is that depth and width serve different functions. Width increases the model&#8217;s representational capacity at each layer by the size of the residual stream and the richness of the key-value memory in the FFN. Depth increases the number of sequential computational steps the model can take, which means the number of times attention and FFN transformations can be composed. Tasks requiring multi-step reasoning appear to benefit disproportionately from depth, while factual recall scales more uniformly with total parameter count regardless of how it is distributed between depth and width.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Conclusion<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The transformer block is elegant in its modularity: a residual stream, two sub-components (attention and FFN), and two layer normalisation steps. The full model is simply this block repeated <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>N<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">N<\/annotation><\/semantics><\/math> times. But the interactions between these components, including the gradient flow through residual connections, the factual storage in FFN key-value memories, and the progressive abstraction through depth, give rise to capabilities that are not predictable from any single component in isolation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Part 4 will move from architecture to training: the next-token prediction objective, loss functions, the Chinchilla scaling laws, and the dramatic effect of RLHF and instruction tuning on model behaviour, explaining why InstructGPT, at a fraction of GPT-3&#8217;s parameter count, consistently outperformed it.<\/p>\n\n\n\n<h6 class=\"wp-block-heading\">Coming next in the AI Engineering series is <a href=\"https:\/\/learnerbox.net\/blog\/uncategorized\/how-large-language-models-work-part-4-training-scaling-laws-and-rlhf\/\">Part 4<\/a>: Training, Scaling Laws, and RLHF.<\/h6>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is Part 3 of a five-part series on the internal mechanics of large language models. Part 2 derived scaled dot-product attention and the KV cache. Part 3 traces the complete transformer block consisting of feed-forward networks, layer normalisation, and residual streams; it examines the architectural differences between decoder-only and encoder-decoder models. From Attention Output to Transformer Block At the end of Part 2, self-attention had produced an output matrix O\u2208Rn\u00d7dO \\in \\mathbb{R}^{n \\times d} or one updated vector per token, now containing contextual information drawn from every other position in the sequence. But this is only the first half of a single transformer block. Before the signal moves to the next layer, it passes through three more components: a residual connection, layer normalisation, and a position-wise feed-forward network. Together with multi-head attention, these four elements constitute the repeating unit of every transformer-based LLM, stacked NN times to form the full model. Understanding each component precisely is important not just for implementation, but for diagnosing failure modes, interpreting mechanistic interpretability research, and making informed decisions about architectural variants when selecting or fine-tuning models. Residual Connections The residual connection, introduced in ResNets for computer vision and adopted into transformers from the outset, is deceptively simple. Rather than passing the attention output OO directly to the next component, the original input XX is added back:X\u2032=X+MultiHead(X)X&#8217; = X + \\text{MultiHead}(X) This addition of the residual or skip connection has several important consequences. First, it solves the vanishing gradient problem for very deep networks. During backpropagation, gradients flow backward through the network. Without residual connections, multiplying many Jacobians together through NNN sequential non-linear transformations causes gradient magnitudes to decay exponentially, making early layers extremely slow to learn. The residual path provides a direct gradient highway that bypasses each block, so that gradients can flow backward through the addition operation unchanged, regardless of how many layers separate the loss from the input. Second, and more subtly, residual connections give the network an inductive bias toward learning incremental transformations. Rather than learning to reconstruct the full representation from scratch at each layer, each block learns only the delta or the correction to add to the existing representation. In mechanistic interpretability, researchers conceptualise the transformer as a residual stream: a dd-dimensional vector that is progressively written to and read from by successive attention heads and feed-forward layers, each contributing small structured updates. This framing, developed extensively by Anthropic, EleutherAI, and Neel Nanda&#8217;s research group, has proven highly productive for understanding what specific components of large models actually compute. Layer Normalisation Before and\/or after each sub-component, layer normalisation is applied. For a vector x\u2208Rd\\mathbf{x} \\in \\mathbb{R}^d:LayerNorm(x)=\u03b3\u2299x\u2212\u03bc\u03c3+\u03f5+\u03b2\\text{LayerNorm}(\\mathbf{x}) = \\gamma \\odot \\frac{\\mathbf{x} &#8211; \\mu}{\\sigma + \\epsilon} + \\beta where \u03bc=1d\u2211ixi\\mu = \\frac{1}{d}\\sum_i x_i is the mean, \u03c3=1d\u2211i(xi\u2212\u03bc)2\\sigma = \\sqrt{\\frac{1}{d}\\sum_i (x_i &#8211; \\mu)^2} is the standard deviation, \u03f5\\epsilon is a small constant for numerical stability, and \u03b3,\u03b2\u2208Rd\\gamma, \\beta \\in \\mathbb{R}^d are learned scale and shift parameters. Layer normalisation stabilises training by preventing the internal covariate shift problem, which is the tendency for the distribution of a layer&#8217;s inputs to change as upstream parameters update, forcing each layer to continuously readapt. By normalising each token&#8217;s representation independently across the feature dimension (as opposed to batch normalisation, which normalises across the batch dimension), layer norm is compatible with variable-length sequences and works correctly with batch size 1, making it well-suited for autoregressive inference. Two conventions exist for where layer norm is placed within the block: Post-norm (original Transformer, &#8220;Attention Is All You Need&#8221;): LayerNorm is applied after the residual addition:X\u2032=LayerNorm(X+MultiHead(X))X&#8217; = \\text{LayerNorm}(X + \\text{MultiHead}(X)) Pre-norm (GPT-2, GPT-3, most modern LLMs): LayerNorm is applied to the input before the sub-component:X\u2032=X+MultiHead(LayerNorm(X))X&#8217; = X + \\text{MultiHead}(\\text{LayerNorm}(X)) Pre-norm has become the dominant convention because it produces more stable training dynamics at large scale. Gradients flow more cleanly through the unmodified residual path, and the model is less sensitive to initialisation and learning rate choice. The architectural difference is subtle but has meaningful empirical consequences; models trained with post-norm often require careful learning rate warmup schedules that pre-norm models do not. The Feed-Forward Network After the attention sub-layer (with its own residual connection and layer norm), each transformer block applies a position-wise feed-forward network (FFN). The term &#8220;position-wise&#8221; means the same two-layer MLP is applied independently to each token&#8217;s vector, and the FFN has no cross-token interactions, unlike attention. The standard formulation:FFN(x)=W2\u22c5\u03c3(W1x+b1)+b2\\text{FFN}(\\mathbf{x}) = W_2 \\cdot \\sigma(W_1 \\mathbf{x} + \\mathbf{b}_1) + \\mathbf{b}_2 where W1\u2208Rdff\u00d7dW_1 \\in \\mathbb{R}^{d_{\\text{ff}} \\times d}, W2\u2208Rd\u00d7dffW_2 \\in \\mathbb{R}^{d \\times d_{\\text{ff}}}\u200b, and dffd_{\\text{ff}}\u200b is the intermediate dimension, typically 4d4d. In GPT-3, d=12288d = 12288 and dff=49152d_{\\text{ff}} = 49152, giving each FFN roughly 4\u00d7122882\u22486034 \\times 12288^2 \\approx 603 million parameters, more than the attention sub-layer at that layer. The activation function \u03c3\\sigma\u03c3 has evolved across generations. The original transformer used ReLU. GPT-2 and GPT-3 used GeLU (Gaussian Error Linear Unit), which approximates ReLU with a smooth, non-zero gradient for slightly negative inputs:GeLU(x)=x\u22c5\u03a6(x)\u22480.5x\u2009\u2063(1+tanh\u2061\u2009\u2063(2\u03c0(x+0.044715&#215;3)))\\text{GeLU}(x) = x \\cdot \\Phi(x) \\approx 0.5x\\!\\left(1 + \\tanh\\!\\left(\\sqrt{\\frac{2}{\\pi}}\\left(x + 0.044715x^3\\right)\\right)\\right) where \u03a6\\Phi is the standard normal CDF. More recent models use SwiGLU, a gated variant introduced by Noam Shazeer in 2020 and adopted in PaLM, Llama, and most frontier models:SwiGLU(x)=SiLU(W1x)\u2299(W3x)\\text{SwiGLU}(\\mathbf{x}) = \\text{SiLU}(W_1 \\mathbf{x}) \\odot (W_3 \\mathbf{x}) where SiLU(x)=x\u22c5\u03c3(x)\\text{SiLU}(x) = x \\cdot \\sigma(x) is the Sigmoid Linear Unit and W3W_3\u200b is an additional learned gate projection. SwiGLU consistently outperforms GeLU on downstream benchmarks, though the underlying reason remains an active area of research. When using SwiGLU, dffd_{\\text{ff}}\u200b is typically set to 83d\\frac{8}{3}d rather than 4d4d to keep parameter counts comparable across architectures. What does the FFN actually learn? Mechanistic interpretability work, particularly from Anthropic and the Neel Nanda group, has provided strong evidence that FFN layers function as key-value memories. Each row of W1W_1\u200b acts as a pattern detector (a &#8220;key&#8221;), and the corresponding row of W2W_2 stores an associated &#8220;value&#8221; that gets added to the residual stream when that pattern is detected. This explains why larger FFNs improve factual recall (they have more memory slots) and why deleting specific FFN neurons can surgically remove specific factual associations from a model&#8217;s behaviour. The Complete Transformer Block Assembling all components, the full pre-norm transformer block for a decoder-only model is:a=x+MultiHead(LayerNorm(x))\\mathbf{a} = \\mathbf{x} + \\text{MultiHead}(\\text{LayerNorm}(\\mathbf{x})) x\u2032=a+FFN(LayerNorm(a))\\mathbf{x}&#8217; = \\mathbf{a} + \\text{FFN}(\\text{LayerNorm}(\\mathbf{a})) This two-step computation, attention followed by FFN, each with its own pre-norm and residual, is repeated NN times. In GPT-3, N=96N = 96. In Llama 3 70B, N=80N = 80. In a typical GPT-4-class model, NN is believed to be in the range of 96\u2013120 layers. Each repetition allows the model to build increasingly abstract representations. Early layers handle low-level syntactic patterns, while later layers encode semantic and factual content. Decoder-Only vs Encoder-Decoder Architecture Two principal transformer architectures are in widespread use, differing in how they process input and generate output. Decoder-only models (GPT, Llama, Mistral, Gemma, Falcon) use a single stack of transformer blocks with causal (masked) self-attention. Every token can attend only to previous tokens. The entire input prompt and the generated output share the same context window and are processed by the same stack. At inference time, the model autoregressively generates one token at a time, each conditioned on all prior tokens. This architecture is dominant for general-purpose language models because it scales efficiently and the training objective of next-token prediction across the entire sequence is simple, scalable, and empirically powerful. Encoder-decoder models (T5, BART, mT5, the original Transformer for machine translation) use two distinct stacks. The encoder processes the full input with bidirectional attention. Every token can attend to every other token simultaneously, with no causal mask. The encoded representation is then passed to the decoder via a cross-attention mechanism: each decoder token&#8217;s query attends to the encoder&#8217;s key-value pairs in addition to previously generated decoder tokens. The cross-attention block takes the form:CrossAttn(Qdec,&nbsp;Kenc,&nbsp;Venc)=softmax\u2009\u2063(QdecKenc\u22a4dk)Venc\\text{CrossAttn}(Q_{\\text{dec}},\\ K_{\\text{enc}},\\ V_{\\text{enc}}) = \\text{softmax}\\!\\left(\\frac{Q_{\\text{dec}} K_{\\text{enc}}^\\top}{\\sqrt{d_k}}\\right)V_{\\text{enc}} This architecture was originally designed for sequence-to-sequence tasks such as translation, summarisation, or question answering, where the full input is available before generation begins. It has largely been supplanted by decoder-only models for general language tasks, primarily because the instruction-tuned decoder-only paradigm proved more flexible and scalable. However, encoder-decoder models retain advantages for tasks requiring deep understanding of a fixed input, such as structured prediction, constrained generation, and certain retrieval tasks. A hybrid, the encoder-only model (BERT, RoBERTa, DeBERTa), uses bidirectional attention with no autoregressive generation. It is optimised for discriminative tasks such as classification, named entity recognition, or semantic similarity, rather than generation, and remains widely used in production embedding pipelines and retrieval systems. Depth, Width, and the Scaling Hypothesis The transformer block&#8217;s design raises a natural question: does it matter whether a model has more layers (depth) or larger hidden dimension (width)? Empirically, the two interact in complex ways, and the optimal allocation of a fixed parameter budget between depth and width is one of the central questions addressed by scaling law research, which is the subject of Part 4. What is clear from both theory and experiment is that depth and width serve different functions. Width increases the model&#8217;s representational capacity at each layer by the size of the residual stream and the richness of the key-value memory in the FFN. Depth increases the number of sequential computational steps the model can take, which means the number of times attention and FFN transformations can be composed. Tasks requiring multi-step reasoning appear to benefit disproportionately from depth, while factual recall scales more uniformly with total parameter count regardless of how it is distributed between depth and width. Conclusion The transformer block is elegant in its modularity: a residual stream, two sub-components (attention and FFN), and two layer normalisation steps. The full model is simply this block repeated NN times. But the interactions between these components, including the gradient flow through residual connections, the factual storage in FFN key-value memories, and the progressive abstraction through depth, give rise to capabilities that are not predictable from any single component in isolation. Part 4 will move from architecture to training: the next-token prediction objective, loss functions, the Chinchilla scaling laws, and the dramatic effect of RLHF and instruction tuning on model behaviour, explaining why InstructGPT, at a fraction of GPT-3&#8217;s parameter count, consistently outperformed it. Coming next in the AI Engineering series is Part 4: Training, Scaling Laws, and RLHF.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[38],"tags":[],"class_list":["post-1040","post","type-post","status-publish","format-standard","hentry","category-ai-theory"],"_links":{"self":[{"href":"https:\/\/learnerbox.net\/blog\/wp-json\/wp\/v2\/posts\/1040","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learnerbox.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learnerbox.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learnerbox.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/learnerbox.net\/blog\/wp-json\/wp\/v2\/comments?post=1040"}],"version-history":[{"count":3,"href":"https:\/\/learnerbox.net\/blog\/wp-json\/wp\/v2\/posts\/1040\/revisions"}],"predecessor-version":[{"id":1049,"href":"https:\/\/learnerbox.net\/blog\/wp-json\/wp\/v2\/posts\/1040\/revisions\/1049"}],"wp:attachment":[{"href":"https:\/\/learnerbox.net\/blog\/wp-json\/wp\/v2\/media?parent=1040"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learnerbox.net\/blog\/wp-json\/wp\/v2\/categories?post=1040"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learnerbox.net\/blog\/wp-json\/wp\/v2\/tags?post=1040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}