The slow part
isn't the thinking.
It's the fetching.
When an AI writes you a paragraph, almost none of that time goes on anything you'd call thought. It goes on hauling numbers out of storage — the same tens of billions of numbers, dragged across the machine again and again, once for every single word it writes.
That one fact explains an astonishing amount: why AI costs what it costs, why some of it runs on a laptop and some needs a warehouse, why the most powerful chip money can buy is often the wrong thing to buy, and why "just add more computing power" so often changes nothing at all.
Single-stream transformer decode is a chain of matrix-vector products with an arithmetic intensity of about 1 FLOP per byte, executed on machines whose roofline ridge sits near 300. Everything else — the pricing, the quantisation, the accelerator taxonomy, the rack-scale interconnects — is a consequence of operating two and a half orders of magnitude below machine balance.
This course works that constraint from the bit cell outward: why the weights can't be cached, what it costs in picojoules to move them, and how every product category from a phone NPU to an NVL72 rack is a different answer to the same bandwidth problem.
Pick your level
The same ten modules, the same diagrams, the same interactive panels and the same numbers — pitched two different ways. Switch whenever you like; the sidebar carries this control on every page, and your place in the course is kept either way.
Three forces, three colours
Everything here is a tug-of-war between three things. Each module is colour-coded to whichever one it's mostly about, so the colour in the sidebar tells you which part of the machine you're standing in.
Every module is tagged with whichever term of the roofline it mostly lives in, and the colour carries through its diagrams and charts.
The arithmetic. How much raw calculation a chip can do per second.
FLOPS, precision, tensor units, achieved utilisation against peak.
The numbers, and the pipe they travel through. How many the machine can hold, and how fast it can read them.
Capacity and off-chip bandwidth — the binding term for everything below the ridge.
The actual objects. Phones, laptops, graphics cards, and the racks of machines in data centres.
Where those two get built into products: NPUs, systolic arrays, unified memory, NVLink domains.
The route
The one idea, up front
Here is the whole course compressed into a single line. The words in it won't mean much yet — that's what the first few modules are for. Come back and look again after module 5; it should feel obvious by then.
The whole course in one line. Modules 2–3 derive it, module 5 validates it against measured Apple Silicon results, where it holds to within about 10%.
Work through it in order — each module leans on words the previous one defined. Mark a module complete at the bottom and the sidebar tracks where you are. Both your level and your progress are stored in this browser, so closing the tab and coming back in a fortnight picks up exactly where you left off. Arrow keys ← → move between modules.
Every panel labelled INTERACTIVE is a working model, not a decoration — the numbers are calculated live from the same arithmetic the module just gave you. Drag the sliders to their extremes; that's where the intuition is.
Two things you need to picture
The working set doesn't fit
What an AI model physically is, and what a computer physically is. Get these two pictures straight and the other nine modules are detail.
Why the parameter set cannot live on-die, what it costs to stream it from off-package DRAM, and why that single fact determines the shape of every AI product made.
Almost every confusing thing about AI hardware comes from skipping these two pictures. Both are simpler than you'd expect, and both are slightly different from what most people imagine.
You already know the memory wall. What's worth doing carefully is the arithmetic of how far past it this particular workload sits — because the answer is not 2× or 10×, and the usual mitigations don't apply.
Picture one: a model is a pile of numbers
The model is a parameter set with no reuse
When someone says "an AI model", the thing they're pointing at is a file on a disk. Open it and there's no code in there, no rules, no sentences. There is a list of numbers. A very, very long one.
Each number in that list is called a parameter — you'll also hear them called weights, and the two words mean the same thing. When you see a model called "Llama 3.3 70B", the 70B is the count: seventy billion numbers.
A dense decoder-only transformer's weights are a set of 2-D tensors — per layer, four attention projections and three feed-forward projections, plus embeddings. The count is the headline: 70B parameters at 2 bytes each in BF16 is 140 GB of weights.
The operative property isn't the size, though — it's the reuse. In autoregressive decode you process one token at a time, so every weight matrix is multiplied against a single activation vector. The kernels are GEMV, not GEMM. There is no blocking, tiling or scheduling trick that creates data reuse that the problem doesn't contain: each weight is loaded, used for exactly one multiply-accumulate, and discarded.
Where did the numbers come from? An automatic process called training, which module 4 covers. For now the only thing that matters is that training happened once, somewhere else, and produced this list. The numbers are now frozen. Your computer never changes them.
Using the model is called inference, and it goes like this: your text becomes numbers, those numbers get combined with the model's numbers through a great deal of multiplication, and out comes one more word. Then the whole thing runs again for the next word. And again. One complete pass per word.
Weights are frozen after training, so unlike a training step there's no write traffic and no optimiser state — just a read-only stream. That sounds like the easy case. It isn't, because the stream is the entire parameter set and it recurs every token, with a serial dependency between tokens that forbids pipelining across them.
Put a number on the intensity. Each parameter participates in one multiply and one add per token, so the arithmetic is 2N FLOPs, and the traffic is N × bytes_per_param. At BF16 that's 2N / 2N = 1 FLOP per byte, exactly, independent of model size, layer count or hidden dimension.
To produce one word, the machine touches every single one of those seventy billion numbers. Not a clever subset, not an index. All of them. The whole course hangs off this fact.
Batch-1 decode runs at an arithmetic intensity of 1 FLOP/byte at BF16. An H100 at 989 dense BF16 TFLOPS over 3.35 TB/s has a ridge point of 295 FLOP/byte. You are operating at roughly 0.3% of machine balance — and no amount of kernel engineering moves you, because the deficit is in the problem, not the implementation. Module 3 does this properly on a roofline.
So how much space does that take? Each number is stored in one or two bytes. Do the multiplication and a 70-billion-parameter model comes to somewhere between 40 and 140 gigabytes, depending on how tightly it's packed — which is module 4's subject.
Picture two: a computer is a calculator bolted to a warehouse
Why it can't be cached: SRAM stopped shrinking
Now the other half. Strip a computer down and two parts matter for our purposes.
The processor does the arithmetic. It is spectacularly fast — a good one performs trillions of calculations every second.
The memory is where the numbers sit while they're being worked on. It's a separate place, physically elsewhere on the board, joined to the processor by what amounts to a pipe.
And here's the part nobody mentions: the pipe is the problem. The processor can consume numbers far faster than memory can deliver them. Not slightly faster — roughly a hundred times faster.
The obvious architectural response to a read-only stream with no reuse is to stop streaming it: put the working set on-die and eat the fetch once. Run the area numbers and that door closes hard.
SRAM bitcell scaling has effectively stopped. TSMC's N5→N3 transition delivered roughly 0–5% bitcell shrink, and N3E none at all, against 1.6–1.7× logic density gains over the same step. N2 gets the high-density cell to about 0.0175 µm² — roughly 38 Mb/mm² — and TSMC's claimed ~22% SRAM density improvement over N3E comes mostly from periphery rather than the cell.
At 38 Mb/mm², holding a 40 GB (320 Gb) quantised model in on-die SRAM needs about 8,400 mm² of bitcell area alone — before periphery, before any logic, before yield. A full-field reticle is 858 mm². You are an order of magnitude past the largest die that can be printed, for the cells only.
So the weights live off-die in DRAM, permanently, and the entire discipline becomes an exercise in off-chip bandwidth and the energy of moving bits across a package boundary.
Two words for the two properties of that warehouse. You'll use both constantly from here on:
- Capacity — how much fits, in gigabytes. This one is binary: either your model fits or it doesn't.
- Bandwidth — how fast things come out, in gigabytes per second, written GB/s. This one is the speed limit.
Memory isn't one thing, either. It's a ladder, and each rung trades size against speed. This shape — tiny and instant at the top, vast and sluggish at the bottom — is true of every computer ever built, including the one you're reading this on.
The hierarchy is the usual one, but the ratios are what matter here. Note that the capacity you'd need sits three rungs below the bandwidth you'd want:
It feels backwards — surely fetching a number is easier than multiplying two of them? But physically, multiplying happens inside a few thousand transistors sitting right next to each other, while fetching means sending a signal a comparatively enormous distance, through wires, to a chip that has to physically activate a row of memory cells to answer. Distance costs time and energy; arithmetic is nearly free. Engineers have been fighting this since the 1990s, when it was named the memory wall. It has widened every year since.
Horowitz's canonical ISSCC 2014 numbers at 45 nm: a 32-bit floating-point multiply costs about 3.7 pJ; reading 32 bits from off-chip DRAM costs roughly 640 pJ. Two orders of magnitude, and the ratio has widened since, because logic energy has scaled faster than I/O energy.
Interface energy has improved but not transformed: HBM2 landed around 6.25 pJ/bit, HBM3E around 4.05 pJ/bit, with published HBM3 PHYs near 0.5 pJ/bit for the PHY alone.
Run that against decode. Streaming 40 GB — 3.2 × 10¹¹ bits — once per token at 4 pJ/bit is 1.28 joules per token in DRAM traffic alone. At 20 tokens per second that's ~26 W spent purely moving weights, before a single MAC fires. The arithmetic on the same token, at ~0.1 pJ per 8-bit op, rounds to nothing. This is why "AI is power-hungry" is really a statement about data movement.
Now put the two pictures together
The consequence
A model is 40–140 GB of numbers. A machine can pull numbers out of memory at some rate — call it 500 GB per second for a good laptop. And every word needs a complete pass through the whole pile.
So: 40 gigabytes to read, at 500 gigabytes per second, is 0.08 seconds. That's about 12 words per second, and that is your answer — not because of any calculation the chip did, but because that's how long the fetching took. The arithmetic occupied the processor for well under a thousandth of that time. It spent the rest waiting.
Decode throughput is therefore set by bandwidth ÷ bytes_per_token and essentially nothing else. A 40 GB quantised 70B on 500 GB/s of LPDDR gives ~12 tok/s; the same model on an 8 TB/s HBM3e part gives ~200. The FLOPS column of both spec sheets is, for this workload at this batch size, decorative.
Everything that follows is a way of attacking one of the three terms: reduce bytes per token (quantisation, MoE sparsity, speculative decode), raise bandwidth (HBM stacks, wider buses, unified memory), or raise the intensity so the FLOPS start to matter again (batching). Module 3 formalises this, and modules 6–7 are a tour of who chose which.
This is why a gaming computer with a famously powerful graphics card can lose, at this one task, to a laptop with no graphics card at all but faster memory. It's why the specification worth checking before you buy is one most reviews don't even print. And it's why a great deal of confident advice about AI hardware is measurably wrong.
It's also why TOPS figures on consumer marketing material are close to useless for this workload, why the interesting competitive axis has moved to packaging and memory rather than logic, and why an accelerator's bytes per second per watt predicts its real-world value here far better than its peak FLOPS.
What the thing called "a model" actually is, and why running one is a transport problem rather than a thinking problem.
- Why a model's size in gigabytes is the first number to ask about, ahead of anything about speed.
- What bandwidth is, and why it decides how fast an AI writes.
- Why moving a number costs more than multiplying it — and why that gap keeps growing.
Why this workload sits two and a half orders of magnitude below machine balance, and why that's a property of the problem rather than the implementation.
- The area argument for why the parameter set can never be resident in on-die SRAM, with the bitcell numbers behind it.
- The energy argument: ~1.3 J per token of pure DRAM traffic for a 40 GB model, versus negligible arithmetic.
- Why decode throughput reduces to bandwidth ÷ bytes-per-token, and the three ways to attack that ratio.
The words everyone uses
Prefill and decode are different machines
Token, context, prefill, decode, time-to-first-token. Six bits of jargon that carry the whole rest of the course — and one genuinely surprising fact about how an AI splits its work in two.
The same weights and the same kernels, on opposite sides of the roofline. Almost every misleading inference benchmark comes from quoting one phase and measuring the other.
A running AI is not one job. It's two jobs with completely different bottlenecks, stuck together in a loop — and knowing which one you're looking at explains most of what seems inconsistent about AI speed.
Ingest is matrix–matrix; generation is matrix–vector. That one shape difference puts the two phases on opposite sides of the ridge, and everything about serving economics follows from it.
A token is text, pre-chopped
Tokens, and why the tokenizer is a hardware concern
Models don't see letters, and they don't quite see words either. Before your text reaches the model, a piece of software called a tokenizer chops it into chunks from a fixed list. A token is one of those chunks: roughly four characters of English, or about three-quarters of a word.
Common words are usually one token each. Rare ones get broken into pieces. Numbers, code, emoji and non-English scripts fragment much harder — which is why the same paragraph can cost twice as much in Japanese as in English.
Why care? Because the token is the unit of everything: what you're billed, what counts against limits, and what the machine's time is spent on. A 40-page document isn't "40 pages" to the machine — it's about 20,000 tokens, and every one of them is work.
Tokenizers are byte-pair encoding: start from bytes, iteratively merge the most frequent adjacent pair, stop at a target vocabulary size. Two consequences worth holding.
First, vocabulary size sets the width of the embedding table and the output projection — vocab × d_model parameters each. Going from a 100k to a 200k vocabulary on a model with d_model = 8192 adds roughly 1.6 B parameters across the two, which is real capacity and real bandwidth.
Second, fertility — tokens emitted per unit of source text — is the multiplier on everything downstream. Frontier tokenizers sit at 100k–200k entries (cl100k_base holds 100,256; the o200k generation about 200,000), and the larger vocabulary was adopted substantially to cut fertility on CJK and code, where a naive tokenizer can burn several tokens per character.
Tokenizer bench
InteractiveThe two jobs: reading and writing
Prefill: GEMM. Decode: GEMV.
Here's the surprising part. Answering you involves two phases that stress the machine in completely different ways.
Prefill is reading your question. Crucially, the machine can process every token of your input at once, because they're all already there — like skimming a whole page in one glance rather than word by word. That means it can load a chunk of the model once and use it against thousands of your tokens before moving on. Lots of work per delivery. This phase is limited by how fast the chip can calculate.
Decode is writing the answer, and it cannot work that way. Word five depends on word four, so they have to happen in order, one at a time. Each one drags the entire model out of memory to produce a single word. Almost no work per delivery. This phase is limited by the pipe.
Prefill processes the full prompt in parallel: weight matrices are loaded once and multiplied against a [seq_len × d] activation matrix. Arithmetic intensity scales with sequence length, so a 2,000-token prompt lands you far to the right of the ridge — genuinely compute-bound, and the one regime where peak FLOPS is the honest figure of merit.
Decode has a serial dependency across tokens, so the effective batch is 1 (or the server's concurrency) and the kernels degenerate to GEMV. Intensity collapses to batch FLOP/byte at BF16. Same weights, same code path, opposite side of the roofline.
Worth noting the second-order term: attention itself is O(seq²) in prefill, so ingest cost is superlinear in prompt length — at 100k-token prompts the attention term stops being a rounding error against the 2N·seq weight term.
Think of the delivery van from module 1. In prefill, one van-load of ingredients serves two thousand meals. In decode, one van-load serves one meal — and then the van goes back for the same ingredients again. The kitchen is identical in both cases. The throughput isn't.
Prefill is a well-blocked dense GEMM: cache-friendly, high reuse, scales with tensor-core throughput. Decode is a streaming pass over a working set orders of magnitude larger than any cache, with a loop-carried dependency preventing cross-iteration pipelining. If you've optimised both a BLAS3 kernel and a memory-bound stencil, you've met both of these before — the novelty is that they're the same program.
The four numbers people quote
| Metric | What it measures | Set by | Typical today |
|---|---|---|---|
| TTFT | You hit enter; the first word appears | Prefill compute + queueing + network | 0.2–1 s (cloud) |
| Tokens/sec | How fast text streams once it's started | Memory bandwidth | 30–150 tok/s |
| Latency | Total time for your request | TTFT + output ÷ tok/s | 1–30 s |
| Throughput | What the whole server emits, all users summed | Batching, memory capacity | 10³–10⁴ tok/s/node |
Speed-for-you and speed-for-everyone are in tension, and the knob between them is how many people's requests get handled together. A server that waits 40 milliseconds to gather 64 users' requests into one bundle reads the model once for all 64 — sixty-four times the total output for the same fetching. Your laptop, serving only you, gets the worst possible efficiency and the best possible privacy. Both facts come from the same equation.
Latency and throughput trade off through batch size, and the mechanism is pure amortisation of weight traffic: one weight sweep serves B tokens, so intensity rises linearly with B until you hit the ridge. Continuous batching (admitting new sequences into an in-flight batch rather than waiting for the slowest to finish) is what makes this practical at serving scale, and paged KV cache is what stops the memory cost from exploding while you do it.
Where does your wait actually go?
InteractiveContext: the thing that fills up
Context window and the KV cache tax
The context window is how much the model can hold in front of it at once: your prompt, plus its answer, plus everything said earlier in the conversation, because the whole history gets re-sent every turn. Current models advertise 128,000 to 1,000,000 tokens.
For hardware purposes, context isn't free storage — it's a second pile of numbers that grows while you talk. Every token processed leaves behind some notes so the model doesn't have to re-read the entire conversation from scratch each time. Those notes are called the KV cache, and for a 70B model they cost about 0.33 MB per token — roughly 42 GB at a full 128,000-token context, on top of the model itself.
Hold the shape of that: the model is a fixed cost, the conversation is a growing tax. Module 5 does the arithmetic properly.
Context length is a memory allocation, not a capability flag. Every processed token leaves K and V projections resident so attention doesn't recompute the prefix, and that cache is read in full on every subsequent decode step — so it's both a capacity cost and a bandwidth cost that grow linearly with sequence length.
For a Llama-3-class 70B with GQA (80 layers, 8 KV heads, 128 head dim, FP16 cache): 2 × 80 × 8 × 128 × 2 = 327,680 bytes/token ≈ 0.33 MB, so ~42 GB at 128k. Without GQA's 8× head sharing that same cache would be ~336 GB. Module 5 has the full derivation and the interactive.
This is why "just paste the whole document in" gets expensive in a way that isn't obvious. You pay once in reading time — the wait before the first word gets longer — and then you pay again in memory for every word it writes afterwards. On a machine that's tight on memory, it's the conversation, not the model, that finally breaks things.
It's also why long-context RAG is often a worse deal than it looks: you pay the O(seq²) prefill on every request, and carry the KV footprint for the whole generation. Prefix caching helps when the prefix is genuinely shared and stable; it does nothing for per-request retrieved context.
Why the same model on the same machine can feel fast or slow depending purely on what you asked it.
- Why a long question delays the start of the answer, while a long answer stretches the whole wait — different problems, different fixes.
- Why a company's server can be a hundred times more efficient than your laptop without feeling any faster to you.
- Why AI is billed in tokens, and why code and Japanese cost more per page than English.
Why a single inference workload straddles both sides of the roofline, and how to tell which side a benchmark is reporting.
- Why prefill intensity scales with sequence length while decode intensity is pinned at the batch size.
- Why batching is the highest-leverage knob in serving economics, and what continuous batching and paged KV are actually solving.
- Where the KV cache sits in the budget, and why GQA was the change that made long context affordable.
What the machine actually does
Roofline, and the ridge you never reach
Underneath everything, an AI answering you is doing one thing over and over: multiplying numbers together and adding them up. The interesting part is how little of that there is compared to the fetching.
Two spec-sheet numbers give you a machine's break-even intensity. Batch-1 decode sits two to three orders of magnitude below it, and that gap is the single most useful quantity in the field.
One word costs one full sweep
2N FLOPs per token, N·b bytes per token
The arithmetic inside a model is repetitive to the point of being boring: take a list of numbers, multiply each one by a corresponding parameter, add up the results, repeat a few hundred billion times. There's no branching, no searching, no clever algorithm. Just multiply-and-add, at colossal scale.
Which gives us the most useful estimate in the field, and it's almost embarrassingly simple: every parameter takes part in exactly one multiply and one add per word. Two operations per parameter.
A transformer layer is seven weight matrices — W_q, W_k, W_v, W_o plus gate/up/down in the MLP. The forward pass is a chain of projections against those, and at short context the weight matmuls dominate the FLOP count; attention's score computation is a second-order term until sequence length gets large.
Each parameter participates in one MAC per token, giving the standard estimate:
Now weigh that against the fetching
Against machine balance
Take an 8-billion-parameter model, packed at two bytes per number, so 16 GB of weights. Ask the most expensive chip you can rent to produce one word:
8B at BF16 — 16 GB of weights — one decode step on an H100:
Read those two numbers again. The calculating takes sixteen millionths of a second. The fetching takes nearly five thousandths — three hundred times longer. The most expensive computing device you can rent spends 99.7% of its time waiting for the delivery van. It isn't a bad chip; it's a chip being asked a question with hardly any arithmetic in it.
The part worth internalising isn't the ratio itself but its insensitivity: it doesn't improve with model size, layer count, or kernel quality, because both terms scale with N. You can only change it by changing bytes per parameter or by finding more tokens to amortise across.
Work per delivery
Arithmetic intensity and the ridge
This ratio has a name: arithmetic intensity — how much calculating you get per byte fetched. Every task has one. Every machine has a break-even point where its calculating and its fetching are equally busy.
Below the break-even you're waiting on memory and the chip's advertised speed is meaningless. Above it, the advertised speed is real. Generating text one word at a time sits far below it, on every machine ever made.
There's one exception that matters enormously: if the machine handles several people's requests at the same time, one fetch of the model serves all of them. Two people doubles your work-per-delivery. Three hundred people is roughly where a big datacenter chip finally becomes busy.
Intensity for decode collapses to something clean. A weight block of P params, batch B: 2·P·B FLOPs ÷ (P · bytes_per_param) bytes. At BF16 that's exactly B — arithmetic intensity equals batch size. At INT8 it's 2B, at INT4 4B: lower precision buys intensity as well as capacity, which is worth remembering when people describe quantisation as purely a memory-saving trick.
Ridge point is peak FLOPS ÷ bandwidth. The right-hand column below is the batch you'd need before the FLOPS column means anything:
| Chip | Dense BF16 | Bandwidth | Break-even | What that means |
|---|---|---|---|---|
| Apple M4 Max | ~34 TFLOPS* | 546 GB/s | ~62 | needs ~62 tokens in flight to saturate |
| RTX 5090 | ~210 TFLOPS | 1,792 GB/s | ~117 | consumer memory keeps the ratio lowish |
| H100 SXM | 989 TFLOPS | 3,350 GB/s | ~295 | needs ~295 tokens in flight |
| B200 | 2,250 TFLOPS | 8,000 GB/s | ~281 | HBM3e barely keeps pace with Blackwell |
| TPU v7 Ironwood | 2,307 TFLOPS | 7,370 GB/s | ~313 | built for large-batch serving |
Look at that last column. Every one of these machines needs dozens to hundreds of requests happening simultaneously before its arithmetic is the limiting factor. You, sitting alone at your laptop, supply exactly one.
Note how little the ridge has moved across four generations and three vendors — HBM capacity and bandwidth have scaled roughly in step with tensor throughput, so the balance point stays pinned near 300. That's a deliberate design equilibrium, not a coincidence, and it tells you the vendors are targeting large-batch serving.
Roofline explorer
Interactivebandwidth × intensity, flat roof is peak FLOPS, intersection is the ridge. Two things to watch: how far left batch 1 sits, and how quantisation translates the operating point right rather than just shrinking the footprint.Where the arithmetic does matter
- Reading long prompts. Thousands of tokens at once, genuinely limited by calculation. This is where a fast chip earns its money — and where a phone falls off a cliff.
- Serving many people. Bundling dozens of users into one sweep through the model. This is how a cloud provider sells tokens for a fraction of what they'd cost you at home.
- Training. Every step handles thousands of tokens and the learning pass roughly triples the arithmetic. That's module 4.
It explains the most common disappointment in local AI: someone buys a graphics card with an enormous advertised speed and finds text generation no faster than on a cheaper card with the same memory bandwidth. It also explains why packing numbers smaller makes models faster, not just smaller — fewer bytes to fetch is the whole game.
It's also why "AI accelerator" specs should always be read as a pair — FLOPS and GB/s — and why a sparsity-doubled FP4 headline number tells you almost nothing about single-stream decode. A chip is only as useful as the smaller of those two relative to your workload's intensity.
And it's why any "AI accelerator" claim should be read as two numbers, never one: how much arithmetic, over how fast a pipe.
Why an enormously expensive chip running your personal chatbot is idle almost all the time — and why that isn't a fault.
- How to work out a machine's break-even point from two numbers on its spec sheet.
- Why serving lots of people at once is the single biggest cost lever in AI, and costs no extra hardware.
- Why smaller numbers mean faster generation even when arithmetic wasn't the bottleneck.
How to place any workload on any machine's roofline from two spec numbers, and what the distance to the ridge implies.
- Why decode intensity equals batch size at BF16, and scales inversely with bytes per parameter.
- Why ridge points across vendors and generations all cluster near 300 FLOP/byte.
- Why kernel work can't close a 300× intensity deficit — only batching, quantisation or sparsity can.
Making a model vs running one
Training and inference are different machines
These are two completely different jobs that happen to involve the same pile of numbers. One needs a building full of machines for months. The other needs one machine for a second. And the bridge between them is a trick about how precisely you write numbers down.
~16 bytes per parameter versus ~0.5, throughput-bound versus latency-bound, collective-heavy versus embarrassingly serial. Precision is the bridge, and it's the one knob that moves both problems at once.
Training: writing the cookbook
Training's cost is state, not arithmetic
Everything so far has been about running a finished model. Making one in the first place is a different kind of job entirely.
Training shows the machine enormous amounts of text and, every time it guesses the next word wrong, nudges every one of its billions of numbers very slightly in a direction that would have been less wrong. Do that trillions of times and the numbers settle into something useful.
The arithmetic is about three times heavier than running the finished model. That part is just a bigger number. The part that reshapes the hardware is what training has to keep: for every parameter, you're also storing which direction you're currently nudging it, and a running memory of how you've been nudging it recently. Several extra numbers per parameter, all of which have to be in fast memory at once.
Backprop is roughly 3× the forward FLOPs (≈6 FLOPs/param/token against 2), which is unremarkable. The structural difference is resident state.
Standard mixed-precision with Adam: BF16 weights (2 B) + FP32 master copy (4 B) + gradients (2–4 B) + first and second moments (4 B each) ≈ 16 bytes per parameter, before activations. Activation memory then scales with batch × sequence × depth, which is what activation checkpointing trades against recompute FLOPs.
That 1.1 terabytes is why training hardware looks the way it does. The numbers get split across hundreds or thousands of machines, and at the end of every single step all of them have to compare notes with all the others. The wires between machines stop being plumbing and become part of the computer.
Sharding (ZeRO/FSDP for state, tensor parallel within a node, pipeline parallel across them) puts an all-reduce on the critical path of every step. At that point interconnect bandwidth is a first-order performance term, not I/O — which is precisely why NVLink domains and TPU ICI toruses exist, and why training capacity is sold by the rack rather than the card. Module 7 has the topologies.
Two jobs, two shopping lists
| Training | Running it (one user) | |
|---|---|---|
| Work per step | millions of tokens at once | one token — or tens, if bundled |
| Limited by | arithmetic and the wires between machines | memory bandwidth, then capacity |
| Optimised for | total throughput over weeks | responsiveness in milliseconds |
| Memory per number | ~16 bytes | 0.5–2 bytes |
| Precision | BF16 / FP8 with an FP32 master copy | INT8, INT4, MXFP4 — whatever survives |
| When it goes wrong | a machine dies and the run stalls | a person waits, then leaves |
| Wants hardware that is | many chips, huge arithmetic, fast fabric | one chip, fat memory pipe, enough capacity |
This is why a chip can be excellent at one and mediocre at the other. A phone's AI chip is a fine engine for a small model and cannot train anything meaningful. A rack of datacenter machines is a training instrument whose speed for one person's chat would be embarrassed by a laptop with similar memory bandwidth. Neither is bad. They're answering different questions.
The corollary that trips people up: an accelerator optimised for training — enormous FLOPS, modest per-chip bandwidth, scale-out fabric — can be a poor single-stream decode engine, and vice versa. Any evaluation that doesn't state batch size and phase is uninterpretable.
Precision: how many digits you bother keeping
Numeric formats: range versus mantissa
Here's the bridge between the two worlds, and it's a genuinely elegant idea.
Every one of those billions of numbers has to be written down in some amount of space. Write it very precisely — lots of decimal places — and it takes four bytes. Round it off a bit and it takes two. Round it aggressively and it takes half a byte.
Think of prices. "£12.3847" is precise. "£12.38" loses almost nothing useful. "£12" loses a bit more. "About a tenner" loses quite a lot. The question is how much rounding a model tolerates before it gets noticeably worse — and the surprising answer is: a great deal.
Training needs precision, because it's making tiny adjustments and tiny adjustments get lost in rounding. But once the model is finished and the numbers are frozen, you can round them hard. That process is called quantisation, and it is the single reason running AI on your own computer is possible at all.
Training needs dynamic range more than mantissa precision, because gradients span many orders of magnitude — which is exactly why BF16 displaced FP16. Identical width, but BF16 keeps FP32's 8-bit exponent and spends only 7 bits on mantissa, so it rarely overflows and generally doesn't need loss scaling.
Inference has the opposite freedom: weights are frozen, their distributions are known and measurable, so you can compress hard provided you keep a scale factor per small block to preserve local range. That's the microscaling idea behind MXFP4 and friends, and behind llama.cpp's K-quants. The practical gotcha is outlier channels — a handful of dimensions with much larger magnitudes — which is what AWQ and GPTQ-style methods exist to handle.
Precision & quantisation dial
InteractiveQuantisation is why local AI exists. A 70B model written out precisely is ~140 GB — a rack of servers. The same model rounded to about half a byte per number is ~40 GB — a £2,000 desktop. You're not choosing between "good" and "bad"; you're choosing which 40 GB of capability you'd rather have: a large model rounded hard, or a small one kept sharp. Module 8 answers that.
And because bytes-per-parameter appears in the denominator of intensity as well as the footprint, quantisation is simultaneously a capacity fix, a bandwidth fix and an intensity fix. There are very few knobs in systems work that move three constraints in the same direction.
Why the hardware that makes a model isn't the hardware you'd choose to run one — and why both exist.
- Where training's sixteen-bytes-per-number comes from, and why it forces whole buildings of machines.
- What quantisation is, and why rounding a finished model costs so much less than you'd think.
- Why rounding makes a model faster as well as smaller.
Why training and serving pull hardware design in opposite directions, and where precision sits as the shared lever.
- The ~16 B/param accounting, and why it makes sharding mandatory rather than optional.
- Why BF16 won training on exponent range while INT4/MXFP4 won inference on frozen distributions.
- Why bytes-per-parameter moves capacity, bandwidth and arithmetic intensity simultaneously.
The memory wall
This is the module everything has been building towards. Two questions decide whether a model is usable on a given machine — does it fit, and how fast can the machine read it — and both have arithmetic you can do in your head.
Capacity gates feasibility, bandwidth gates throughput, and the ratio between package technologies spans two orders of magnitude. Here are the real figures, and a prediction you can check against measurements.
Three ways to hold a model
Three memory topologies
Where the model's numbers physically sit turns out to matter enormously, and there are three arrangements in the wild.
A discrete graphics card has its own private memory, very fast, and usually not very much of it. A plain computer has ordinary system memory: plenty of it, but slow. And then there's unified memory, where everything shares one pool that is both large and reasonably fast.
The three arrangements differ in where the DRAM sits relative to the compute die, and that placement determines both the achievable bandwidth and the practical capacity ceiling:
- Discrete GDDR — high pin-rate DRAM on a wide bus around the die. Great bandwidth per dollar; capacity limited by board area and the bus width you can route (5090: 512-bit, 32 GB).
- Host DDR — enormous capacity, but a narrow dual-channel path (~90 GB/s) and a PCIe hop to any accelerator.
- Unified LPDDR — DRAM on package, wide and short. Apple's tiers run 153–1,200 GB/s at up to 512 GB, with zero-copy between CPU, GPU and NPU because there's only one pool.
- HBM — stacked DRAM dies with TSVs on an interposer beside the compute die. Bandwidth comes from thousands of slow pins rather than hundreds of fast ones, which is also why it's more energy-efficient per bit (~4 pJ/bit for HBM3E). Capacity per stack is the constraint, hence 192 GB parts.
The bandwidth ladder
Here is the number that predicts generation speed, across five orders of device. It's a logarithmic scale — a phone and a datacenter chip aren't in the same universe.
Peak figures; real kernels reach 70–90%. Log scale — note that the span from phone LPDDR to HBM3e is roughly 100×, while the span in peak FLOPS across the same devices is closer to 1000×.
| Device | Memory | Capacity | Bandwidth | 40 GB model ceiling |
|---|
Does the arithmetic actually work? Yes — to within 10%
The claim from the front page was that speed ≈ bandwidth ÷ model size. That's the kind of claim that deserves checking against real published measurements rather than being asserted. A 70B model packed to 4 bits is about 40 GB:
Predicted decode throughput as bandwidth ÷ (bytes_per_token × 1.05), against published llama.cpp/MLX figures at batch 1:
| Machine | Bandwidth | Predicted | Measured | Accuracy |
|---|---|---|---|---|
| M3 Max, 128 GB | 400 GB/s | 10.0 tok/s | 9.8 tok/s | 98% |
| M4 Max, 64 GB | 546 GB/s | 13.6 tok/s | ~12.5 tok/s | 92% |
| M5 Max (70B class, Q4) | 614 GB/s | 15.4 tok/s | 25–32 tok/s* | — |
Two decimal places of agreement from a one-line estimate is unusual. Use it: before buying anything, divide its bandwidth by your model's size and ask whether the answer is a speed you'd tolerate.
The residual is kernel efficiency and KV traffic; there's no hidden term. Which is the useful part — it means a spec sheet is sufficient for capacity planning at batch 1, and you only need real measurements once you're batching.
The conversation is a second, growing model
KV cache: the term that grows
Module 2 introduced the KV cache — the notes the model keeps about everything said so far. Here's what it actually costs, and why it's usually what breaks a machine rather than the model itself.
Notice the shape of that: in a long conversation, the conversation outweighs the model. And because those notes must also be read on every single word, a long chat generates more slowly than a fresh one on identical hardware.
And it's read every step, so it's a bandwidth term as well as a capacity term — decode throughput degrades measurably as context fills, which is why steady-state tok/s benchmarks at 1k context overstate what you'll see at 100k.
When it doesn't fit: the cliff
Say your model is 40 GB and your graphics card holds 32. The software will happily put the leftover part in ordinary system memory and fetch it across the narrow link every word. The arithmetic is unforgiving:
Spill across PCIe 5.0 ×16 at ~64 GB/s, against 1,792 GB/s of local GDDR7:
| Where the 40 GB lives | Per-token time | Speed | How it feels |
|---|---|---|---|
| All of it on the card @ 1,792 GB/s | 22 ms | 45 tok/s | faster than you can read |
| 32 GB on card + 8 GB across PCIe | 143 ms | 7 tok/s | readable, frustrating |
| 24 GB on card + 16 GB across PCIe | 263 ms | 3.8 tok/s | painful |
| Spilling to SSD (~7 GB/s) | seconds | <1 tok/s | abandon hope |
Will it fit — and what will it cost you?
InteractiveWhen someone asks "what should I buy for AI?", the useful answer is almost never about the chip's speed. It's how many gigabytes, and how fast can it read them? Those two numbers, plus the size of what you want to run, determine everything you'll experience.
For procurement the ordering is: capacity (feasibility) → bandwidth (throughput) → FLOPS (only once you're batching or prefilling long contexts). A 5090's 32 GB binds long before its 210 TFLOPS do, and no amount of compute buys you past a capacity wall.
Why a laptop with lots of unified memory can run models a powerful gaming card physically cannot — and why the gaming card is still three times faster on anything that fits.
- How to predict a machine's generation speed from its spec sheet, before buying, to within about 10%.
- Why moving "just a few layers" off the fast memory costs most of your performance.
- Why long conversations slow down, and why it's the conversation, not the model, that finally breaks things.
How to size any model against any memory topology, and why the spill cliff is non-linear.
- Why HBM, GDDR and unified LPDDR occupy different points on the capacity–bandwidth–energy surface.
- The KV cache formula, why GQA was load-bearing for long context, and why it's a bandwidth term too.
- Why batch-1 decode throughput is predictable from a spec sheet to within ~10%, and where that stops being true.
Chips built only for this
Dedicated AI silicon
NPUs, neural engines, TPUs, tensor cores. Underneath the branding there's one idea — build the multiplication into the wiring — and then some very different answers about power, flexibility and scale.
Spatial reuse, dataflow choice, and why a 128×128 systolic array running a matrix-vector product is mostly multiplying by nothing.
A general-purpose processor spends most of its transistors, and most of its electricity, on not knowing what comes next: working out which instruction follows, guessing at branches, shuffling data between hiding places. A giant multiplication knows exactly what comes next, forever. Every category of AI chip is a different bet on how much of that machinery you can throw away.
Every AI accelerator is a wager on how much control-plane overhead you can delete, and how much operand reuse you can express spatially rather than through a cache hierarchy. The interesting differences are in the dataflow and in what happens when the problem shape doesn't match the array.
The idea: stop going back to the storeroom
Systolic arrays: reuse in the wires
Think about what an ordinary processor does for a single multiply-and-add: fetch two numbers from their hiding places, multiply them, add the result to a running total, put the total back. The multiplication is nearly free. All the cost is in the fetching and the putting back.
A systolic array deletes the trips. Lay out a grid of tiny multiplying units and load a chunk of the model into them, permanently. Then pump your numbers in at the edge and let each unit hand its result to its neighbour, like a bucket brigade. One number entering the edge gets used by every unit in its row, and nothing goes back to memory in between.
A weight-stationary systolic array amortises operand fetch spatially: an N×N array performs N² MACs per cycle while consuming ~2N operands per cycle, so operand reuse scales with N rather than depending on a cache hierarchy to find it. No register file pressure, no scheduling, minimal control overhead per MAC — which is where the energy advantage over a general-purpose SIMT pipeline comes from.
Run the panel below and watch the MACs-per-read figure climb as the wavefront fills the array. That ratio is the entire justification for the architecture.
Systolic array, one clock at a time
InteractiveArrays like this are wonderful when there's plenty to multiply and the shapes are predictable. Feed one a single word at a time — which is exactly what writing an answer is — and most of the grid sits there multiplying by nothing. This is the structural reason big AI chips are built for serving many people at once, and not for being your personal assistant.
Utilisation collapses when the problem shape doesn't fill the array. A 128×128 MXU fed a GEMV occupies one column of the systolic dimension; the rest is multiplying zeros or idling. This is the same batch-1 story from module 3 expressed in array geometry rather than in roofline coordinates, and it's why inference-oriented parts trend toward more, smaller matrix units rather than one enormous one.
Google's TPUs: built by the rack, not the card
TPUs have never been sold as something you put in your desktop. The design target is a pod: thousands of chips wired straight to each other, addressed as one enormous machine.
TPUs are designed pod-first: chips connect over a dedicated inter-chip interconnect in a torus, so a job addresses thousands of chips as one machine without touching a general-purpose network. The design point is high-batch serving and training, not single-stream latency.
Google positioned Ironwood explicitly as an inference generation — more memory and more bandwidth per chip than its training-focused ancestors, because serving enormous models to enormous numbers of people is now the dominant workload. The lineage is direct: the first TPU in 2015 was a 256×256 grid doing nothing but this.
Ironwood's positioning as an inference generation shows in the balance: bandwidth scaled harder than FLOPS relative to v5p, holding the ridge near 313 while capacity doubled. TPU v1 (2015) was a 256×256 8-bit weight-stationary array; everything since has been that idea plus memory plus fabric.
Apple's Neural Engine: the opposite bet
The ANE optimises for battery, not speed. It's a fixed-purpose engine that runs small, pre-compiled networks at a fraction of the power the graphics side would need — which is why it handles the things that must run constantly: face detection, dictation, live text, photo analysis, and Apple's own on-device model.
The ANE is a Core ML target: compiled graphs, static shapes, quantised fixed pipelines, optimised for perf-per-watt on perception workloads rather than for arbitrary dynamic-shape kernels. It's an excellent engine for what it was designed for and a poor fit for autoregressive decode.
If you run a local AI model on a Mac today, the Neural Engine does nothing. The work goes to the graphics cores instead. Two reasons: the ANE wants fixed, predictable shapes and a language model's generation loop isn't that — and more fundamentally, this job is limited by fetching, so an engine whose advantage is doing arithmetic efficiently can't win a race that isn't about arithmetic.
Local LLM runtimes on macOS target the GPU via Metal, not the ANE. Partly the programming model (dynamic shapes, custom attention kernels, a rapidly moving quant-format landscape versus a compiled Core ML graph), but fundamentally: decode is bandwidth-bound, and an engine whose advantage is joules-per-FLOP can't win a contest decided by GB/s.
That's also why Apple's M5-generation change matters more than any TOPS figure: putting tensor units inside the GPU cores puts matrix acceleration on the side of the chip that already has the bandwidth and the flexible programming model.
Same words, different machines
| Phone NPU | Laptop NPU / ANE | Datacenter accelerator | |
|---|---|---|---|
| Power budget | ~1–2 W | ~2–5 W | 700–1,400 W |
| Peak | tens of TOPS (INT8) | ~38 TOPS (M4-generation ANE) | petaFLOPS |
| Memory | shared, ~85 GB/s | unified, 150–1,200 GB/s | dedicated HBM, 4.8–8 TB/s |
| Model it suits | 0.5–4 B, heavily packed | 3–70 B | hundreds of B, sparse |
| Designed for | always-on sensing, battery life | on-device assistants, privacy | many users at once, and training |
| Flexibility | fixed-function graphs | compiled graphs (Core ML) | fully programmable (CUDA/XLA) |
When a laptop is advertised with "45 TOPS of AI", that number describes a low-power engine meant for background tasks — not a promise about running a large model. The question to ask any AI chip is still module 3's pair: how much arithmetic, over how fast a pipe, into how much memory — and at what power.
TOPS is a marketing scalar that omits precision, sparsity assumptions, sustained-versus-burst, and — crucially — the memory system behind it. For this workload, bytes per second per watt is the figure of merit that actually correlates with delivered performance.
Why an "AI chip" in a phone and an "AI chip" in a data centre share a name, an idea, and almost nothing else.
- What a systolic array buys you, counted in trips to memory — and why it half-empties when serving one person.
- Why your Mac's dedicated AI engine sits out the exact task it sounds built for.
- Why TPUs are sold by the rack and graphics cards by the card, and what that says about their intended jobs.
Why spatial reuse is the organising principle of AI silicon, and where it breaks down.
- Why an N×N weight-stationary array gives O(N) operand reuse, and why GEMV wastes most of it.
- Why perf-per-watt advantages don't transfer to a bandwidth-bound regime — the ANE case.
- Why vendors keep the ridge near 300 and sell pods rather than parts.
The device landscape
From a two-watt phone chip to a rack that draws as much as a hundred homes. Four tiers, the same three numbers, seven orders of magnitude between the ends.
Four tiers, ordered by where the DRAM sits and what the coherence domain spans. The jump that matters isn't chip count — it's when the interconnect becomes the memory bus.
Device comparator
InteractiveTier 1 — phones: limited by heat, not by chips
A flagship phone pairs a capable AI engine with a memory system of roughly 85 GB/s, shared with everything else the phone is doing.
Flagship SoCs pair a sizeable NPU with a 64-bit LPDDR5X subsystem at roughly 85 GB/s, shared with display, camera and OS. Qualcomm's Snapdragon 8 Elite Gen 5 supports INT2 through FP16 in its Hexagon NPU.
Run module 5's arithmetic on it. A 3-billion-parameter model packed to 4 bits is about 1.8 GB, so 85 ÷ 1.8 ≈ 47 words per second — genuinely useful. An 8B model at 4.5 GB gives about 19, and real-world figures land nearer 5 once heat and the rest of the phone are accounted for. A 70B model needs 40 GB and isn't a near miss; it's a category error.
3B at Q4 ≈ 1.8 GB → ~47 tok/s ceiling; 8B at Q4 ≈ 4.5 GB → ~19 tok/s ceiling, with reported sustained figures nearer 5 once thermal throttling and bandwidth contention are included. The 70 GB-class models are not a capacity near-miss, they're two orders out.
Phones are limited by heat, not by chips. Peak figures are burst figures; sustained performance after sixty seconds can be half of it. That's why on-device AI targets short, frequent, small-model tasks — summarise this notification, transcribe this sentence — rather than long generations.
Tier 2 — unified memory: the sweet spot for running models yourself
Apple Silicon's trick is that every part of the chip shares one pool of memory with no copying — so the memory available to the AI is whatever fraction of your RAM you want it to be (about 75% by default). Buy 128 GB and you have something close to a 96 GB graphics card, at a speed that scales with the chip tier:
One physical pool addressed by CPU, GPU and ANE with no copies and no PCIe hop. The practical effect is that the capacity ceiling moves from "what fits on a board" to "what you configured at purchase", at bandwidths that are a respectable fraction of GDDR:
| Generation | Base | Pro | Max | Ultra | Max memory |
|---|---|---|---|---|---|
| M1 (2020–22) | 68 | 200 | 400 | 800 | 128 GB |
| M2 (2022–23) | 100 | 200 | 400 | 800 | 192 GB |
| M3 (2023–25) | 100 | 150 | 400 | 819 | 512 GB |
| M4 (2024–25) | 120 | 273 | 546 | — | 128 GB |
| M5 (2025–26) | 153 | ~307 | ~614 | ~1,200 | 512 GB |
Two things worth noticing. The Pro tier went down in the M3 generation before recovering — newer isn't automatically better for this job. And an Ultra at ~1.2 TB/s with up to 512 GB is a genuinely strange machine by 2020 standards: two-thirds of a top gaming card's speed attached to sixteen times its memory, drawing a couple of hundred watts.
Note the M3 Pro regression — bandwidth is not monotonic across generations, because the bus width is a packaging and cost decision rather than a process one. And an M5 Ultra at ~1.2 TB/s with 512 GB occupies a point on the capacity–bandwidth plane that no discrete part offers at any price: ~67% of a 5090's bandwidth with 16× the capacity, at roughly a third of the power.
Tier 3 — graphics cards: speed per pound, capacity per anxiety
| Card | Memory | Bus | Bandwidth | Biggest model at 4-bit |
|---|---|---|---|---|
| RTX 5090 | 32 GB | 512-bit | 1,792 GB/s | ~49B — 32B comfortably |
| RTX 5080 | 16 GB | 256-bit | 960 GB/s | ~24B — 14B comfortably |
| RTX 5070 Ti | 16 GB | 256-bit | 896 GB/s | ~24B — 14B comfortably |
| RTX 5070 | 12 GB | 192-bit | 672 GB/s | ~18B — 8B comfortably |
CUDA is the other half of the story and the reason this tier dominates in practice: a decade of accumulated software, every framework, every serving tool. Bandwidth is excellent — a 5090 reads its memory three times faster than an M5 Max — but capacity is the ceiling, and 32 GB is where the consumer line stops.
CUDA's moat is the real differentiator at this tier; the hardware is a fast, capacity-starved part with an unmatched kernel ecosystem. Note the segmentation logic: bus width tracks price precisely, because bandwidth is the scarce resource and NVIDIA knows exactly what it's rationing.
Tier 4 — the data centre: the rack is the computer
Here's where the desktop mental model breaks. A datacenter machine is not one chip with more memory — it's eight chips wired into a single unit, so a model too big for one gets split across all of them, with the pieces talking constantly as every word is produced.
A node is 8 accelerators in a coherent NVLink domain; a model exceeding one device's capacity is sharded tensor-parallel, and per-layer activations cross the fabric on every forward pass. That only works because NVLink is ~14× PCIe — at PCIe rates the collective overhead would dominate the step.
| Accelerator | Memory | Bandwidth | Link to its neighbours | Era |
|---|---|---|---|---|
| H100 SXM | 80 GB HBM3 | 3.35 TB/s | NVLink 4 · 900 GB/s | 2022 — still everywhere |
| H200 SXM | 141 GB HBM3e | 4.8 TB/s | NVLink 4 · 900 GB/s | same die, more memory |
| B200 | 192 GB HBM3e | 8.0 TB/s | NVLink 5 · 1.8 TB/s | Blackwell, current |
| TPU v7 Ironwood | 192 GB HBM | 7.37 TB/s | ICI · 1.2 TB/s | available April 2026 |
| Rubin (VR200) | 288 GB HBM4 | ~20 TB/s | NVLink 6 · 3.6 TB/s | announced, H2 2026 |
This tier structure is why the you-versus-the-cloud question has a clean answer rather than a fuzzy one (module 9). You can't buy your way gradually up the ladder: between a 32 GB card and a 1.1 TB machine there is no consumer product, because the thing bridging them is a very expensive interconnect, not a bigger card.
And it's why capability tiers are discontinuous rather than a smooth price curve. The gap between the top consumer part and the bottom datacenter node isn't priced by silicon area — it's priced by the fabric and the packaging, neither of which has a consumer SKU.
Where any piece of AI hardware sits, and what it can and can't be asked to do, from its spec sheet alone.
- Why unified memory made mid-size models practical at home, and what it gives up versus a graphics card.
- Why the link between chips, not the chips, is what makes a datacenter machine different in kind.
- Why phone AI is built around bursts of small models, and will be while batteries exist.
How to place any product on the capacity–bandwidth–power surface, and why the tiers are discontinuous.
- Why unified LPDDR occupies a point no discrete part offers, and what it costs in peak bandwidth.
- Why NVLink at ~14× PCIe is the enabling condition for tensor-parallel sharding.
- Why bus width tracks consumer price so precisely — bandwidth is the rationed resource.
Running one yourself
The practical module. What the software is, how to read a model's name, what "8B at Q4" costs you in gigabytes, and how to spend a fixed amount of memory for the most capability.
Runtime landscape, quant format taxonomy, and why mixture-of-experts decoupled capacity cost from bandwidth cost — the most consequential architectural change for local inference in years.
The software, in four layers
| Tool | What it is | Pick it when |
|---|---|---|
| llama.cpp | The C++ engine most local tooling is built on. Reads GGUF files, supports every packing format and every kind of hardware. | You want control, scripting, or an unusual platform. |
| Ollama | A background service plus a command line wrapping llama.cpp. ollama run qwen3 and you're done. | You want it working in sixty seconds, or a local service for your own app to call. |
| LM Studio | A desktop app: browse, download, chat, serve. Tells you which versions fit your machine. | You're exploring models and want the memory arithmetic done for you. |
| MLX / MLX-LM | Apple's own framework for Apple Silicon, built around unified memory. | You're on a Mac and want maximum speed, or want to fine-tune locally. |
| vLLM / SGLang | Serving stacks with continuous batching and paged KV cache. | You're serving many users on real GPUs, not chatting on a laptop. |
Reading a model's name
"Qwen3-8B-Instruct-Q4_K_M.gguf" looks like noise. It's four facts. 8B — eight billion numbers, which fixes the memory and the speed. Instruct — trained to follow instructions rather than just continue text. Q4_K_M — packed to roughly four bits per number, so about 0.56 GB per billion parameters. GGUF — the file format.
Size, post-training objective, quant scheme, container. Q4_K_M is llama.cpp's K-quant family, medium variant: ~4.5 bits/weight once block scales and the mixed-precision handling of sensitive tensors are counted, giving ~0.56 GB/B-param. The alternatives you'll meet are AWQ and GPTQ (calibration-based, better outlier handling, GPU-oriented) and native MXFP4 for models trained or released in it.
| Model size | Full precision | 8-bit | 4-bit | 3-bit | Lands on |
|---|---|---|---|---|---|
| 3B | 6 GB | 3.2 GB | 1.8 GB | 1.3 GB | a phone |
| 8B | 16 GB | 8.5 GB | 4.6 GB | 3.4 GB | any 16 GB laptop |
| 14B | 28 GB | 14.9 GB | 8.1 GB | 5.9 GB | 16 GB card / 24 GB Mac |
| 32B | 64 GB | 34 GB | 18.6 GB | 13.4 GB | 24–32 GB of fast memory |
| 70B | 140 GB | 74 GB | 40.6 GB | 29.4 GB | 64–128 GB unified |
| 120B sparse | 234 GB | 124 GB | ~61 GB* | — | 128 GB unified / 80 GB card |
The change that made local AI good: only part of the model fires
MoE decouples capacity from bandwidth
Until recently, "bigger model" always meant "proportionally slower", because every number was read for every word. Mixture-of-experts models broke that link. The model is divided into many sections and only a few of them are consulted for any given word.
So the cost splits in two: you must store all of it, but you only read a little of it per word. Storage is charged on the total; speed is charged on the part that fires.
*OpenAI's gpt-oss-120b is the clean example. It holds 116.8 billion numbers — about 61 GB, so it needs a serious machine — but only 5.1 billion are used per word. It therefore generates far faster than a traditional model of its size ever could. This, more than any hardware change, is why running capable AI at home got dramatically better in 2025–26.
Sparse MoE routing means capacity cost scales with total parameters while bandwidth cost scales with active parameters. gpt-oss-120b: 116.8 B total, 5.1 B active per token, shipped natively in MXFP4 at ~61 GB, 128k context. That's a ~23× reduction in per-token weight traffic against a dense model of equal capacity.
The systems consequence is that the binding constraint flips from bandwidth to capacity for this class of model — which is exactly the regime where unified memory's capacity advantage beats GDDR's bandwidth advantage. It also changes the arithmetic intensity picture: fewer bytes per token at constant FLOPs per active parameter, so MoE is an intensity win as well as a speed win.
Spending a fixed amount of memory
This is the real decision. Given N gigabytes, do you run a big model rounded hard, or a smaller one kept sharp? The evidence is consistent: down to about four bits, the bigger model wins. At three bits and below the bigger model degrades faster than the smaller one gains, and the ordering flips.
Empirically the frontier runs through "largest model that fits at ~4.5 bits/weight" for most tasks, with the crossover around 3 bits where K-quant degradation becomes non-linear and hits reasoning and code before chat.
Budget planner
InteractiveWhat "fast enough" actually means
Calibrate against yourself: comfortable adult reading is roughly 5–8 words per second. The thresholds are less dramatic than people assume.
| Speed | Experience | Example setup (Sept 2026) |
|---|---|---|
| < 3 /s | Unusable for chat; fine for a job you leave running overnight | 70B at 4-bit with part of it spilled to system memory |
| 5–10 /s | Keeps pace with reading. Fine for prose, painful for code | 70B at 4-bit on an M3 Max (measured 9.8) |
| 15–30 /s | Comfortable. Feels like a normal assistant | 32B at 4-bit on a 5090; 70B on a current Max or Ultra |
| 50–150 /s | Faster than you can read; automated multi-step work becomes practical | 8B on any modern card; sparse models locally |
Conversation length is a memory setting. The software reserves space for the whole conversation up front, so asking for a 128,000-token context on a model you barely fit is how "it worked yesterday" becomes an out-of-memory error. Set it to what you need.
Laptops get hot. Sustained generation throttles. Benchmarks are measured cold.
Stuffing documents into every request is the hidden cost. 50,000 tokens of retrieved context means paying that reading cost on every single request — frequently more total time than the answer itself.
Exactly which models a given machine can run, how fast, and what you give up at each level of rounding — before downloading anything.
- Why "about 0.56 GB per billion parameters at 4-bit" is the only conversion you need day to day.
- Why sparse models are stored like giants and run like sprinters.
- Why the right way to spend memory is usually a bigger model rounded to 4 bits, not a smaller one kept at 8.
How to size and select a local deployment, and why the MoE shift changed which hardware to want.
- The quant format taxonomy — K-quants vs AWQ/GPTQ vs native MXFP4 — and what each is solving.
- Why MoE moves the binding constraint from bandwidth to capacity, favouring unified memory.
- Why context length is an allocation decision, not a capability flag.
Your machine or somebody's rack?
Not "good model versus bad model". Four separate trade-offs — capability, cost, responsiveness, control — that happen to point in different directions.
Why frontier models are structurally un-shippable to consumer hardware, and where the capex/opex crossover actually falls once you model it properly.
Why the biggest models stay in data centres
Everything in module 7 converges here. A current top-tier model is enormous — the openly published ones that approach that class hold 400 to 700 billion numbers, and the private ones are generally assumed to be larger. Even packed efficiently, that's hundreds of gigabytes of weights before the conversation is counted.
Open-weight frontier-class models (DeepSeek-V4, Qwen 3.5, GLM-5 generation) are 400B–671B total parameters; at FP8 that's ~670 GB of weights before KV. No single accelerator made holds it — B200 and TPU v7 top out at 192 GB, Rubin at 288 GB.
That number is bigger than any single chip on the market can hold. So serving one of these is necessarily a multi-machine job: the model is split across a node, the pieces talk to each other constantly, and hundreds of users' requests are bundled together to make the economics work. You are not renting a model. You're renting a slice of a machine that isn't sold in a smaller size.
So frontier serving is necessarily multi-chip and necessarily batched — tensor-parallel across the node with continuous batching to push intensity toward the ridge. The unit of deployment is a node or a rack, and that unit has no consumer equivalent at any price.
The four trade-offs, concretely
| Axis | A model on your machine | A frontier model over the internet |
|---|---|---|
| Capability | Roughly where the frontier was 18 months ago on chat and summarising; noticeably weaker on long reasoning, hard code, and multi-step autonomous work | The actual frontier, improving without you doing anything |
| Cost per use | Electricity. Effectively nothing | ~$0.15–$10 per million input tokens; output typically 3–6× that (Sept 2026 range) |
| Cost up front | The machine — $600 to $10,000, and it's yours | Nothing |
| Time to first word | No network, no queue. Often better for short prompts | Network and queue, but enormous compute for long ones |
| Generation speed | Bandwidth ÷ model size. 5–40 /s typically | Usually 50–150 /s, and it scales on demand |
| Privacy | Nothing leaves the device. Makes regulated work vastly simpler | Contractual — read the data-retention terms |
| Stability | The file on your disk is frozen forever. Reproducible in two years | Models get retired; behaviour shifts under you |
| Scaling up | One machine, one or two users at a time | Effectively unlimited, instantly |
Break-even calculator
InteractiveAt personal volumes — a few million tokens a month — a paid service costs a few dollars and hardware never pays for itself. Buy local for privacy, for offline use, or because you want the machine; not to save money. At bulk volumes — classification, extraction, summarising a corpus, hundreds of millions of tokens of easy work — local hardware pays for itself in weeks. The volume axis matters more than every other input combined.
The answer most people land on: both
The mature pattern is routing by difficulty and sensitivity rather than picking a side:
- Local for high-volume mechanical work, anything touching sensitive data, anything that must work offline, and anything that needs to behave identically in two years' time.
- Remote for genuinely hard reasoning, long autonomous runs, the rare request where quality dominates cost, and anything needing more context than your memory allows.
- Both, with something cheap deciding which — and that something can be the local model.
Every module before this one was about hardware, and this is the payoff: the line between "runs on your machine" and "runs in somebody's data centre" isn't drawn by business strategy or licensing. It's drawn in gigabytes. The biggest models don't fit, and the gap between 32 GB and a terabyte isn't a product gap — it's an interconnect you can't buy.
And the gap is widening in one direction while narrowing in another: frontier parameter counts keep growing, but sparsity means the active set grows much more slowly — which is why locally-runnable models have closed distance on capability faster than the capacity gap would suggest.
Why a top-tier model couldn't be shipped to your laptop even if someone published it tomorrow — and when a local model is nonetheless the better choice.
- Where the break-even between buying hardware and paying per token actually falls, and which variable moves it most.
- Why local wins the wait-for-the-first-word race while losing the words-per-second one.
- Why "the model is on my disk" is a durability and reproducibility property, not only a privacy one.
Why frontier inference is structurally rack-scale, and how to model the crossover honestly.
- Why the deployment unit for a 670 GB model is a node, and what that implies for consumer availability.
- Why batch economics make hosted tokens cheaper than your own marginal electricity at low volume.
- Why sparsity is closing the capability gap faster than the capacity gap.
One mental model
Ten modules, one chain of cause and effect. If you can walk it in both directions, you can work out almost any AI hardware question from scratch instead of looking it up.
The whole dependency chain, five closed-form estimates, and a capstone that evaluates all of them and names the binding constraint.
Five things you can now work out on the back of an envelope
Five closed forms
| Question | How to answer it | From |
|---|---|---|
| How much arithmetic per word? | Two operations per number that fires | Module 3 |
| How many bytes fetched per word? | Numbers that fire × bytes each | Modules 4, 8 |
| How fast will it write? | Bandwidth ÷ bytes per word | Module 5 — accurate to ~10% |
| Is it waiting or calculating? | Requests at once, vs the machine's break-even | Module 3 |
| Will it even fit? | Model + conversation + working space, vs capacity | Module 5 |
| Question | Expression | From |
|---|---|---|
| FLOPs per token | 2 × N_active | Module 3 |
| Bytes per token | N_active × bytes_per_param | Modules 4, 8 |
| Decode throughput | bandwidth ÷ bytes_per_token | Module 5 — validated to ~10% |
| Regime | batch vs peak_FLOPS ÷ bandwidth | Module 3 (roofline) |
| Footprint | N·b + 2·L·H_kv·d·b·ctx + overhead | Module 5 |
The whole stack, one panel
CapstoneSeven questions that cut through any AI hardware claim
- How many gigabytes? Capacity is binary; it decides what's possible at all.
- How many gigabytes per second? Divide by your model's size for a speed estimate that's usually within 10%.
- That arithmetic figure — at what precision, and does it assume sparsity? Marketing numbers routinely double via sparsity assumptions and quadruple via 4-bit.
- How many requests at once was that benchmark? Throughput at 256 tells you nothing about your one.
- Reading or writing? "Tokens per second" without the phase is meaningless — they differ by orders of magnitude.
- Total or active parameters? For sparse models, one sets your memory requirement and the other sets your speed.
- Sustained or burst? Especially on anything with a battery.
What's moving next
The through-line of 2025–26 has been memory catching up to arithmetic, not arithmetic getting faster. New memory technology roughly doubled bandwidth at the top end; Apple pushed unified memory to about 1.2 TB/s and 512 GB; and on the software side, sparse models and speculative decoding both attack the same target — bytes fetched per word produced. Watch that number. It's the one that's actually been improving, and it's the one your experience is made of.
The interesting movement is all in the memory and packaging layer: HBM4 roughly 2.5×'s per-stack bandwidth (Rubin's ~20 TB/s against Blackwell's 8), unified memory reached 1.2 TB/s at 512 GB, and on the algorithmic side MoE sparsity and speculative decoding both attack bytes-per-emitted-token rather than FLOPs. Logic scaling contributes comparatively little here. If you're picking a specialism, the leverage is in packaging, interconnect and memory architecture — not in making the MACs faster.
Almost every counter-intuitive fact in this field dissolves once you stop thinking of AI as computation and start thinking of it as data movement with some arithmetic attached. Slow local models, idle datacenter chips, rounding making things faster, huge sparse models outrunning small dense ones, a laptop beating a gaming PC — same explanation, every time.
You started not knowing what a parameter was. You can now reason about AI hardware from first principles.
- You can predict a machine's generation speed from its specifications, and say why.
- You can size any model against any machine, including the conversation everyone forgets.
- You can tell which half of a hardware marketing claim is doing the work.
- You can decide local-versus-cloud on the actual constraints rather than on vibes.
A complete mental model of the inference stack from bitcell to rack, with the numbers to back each layer.
- You can place any workload on any machine's roofline and predict achieved utilisation.
- You can size memory footprint including KV, and reason about the spill cliff quantitatively.
- You can explain why the industry's leverage moved from logic to packaging and memory.
- You can read a vendor claim and immediately identify the three things it omitted.
Every term, defined
Every word this course introduces, with the definition attached to it in the text, and a link to the module where it first appears. Built automatically from the pages themselves, so it can't drift out of sync with them.
Sources & as-of dates
Hardware figures rot. Everything below is dated, and anything from the newest generation should be treated as a vendor claim until independent measurement catches up.
Figures gathered in September 2026. Capacity and bandwidth specs are stable once a product ships; benchmark speeds vary with software version, packing format, conversation length and temperature, so treat those as ranges. Where a figure is an estimate or a community measurement rather than a vendor specification, it says so inline.
Apple Silicon
NVIDIA
Google TPU
Memory, energy and process — the engineer track's figures
Mobile
Inference performance
Local models & tooling
Tokenisation & pricing
Built with
Hand-written HTML, CSS and JavaScript — no framework, no build step, no analytics, no network calls beyond two web fonts. Your reading level and your progress are stored in your own browser's local storage and go nowhere else. The interactive panels compute their numbers live from the equations in module 10 rather than from lookup tables, so you can check them against the figures above.
Diagrams come in two deliberate registers: hand-drawn for concepts, spec-sheet-precise for hardware. If it looks like a whiteboard it's an idea; if it looks like a datasheet it's a machine.