Contact, if you are interested in this website/domain name/Sponsorship/Advertisement/Partnership
AI models

Choosing hardware for local LLMs: memory first, bandwidth second

By the Quantization.com editorial teamUpdated 10 min read

Two numbers decide how well a machine runs a local language model. Fast memory capacity decides whether a model fits, and memory bandwidth sets the ceiling on generation speed. Compute matters less than most people expect for single-user chat. Quantization helps on both fronts, because it shrinks the weights you have to store and the bytes you have to read for every token.

Memory is the gate

Inference runs at full speed only when everything sits in the fastest memory the processor can reach: VRAM on a discrete GPU, or the unified pool on Apple Silicon. Three things compete for it:

  • Weights: the quantized parameters, which are by far the largest item for short-context use.
  • KV cache: keys and values for every token in context. This grows with context length and with the number of parallel requests. See KV cache quantization for the formula.
  • Overhead: compute buffers, runtime allocations and, on a desktop, the display and other apps.

If the weights do not fit, the runtime either fails to load or spills layers into much slower system RAM. So start with arithmetic.

The sizing method: params × bits ÷ 8, plus overhead

weight GB ≈ parameters (billions) × bits per weight ÷ 8

Use the effective bits per weight, including scales, rather than the nominal label. llama.cpp's quantize documentation reports Llama 3.1 8B at 4.89 bits per weight for Q4_K_M, 5.70 for Q5_K_M and 8.50 for Q8_0, because block scales and mixed tensor types add to the nominal width.

A quick check: llama.cpp lists the F16 file at 14.96 GiB (16.06 GB), which implies about 8.03 billion parameters. 8.03 × 4.89 ÷ 8 ≈ 4.91 GB, and the listed Q4_K_M file is 4.58 GiB (4.92 GB). Then add the KV cache for your context and a reserve for buffers. Keeping roughly 20% free is a reasonable starting assumption at 8K–16K context.

Estimated weight size (GB) by model size and quant type, computed as params × bpw ÷ 8
ParametersQ4_K_M (4.89 bpw)Q5_K_M (5.70 bpw)Q8_0 (8.50 bpw)FP16 (16 bpw)
8B4.95.78.516.0
14B8.610.014.928.0
24B14.717.125.548.0
32B19.622.834.064.0
70B42.849.974.4140.0

Want this done for your model?

Tell us your model, hardware and target. We send back a free optimization plan: recommended format, expected memory and a quality-check method.

Get the free plan

What fits at each VRAM tier

Inverting the formula: maximum parameters ≈ (0.8 × capacity) × 8 ÷ bits per weight, keeping about 20% free for cache and buffers. These are planning estimates, not guarantees.

Estimated largest dense model that fits, in billions of parameters (80% of memory for weights)
MemoryQ4_K_MQ5_K_MQ8_0Typical fit
8 GB≈ 10≈ 9≈ 67–8B at Q4/Q5, short context
12 GB≈ 15≈ 13≈ 912–14B at Q4, 8B at Q8
16 GB≈ 21≈ 18≈ 1214B at Q5/Q6, about 20B at Q4
24 GB≈ 31≈ 27≈ 1824–27B at Q5, 32B at Q4 with modest context
32 GB≈ 42≈ 36≈ 2432B at Q5, 24B at Q8
48 GB≈ 63≈ 54≈ 3632B at Q8, 70B only at ≈ 4.4 bpw or less
80 GB≈ 105≈ 90≈ 6070B at Q5–Q6, moderate context

Try it: LLM VRAM calculator

Weights, KV cache and overhead for any model, quant and context length — with a fit check across 20 GPUs and Macs.

Open the tool

Mixture-of-experts (MoE) models break the simple rule. Memory must hold all experts, so size by total parameters. Each token reads only the active experts, though, so speed follows active parameters.

Memory bandwidth sets tokens per second

Each token in single-user decoding reads essentially every weight once, plus the KV cache. The arithmetic per byte is light, so the processor mostly waits on memory. That gives an upper bound:

max tokens/s ≈ memory bandwidth (GB/s) ÷ bytes read per token (GB)

Bytes read per token ≈ weight size (active weights for MoE) + KV cache in use. Treat the result as a ceiling: real decode speed lands below it. Prompt processing (prefill) is compute-bound and follows different rules.

Worked example: ceilings for an 8B model at Q4_K_M (4.9 GB)

  • 448 GB/s (RTX 5060 Ti): 448 ÷ 4.9 ≈ 91 tokens/s maximum
  • 960 GB/s (RTX 5080): ≈ 196 tokens/s maximum
  • 1,792 GB/s (RTX 5090): ≈ 366 tokens/s maximum
  • 614 GB/s (M5 Max, 40-core GPU): ≈ 125 tokens/s maximum
  • 89.6 GB/s (dual-channel DDR5-5600, theoretical: 5,600 MT/s × 8 bytes × 2 channels): ≈ 18 tokens/s maximum

The same arithmetic for a 70B Q4_K_M model (42.8 GB) gives about 14 tokens/s maximum at 614 GB/s and about 28 tokens/s at 1.2 TB/s (M5 Ultra). These are computed ceilings, not measured benchmarks.

This is why quantization speeds up decoding. Going from Q8_0 to Q4_K_M cuts bytes per token by about 42%, which raises the ceiling by about 74% if the dequantization kernels keep up. In batched serving, one weight read serves many sequences, so throughput grows with batch size until compute or KV cache becomes the limit.

NVIDIA GPUs, Apple Silicon and CPU-only machines

NVIDIA consumer and workstation cards

Consumer GeForce cards pair high bandwidth with limited capacity. NVIDIA lists 12 GB at 672 GB/s (RTX 5070), 16 GB at 896–960 GB/s (RTX 5070 Ti, RTX 5080) and 32 GB at 1,792 GB/s (RTX 5090). The RTX 5060 Ti has 8 or 16 GB at 448 GB/s, and the older RTX 3090 and RTX 4090 have 24 GB. Workstation cards add capacity: the RTX PRO 6000 Blackwell lists 96 GB of GDDR7 with ECC at 1,792 GB/s.

NVIDIA data-center GPUs

Data-center parts use high-bandwidth HBM. NVIDIA lists 80 GB at 2,039 GB/s for A100 80GB SXM, 80 GB at 3.35 TB/s for H100 SXM and 94 GB at 3.9 TB/s for H100 NVL. The L40S sits between the two classes with 48 GB of GDDR6 at 864 GB/s. They suit batched serving stacks such as vLLM.

Format support also depends on GPU generation. vLLM's compatibility table lists FP8 W8A8 for Ada and Hopper but not Ampere, and its INT4 W4A16 path needs an Ampere-generation or newer GPU. bitsandbytes NF4 runs on Pascal and newer. Check before you choose a quantized checkpoint (see GPTQ vs AWQ vs GGUF).

Apple Silicon unified memory

On Apple Silicon, the CPU and GPU share one memory pool, so a machine with large RAM can hold models that no single consumer GPU could. Apple's specifications list 153 GB/s for M5, 307 GB/s for M5 Pro, 460 or 614 GB/s for M5 Max depending on GPU core count, and 1.2 TB/s for M5 Ultra. M5 Ultra configurations go up to 512 GB.

Treat the headline RAM figure with caution, because by default the GPU does not get all of it. Metal publishes a recommendedMaxWorkingSetSize for each GPU, which Apple describes as an approximation of how much memory the GPU can allocate without hurting performance. llama.cpp's Metal backend reads that value as the device's usable total, prints it at startup and can warn when allocations exceed it. On Apple Silicon Macs this figure is typically below installed RAM, so read it from your own startup log rather than assuming a fixed fraction. For MLX, whose large-model handling needs macOS 15 or later, the mlx-lm documentation describes raising the system wired-memory limit with sudo sysctl iogpu.wired_limit_mb=N, where N is larger than the model but smaller than total memory. A higher limit lets the GPU wire memory that macOS and your applications would otherwise use, so leave a margin.

CPU-only inference

llama.cpp runs well on CPUs with AVX2, AVX-512 or ARM NEON. Speed again follows memory bandwidth: a dual-channel DDR5 desktop tops out near 90 GB/s in theory, while multi-channel server platforms reach several times that. CPU-only suits small models, MoE models with few active parameters and latency-tolerant batch jobs. Long prompts are slow, because prefill needs compute.

Multi-GPU splits and offloading

Splitting across GPUs

llama.cpp's default --split-mode layer gives each GPU a contiguous slice of layers along with that slice's KV cache. Capacity adds up, so two 24 GB cards hold what one 48 GB card would. Single-stream speed does not add up, because each token passes through the GPUs one after another. The experimental --split-mode tensor splits every layer across GPUs so they read their shares at the same time, which can raise single-stream speed. It needs a fast interconnect and does not support a quantized KV cache. -ts 3,1 sets an uneven split for mismatched cards. In vLLM, --tensor-parallel-size sets the number of GPUs.

llama-server -m model-Q4_K_M.gguf -ngl all -ts 1,1 -c 16384

Offloading to system RAM

When a model does not fit, llama.cpp can keep some layers on the CPU (-ngl sets how many go to the GPU), and its default --fit logic tries to choose sensible values automatically. The cost follows from the bandwidth rule. Each token's time is the sum of the GPU part and the CPU part, and the slow part dominates.

Worked example: 70B Q4_K_M on one 32 GB GPU

Put 28 GB of weights on a 1,792 GB/s GPU and the remaining 14.8 GB in dual-channel DDR5 at 89.6 GB/s:

  • GPU time per token: 28 ÷ 1,792 ≈ 0.016 s
  • CPU time per token: 14.8 ÷ 89.6 ≈ 0.165 s
  • Ceiling: 1 ÷ 0.181 ≈ 5.5 tokens/s, even though two-thirds of the model is on the fast GPU

MoE models offload more gracefully. llama.cpp's --cpu-moe and --n-cpu-moe N keep expert weights in system RAM and attention plus shared weights on the GPU. Each token touches only a few experts, so less data crosses the slow path.

A practical selection checklist

  1. Pick the largest model you need and the quant you will accept. Compute weight size with params × bpw ÷ 8.
  2. Add the KV cache for your real context length and number of concurrent users.
  3. Choose memory capacity with about 20% headroom, or more for long contexts.
  4. Divide bandwidth by bytes per token to check that the speed ceiling meets your needs, and expect real results below it.
  5. Confirm that your runtime and quant format support the hardware (CUDA, ROCm, Metal or CPU).

Key takeaways

  • Weight size ≈ parameters × effective bits per weight ÷ 8. Q4_K_M is about 4.9 bpw and Q8_0 about 8.5 bpw.
  • Reserve about 20% of memory for KV cache and buffers, and more for long contexts or several users.
  • Decode speed ceiling ≈ bandwidth ÷ bytes read per token, so quantization raises speed as well as fit.
  • Apple Silicon offers large unified pools, but macOS caps GPU-usable memory below installed RAM by default.
  • Splitting across GPUs adds capacity. Offloading to system RAM works, but the slow memory dominates per-token time.

Frequently asked questions

How much VRAM do I need to run a 70B model?

At Q4_K_M, the weights alone are about 43 GB, so plan for at least 48 GB plus cache. 64 GB or more, or two 32 GB GPUs, leaves room for useful context. Lower-bit types such as IQ3 fit in less memory, at some cost in quality.

Is a faster GPU always better for local LLMs?

For single-user generation, memory bandwidth and capacity matter more than compute. Two cards with similar memory bandwidth decode at similar speeds even if one has far more compute. Compute matters more for prompt processing and batched serving.

Can I run models without a GPU?

Yes. llama.cpp and Ollama run on CPUs, at speeds set by RAM bandwidth. Small and MoE models suit this best.

Does Q8 run slower than Q4?

Usually yes for decoding, because each token reads almost twice as many bytes. Q8_0 is close to lossless, while Q4_K_M has measurable but usually small quality loss.

Do two GPUs double my tokens per second?

Not with the default layer split, which adds capacity but processes layers one after another. Tensor-parallel modes can raise single-stream speed, but they depend on fast GPU-to-GPU links.

Sources and further reading

  1. llama.cpp quantize README: bits per weight and file sizes for Llama 3.1 8B quant types.
  2. llama.cpp: Using multiple GPUs: split modes, tensor split and their limitations.
  3. NVIDIA GeForce graphics card comparison: memory size and bandwidth for RTX 50 series cards.
  4. NVIDIA H100: memory capacity and bandwidth for SXM and NVL.
  5. NVIDIA A100: 80 GB HBM2e bandwidth figures.
  6. Apple Mac Studio technical specifications: unified memory and bandwidth for M5 Max and M5 Ultra.
  7. Apple MacBook Pro technical specifications: memory bandwidth for M5, M5 Pro and M5 Max.
  8. Apple Metal: recommendedMaxWorkingSetSize: the GPU working-set guidance that runtimes read.
  9. mlx-lm README: large models on macOS and the wired memory limit setting.
  10. vLLM quantization overview: hardware compatibility of quantization formats.
VRAM calculatorFree plan