Topic 2
Measuring decode and prefill on a roofline
To judge a measurement, you need the ceiling it is up against. We measured two on each device: a large memory copy (the most bytes per second it reached) and a large matrix multiply (the most operations per second). Apple publishes 153 GB/s of memory bandwidth for the M5; our best copy reached 122.3 GB/s on the CPU and 129.6 GB/s on the GPU.
A roofline draws both ceilings on one chart. Work with few operations per byte sits under the sloped roof (bandwidth); work with many sits under the flat roof (compute). The roofs meet at the ridge: 16 operations per byte on the CPU, 27 on the GPU.
Decode is on the bandwidth side. At batch 1, a step took 9.1 ms on the CPU: 507 MB in 9.1 ms is 55.7 GB/s, 46% of the measured copy ceiling. The GPU did 6.3 ms, 80.5 GB/s, 62%. Both sit at about 0.5 operations per byte, far left of either ridge. We did not break down where the rest of the time goes.
Prefill is on the compute side. A 960-token prompt took 239.4 ms on the CPU: about 998 billion operations per second, 51% of the matrix-multiply ceiling, at about 480 operations per byte. That is 0.25 ms per prompt token against 9.1 ms per decode step.
AI Engineering calls the bandwidth share MBU (model bandwidth utilization): parameters × bytes per parameter × tokens/s, over the peak bandwidth. Its example: a 7B model in 16-bit at 100 tokens/s uses 700 GB/s, 70% of an A100-80GB's 2 TB/s. The formula assumes one sequence; with a batch, the weights are read once for all of them.
Quick check