How the numbers are made

Every estimate in the calculator comes from one plain TypeScript model, engine.ts, which runs in your browser. This page writes out its formulas, the constants they use and the published measurements the speed constants are fitted to.

Contents
  1. Overview
  2. Model shape
  3. Memory
  4. Decode speed
  5. Prompt processing
  6. Calibration
  7. Fine-tuning
  8. Embedding and reranking
  9. Several models
  10. Cost and energy
  11. Launch commands
  12. Sources
  13. Cite

Overview

Memory is counted part by part: weights, KV cache, activations, runtime overhead and, when used, a speculative drafter. Speed follows from the hardware: generating a token means reading the weights and the KV cache from memory, so decode is limited by memory bandwidth; reading a prompt is a large matrix multiplication, so prompt processing is limited by compute. Fixed costs per step and per layer (kernel launches, scheduling) are added on top.

How close a runtime gets to the hardware's peak depends on the runtime and the GPU, so those efficiencies are fitted to 123 published measurements. The results are estimates. Drivers, kernels, settings and the prompts you send all move real numbers.

Model shape

Each model is described by its Hugging Face config.json: layers L, hidden size h, attention heads nh, KV heads nkv, head size dh, feed-forward size dff, vocabulary V, and the parameter count P from the model's published weights. Hybrid models also give the number of sliding-window layers (window w), linear-attention or state-space layers, and Multi-head Latent Attention (MLA) models give the size of their compressed KV latent.

For a mixture-of-experts (MoE) model with E experts and k active per token, the parameters used per token Pactive come from the model card when published, and otherwise from:

Pactive = P / E × k

Memory

Weights

Weights take their bits per weight b. GGUF figures are whole-file averages, which already include the embeddings. Other quantized formats keep the embeddings and output head (Pemb = V·h, twice when they aren't tied) in 16-bit:

W = (P − Pemb) × b / 8 + 2 × Pemb bytes
FormatBits per weight
FP16 / BF1616
FP88
INT88.1
GGUF Q8_08.5
NVFP66.5
GGUF Q6_K6.56
GGUF Q5_K_M5.7
GGUF Q4_K_M4.85
GGUF Q4_04.54
NVFP44.5
INT4 (bitsandbytes)4.5
EXL24.5
MXFP44.25
AWQ / GPTQ4.25
GGUF Q3_K_M3.91
GGUF Q2_K3

KV cache

Each sequence of s tokens stores keys and values in every attention layer:

KV(s) = [Lfull × s + Lwindow × min(s, w)] × c × β + Lstate × S
c
values per token per layer: 2 × nkv × dh, or the latent size for MLA (576 by default)
β
bytes per value: 2 for FP16/BF16, 1 for FP8 and INT8, 0.5 for INT4
S
the fixed recurrent state of a linear-attention or state-space layer, whatever the length

One copy of the model serves nseq = ⌈users / copies⌉ × batch sequences at once. With prefix caching, the shared share f of the prompt is stored once: KV(s) × (nseq × (1 − f) + f). Tensor parallelism over tp GPUs splits the KV heads, so each GPU keeps ⌈nkv / tp⌉ / nkv of the cache (MLA latents are copied to every GPU). Pipeline parallelism over pp stages divides it by pp.

Activations and runtime overhead

Runtimes process prompts in chunks of C tokens (8,192 for vLLM, 512 for llama.cpp), and keep the logits of every running sequence:

A = [C × (4h + 2dff / tp) × 2 + nseq × V × 4 / tp] / pp

Without fused (flash) attention, llama.cpp, Ollama and Transformers materialize the score matrix of a chunk in FP32, C × s × nh × 4 bytes. Each runtime also holds a fixed amount for its CUDA context, graphs and buffers, plus 0.5 GB when a copy spans several GPUs.

Speculative decoding drafters

A draft model adds its parameters in BF16. Learned drafters are sized from the target model, with one transformer layer counted as 12h² parameters: an EAGLE-3 head is one layer plus a 32K-token output head (12h² + 32,000h), a DFlash drafter about five layers, and multi-token prediction (MTP) one extra layer at the model's own precision. N-gram and suffix lookup add nothing.

Usable memory and verdict

Per GPU, the total is W × (1 − o) / (tp × pp) plus the KV cache, activations, scores, overhead and drafter, where o is the share of weights offloaded to CPU memory (offloading the KV cache keeps 30% of it on the GPU). It is compared with the memory the runtime lets itself use. Apple Silicon can only wire about 75% of unified memory to the GPU, two thirds on machines with 36 GB or less.

RuntimeMemory it usesFixed overheadPrompt chunk
vLLM90%1.5 GB8,192
SGLang88%1.5 GB8,192
TensorRT-LLM90%1.2 GB8,192
llama.cpp100%0.4 GB512
Ollama100%0.5 GB512
Transformers100%0.8 GB4,096
Other90%1 GB4,096

Below 50% of usable memory the setup is comfortable, then moderate up to 75%, high up to 90%, very high up to 100%, and it doesn't fit beyond. The number of users that fit is the memory left after everything but the KV cache, divided by the KV cache of one user, times the number of copies.

Decode speed

Each decode step produces one token for each of the b sequences in flight. Its time is the larger of reading memory and computing, plus communication and fixed costs:

t(b) = max(Wread / (tp × B × η) + b × KVgpu / (B × η), 2Pactive × b / (0.6 × F × tp)) + tcpu + ttp + tpp + tstep + L × tlayer
B
the GPU's memory bandwidth from its spec sheet
η
the share of it the runtime achieves (fitted, see Calibration)
F
dense FP16/BF16 tensor throughput with FP32 accumulate
tstep, tlayer
fixed cost per step and per layer (launches, scheduling); MoE layers add routing and small expert matmuls

Wread is the weights streamed per step. The input embedding table is only looked up, so it isn't streamed when it is separate from the output head. An MoE model always reads its shared weights, plus the experts the batch touches. With b tokens each picking k of E experts, the expected number touched is:

Etouched = E × (1 − (1 − k / E)b)

Weights and KV cache offloaded to the CPU are read at 60 GB/s (dual-channel DDR5), which adds tcpu.

Several GPUs

Tensor parallelism splits every layer across tp GPUs, which then all-reduce activations twice per layer. An all-reduce of x bytes over n GPUs costs a latency term plus the ring algorithm's traffic:

AR(x, n) = λ × (1 + log2n / 2) + 2(n − 1) / n × x / Blink

So ttp = 2L × AR(2bh, tp). Pipeline parallelism passes activations between pp stages: tpp = (pp − 1) × AR(2bh, 2). Tensor parallelism that spans machines uses the network between them.

LinkBandwidth per directionLatency λ
NVLink 5900 GB/s5 µs
NVLink 4450 GB/s6 µs
NVLink 3300 GB/s7 µs
PCIe 564 GB/s15 µs
PCIe 432 GB/s20 µs
InfiniBand NDR50 GB/s15 µs
InfiniBand HDR25 GB/s18 µs
400G Ethernet50 GB/s25 µs
100G Ethernet12.5 GB/s30 µs
10G Ethernet1.25 GB/s60 µs
Thunderbolt 510 GB/s40 µs

Several copies of a model (replicas) each get tp × pp GPUs and split the users between them. Per-user speed is 1 / t(b); total throughput is that speed times the sequences in flight times the copies. Requests per second assume 512 output tokens per request.

Speculative decoding

A drafter proposes k tokens and the model checks them in one step over k + 1 tokens per sequence, so that step is t(b) with b(k + 1) tokens: more compute and, for MoE models, more experts touched. With acceptance rate a per drafted token, a step yields on average (1 − ak+1) / (1 − a) tokens (Leviathan et al.). Drafting takes its own time: each pass reads the drafter and runs its layers, tdraft = passes × (bytes read / (tp × B × η) + layers × tlayer). Draft models, EAGLE-3 heads and MTP make one pass per drafted token, DFlash one pass for the whole block; MTP and DFlash also run the model's output head, which is large for big vocabularies. N-gram and suffix lookup take no GPU time. Verifying costs about 3% more per drafted token (rejection sampling, KV writes):

g = [(1 − ak+1) / (1 − a)] × t(b) / ([t(b, b(k+1)) + tdraft] × (1 + 0.03k))

Measured gains shrink with the batch size faster than this, as kernels don't overlap compute and memory perfectly, so the speedup used is 1 + (g − 1) / (1 + b / 8). vLLM reports an acceptance length (tokens per step); the calculator's acceptance rate is the a that gives the same length. The rates it suggests (from 0.4 for n-gram lookup to 0.85 for MTP) are typical values; yours depend on the model and the prompts.

Prompt processing

Reading an s-token prompt costs 2Pactive FLOPs per token plus attention, which grows with the square of the length:

Fattn = 2 × [Lfull × s² + Lwindow × s × min(s, w)] × nh × dh

Time to first token is the larger of that compute and re-reading the weights once per chunk, plus communication and a fixed cost:

TTFT = max((2Pactives + Fattn) / (F × tp × φ × μ), ⌈s / C⌉ × W / (tp × B × η)) + ttp + t0
φ
1.6 for FP8 weights on GPUs with FP8 tensor cores, 2.4 for NVFP4 and MXFP4 on FP4 GPUs, otherwise 1
μ
the share of peak compute the runtime achieves on prompts (fitted)
t0
scheduling, tokenization and sampling: 15 ms unless fitted

Calibration

The efficiencies η, μ, tlayer and t0 start from typical values per runtime. Where published measurements exist, they are fitted to them by scripts/fit-speed.ts. The fit minimizes the squared log error, so being 2× too fast costs as much as being 2× too slow. It runs first over all GPUs of a runtime, then per GPU class (vendor plus consumer, workstation or datacenter), but only for a class with more GPUs than constants to fit. That matters: on prompts, llama.cpp reaches about 1.2× the catalog's FP16 figure on GeForce cards (its integer kernels beat the half-rate figure GeForce cards are rated at), about 0.5× on NVIDIA workstation cards and 0.15× to 0.3× on datacenter GPUs. Ollama runs llama.cpp and uses its constants.

RuntimeGPUsBandwidth ηPer layerPrompt μFixed t₀
llama.cppAll GPUs92%57 µs61%
llama.cppNVIDIA consumer85%12.5 µs121%
llama.cppNVIDIA workstation82%12.5 µs48%
llama.cppNVIDIA datacenter75%46.9 µs31%
llama.cppAMD datacenter15%
llama.cppAMD consumer77%37.4 µs39%
llama.cppAMD workstation50%
llama.cppApple93%79.5 µs74%
TensorRT-LLMAll GPUs93%50.6 µs72%4.59 ms
vLLMAll GPUs76%50.1 µs
vLLMAMD datacenter58%0.38 µs

Empty cells use the runtime's All GPUs line. Runtimes without measurements here (SGLang, Transformers) keep the starting values:

RuntimeBandwidth ηPer stepPer layerPer MoE layerPrompt μ
vLLM72%0.6 ms4 µs+50 µs45%
SGLang74%0.5 ms4 µs+40 µs45%
TensorRT-LLM78%0.4 ms3 µs+35 µs55%
llama.cpp75%0.5 ms8 µs+50 µs70%
Ollama72%1 ms10 µs+55 µs65%
Transformers50%5 ms60 µs+150 µs30%
Other70%1 ms10 µs+60 µs40%

Accuracy

Typical error is exp(mean |log(predicted / measured)|) − 1, so 10% means predictions are usually within about 10%. The figures below are on the measurements used for the fit. On a GPU left out of the fit, which is what a GPU without measurements gets, decode speed is typically within 10% and llama.cpp prompt processing within 25%.

RuntimeMeasurementBenchmarksGPUsTypical error
vLLMDecode speed766%
TensorRT-LLMDecode speed646%
TensorRT-LLMTime to first token432%
llama.cppDecode speed53488%
llama.cppPrompt processing534817%
All 123 benchmarks, measured and predicted
GPUModelRuntimeMeasurementMeasuredPredictedOff bySource
RTX 5090 (32GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens300292-3%llama.cpp #15013
RTX 5090 (32GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens14,97018,286+22%llama.cpp #15013
RTX PRO 6000 Blackwell (96GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens281286+2%llama.cpp #15013
RTX PRO 6000 Blackwell (96GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens16,61917,655+6%llama.cpp #15013
H100 SXM (80GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens281285+1%llama.cpp #15013
H100 SXM (80GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens11,26322,261+98%llama.cpp #15013
A100 SXM (80GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens201223+11%llama.cpp #15013
A100 SXM (80GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens5,2867,111+35%llama.cpp #15013
RTX 4090 (24GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens189186-2%llama.cpp #15013
RTX 4090 (24GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens14,77114,629-1%llama.cpp #15013
RTX 5080 (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens185178-3%llama.cpp #15013
RTX 5080 (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens9,48810,039+6%llama.cpp #15013
RTX 5070 Ti (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens182168-8%llama.cpp #15013
RTX 5070 Ti (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens8,4207,877-6%llama.cpp #15013
RTX 6000 Ada (48GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens179174-3%llama.cpp #15013
RTX 6000 Ada (48GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens10,57712,800+21%llama.cpp #15013
RTX 3090 Ti (24GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens172186+8%llama.cpp #15013
RTX 3090 Ti (24GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens6,9247,111+3%llama.cpp #15013
RTX PRO 4500 Blackwell (32GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens169164-3%llama.cpp #15013
RTX PRO 4500 Blackwell (32GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens7,2527,111-2%llama.cpp #15013
RTX 3090 (24GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens162175+8%llama.cpp #15013
RTX 3090 (24GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens5,5606,321+14%llama.cpp #15013
L40 (48GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens154127-17%llama.cpp #15013
L40 (48GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens10,0984,163-59%llama.cpp #15013
RTX 4080 SUPER (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens147142-4%llama.cpp #15013
RTX 4080 SUPER (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens9,4399,309-1%llama.cpp #15013
RTX 4080 (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens143139-3%llama.cpp #15013
RTX 4080 (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens9,2068,678-6%llama.cpp #15013
RTX A6000 (48GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens145144-1%llama.cpp #15013
RTX A6000 (48GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens5,6625,505-3%llama.cpp #15013
RTX 3080 (10GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens140146+4%llama.cpp #15013
RTX 3080 (10GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens5,5705,333-4%llama.cpp #15013
RTX PRO 4000 Blackwell (24GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens136128-6%llama.cpp #15013
RTX PRO 4000 Blackwell (24GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens5,6745,333-6%llama.cpp #15013
RTX A5000 (24GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens136144+6%llama.cpp #15013
RTX A5000 (24GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens4,5523,938-13%llama.cpp #15013
V100 (32GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens135131-3%llama.cpp #15013
V100 (32GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens2,9742,860-4%llama.cpp #15013
RTX 4070 Ti SUPER (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens133131-1%llama.cpp #15013
RTX 4070 Ti SUPER (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens7,6127,877+3%llama.cpp #15013
RTX 5070 (12GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens128131+2%llama.cpp #15013
RTX 5070 (12GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens5,7835,505-5%llama.cpp #15013
A40 (48GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens126108-15%llama.cpp #15013
A40 (48GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens5,2563,436-35%llama.cpp #15013
A30 (24GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens132135+2%llama.cpp #15013
A30 (24GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens3,0693,793+24%llama.cpp #15013
RTX 2080 Ti (11GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens109121+11%llama.cpp #15013
RTX 2080 Ti (11GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens3,1082,404-23%llama.cpp #15013
RTX 5060 Ti (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens93.591.0-3%llama.cpp #15013
RTX 5060 Ti (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens4,1964,163-1%llama.cpp #15013
RTX A4000 (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens85.288.5+4%llama.cpp #15013
RTX A4000 (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens2,8082,738-2%llama.cpp #15013
RTX 3060 (12GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens76.974.4-3%llama.cpp #15013
RTX 3060 (12GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens2,4082,226-8%llama.cpp #15013
RTX 4060 Ti (8GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens64.060.3-6%llama.cpp #15013
RTX 4060 Ti (8GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens3,8033,908+3%llama.cpp #15013
RTX 4000 Ada (20GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens61.472.2+18%llama.cpp #15013
RTX 4000 Ada (20GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens3,1723,793+20%llama.cpp #15013
DGX Spark GB10 (128GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens56.755.6-2%llama.cpp #15013
DGX Spark GB10 (128GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens3,6613,556-3%llama.cpp #15013
RTX 2000 Ada (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens50.746.1-9%llama.cpp #15013
RTX 2000 Ada (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens2,2501,707-24%llama.cpp #15013
T4 (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens44.056.1+27%llama.cpp #15013
T4 (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens1,3101,488+14%llama.cpp #15013
Instinct MI300X (192GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens219322+47%llama.cpp #15021
Instinct MI300X (192GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens11,94614,629+22%llama.cpp #15021
RX 7900 XTX (24GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens170146-14%llama.cpp #15021
RX 7900 XTX (24GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens3,8743,507-9%llama.cpp #15021
Instinct MI210 (64GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens130205+58%llama.cpp #15021
Instinct MI210 (64GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens2,5722,048-20%llama.cpp #15021
Radeon PRO W7900 (48GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens127140+10%llama.cpp #15021
Radeon PRO W7900 (48GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens3,4734,491+29%llama.cpp #15021
RX 9070 (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens115106-8%llama.cpp #15021
RX 9070 (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens2,4532,048-16%llama.cpp #15021
RX 7900 XT (20GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens112127+13%llama.cpp #15021
RX 7900 XT (20GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens3,2622,926-10%llama.cpp #15021
Radeon AI PRO R9700 (32GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens98.0113+16%llama.cpp #15021
Radeon AI PRO R9700 (32GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens4,7733,556-26%llama.cpp #15021
RX 7900 GRE (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens97.597.0-1%llama.cpp #15021
RX 7900 GRE (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens1,5992,612+63%llama.cpp #15021
RX 9070 XT (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens97.3106+9%llama.cpp #15021
RX 9070 XT (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens4,9042,753-44%llama.cpp #15021
RX 7800 XT (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens96.0104+8%llama.cpp #15021
RX 7800 XT (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens2,3052,107-9%llama.cpp #15021
RX 9060 XT (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens65.458.2-11%llama.cpp #15021
RX 9060 XT (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens1,4791,450-2%llama.cpp #15021
Ryzen AI Max+ 395 (96GB of 128GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens49.947.5-5%llama.cpp #15021
Ryzen AI Max+ 395 (96GB of 128GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens1,0041,679+67%llama.cpp #15021
RX 7600 XT (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens47.652.9+11%llama.cpp #15021
RX 7600 XT (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens1,1991,280+7%llama.cpp #15021
M1 Ultra (128GB)Llama-2-7b-hf FP16llama.cppDecode speed, 128 tokens47.847.70%llama.cpp #4167
M1 Ultra (128GB)Llama-2-7b-hf FP16llama.cppPrompt processing, 512 tokens1,2941,138-12%llama.cpp #4167
M1 Ultra (128GB)Llama-2-7b-hf Q8_0llama.cppDecode speed, 128 tokens79.179.3+0%llama.cpp #4167
M1 Ultra (128GB)Llama-2-7b-hf Q8_0llama.cppPrompt processing, 512 tokens1,1681,138-3%llama.cpp #4167
M1 Ultra (128GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens114122+7%llama.cpp #4167
M1 Ultra (128GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens1,1801,138-4%llama.cpp #4167
M2 Ultra (192GB)Llama-2-7b-hf FP16llama.cppDecode speed, 128 tokens49.547.7-4%llama.cpp #4167
M2 Ultra (192GB)Llama-2-7b-hf FP16llama.cppPrompt processing, 512 tokens1,6281,488-9%llama.cpp #4167
M2 Ultra (192GB)Llama-2-7b-hf Q8_0llama.cppDecode speed, 128 tokens82.879.3-4%llama.cpp #4167
M2 Ultra (192GB)Llama-2-7b-hf Q8_0llama.cppPrompt processing, 512 tokens1,4871,488+0%llama.cpp #4167
M2 Ultra (192GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens125122-3%llama.cpp #4167
M2 Ultra (192GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens1,4891,4880%llama.cpp #4167
M5 (16GB)Llama-2-7b-hf Q8_0llama.cppDecode speed, 128 tokens18.418.8+2%llama.cpp #4167
M5 (16GB)Llama-2-7b-hf Q8_0llama.cppPrompt processing, 512 tokens715819+15%llama.cpp #4167
M5 (16GB)Llama-2-7b-hf Q4_0llama.cppDecode speed, 128 tokens31.933.3+4%llama.cpp #4167
M5 (16GB)Llama-2-7b-hf Q4_0llama.cppPrompt processing, 512 tokens723819+13%llama.cpp #4167
H100 SXM (80GB)Llama-3.1-8B-Instruct FP8TensorRT-LLMDecode speed, 1,500 tokens221208-6%NVIDIA NIM
H100 SXM (80GB)Llama-3.1-8B-Instruct FP8TensorRT-LLMTime to first token, 1,000 tokens19.019.00%NVIDIA NIM
H100 SXM (80GB)Llama-3.1-8B-Instruct FP16TensorRT-LLMDecode speed, 1,500 tokens153145-6%NVIDIA NIM
H100 SXM (80GB)Llama-3.1-8B-Instruct FP16TensorRT-LLMTime to first token, 1,000 tokens27.427.0-1%NVIDIA NIM
H200 SXM (141GB)Llama-3.1-8B-Instruct FP8TensorRT-LLMDecode speed, 1,500 tokens236252+7%NVIDIA NIM
H200 SXM (141GB)Llama-3.1-8B-Instruct FP8TensorRT-LLMTime to first token, 1,000 tokens19.819.0-4%NVIDIA NIM
L40S (48GB)Llama-3.1-8B-Instruct FP8TensorRT-LLMDecode speed, 1,500 tokens71.678.0+9%NVIDIA NIM
L40S (48GB)Llama-3.1-8B-Instruct FP8TensorRT-LLMTime to first token, 1,000 tokens44.644.0-1%NVIDIA NIM
H200 SXM (141GB)Llama-3.3-70B-Instruct FP8vLLMDecode speed, 1,500 tokens, 4 at once46.540.2-14%InferenceX
B200 (180GB)Llama-3.3-70B-Instruct FP8vLLMDecode speed, 1,500 tokens, 4 at once61.259.6-3%InferenceX
Instinct MI300X (192GB)Llama-3.3-70B-Instruct FP8vLLMDecode speed, 1,500 tokens, 4 at once38.440.7+6%InferenceX
Instinct MI325X (256GB)Llama-3.3-70B-Instruct FP8vLLMDecode speed, 1,500 tokens, 4 at once48.045.9-4%InferenceX
Instinct MI355X (288GB)Llama-3.3-70B-Instruct FP8vLLMDecode speed, 1,500 tokens, 4 at once61.660.6-2%InferenceX
H200 SXM (141GB)Llama-3.3-70B-Instruct FP8TensorRT-LLMDecode speed, 1,500 tokens, 4 at once49.747.8-4%InferenceX
B200 (180GB)Llama-3.3-70B-Instruct FP8TensorRT-LLMDecode speed, 1,500 tokens, 4 at once68.569.8+2%InferenceX
2× RTX PRO 6000 Blackwell (96GB)Qwen3.8-Flash-Next NVFP4vLLMDecode speed, 1,750 tokens, 1 at once, MTP 3 tokens (2.54 per step)170178+5%Contributed run
2× RTX PRO 6000 Blackwell (96GB)Qwen3.8-Flash-Next NVFP4vLLMDecode speed, 1,750 tokens, 12 at once, MTP 3 tokens (2.28 per step)56.861.0+7%Contributed run

Known gaps: llama.cpp prompt processing on datacenter GPUs varies more than one constant per class can follow (the H100 is predicted about 2× too fast, the L40 about 2.4× too slow), very large MoE models are on the optimistic side, and speeds for SGLang and Transformers are not checked against measurements yet.

Measurements from more hardware make the fit better. The benchmark script measures a running vLLM server or a GGUF file with llama-bench and writes a report to paste into a benchmark issue.

Fine-tuning

Memory

Full fine-tuning keeps the weights at the training precision (2 bytes for BF16, 4 for FP32, 1 for FP8), gradients of at least 2 bytes, an FP32 master copy (4 bytes) in mixed precision, and Adam's two moments (8 bytes, 2 with an 8-bit optimizer, 4 when the trainer stays in pure BF16). ZeRO stage 1 splits the optimizer states across GPUs, stage 2 also the gradients, stage 3 also the weights.

LoRA freezes the model in BF16 (QLoRA stores it in 4-bit NF4 with double quantization, 0.516 bytes per parameter, and keeps embeddings in 16-bit) and trains rank-r adapters on the attention (q, k, v, o) and MLP (gate, up, down) projections of every layer:

PLoRA = L × r × [(h + q) + 2(h + kv) + (q + h) + 2(h + dff) + (dff + h)]

with q = nhdh and kv = nkvdh. Adapters take 2 bytes per parameter, their gradients 2, and their optimizer states 12 (4 for the FP32 copy and 8 for Adam, or 2 with an 8-bit optimizer).

Activations kept for the backward pass follow Korthikanti et al.: 34 × s × m × h bytes per layer for micro-batch m, plus 5 × nh × s² × m without flash attention. Gradient checkpointing keeps only each layer's input (2smh bytes) and recomputes one layer at a time; Unsloth also offloads those checkpoints, keeping about 30% on the GPU. Logits take 6 bytes per vocabulary entry per token, 0.5 with chunked loss (Unsloth, torchtune). The trainer gets 95% of GPU memory plus 1 GB of overhead.

Speed

tokens/s = NGPU × F × MFU × φ × q / (κ × Pactive)

κ is 6 FLOPs per parameter per token for full fine-tuning (forward 2, backward 4) and 4 for LoRA, which skips weight gradients, plus 2 when checkpointing recomputes the forward pass. φ is 1.4 for FP8 training on FP8 GPUs and q is 0.75 for QLoRA's dequantization. Training time is samples × epochs × sequence length divided by tokens per second.

TrainerModel FLOPs utilization (MFU)
Unsloth50%
torchtune42%
Transformers Trainer35%
Other35%

Embedding and reranking

Encoders read each input once and keep no KV cache. Memory is the weights, activations of the batch (batch × s × (4h + 2dff) × 2 bytes) and 0.75 GB of overhead, out of 92% of GPU memory. A pass over n tokens takes:

t = max(n × (2P + 4Lsh) / (F × MFU), W / (0.7 × B)) + 2 ms

with an MFU of 25% under 200M parameters, 40% under 2B and 50% above, and 85% scaling efficiency across GPUs.

Several models

The Advanced view places several models on a pool of machines with a greedy plan that is simple to follow rather than optimal. Pinned models are placed first, then the largest. Each model takes the fewest GPUs that fit and meet its targets (minimum speed per user, maximum time to first token), adding tensor parallelism or copies when one GPU group is too slow; a model spans identical machines with pipeline parallelism only when no single machine works. Automatic precision starts every model at the highest quality and steps all of them down together while that places more models or meets more targets, then lets each step back up if nothing gets worse. Idle GPUs end up as tensor parallelism or extra copies for the model that gains the most speed per user. Every placement is scored with the same engine.

Find hardware runs the current model on every GPU of the catalog at full, 8-bit and 4-bit precision; Find models runs every catalog model on your hardware.

Cost and energy

power = TDP × NGPU × load

Load is 75% for inference, 90% for training and 60% for embedding. Energy per day is power × 24 h; emissions are that energy times the grid's carbon intensity (380 g CO₂ per kWh unless you change it); electricity costs $0.15 per kWh unless you change it. Cloud rental is a rough on-demand price per GPU-hour times the GPUs, over 720 hours a month.

Launch commands

The commands under Run it are built from the same setup: tensor and pipeline parallelism, context length, users, precision, KV cache format, speculative decoding, offloading and, for several copies, one process per copy with its own GPUs and port. They cover vLLM, SGLang, TensorRT-LLM, llama.cpp, Ollama, Transformers and Text Embeddings Inference, and Unsloth, TRL and torchtune for fine-tuning. Flags follow each project's documentation; check them against the version you install.

Sources

Data

Methods

Related work on predicting LLM speed

Cite

If the calculator helps your work, please cite it:

Marius Brouty. VRAM Calculator: memory and speed estimates for LLM inference and fine-tuning. 2026. github.com/Marius-brt/VRAM-Calculator

@software{brouty_vram_calculator_2026,
  author = {Brouty, Marius},
  title  = {VRAM Calculator: memory and speed estimates for LLM inference and fine-tuning},
  year   = {2026},
  url    = {https://github.com/Marius-brt/VRAM-Calculator}
}