Multi-GPU LLM Calculator: VRAM Split and RAM Offload
Compare 2×3090, RTX 5090 and Apple silicon. Plan layers, tensor parallelism or MoE experts in RAM, with per-device memory, prefill/decode estimates and cited benchmarks.
Plan a local LLM across up to four GPUs and system RAM. Compare two RTX 3090s, one RTX 5090, Apple silicon and a CPU baseline with the same model and context. This multi GPU LLM calculator is for engineers, students and builders choosing hardware or avoiding out-of-memory errors.
Choose Model → compare hardware for one model on several configurations. Choose My hardware → scan models and quants for the catalogue at FP16, Q8_0 and Q4_0. Shared records follow the VRAM calculator's (#770) schema and pinned Hugging Face revisions. Custom rows support missing hardware and models.
Select each GPU separately, then set prompt/output tokens, cache precision, runtime and model format. Capacity includes assigned weights, allocated KV/state, explicit reserves and headroom. Unified memory is one shared pool with an editable usable share. For a measured weight allocation, enable the size override: it scales both storage and weight traffic while excluding unused checkpoint components from ordinary text execution.
Layer splitting places contiguous decoder blocks on devices and leaves a CPU prefix. A single sequence visits devices serially. Tensor parallelism shards each GPU block and adds collective traffic and latency. MoE offload to RAM stores routed experts on the CPU; only distinct experts touched by the batch contribute traffic, capped by each assigned expert pool. Shared dense weights are read once per batch.
The 2x3090 vs 5090 LLM result depends on capacity as well as bandwidth. Avoiding CPU blocks can outweigh a faster single GPU. DDR bandwidth, negotiated PCIe lanes and actual peer access matter. NVLink is rejected for incompatible participating cards.
Read three separate verdicts: memory fit, runtime support, and measured evidence. Decode is per-sequence final-context speed; prefill is aggregate. ≤ means a bandwidth ceiling; — means unavailable. Q4_0 prefill profiles are historical calibrations; other precisions/runtimes need effective compute inputs. Conservative cache reservation does not imply scanning outside a sliding attention window.
The llama.cpp tensor split and command planner follows a pinned loader convention: the output projection accompanies offloaded blocks, while discrete-device input embeddings remain in host RAM. Verify startup logs. The LLM offload calculator does not simulate swapping, exact per-layer tensor sizes, thermals, kernel scheduling or output quality. Benchmark before buying hardware.
Cards use compact source IDs and vertical scrolling. Full original links follow; dates, builds and conditions remain in benchmark provenance and Method.
Hardware: H1 RTX 4090 desktop (https://www.pny.com/file%20library/company/support/product%20brochures/geforce%20graphics/english/xlr8-geforce-rtx-4090-epic-x-oc-tf-b.pdf) · H2 RTX 4090 laptop (Dell 7680) (https://www.delltechnologies.com/asset/en-us/products/workstations/technical-support/precision-7680-technical-guidebook.pdf) · H3 RX 7900 XTX desktop (https://www.sapphiretech.com/en/consumer/nitro-radeon-rx-7900-xtx-vaporx-24g-gddr6) · H4 M2 Ultra 76-core / 64 GiB (https://support.apple.com/en-us/111835) · H5 M4 mini 10-core / 24 GiB (https://support.apple.com/en-us/121555) · H6 Ryzen 9950X / 2-channel DDR5 (https://www.amd.com/en/products/processors/desktops/ryzen/9000-series/amd-ryzen-9-9950x.html) · H7 RTX 3090 desktop (https://www.pny.com/geforce-rtx-3090-xlr8-gaming-epic-x-rgb-triple-fan-m?iscommercial=true) · H8 RTX 5090 desktop (https://www.pny.com/en-eu/geforce-rtx-5090-models?isCommercial=true&sku=VCG509032TFXPB1) · H9 M4 Max 40-core / 128 GiB (https://support.apple.com/en-us/122211) · H10 M3 Ultra 80-core / 256 GiB (https://support.apple.com/en-us/122211).
Models: M1 Llama 2 7B (https://huggingface.co/NousResearch/Llama-2-7b-hf/blob/8efe6c9b93655b934e27bd9981e3ec13e55aee9d/config.json) · M2 Llama 3.1 8B (https://huggingface.co/NousResearch/Meta-Llama-3.1-8B-Instruct/blob/d10aef7999a2b5ba950ab3974312feeedbfe0b77/config.json) · M3 Qwen2.5 7B (https://huggingface.co/Qwen/Qwen2.5-7B-Instruct/blob/a09a35458c702b33eeacc393d103063234e8bc28/config.json) · M4 Qwen3 30B A3B (https://huggingface.co/Qwen/Qwen3-30B-A3B/blob/ad44e777bcd18fa416d9da3bd8f70d33ebb85d39/config.json) · M5 DeepSeek V2 Lite (https://huggingface.co/deepseek-ai/DeepSeek-V2-Lite/blob/604d5664dddd88a0433dbae533b7fe9472482de0/config.json) · M6 Mistral 7B v0.1 (https://huggingface.co/mistralai/Mistral-7B-v0.1/blob/27d67f1b5f57dc0953326b2601d68371d40ea8da/config.json) · M7 Qwen3.5 4B hybrid (https://huggingface.co/Qwen/Qwen3.5-4B/blob/851bf6e806efd8d0a36b00ddf55e13ccb7b8cd0a/config.json) · M8 Llama 3.3 70B (https://huggingface.co/unsloth/Llama-3.3-70B-Instruct/blob/99cd0d2c829e92a67c844f9144c2509632e5c87f/config.json) · M9 Qwen2.5 32B (https://huggingface.co/Qwen/Qwen2.5-32B-Instruct/blob/5ede1c97bbab6ce5cda5812749b4c0bdf79b18dd/config.json).
Measured runs: R1 M2 Ultra 76-core metal (https://github.com/ggml-org/llama.cpp/discussions/4167) · R2 RTX 4090 desktop cuda (https://github.com/ggml-org/llama.cpp/discussions/15013#discussioncomment-14016393) · R3 RX 7900 XTX desktop vulkan (https://github.com/ggml-org/llama.cpp/discussions/10879#discussioncomment-18386832) · R4 RX 7900 XTX desktop rocm (https://github.com/ggml-org/llama.cpp/discussions/15021#discussioncomment-18388777) · R5 RTX 3090 desktop cuda (https://github.com/ggml-org/llama.cpp/discussions/15013#discussioncomment-13960712) · R6 RTX 5090 desktop cuda (https://github.com/ggml-org/llama.cpp/discussions/15013) · R7 M4 Max 40-core metal (https://github.com/ggml-org/llama.cpp/discussions/4167) · R8 M3 Ultra 80-core metal (https://github.com/ggml-org/llama.cpp/discussions/4167). These are Llama-2 7B Q4_0 pp512/tg128 references, not measurements of every model or split.
How it is calculated
Memory placement
Weights use the pinned Hugging Face safetensors parameter count and packed bytes per value: FP16 = 2; Q4_0 = 18/32; Q8_0 = 34/32 (GGML block definitions, s19). Other 4/8-bit formats use editable metadata overhead. An actual loaded tensor allocation replaces the estimated stored bytes. Effective bytes/parameter = overridden bytes ÷ retained parameters; the same density scales executed dense, routed-expert and output weight traffic. Unused vision/MTP tensors occupy memory but have no ordinary text traffic. An override alone cannot identify unequal tensor precisions; allocation among components is proportional to their parameter counts.
For full attention, KV bytes are . GQA uses KV heads, not query heads. Compressed MLA uses the stored latent + rotary dimensions; expanded layout uses the ordinary per-head tensors. Sliding layers retain min(context, window) only in optimized allocation. Hybrid F/S/R order assigns full attention, sliding attention and fixed recurrent state to the correct contiguous blocks. The Qwen3.5 state count follows the shared #770 tensor-dimension derivation.
Each device requires headroom × (weights + KV/state) + runtime reserve + draft allocation. System RAM holds CPU weights/cache, optional extra model copy and host reserve. Apple/CPU capacity is installed memory × usable share, one pool only. Automatic layer allocation fills later device slots first and spills a contiguous prefix into CPU RAM. Input embeddings, final projection/norm, non-executed auxiliaries and decoder-block weights are separate pools. Vocabulary × hidden size and tie_word_embeddings come from each pinned config; a tied input/output matrix is counted once in the output pool. Remaining block weight mass is approximated as uniform. Input lookup reads only touched rows. Exact quantized tensor sizes and allocator layout still require runtime logs.
Decode and prefill
For a serial layer split, . Tensor mode replaces the GPU sum with the slowest concurrent shard. CPU bandwidth is channels × transfers/s × 8 bytes × efficiency; DDR5 subchannels are not counted twice. CPU experts execute on CPU, rather than streaming complete expert weights over PCIe every token. For batch tokens T, each assigned routed-expert pool reads min(assigned storage, assigned active-expert bytes × T). CPU and GPU fractions are capped independently. Shared dense block weights and the output matrix are read once per batch, not once per sequence; compute remains proportional to executed tokens. Routed expert pools are derived from pinned config dimensions; shared experts belong to the dense pool. Prefill uses T = batch × prompt tokens.
Link time is bytes / sustained one-way bandwidth + message count × latency. Tensor mode assumes two reductions per GPU layer and a ring-equivalent per-rank traffic factor . Layer mode transfers hidden activations across device boundaries. GPU-to-GPU host staging pays two serial PCIe legs. CPU-to-GPU layer/expert activations use a separate one-leg PCIe path, even when the GPUs communicate over NVLink. This is a transparent topology approximation, not a collective implementation simulator.
Prefill includes operations and full/sliding attention pairs. Historical Q4_0 profiles infer effective operations/s as 2 × 6.738B × original measured pp512; scaling to another architecture, precision or backend is an extrapolation. Profiles apply only to llama.cpp Q4_0. Other precisions/runtimes require manual or custom-row effective compute; the model scan otherwise shows a bandwidth ceiling and leaves prefill blank. Manual or custom-row effective compute overrides are available. Unknown compute gives a decode bandwidth ceiling and no prefill prediction. Cache traffic uses the active sliding window independently of reserved capacity. MLA access uses the selected compressed/expanded tensor layout; recurrent state is read and written once per iteration. Decode is per sequence at final context; prefill is aggregate across sequences. Net speculative gain affects decode only; energy = assumed whole-system watts / aggregate decode tokens/s.
The benchmark table compares the bandwidth model at the midpoint (64 tokens) of a reference tg128 run with its measured rate. It fixes batch 1, Q4_0 and FP16 KV. Prefill profiles are calibrated from these same measurements, so prefill agreement is not independent validation. The nearest reference remains separate from the user's split verdict.
Pinned llama.cpp placement convention
The loader at 961c376a2daa42220ec09663b9bde32c5fba1f70 (https://github.com/ggml-org/llama.cpp/blob/961c376a2daa42220ec09663b9bde32c5fba1f70/src/llama-model.cpp) (26 October 2026) uses i_gpu_start = max(n_layer_all + 1 − n_gpu_layers, 0). Thus N offloaded decoder blocks require N+1 including the output layer. The generated command uses -ngl all for all blocks, -ngl N+1 for a partial split, and -ngl 0 for CPU-only. Layer proportions include the output-layer position. Its weights are reserved on the last active GPU; tensor mode shards them. Input embeddings and retained auxiliary tensors stay in CPU RAM on discrete rigs. Unified systems charge everything to one pool. Custom rows must provide input/output component counts. Other runtime loaders and optional predictor blocks need separate log verification.
Reading the compact cards
Devices = all decoder blocks fit; host input/auxiliary tensors can remain. CPU blocks / CPU experts indicate the relevant offload. Runtime 'Verify' is provisional; 'Unsupported' suppresses the speed. 'Nearest Rn' is a nearby single-device reference, not a matched workload. Speed cards show per-sequence decode and aggregate prefill in tokens/s. Rows use source IDs Hn, Mn and Rn, whose full links appear below the calculator. Scroll the table vertically for additional rows.
Original measurement conditions
- R1: M2 Ultra 76-core; metal; 2023-11-22; build 8e672ef. ggerganov original M2 Ultra 76-core result; Metal; Llama 2 7B 6.74B; 3.56 GiB; pp512; tg128 from empty context; ngl99; historical baseline.
- R2: RTX 4090 desktop; cuda; 2025-08-06; build 224145325. lhl; CUDA 12.9; driver575.64.03; Llama 2 7B; 3.56 GiB; pp512/tg128; ngl99; FA off.
- R3: RX 7900 XTX desktop; vulkan; 2026-09-10; build 304665f. Diablo-D3 Powercolor Red Devil; Vulkan; Adrenalin26.8.1; Windows11; Llama 2 7B; pp512/tg128; ngl100; FA off; r100.
- R4: RX 7900 XTX desktop; rocm; 2026-09-10; build 304665f. Diablo-D3 Powercolor Red Devil; HIP/ROCm; Adrenalin25.10.2; Windows11; Llama 2 7B; pp512/tg128; ngl100; FA off; r100.
- R5: RTX 3090 desktop; cuda; 2025-08-01; build c76b420. m18coppola original comment; CUDA; no FA; Llama 2 7B; pp512/tg128; single GPU, not a dual-3090 measurement.
- R6: RTX 5090 desktop; cuda; Report date not shown; scoreboard checked 2026-10-27; build 8cf6b42. totaldev selected no-FA scoreboard row; pp512/tg128; ngl99; 3.56 GiB; original report date unavailable.
- R7: M4 Max 40-core; metal; Report date not shown; checked 2026-10-27; build 8e672ef. Selected historical Metal row, Llama 2 7B; pp512/tg128; memory configuration not reported.
- R8: M3 Ultra 80-core; metal; Report date not shown; checked 2026-10-27; build 8e672ef. Selected historical Metal row, Llama 2 7B; pp512/tg128. Vendor BW 819; discussion rounds it to 800.
Assumptions
- Snapshot checked 26–27 October 2026. Hardware/model records reuse #770 revision 638 schema, row keys, pinned HF commits and source fields, with 3090/5090, newer Mac configurations and larger dense models added here. The second calculator is not modified.
- GB/s is decimal bandwidth; memory allocations use binary GiB. Vendor-labelled memory is interpreted as binary installed capacity; confirm OS-reported bytes.
- The default 65% memory/DDR efficiency, 75% link efficiency, 15 µs latency, 75% usable unified share, 1.5 GiB device reserve, 5% payload headroom, 2 GiB host reserve and 650 W wall draw are editable planning assumptions, not measured specifications.
- Weight-size overrides apply one effective byte density to retained/executed component counts; nonuniform quantization and extra tensor copies require manual budgeting. The roofline and partition equations are derived here. They count traffic and work; they do not fit efficiency coefficients to a benchmark.
- Simultaneous sequences reuse dense weights once per batch. Distinct routed-expert reads use a capped linear union approximation, separately bounded by CPU- and GPU-assigned storage. Actual routing overlap may be lower. No prefix sharing, KV deduplication or operating-system swap.
- The context sweep recomputes whole-layer allocation. Jumps represent a layer moving to CPU RAM. It is a capacity-first allocation, not an automatic speed optimizer.
- Only eight individually cited llama.cpp measurements are selected. No llama.cpp scoreboard or llmfit community dataset is mirrored. No llmfit code/data or Epoch AI data is redistributed, so their licences are not invoked.
Where it applies
Runtime and interconnect limits
Memory fit, runtime support and measured evidence are independent. Unsupported configurations suppress displayed speeds; a 'verify' verdict is provisional. llama.cpp GGUF, vLLM, MLX and ExLlama formats are checked conservatively against maintainer documentation. CPU layer execution is different from vLLM weight swapping; confirm the actual offload mechanism. Quantized KV, MLA and hybrid adapters require the exact build's kernels.
llama.cpp tensor mode is experimental, requires flash attention and currently documents non-quantized KV. DeepSeek2 is on its unsupported architecture list. Other tensor cases require validating whole-head sharding, actual split ratios and collectives. Approximate fractional layer-equivalents do not guarantee a legal shard. Deprecated row mode is not modelled.
3090 NVLink requires a compatible bridge and software path; 4090/5090 do not have NVLink. Never assume CUDA P2P works just because PCIe slots exist. Driver, IOMMU/ACS, OS, NCCL/RCCL, NUMA placement and chipset sharing can change both correctness and speed. Enter negotiated lanes and the bottleneck generation, not connector size. Test transfers on your actual machine. Metal's recommended working-set limit is not necessarily the chosen planning share.
The planner does not predict kernel launch overhead beyond editable link latency, exact per-block tensor placement, quantization quality, heterogeneous kernel efficiency, thermal/power limits, server scheduling, disk paging, multi-node RPC, loading time or total cost. Prefill workspace is reserved rather than simulated; enlarge it for long contexts and large batches. A draft multiplier does not establish draft compatibility or output acceptance.
Historical measured rows differ in build, driver and sometimes flash attention. Dates missing from the original selected scoreboard row are marked unavailable and given a check date instead. The matched tg128 midpoint approximation is not a confidence interval. The 2×3090/large-model/RAM scenarios have no matched measurement in this selected sample; benchmark before making a purchase.
The common 65% device-bandwidth assumption overpredicts some Apple reference rows. The visible matched estimate/measured ratios show why this factor is not a universal accuracy claim. Calibrate each platform before comparing close results.
Sliding cache allocation is independent of attention access: Mistral documentation (https://huggingface.co/docs/transformers/v4.38.0/en/model_doc/mistral). A large conservative cache may force CPU spill, which can legitimately change speed; it does not increase per-device attention reads while the same layers remain resident. NVLink capability is an explicit hardware field; unknown custom configurations must use PCIe or provide verified link capability. A physical NVLink bridge and working runtime path are still required on supported 3090s.
References
- Hugging Face, KV cache quantization worked example, 16 May 2024: https://huggingface.co/blog/kv-cache-quantization (s1).
- Kwon et al., Efficient Memory Management for Large Language Model Serving with PagedAttention, 2023, DOI:10.1145/3600006.3613165; open manuscript https://arxiv.org/abs/2309.06180, PDF p.4 OPT-13B example (s2).
- Hardware: vendor specification URLs and check dates are recorded on every hardware_catalog row (PNY, Dell, Sapphire, Apple, AMD; s10–s13, s24–s25, s28–s30). No TechPowerUp tables used.
- Models: pinned Hugging Face config.json, exact commit, safetensors metadata source and check date on each model_catalog row (s3–s9, s26–s27).
- Original Metal runs: https://github.com/ggml-org/llama.cpp/discussions/4167 ; selected row builds/dates in measured_runs (s14).
- Original CUDA runs: https://github.com/ggml-org/llama.cpp/discussions/15013 ; RTX 3090 original https://github.com/ggml-org/llama.cpp/discussions/15013#discussioncomment-13960712 , 2025-08-01, c76b420 (s15).
- Original Vulkan run: https://github.com/ggml-org/llama.cpp/discussions/10879#discussioncomment-18386832 , 2026-09-10, 304665f (s16).
- Original HIP/ROCm run: https://github.com/ggml-org/llama.cpp/discussions/15021#discussioncomment-18388777 , 2026-09-10, 304665f (s17).
- llama.cpp multi-GPU maintainer guide, checked 2026-10-27: https://github.com/ggml-org/llama.cpp/blob/master/docs/multi-gpu.md (s18).
- GGML block definitions: https://github.com/ggml-org/llama.cpp/blob/master/ggml/src/ggml-common.h (s19).
- Runtime docs: https://docs.vllm.ai/en/latest/features/quantization/ ; https://github.com/ml-explore/mlx-lm ; https://github.com/turboderp-org/exllamav2 ; https://huggingface.co/docs/transformers/main/en/kv_cache (s20–s23).
- Pinned llama.cpp loader convention, 2026-10-26: https://github.com/ggml-org/llama.cpp/blob/961c376a2daa42220ec09663b9bde32c5fba1f70/src/llama-model.cpp
- Mistral sliding attention and cache behavior: https://huggingface.co/docs/transformers/v4.38.0/en/model_doc/mistral
Inputs
| Input | Symbol | Unit | Default |
|---|---|---|---|
| Planning direction | plan_mode | Model → compare hardware | |
| Model configuration Custom row: provide counts in billions, actual F/S/R layer order, cache geometry, limit and sources. Shared with VRAM calc #770. | model_pick | Llama 3.3 70B | |
| Weight precision | w_type | GGUF Q4_0 • 4.5 bits/weight | |
| Other quantization metadata overhead Percent above ideal 4/8-bit storage; enter 10 for 10%. | q_extra | 10 | |
| Checkpoint components retained Extra retained components consume memory; ordinary text compute excludes unused vision/MTP. | retention | Text decoder only | |
| Use actual complete weight-file size Prefer exact sum of all quantized shards. Applies to the selected model and hardware comparison; model scan uses parameter estimates. | weight_override | false | |
| Complete weight tensor allocation Use loaded tensor bytes if available; file headers and disk padding may differ. | file_gib | GiB | 40 |
| Prompt tokens per sequence Token counts, not words. Context budget includes requested output. | S_prompt | 4096 | |
| Requested output tokens Decode rate is at the final context, not an empty-context benchmark. | N_out | 256 | |
| Concurrent sequences Aggregate throughput = per-sequence throughput × sequences. No server scheduling simulation. | B_n | 1 | |
| KV cache precision Packing includes block scales; runtime kernel support is a separate verdict. | kv_type | FP16 • 2 bytes/value | |
| Attention cache allocation Hybrid recurrent state is fixed; only F layers get full-context KV. Confirm your runtime layout. | cache_layout | Compressed MLA / capped sliding window | |
| Runtime | runtime_pick | llama.cpp | |
| Model format | file_format | GGUF | |
| GPU backend | gpu_backend | CUDA / HIP / Metal from hardware | |
| Distribution strategy Tensor mode is experimental in llama.cpp. This models tensor, not its older row mode. | split_mode | Contiguous layers + CPU remainder | |
| Layer allocation Auto prioritizes fitting whole layers; it is not a latency optimizer. | allocation | Fill available memory automatically | |
| Maximum GPU layers 999 means all layers permitted. Set 0 for a CPU baseline. | gpu_limit | 999 | |
| Routed expert pool kept in RAM 1 = all routed experts; shared experts stay with the dense GPU pool. Intermediate fractions are an idealized custom placement. | expert_fraction | 1 | |
| Tensor proportions | tensor_balance | Proportional to available memory | |
| Primary device / unified system Choose Apple / CPU here for a single shared memory pool. Custom capacity is GiB; bandwidth is decimal GB/s. | gpu0 | RTX 3090 desktop 24 GiB | |
| Number of discrete GPUs Slots follow the device order used by the runtime. | n_gpu | 2 | |
| GPU 1 For one machine use compatible discrete devices. A mixed CUDA/HIP build needs separate validation. | gpu1 | RTX 3090 desktop 24 GiB | |
| GPU 2 For one machine use compatible discrete devices. A mixed CUDA/HIP build needs separate validation. | gpu2 | RTX 3090 desktop 24 GiB | |
| GPU 3 For one machine use compatible discrete devices. A mixed CUDA/HIP build needs separate validation. | gpu3 | RTX 3090 desktop 24 GiB | |
| Layers on GPU 0 Contiguous blocks; CPU gets the first remaining layers. | layer0 | 40 | |
| Tensor proportion for GPU 0 Ratios are normalized; check whole-head sharding in your build. | ratio0 | 1 | |
| Layers on GPU 1 Contiguous blocks; CPU gets the first remaining layers. | layer1 | 40 | |
| Tensor proportion for GPU 1 Ratios are normalized; check whole-head sharding in your build. | ratio1 | 1 | |
| Layers on GPU 2 Contiguous blocks; CPU gets the first remaining layers. | layer2 | 40 | |
| Tensor proportion for GPU 2 Ratios are normalized; check whole-head sharding in your build. | ratio2 | 1 | |
| Layers on GPU 3 Contiguous blocks; CPU gets the first remaining layers. | layer3 | 40 | |
| Tensor proportion for GPU 3 Ratios are normalized; check whole-head sharding in your build. | ratio3 | 1 | |
| Runtime / workspace reserve per active device Includes runtime buffers and your allowance for prefill activations. Increase for long prompts / large batches. | device_reserve | GiB | 1.5 |
| Payload headroom multiplier 1.05 adds 5% to weights + KV/state. Does not predict exact allocator peaks. | headroom | 1.05 | |
| Usable CPU / unified memory share Single shared pool, never added to GPU VRAM. 0.75 is a planning budget, not an OS guarantee. | usable_share | 0.75 | |
| Available host RAM on discrete-GPU rig Memory available to this workload after the OS; not swap. | ram_budget | GiB | 64 |
| Host runtime / staging reserve | host_extra | GiB | 2 |
| Retain an additional full CPU weight copy Enable when your loader/runtime duplicates device weights. File-backed mmap pages need not all stay resident. | host_copy | false | |
| Populated 64-bit DDR channels Count 64-bit channels, not 32-bit DDR5 subchannels. | ram_channels | 2 | |
| DDR data rate (MT/s) 5600 MT/s = 5600 million transfers/s; the MHz unit carries that scale. Already double-data-rate; do not multiply by 2 again. | ram_rate | MHz | 5600 |
| Sustained DDR / theoretical bandwidth Editable estimate; replace with measured STREAM-like read bandwidth for your NUMA placement. | eta_ram | 0.65 | |
| Effective CPU compute (TFLOP/s) 1 THz here means 10¹² floating-point operations/s. Effective precision-specific assumption, not advertised AI TOPS. | C_cpu | THz | 1 |
| GPU interconnect path | fabric | PCIe via host staging | |
| Negotiated PCIe generation Also sets the CPU↔GPU path when GPU↔GPU uses NVLink. | pcie_gen | Gen 4 • 16 GT/s | |
| Bottleneck negotiated PCIe lanes Use x8 if two cards divide the CPU's x16 link; account for chipset / NUMA bottlenecks. Also sets the CPU↔GPU path when GPU↔GPU uses NVLink. | pcie_lanes | 8 | |
| Measured one-way path bandwidth For NVLink use measured one-way payload bandwidth, not a bidirectional marketing sum. | link_rate | GB/s | 50 |
| Link payload efficiency Host staging adds two serial PCIe legs. If measured end-to-end already, choose Custom and efficiency 1. | eta_link | 0.75 | |
| Latency per boundary / collective Tensor mode assumes two reductions per GPU layer; latency is paid by each collective. | link_latency | us | 15 |
| Communicated bytes per activation value 4 for FP32 reductions, 2 only if the runtime actually compresses on-wire values. | activation_bytes | byte | 4 |
| Sustained device / physical memory bandwidth Common editable factor. Mixed GPUs can have different real utilization; use custom bandwidth rows with this factor = 1. | eta_bw | 0.65 | |
| Device prefill compute basis Historical profiles are llama.cpp Q4_0 only: 2 × 6.738B × measured pp512. Other precisions/runtimes need manual or custom-row effective compute. Scaling to another architecture still needs calibration. | compute_mode | Historical Q4_0 pp512 profiles | |
| Compute profile scaling 1 retains effective measured profile. Adjust for quantization, runtime and kernels. | eta_c | 1 | |
| GPU 0 effective compute (TFLOP/s) After utilization, at this precision/backend; THz represents 10¹² operations/s. | compute0 | THz | 70 |
| GPU 1 effective compute (TFLOP/s) After utilization, at this precision/backend; THz represents 10¹² operations/s. | compute1 | THz | 70 |
| GPU 2 effective compute (TFLOP/s) After utilization, at this precision/backend; THz represents 10¹² operations/s. | compute2 | THz | 70 |
| GPU 3 effective compute (TFLOP/s) After utilization, at this precision/backend; THz represents 10¹² operations/s. | compute3 | THz | 70 |
| Net speculative decoding speed multiplier Use only a measured net gain including draft/verification overhead. Capacity includes the separate draft allocation. | spec_factor | 1 | |
| Draft model + cache per active GPU Conservative per-device reservation; includes any replicated draft state. | draft_memory | GiB | 0 |
| Whole-system decode wall power User assumption or measured wall power; not GPU TDP. Applies only to your selected hardware. | wall_power | W | 650 |
Results
With the default inputs above, the calc gives:
| Result | Value |
|---|---|
| 1 · Memory verdict | All decoder blocks fit; host input/auxiliary tensors remain |
| 2 · Runtime / split verdict | Documented format / hardware; verify model build |
| 3 · Measured evidence | No measured row for this multi-device / RAM split |
| Final-context decode (tokens/s per sequence) | 15 |
| Prefill (tokens/s aggregate) | 481 |
| Decode wall energy | 43.3 J/token |
| Model weights | 36.96 GiB |
| Total KV / state | 1.33 GiB |
| GPU / primary-device layers | 80 |
| CPU remainder layers | 0 |
| Link delay per decode iteration | 0.038 ms |
| Placement flags • verify actual allocations | llama-server flags: -sm layer -ngl all -ts 0.444444,0.555556 -c 4352 -np 1 -ctk f16 -ctv f16 • verify device order and allocation logs |
Checked against sources
Each case below was calculated by this calc and agrees with the value from its source (within the tolerance where one is shown).
HF worked example • Llama-2 cache at 10k tokens
Source: Hugging Face KV cache quantization blog, 2024-05-16: Llama-2 7B FP16 cache at 10,000 tokens ≈5 GB. The exact tensor count is 5.24288 decimal GB, so ±0.25 GB reflects the source rounding; no equation is adjusted. https://huggingface.co/blog/kv-cache-quantization
Inputs: the default inputs above.
| Result | Source | This calc |
|---|---|---|
| Llama-2 reference cache at 10,000 tokens | 5 × 10⁹ ± 250,000,000 byte | 5.243 × 10⁹ byte |
PagedAttention • OPT-13B KV memory
Source: Kwon et al. 2023, DOI:10.1145/3600006.3613165, open manuscript PDF page 4. Published 800 KB/token is binary 800 KiB; the stated 1.6 GB at 2048 tokens is 1.5625 GiB rounded. The unit convention is corrected explicitly rather than fitting the method. https://arxiv.org/abs/2309.06180
Inputs: the default inputs above.
| Result | Source | This calc |
|---|---|---|
| OPT-13B reference KV per token | 800 KiB | 800 KiB |
| OPT-13B reference cache at 2048 tokens | 1.6 ± 0.05 GiB | 1.563 GiB |
Original GGUF tensor storage • Llama-2 Q4_0
Source: Original llama-bench Llama-2 7B Q4_0 rows report 3.56 GiB. Uniform block packing predicts about 3.53 GiB; real files retain some higher-precision tensors. ±0.05 GiB is an approximation check, not a VRAM or speed measurement. https://github.com/ggml-org/llama.cpp/discussions/15013#discussioncomment-14016393
Inputs: Model configuration = Llama 2 7B; the others as above.
| Result | Source | This calc |
|---|---|---|
| Model weights | 3.56 ± 0.05 GiB | 3.53 GiB |
Original RTX 3090 run • reference transfer
Source: m18coppola original no-FA CUDA result, 2025-08-01, build c76b420. This verifies transcription, not analytical speed accuracy. https://github.com/ggml-org/llama.cpp/discussions/15013#discussioncomment-13960712
Inputs: the default inputs above.
| Result | Source | This calc |
|---|---|---|
| Nearest measured tg128 | 158.2 Hz | 158.2 Hz |
| Nearest measured pp512 | 5,175 Hz | 5,175 Hz |
Original RTX 4090 run • reference transfer
Source: lhl original CUDA result, 2025-08-06, build 224145325. This verifies transcription, not analytical speed accuracy. https://github.com/ggml-org/llama.cpp/discussions/15013#discussioncomment-14016393
Inputs: Primary device / unified system = RTX 4090 desktop 24 GiB; the others as above.
| Result | Source | This calc |
|---|---|---|
| Nearest measured tg128 | 186.2 Hz | 186.2 Hz |
| Nearest measured pp512 | 11,993 Hz | 11,993 Hz |
Bandwidth-model cross-check • original RTX 3090 tg128
Source: Independent m18coppola CUDA Llama-2 7B Q4_0 no-FA tg128 measurement, 2025-08-01, c76b420. Prediction uses mean context 64 and a generic 65% bandwidth assumption; ±25% is a modeling comparison tolerance, not experimental uncertainty or a guarantee for other hardware. https://github.com/ggml-org/llama.cpp/discussions/15013#discussioncomment-13960712
Inputs: the default inputs above.
| Result | Source | This calc |
|---|---|---|
| Matched reference decode prediction | 158.2 ± 39.54 Hz | 161.8 Hz |
Tensor restrictions apply with one GPU: quantized KV
Source: llama.cpp maintainer multi-gpu guide: tensor mode requires non-quantized KV, regardless of rank count. https://github.com/ggml-org/llama.cpp/blob/961c376a2daa42220ec09663b9bde32c5fba1f70/docs/multi-gpu.md
Inputs: Model configuration = Llama 2 7B; Number of discrete GPUs = 1; Distribution strategy = Tensor parallel + CPU layer remainder; KV cache precision = Q4_0 • 18/32 bytes/value; Prompt tokens per sequence = 512; the others as above.
| Result | Source | This calc |
|---|---|---|
| Runtime compatibility: 0 no, 1 verify, 2 documented | 0 | 0 |
Tensor restrictions apply with one GPU: DeepSeek2
Source: DeepSeek2 is explicitly excluded from tensor-mode architectures in the pinned llama.cpp maintainer multi-gpu guide. https://github.com/ggml-org/llama.cpp/blob/961c376a2daa42220ec09663b9bde32c5fba1f70/docs/multi-gpu.md
Inputs: Model configuration = DeepSeek V2 Lite; Number of discrete GPUs = 1; Distribution strategy = Tensor parallel + CPU layer remainder; Prompt tokens per sequence = 512; the others as above.
| Result | Source | This calc |
|---|---|---|
| Runtime compatibility: 0 no, 1 verify, 2 documented | 0 | 0 |
RTX 5090 has no NVLink
Source: PNY VCG509032TFXPB1 vendor specification states NVLink Not Supported. The invalid path is rejected, not merely annotated. https://www.pny.com/en-eu/geforce-rtx-5090-models?isCommercial=true&sku=VCG509032TFXPB1
Inputs: Primary device / unified system = RTX 5090 desktop 32 GiB; GPU 1 = RTX 5090 desktop 32 GiB; Distribution strategy = Tensor parallel + CPU layer remainder; GPU interconnect path = NVLink • enter measured one-way rate; the others as above.
| Result | Source | This calc |
|---|---|---|
| Runtime compatibility: 0 no, 1 verify, 2 documented | 0 | 0 |
Pinned loader: 20 decoder blocks plus output = 21
Source: Pinned runtime 961c376a2daa42220ec09663b9bde32c5fba1f70: i_gpu_start=max(n_layer_all+1-n_gpu_layers,0); output assigned as layer n_layer_all. Thus 20 decoder blocks plus the output require 21 GPU layers, leaving 60 of the 80 Llama-3.3 blocks on CPU. This tests runtime convention, not speed. https://github.com/ggml-org/llama.cpp/blob/961c376a2daa42220ec09663b9bde32c5fba1f70/src/llama-model.cpp
Inputs: Maximum GPU layers = 20; the others as above.
| Result | Source | This calc |
|---|---|---|
| GPU / primary-device layers | 20 | 20 |
| CPU remainder layers | 60 | 60 |
| Pinned llama.cpp offloaded block-plus-output count | 21 | 21 |







Responses