Running an open-weight model isn't just about fitting the weights into VRAM. You need memory for the model, the KV cache, the inference framework overhead, and a safety margin. Here's how to size it properly.
§1 The Core Formula
Your total VRAM requirement is:
Let's break each piece down.
1. Model Weights
The weight memory depends on the number of parameters and the precision (bytes per parameter):
(Dividing by 9.537 converts billions of bytes to GiB — the unit your GPU reports.)
| Format | Bytes/Param | 7B Model | 70B Model | Notes |
|---|---|---|---|---|
| FP32 | 4.0 | ~28 GB | ~280 GB | Training only. Nobody serves in FP32. |
| FP16 / BF16 | 2.0 | ~14 GB | ~140 GB | Standard for unquantized inference. |
| FP8 | 1.0 | ~7 GB | ~70 GB | Hardware-dependent (H100, Ada). Slight quality loss. |
| NVFP4 | 0.5 | ~3.7 GB | ~37 GB | NVIDIA 4-bit float (Blackwell+). Better than INT4 at same size. Requires Hopper/Blackwell. |
| MXFP4 | 0.5 | ~3.7 GB | ~37 GB | OCP Microscaling 4-bit float. Compresses weights+activations. Calibrated variants available. |
| INT8 | 1.0 | ~7 GB | ~70 GB | Good quality/size tradeoff. Broadly supported. |
| INT4 / Q4 | 0.5 | ~3.7 GB | ~37 GB | The sweet spot for consumer GPUs. GGUF default. |
| Q2 / Q3 | 0.25–0.375 | ~1.8–2.6 GB | ~18–26 GB | Noticeable quality degradation. Desperation mode. |
| Ternary (1.58-bit) | ~0.22 | ~1.6 GB | ~15.5 GB | Weights stored as {−1, 0, +1} with FP16 group scaling (BitNet-style). Now a viable deployment format: Ternary Bonsai 2 27B keeps 98.2% of its FP16 parent at 1.76 bits/weight, where 2-bit quants lose ~16%. Needs a compatible runtime (llama.cpp PQ2_0/PTQ1_0, MLX, GPU kernels). |
2. KV Cache
The KV cache stores attention keys and values for every token in the context window. It grows linearly with sequence length and is often the hidden killer.
Where:
- 2 — one for Keys, one for Values
- layers — number of transformer layers
- hidden_dim — head_dim × num_heads × num_kv_heads (for GQA models)
- context_len — max tokens you'll actually generate/context
- bytes_per_param — usually 2 (FP16), same as weight precision
For Multi-Head Attention (MHA): hidden_dim = head_dim × num_heads. For Grouped-Query Attention (GQA) or Multi-Query Attention (MQA), use num_kv_heads instead of num_heads — this can dramatically reduce KV cache size.
Hybrid-attention models: a newer class of open models — Qwen3.8-Flash-Next (Gated DeltaNet in 3 of every 4 layers), GLM-5.3-Flash (sparse + linear attention) — replaces most full-attention layers with linear/recurrent layers that keep a fixed-size state instead of a per-token KV cache. The formula above significantly overestimates their real memory use, because only the remaining sparse-attention layers grow linearly with context. Where vendors publish compression figures (GLM-5.3-Flash: 4.44× smaller cache than its dense equivalent), treat those as the correction factor.
3. Framework Overhead
Inference frameworks (vLLM, llama.cpp, TGI, etc.) need memory for:
- Computation buffers (attention, MLP intermediates)
- Tokenization and detokenization
- Batch scheduling and request queuing
- CUDA context and driver (~500MB–1GB)
Rule of thumb: 1–2 GB for small models, 2–4 GB for large models. vLLM tends to be on the higher end due to its paged attention allocator.
4. Safety Margin
Always add 10–15% on top of your calculated total. Fragmentation, unexpected batch sizes, and framework version changes will eat into your headroom. A model that "just fits" on paper will OOM in production.
§2 Choosing a Quantization Format
The format you choose is the single biggest lever for reducing VRAM requirements:
| Format | Quality Loss | Best For | Tooling |
|---|---|---|---|
| FP16/BF16 | None | When you have VRAM to spare and need max quality | vLLM, TGI, HF Transformers |
| INT8 | Minimal (~1-2%) | Servers with enough VRAM to halve from FP16 | vLLM AWQ, bitsandbytes |
| FP8 | Minimal (~1-3%) | Hopper/Blackwell GPUs, models shipping native FP8 weights | vLLM, SGLang, TensorRT-LLM |
| NVFP4 | Minimal (~1-3%) | NVIDIA's 4-bit float format, better math than INT4 | vLLM, TensorRT-LLM (Hopper+) |
| MXFP4 | Small (~2-4%) | OCP microscaling format, compresses weights+activations | vLLM, SGLang (calibrated variants) |
| INT4 (AWQ/GPTQ) | Small (~2-4%) | Consumer GPUs, best quality/size tradeoff | vLLM, AutoAWQ, AutoGPTQ |
| Q4_K_M (GGUF) | Small (~2-4%) | CPU/GPU hybrid inference, llama.cpp | llama.cpp, Ollama |
| Q2_K (GGUF) | Noticeable (~5-8%) | Last resort when VRAM is tiny | llama.cpp, Ollama |
| Ternary / 1.58-bit | Small (~2%, trained-or-rotated variants) | 27B-class models under 6 GB; browser (WebGPU), phones | llama.cpp (PQ2_0/PTQ1_0), MLX, gemlite |
§3 CPU Offloading
When a model doesn't fit entirely in VRAM, you can offload some layers to CPU RAM. The tradeoff:
- Pro: Run models larger than your GPU. A 70B model at Q4 fits in 40GB VRAM + ~2GB on CPU on a 48GB card.
- Con: CPU memory bandwidth (~50GB/s DDR5) is ~40× slower than GPU (~2000GB/s HBM). Offloaded layers are a massive bottleneck.
- Rule: Keep at least 80% of layers on GPU for acceptable performance. If you're offloading more than 20%, buy a bigger GPU or use a smaller model.
llama.cpp (and Ollama) support this natively with the -ngl (number of GPU layers) flag. vLLM does NOT support CPU offloading — it requires the full model in VRAM.
§4 Worked Examples
Let's size servers for real models from the Guide, using real architecture specs.
§5 Quick Reference Cheat Sheet
| GPU | VRAM | Best Model (Q4) | Best Model (FP16) | Typical Use |
|---|---|---|---|---|
| RTX 4060 / 3060 | 8 GB | 7B, short ctx | 3B or smaller | Edge, personal |
| RTX 4070 / 3070 | 12 GB | 14B, 4K ctx | 7B, short ctx | Dev, personal |
| RTX 4080 / RTX 5000 Ada | 16 GB | 14B, 16K ctx | 7B, 8K ctx | Dev, light serving |
| RTX 4090 / 3090 | 24 GB | 27B, 8K ctx | 14B, 4K ctx | Serious dev, serving |
| RTX 6000 Ada / A6000 | 48 GB | 70B, 4K ctx | 27B, 8K ctx | Production serving |
| A100 / H100 | 80 GB | 700B+ MoE, 8K ctx | 70B, 16K ctx | Data centre, frontier |
| 2× A100 (TP) | 160 GB | 750B+ MoE, FP8 | 700B+ MoE, Q4 | Large-scale production |
Rules of Thumb
- Weights rule: Q4 params in GB ≈ param count in billions ÷ 2 (e.g., 70B ≈ 35GB)
- FP16 rule: params in GB ≈ param count in billions × 2 (e.g., 70B ≈ 140GB)
- KV cache rule: for GQA models at 4K context, add ~10–15% of weight size. At 32K, add ~80–100%.
- MoE rule: size for TOTAL params, not active. Inference speed depends on active params.
- Overhead rule: add 2–4 GB for framework + CUDA context, then 15% safety margin.
- Offload rule: if >20% of layers are on CPU, you need a bigger GPU or a smaller model.
Recommended Stack by Scale
- Single consumer GPU (8–24GB): Ollama or llama.cpp with GGUF files. Native CPU offload, easy to use.
- Single workstation GPU (24–48GB): vLLM with AWQ or GPTQ quantized models. Best throughput on single card.
- Data centre (80GB+): vLLM or TGI with tensor parallelism across multiple GPUs. FP8 or FP16.
- Broke but determined: llama.cpp with Q2_K and CPU offload. It'll be slow. Very slow. But it'll run.
max_model_len at load time. Setting it lower than the model's maximum context shrinks the KV cache allocation. If you're serving an API where most requests are under 2K tokens, don't allocate for 32K.