the wizard

Why LLMs run on GPUs: reading a prompt vs writing a reply

Why a model reads your prompt fast and writes its reply slowly, measured on a real model: writing a token means reading every weight, and memory speed sets the pace.

Part 6 of 6 · How an LLM runs
  1. How an LLM works: from your text to the next token
  2. How attention works in an LLM, with real numbers
  3. What the KV cache is, and why LLMs need it
  4. Prompt caching explained: why an LLM re-reads your whole chat
  5. What an inference engine does: batching, KV memory and quantization
  6. Why LLMs run on GPUs: reading a prompt vs writing a reply

About this series

The last part of the series puts the earlier ones together. A model reads your prompt in one pass but writes its reply one token at a time (part 1), and those two jobs run very differently on hardware. Writing is slow because of memory, not math. I measured it on a CPU, then worked out what it means on a GPU from NVIDIA's published numbers.


The work is multiplications, lots of them at once

Nearly everything a model does is multiplying hidden states by weight matrices. In SmolLM2, making one token's query is a 576 × 576 matrix: 331,776 multiplications and additions, none of which depends on another. Apart from the input table, which is only looked up, a token uses every weight once, so a model does roughly two calculations (a multiply and an add) per weight per token. For Llama 3 8B that's about 15 billion per token.

That's the kind of work a GPU is built for: a very large number of the same simple calculation on different numbers, all at once. NVIDIA lists its H100 (SXM) at 1,979 teraFLOPS for 16-bit math with sparsity; even half of that, without sparsity, is close to a thousand trillion calculations a second.

Reading a prompt vs writing a reply

There are two phases:

I timed both on SmolLM2-135M, on one CPU core, with the same 256 tokens:

Measured on SmolLM2-135M, one CPU core: time per token for the same 256 tokens, and the time to read the 540 MB weight file once at this machine's measured memory speed.
Time per token
milliseconds per token
Prefill (prompt)4.19
Decode (reply)56.2
Reading the weights once51.2

Writing was 13× slower per token than reading the prompt, on the same machine and the same model.

Decode waits on memory

The third bar explains it. Every decode step uses every weight (SmolLM2 uses the same table for input and output, so that's all of them), so every step reads the whole weight file from memory: 540 MB here. I measured this machine's memory reading speed at 10.6 GB/s, so reading 540 MB takes 51.2 ms. A decode step took 56.2 ms. Almost all of each step was spent reading the weights; the math fit in the rest.

Prefill reads the weights once and uses them for all 256 prompt tokens, so the reading cost is shared out. Batching (part 5) is the same trick for decode: 16 requests per step shared one read of the weights, which is why 16 at once took only 1.8× as long as one.

The same on a GPU

NVIDIA lists the H100 (SXM) with 80 GB of memory read at 3.35 TB/s. Llama 3 8B at 16 bits is 16.1 GB (part 1), of which a decode step reads about 15.0 GB: everything but the input table. So:

Reading takes about 300 times longer than the math. With one request, the GPU's arithmetic mostly waits on memory. That's why batching pays: up to around 300 requests per step, each extra request adds math the GPU was idle for anyway. Move the slider:

A best case from NVIDIA's listed H100 SXM numbers (3.35 TB/s; half of the 1,979 teraFLOPS listed with sparsity), not a measurement. Real engines also read KV caches and do other work, so real numbers are lower.
Llama 3 8B, 16-bit on one GPU with 3.35 TB/s and 989.5 teraFLOPS: a best case, ignoring KV-cache reads
Requests at onceReading the weightsThe mathTokens per second (at most)
14.48 ms0.02 ms223
164.48 ms0.24 ms3,573
644.48 ms0.97 ms14,293
2564.48 ms3.88 ms57,173
5124.48 ms7.76 ms65,967

Two limits from parts 3 and 5 still apply. Every request in the batch needs its KV cache in the same 80 GB as the weights, and a bigger model needs more room: Llama 3 70B at 16 bits is 141 GB, more than one H100 holds.

Training fills the GPU

Training doesn't have the decode problem. The model knows the whole text it's learning from, so it predicts every position at once (part 2), and the Transformer paper chose attention partly so that all positions could be computed in parallel. Like prefill, training keeps the arithmetic busy.

The series in one paragraph

A model is a fixed file of numbers (part 1). Tokens look back at each other through attention (part 2). Their keys and values are saved, so writing doesn't redo work (part 3). Nothing is kept between requests unless a provider caches the start of your prompt (part 4). Engines batch many people's requests and juggle their caches (part 5). And every token written means reading the whole model from memory, which is why it all runs on GPUs and why batching matters (this part).


How I measured

← All memories