The GPU-Seconds Behind One Generated Image
14 min read · updated August 4, 2026
One 1024×1024 image at 30 steps with guidance, from a two-billion-parameter backbone, is about 1.3 petaFLOPs of arithmetic. At a stated GPU throughput and a stated utilisation that is roughly 8.2 GPU-seconds, about 0.6 of a US cent of rented compute, and around 1.9 watt-hours. Every one of those numbers is derived below from twelve assumptions you can change.
The short answer
Generation cost is the product of four things: how many times the network runs, how big the network is, how many tokens it processes, and how fast your hardware executes arithmetic. The first three are exactly calculable. The fourth is a hardware specification multiplied by a utilisation figure that has to be measured, and it is the only soft number in the chain.
Because the arithmetic is transparent, a change in any input propagates predictably: steps are linear, guidance is a factor of two, model size is nearly linear, and resolution is somewhere between linear and quadratic in a way this page pins down exactly.
The assumptions, numbered
Every figure on this page depends on these and nothing else. Change one and the arithmetic below still works.
A1 Latent diffusion, autoencoder downsample factor f = 8
A2 Output resolution 1024 × 1024
A3 Transformer backbone, patch size 2 on the latent
A4 Backbone width d = 2,048
A5 Backbone depth L = 40 layers
A6 Parameters, from A4 and A5: P ≈ 12 · L · d²
12 × 40 × 2,048² = 2.01 × 10^9 (about 2B)
A7 Sampling steps S = 30
A8 Classifier-free guidance ON 2 passes per step
A9 Dense FLOPs per pass ≈ 2 · P · N
A10 Attention FLOPs per pass ≈ 4 · L · N² · d
A11 GPU dense throughput, bf16 400 TFLOP/s ← substitute yours
A12 Achieved utilisation of that peak 40% ← measure yours
Deliberately excluded, and why:
• the text encoder — one short pass, negligible against 60 backbone passes
• the VAE decode — one pass, single-digit percent for typical step counts,
but NOT negligible at 4 steps; measure it if you run a distilled model
• data transfer, scheduling and framework overhead — real, and part of what
A12 is forA6 is the standard parameter count for a transformer block: roughly 4d² in the attention projections and 8d² in a four-times-expanded MLP. A9 is the same two-FLOPs-per-parameter-per-token rule used for language model prefill. A10 counts the two matrix products inside attention that are quadratic in sequence length.
FLOPs for one forward pass
Token count, from A1, A2 and A3:
latent grid = 1024 / 8 = 128 × 128
tokens N = (128 / 2) × (128 / 2) = 64 × 64 = 4,096
Dense term (A9):
2 × P × N
= 2 × 2.01×10^9 × 4,096
= 1.649 × 10^13 = 16.49 TFLOP
Attention term (A10):
4 × L × N² × d
= 4 × 40 × 4,096² × 2,048
= 160 × 16,777,216 × 2,048
= 5.50 × 10^12 = 5.50 TFLOP
Total per forward pass:
16.49 + 5.50 = 21.99 TFLOP ≈ 22 TFLOP
Attention is 25% of the work at this resolution. Remember that number —
it is the one that changes most as resolution moves.FLOPs for one image
Passes per image (A7, A8):
30 steps × 2 passes = 60 forward passes
Total arithmetic:
60 × 22.0 TFLOP = 1,319 TFLOP = 1.32 PFLOP
For comparison, using the standard 2·P·tokens rule for a language model:
a 70B model answering with 500 output tokens does about
2 × 70×10^9 × 500 = 7.0 × 10^13 = 70 TFLOP
So one 1024² image at 30 guided steps is roughly 19 times the arithmetic
of a 500-token answer from a 70B language model. Images are not cheap
because they are one request.From FLOPs to GPU-seconds
Effective throughput (A11, A12):
400 TFLOP/s × 0.40 = 160 TFLOP/s
GPU-seconds per image:
1,319 TFLOP / 160 TFLOP/s = 8.24 GPU-seconds
Why A12 is 40% rather than something higher. At batch size 1 a diffusion
backbone is latency-bound: each of the 60 passes is a dependent step, the
kernels are not large enough to keep every unit busy, and there is
per-step scheduling overhead. Well-optimised single-image inference in
the 30-50% band is a realistic expectation, and batching raises it
substantially — see the batching lever below.
The honest status of this number: A11 comes from a specification sheet
and A12 must be measured. Everything above them is arithmetic. If your
measured time differs from 8.24 s, A12 is almost certainly where the
difference is, and the script at the end of this page tells you what
yours actually is.Resolution: why 4× the pixels is 7× the cost
This is the result worth taking away, because it contradicts the intuition that cost tracks pixel count.
Same model (A4-A6), varying only the output resolution. N = (side / 8 / 2)² output N dense TFLOP attn TFLOP total attn share vs 1024² --------------------------------------------------------------------------- 512² 1,024 4.12 0.34 4.46 7.7% 0.20× 1024² 4,096 16.49 5.50 21.99 25.0% 1.00× 1536² 9,216 37.10 27.83 64.93 42.9% 2.95× 2048² 16,384 65.96 87.96 153.92 57.1% 7.00× Read the last two columns together. Going from 1024² to 2048² is 4× the pixels but 7× the arithmetic, because the attention term goes up 16× while the dense term goes up 4× — and attention crosses over from a quarter of the work to well over half. Going the other way is the same effect in your favour: 512² is a quarter of the pixels and one fifth of the cost, not one quarter. GPU-seconds per image at 30 steps with guidance, at 160 TFLOP/s: 512² : 60 × 4.46 / 160 = 1.67 s 1024² : 60 × 21.99 / 160 = 8.24 s 1536² : 60 × 64.93 / 160 = 24.35 s 2048² : 60 × 153.92 / 160 = 57.72 s
The practical consequence is the two-stage pipeline: generate at 1024 and refine at 2048 with a low-strength pass, rather than generating at 2048 directly. That trade is worked out in image-to-image, and the reason a direct high-resolution generation also produces duplicated subjects is in aspect ratio and training buckets.
Every lever, with its multiplier
| Lever | Description |
|---|---|
| steps | Exactly linear. 15 steps is half the cost of 30. Where the quality curve flattens for your model is measurable with the harness in the steps page; it is not a universal number. |
| guidance on or off | Exactly 2× or 1×. The largest single-switch saving available. A guidance-distilled checkpoint halves cost per image with no change to steps. |
| resolution | Between linear and quadratic in pixel count. From the table above: 0.20× at 512², 2.95× at 1536², 7.00× at 2048², relative to 1024². |
| model size | Linear in the dense term only. Doubling P from 2B to 4B takes the 1024² per-pass cost from 22.0 to 38.5 TFLOP — a factor of 1.75, not 2, because the attention term does not move with width alone. |
| guidance interval | Applying guidance on 60% of steps rather than all of them gives 1.6 passes per step instead of 2 — a 20% saving. The mechanism is in the guidance page. |
| step distillation | A checkpoint documented for 4 or 8 steps with guidance baked in. At 8 steps and one pass: 8 × 22.0 = 176 TFLOP, or 1.10 GPU-seconds. That is 7.5× cheaper than the 30-step guided baseline. Watch the VAE decode, which is now a visible share of the total. |
| batching | Does not change FLOPs. It changes A12. If batching raises achieved utilisation from 40% to 70%, cost per image falls by 43% with no change to the image. This is the main reason a provider's cost per image is below what you measure at batch 1. |
| adapters (LoRA, control branches) | An unmerged LoRA adds a few per cent. A control branch adds roughly the encoder share of a pass, at every step it is active — the derivations are in the LoRA and structural conditioning pages. |
The span between the cheapest and dearest configuration of ONE model:
cheapest 1024², 8 distilled steps, no guidance
8 × 1 × 22.0 TFLOP = 176 TFLOP → 1.10 GPU-s
dearest 2048², 30 steps, guidance on
60 × 153.92 TFLOP = 9,235 TFLOP → 57.72 GPU-s
ratio: 52×
Same weights, same prompt, same hardware. Fifty-two times the compute.Cents and watt-hours
A13 GPU rental $2.50 per GPU-hour ← substitute the current rate
A14 Board power 700 W
A15 Datacentre PUE 1.2
Cost per GPU-second: $2.50 / 3,600 = $0.000694
512², 30 steps, guided : 1.67 s → $0.0012
1024², 30 steps, guided : 8.24 s → $0.0057 (0.57 cents)
1536², 30 steps, guided : 24.35 s → $0.0169
2048², 30 steps, guided : 57.72 s → $0.0401
1024², 8 steps, no CFG : 1.10 s → $0.0008
Energy for the 1024² baseline:
700 W × 8.24 s = 5,768 joules
5,768 / 3,600 = 1.60 Wh at the board
× 1.2 (A15) = 1.92 Wh delivered
For scale, that is roughly the energy a 10 W LED bulb uses in about
eleven minutes. The figure is derived, not measured, and it excludes
everything that is not the GPU — networking, storage, the CPU host, and
idle capacity held for burst. The wider question of AI energy figures and
where the circulating numbers come from is covered in the energy page.The gap between this derived cost and what an image generation API charges is not margin alone. It includes batching efficiency working in the provider’s favour, idle capacity working against them, safety filtering, storage, egress and support. What providers actually bill for images, and how the units differ between them, is in image token pricing; the general anatomy of a bill is in how LLM pricing works; and the rental rate in A13 should be checked against current GPU cloud pricing. The energy figure sits alongside the sourced numbers in the energy and water cost of inference.
Where this derivation is wrong, and by how much
A derivation is only useful if you know its error bars. These are the terms it omits or approximates, with an honest estimate of the direction and rough size of each. Taken together they say the FLOP figure is good to within perhaps twenty per cent for a model matching the assumptions, and that the GPU-second figure is only as good as your value for A12.
| Omission or approximation | Description |
|---|---|
| the VAE decode | Excluded entirely. One convolutional pass at full pixel resolution. Small against 60 backbone passes — low single-digit per cent at 30 steps — but at 4 steps it can approach a quarter of the total. Direction: this page underestimates, and underestimates most for distilled models. |
| the text encoder | Excluded. One short sequence through a comparatively small model, once per generation. Well under one per cent at any realistic step count. Direction: underestimates, negligibly. |
| normalisation, activations, elementwise work | Excluded from A9. These are memory-bound rather than FLOP-bound, so they cost time without contributing to the FLOP count — which is precisely one of the things A12 absorbs. Direction: makes the derived FLOPs look cheaper than the observed time. |
| the 12·L·d² parameter estimate | A standard approximation. Real architectures add embeddings, timestep conditioning, adaptive normalisation parameters and cross-attention to the text. Direction: underestimates P, typically by a few per cent to fifteen. |
| attention counted as 4·L·N²·d | Counts the two quadratic matrix products and ignores the softmax and the scaling. Correct to first order. Also assumes full self-attention: a model with windowed or factorised attention pays less, and this page would overestimate it. |
| A12 as a single constant | The largest source of error by a wide margin. Utilisation is not constant across resolutions — the attention-heavy regime at 2048² has a different efficiency profile from the dense-heavy regime at 512² — so one figure across the whole table is a simplification. This is the number to measure rather than to trust. |
| no cold start, no queueing, no idle | The figures are steady-state compute for one image on a busy GPU. A production service pays for capacity it is not using, and that is frequently the larger number. Direction: underestimates real cost per image, potentially by a lot at low utilisation. |
The useful way to hold all of that: the FLOP arithmetic is solid and the relative multipliers — steps, guidance, resolution, model size — are the reliable output of this page. Those ratios do not depend on A11 or A12 at all, which is why the 7× resolution result is trustworthy even if the 8.24-second figure is not yours. Use the ratios for decisions and measure the absolute number.
Measuring your own
The derivation gives you a number. This gives you yours, and the ratio between the two is your actual utilisation, which is the only input above that cannot be looked up.
# gpu_seconds.py — measure per-pass time and back out achieved utilisation.
# Requires: diffusers, torch. Pipeline and argument names should be checked
# against your installed version.
import time, torch
from diffusers import DiffusionPipeline
MODEL = "<your checkpoint>"
PROMPT = "a lighthouse on a rocky shore at dusk"
STEPS = 30
CFG = 5.0 # > 1 means two passes per step
SIDE = 1024
# ---- your model's numbers; read them from the config, do not guess -------
P_PARAMS = 2.01e9 # backbone parameters
L_LAYERS = 40
D_WIDTH = 2048
PATCH = 2
VAE_F = 8
PEAK_TFLOPS = 400.0 # your GPU's dense bf16 spec
pipe = DiffusionPipeline.from_pretrained(MODEL, torch_dtype=torch.float16).to("cuda")
def timed(steps):
g = torch.Generator(device="cpu").manual_seed(0)
torch.cuda.synchronize(); t0 = time.perf_counter()
pipe(PROMPT, num_inference_steps=steps, guidance_scale=CFG,
height=SIDE, width=SIDE, generator=g)
torch.cuda.synchronize(); return time.perf_counter() - t0
timed(4) # warm up; discard
t_long, t_short = timed(STEPS), timed(STEPS // 3)
# Two step counts let you separate fixed overhead from per-step cost.
per_step = (t_long - t_short) / (STEPS - STEPS // 3)
overhead = t_long - per_step * STEPS
passes_per_step = 2 if CFG > 1.0 else 1
N = (SIDE // VAE_F // PATCH) ** 2
dense = 2 * P_PARAMS * N
attn = 4 * L_LAYERS * (N ** 2) * D_WIDTH
per_pass_flops = dense + attn
achieved = (per_pass_flops * passes_per_step / per_step) / 1e12
print(f"total for {STEPS} steps : {t_long:8.3f} s")
print(f"fixed overhead : {overhead:8.3f} s (encode + decode + setup)")
print(f"per step : {per_step*1000:8.1f} ms")
print(f"predicted TFLOP/pass : {per_pass_flops/1e12:8.2f}")
print(f"achieved TFLOP/s : {achieved:8.1f}")
print(f"utilisation of peak : {100*achieved/PEAK_TFLOPS:8.1f} %")
# The overhead line is worth reading on its own. If it is a large share of
# a low-step run, the VAE decode is your bottleneck rather than the
# denoiser, and cutting steps further will not help.Two things to do with the output. Put your measured utilisation into A12 and the rest of this page becomes a cost model for your setup. And compare the overhead line against the per-step cost: at 30 steps it should be small, and at 4 steps it may well dominate, which changes which lever is worth pulling.