Free demoJob-oriented courses at Debugshala, Old Palasia, Indore. Freshers, non-IT and year-gap welcome.Book a free demo +91-8982385539

Transformers and Attention Explained: How LLMs Read Context

Lesson 4 of 9 · 10 min · Updated 13 Nov 2026

Understand the transformer behind every LLM: queries, keys and values, the causal mask, multi-head attention and transformer blocks, with numpy code.

Picture a pharmacist at a busy medical store in Palasia reading a handwritten prescription. Line four says "Take twice daily after food." Twice daily what? Her eyes jump back up the page to the medicine name on line two, and line four suddenly makes sense.

She asks one specific question ("which medicine?"), finds the line that answers it, and pulls in exactly that detail. That habit of looking back, choosing what is relevant and borrowing its meaning is the core idea of the transformer.

What is a transformer?

Mapping the pharmacist to the model: each token in the prompt is a line on the prescription. The question she asks is a query. The label each line offers ("I am a medicine name") is a key. The information she copies across is the value. Doing this for every line at once is self-attention.

A transformer is a neural network architecture that processes a sequence of tokens with stacked layers of self-attention, which lets each token gather information from the other tokens, followed by a feed-forward network that transforms each token's representation.

The design comes from the 2017 paper "Attention Is All You Need". The original had an encoder and a decoder for translation. Most chat LLMs today are decoder-only transformers: a single stack that reads the prompt and predicts the next token, as described in what is an LLM.

The stack's input is the token IDs from the tokenizer, turned into vectors by an embedding table.

How self-attention works: queries, keys and values

For every token, the model makes three vectors by multiplying the token's current vector with three learned weight matrices:

  • Query (Q): what this token is looking for.
  • Key (K): what this token offers to others.
  • Value (V): the information it hands over if chosen.
Self-attention in a transformer: the query of the token "it" is compared with the key of every earlier token, the scores pass through softmax into weights, and the weighted values are summed into a new vector

Attention for one token: compare its query with every key, turn the scores into weights, then take a weighted average of the values.

The steps for one token are:

  1. Take the dot product of its query with every key. A large dot product means "this key matches what I am looking for".
  2. Divide by the square root of the key size, so scores do not grow too large as vectors get longer.
  3. Apply softmax so the scores become weights that add up to 1.
  4. Multiply each value by its weight and add them up. The result replaces the token's vector.

Here it is with tiny, hand-picked vectors so you can see the "it" token finding "bus":

Python
import numpy as np

tokens = ["the", "bus", "was", "full", "so", "it"]
# toy 2-number keys: first number ~ "is a vehicle", second ~ "is a state or verb"
K = np.array([[0.0, 0.1], [1.0, 0.2], [0.1, 1.0], [0.3, 0.9], [0.0, 0.3], [0.5, 0.1]])
V = np.array([[0, 0], [9, 1], [1, 5], [2, 8], [0, 1], [3, 0]], dtype=float)
q_it = np.array([2.0, 0.4])            # "it" is looking for a noun to refer to

scores = K @ q_it / np.sqrt(2)         # dot product with every key, then scale
weights = np.exp(scores) / np.exp(scores).sum()   # softmax: weights add up to 1

for t, s, w in zip(tokens, scores, weights):
    print(f"{t:<5} score={s:5.2f}  weight={w:.2f}  " + "#" * int(w * 40))
print("new vector for 'it':", (weights @ V).round(2))

"bus" gets the biggest weight because its key lines up best with the query of "it". The new vector for "it" now carries much of the value of "bus". In a real model nobody hand-picks these numbers; the matrices that produce Q, K and V are learned in training.

Quick check

In self-attention, what does a token's query get compared with?

Scaled dot-product attention and the causal mask

In practice the model does this for all tokens at once with matrix multiplication. The whole operation fits in one formula: softmax(Q·Kᵀ / √d_k) · V.

A decoder-only LLM adds one rule. When it is learning to predict token 5, it must not see token 5 or anything after it, or it could simply copy the answer. A causal mask sets every score above the diagonal to minus infinity, so those weights become exactly zero after softmax.

Python
import numpy as np

rng = np.random.default_rng(0)
tokens = ["chai", "is", "too", "sweet", "today"]
n, d_model, d_k = len(tokens), 8, 4

X = rng.normal(0, 0.5, (n, d_model))                # one embedding row per token
Wq, Wk, Wv = (rng.normal(size=(d_model, d_k)) for _ in range(3))
Q, K, V = X @ Wq, X @ Wk, X @ Wv                   # learned projections

scores = Q @ K.T / np.sqrt(d_k)                    # (n, n) table of scores
mask = np.triu(np.ones((n, n), dtype=bool), k=1)   # True above the diagonal
scores[mask] = -np.inf                             # no peeking at future tokens

weights = np.exp(scores - scores.max(axis=1, keepdims=True))
weights /= weights.sum(axis=1, keepdims=True)
out = weights @ V

print("attention weights (row = token doing the looking):")
print("        " + "".join(f"{t:>7}" for t in tokens))
for t, row in zip(tokens, weights):
    print(f"{t:>7} " + "".join(f"{w:7.2f}" for w in row))
print("output shape:", out.shape, "| each row sums to", weights.sum(axis=1).round(2))

Read the table row by row: "chai" sees only itself, "is" sees "chai" and itself, and so on. Every zero above the diagonal is the mask at work.

Multi-head attention: several questions at once

One set of Q, K and V can only ask one kind of question. A real layer runs many attention heads in parallel, often 16 to 128, each with its own smaller weight matrices.

One head might track which noun a pronoun refers to, another might match an opening bracket with its closing one. The outputs of all heads are joined and mixed by one more weight matrix.

Quick check

Why does a decoder-only LLM use a causal mask?

Inside one transformer block

Attention is only half of a block. The full decoder block, repeated dozens of times, looks like this:

Decoder-only transformer architecture: token embeddings plus position information flow through N stacked blocks of layer norm, masked multi-head self-attention, a residual add, layer norm, a feed-forward network and another residual add, then to an output layer that gives next-token probabilities

A decoder-only LLM is the same block stacked N times, with an embedding layer at the bottom and a next-token output layer at the top.

  • Layer normalisation keeps the numbers in a stable range before each sub-layer. Many recent models use a lighter variant called RMSNorm.
  • Masked multi-head self-attention mixes information between tokens, as above.
  • Residual connections add each sub-layer's input back to its output. This lets very deep stacks train without the signal fading.
  • The feed-forward network (FFN) works on each token separately: two or three weight matrices with a non-linear activation in between. A large share of the model's parameters, and much of its stored knowledge, live here. The mixture of experts design replaces this FFN with several smaller "expert" networks.

How a transformer knows word order

Attention alone treats the input as a bag of tokens: "dog bites man" and "man bites dog" would look the same. So the model injects position information. The original paper added fixed sine and cosine patterns; many current LLMs use rotary position embeddings (RoPE), which rotate queries and keys by an angle that depends on position.

At the top of the stack, a final layer turns the last token's vector into one score per vocabulary entry. Softmax over those scores gives the next-token probabilities.

Why transformers replaced RNNs

Before transformers, language models were mostly recurrent neural networks such as LSTMs, covered in the RNN and LSTM tutorial. They read text one token at a time, passing a memory vector along.

RNN / LSTM Transformer
How it reads the input One token after another All tokens in parallel
Training speed on GPUs Slow, steps cannot run in parallel Fast, built from big matrix multiplications
Long-range links Memory fades over long distances Any token can attend to any earlier token directly
Cost as input grows Linear in length Attention grows with the square of length

Parallel training is the big win: it made training on trillions of tokens practical. The price is the last row of that table.

The cost of attention on long prompts

Every token is scored against every other token, so a prompt of n tokens produces an n × n table of scores, per head, per layer. Doubling the prompt quadruples that work.

Python
heads, layers, bytes_fp16 = 32, 32, 2

print(f"{'tokens':>8} {'scores per head':>16} {'memory, one head':>18}")
for n in [1_000, 8_000, 32_000, 128_000]:
    entries = n * n                                  # every token vs every token
    mb = entries * bytes_fp16 / 1e6
    print(f"{n:>8,} {entries:>16,} {mb:>15,.0f} MB")

n = 32_000
total = n * n * heads * layers * bytes_fp16 / 1e12
print(f"\nAll {heads} heads x {layers} layers at {n:,} tokens: {total:.1f} TB if stored at once")
print("Doubling the prompt length multiplies this work by", (2 * n) ** 2 // n ** 2)

No real system stores all of that at once. Techniques such as FlashAttention compute attention in small tiles so the full table never sits in memory, and during generation the model keeps earlier keys and values in a KV cache instead of recomputing them.

That trick has its own article, KV cache explained. Long prompts still cost more time and money.

Quick check

A prompt grows from 4,000 to 8,000 tokens. Roughly how does the attention score work change?

Common misunderstandings about transformers

  • "Attention means the model understands." Attention is a weighted average driven by learned numbers. Useful behaviour emerges from training, not from the mechanism alone.
  • "Attention weights explain the answer." They show where information flowed in one layer, not why the model decided something. Treat attention heatmaps as hints, not proof.
  • "More layers is always better." A small model trained well often beats a large one trained badly.

Key takeaways

  • A transformer is a stack of blocks, each with masked multi-head self-attention, a feed-forward network, layer norms and residual connections.
  • Attention compares a query with keys, turns scores into softmax weights, and averages the values.
  • The causal mask limits each token to earlier tokens, which makes next-token training and generation work.
  • Position information, often RoPE today, tells the model word order.
  • Attention cost grows with the square of prompt length, so long contexts are expensive.

Next in this series, see how LLMs are trained to learn where all those weight matrices get their values. To check your understanding of the maths, try a few timed quizzes on Debugshala Test.

Take the free LLM Fundamentals quiz10 quick questions with explanations. No sign-up needed, and you can come back to this lesson after.

FAQ

What is the difference between a transformer and an LLM?

A transformer is an architecture, a way of wiring a neural network. An LLM is a specific large model, usually a decoder-only transformer, trained on huge amounts of text. Transformers also power image and speech models.

What are query, key and value in simple words?

The query is what a token is looking for, the key is what each token advertises about itself, and the value is the information it passes on when chosen. Matching queries to keys produces attention weights, and those weights decide how much of each value flows into the token.

Why is it called "attention"?

Because each token decides how much to focus on every other token, much like you read some words closely and skim others. Mathematically it is a softmax-weighted average of values.

Do I need to code a transformer from scratch to work in generative AI?

No. Most GenAI jobs use pretrained models through libraries and APIs. Building a tiny transformer once in numpy is still worth it, because it makes context limits and costs much easier to reason about.

Where can I learn transformers and LLMs in Indore?

Debugshala teaches transformers, attention and LLM application building in classroom batches at its Old Palasia campus, in English and Hindi. You can try a free demo class before paying, and the course details are on the page for the GenAI course that Debugshala teaches in Indore.

From the team behind this site

Go further with the Generative AI Course at Debugshala

These tutorials are written by Debugshala, a training and placement institute at Old Palasia, Indore. The classroom course adds live mentoring, real projects and interview preparation.

  • Offline classes at Old Palasia, Indore
  • Free demo class before you pay
  • Non-IT, fresher and year-gap friendly
  • Placement assistance

700+ students placed · 200+ hiring partners · 4.9★ Google rating

Embeddings Explained: How AI Turns Meaning into VectorsHow LLMs Are Trained: Pretraining, SFT and RLHF Explained