One of the most critical responsibilities of an AI Infrastructure Engineer is GPU Capacity Planning. Deploying a model without precise memory forecasting leads to catastrophic failure modes: either immediate CUDA Out of Memory (OOM) server crashes under production load, or massive over-provisioning that wastes tens of thousands of dollars per month in idle GPU cloud instances.
VRAM allocation in modern LLM serving is not static; it is composed of four distinct layers:
- Model Parameter Weights (Static)
- Key-Value (KV) Cache (Dynamic, scaling with concurrency and sequence length)
- Activation Memory (Dynamic, scaling with prompt prefill batch size)
- CUDA Runtime & Framework Overhead (Static driver buffers and memory pools)
1. Calculating Model Parameter Weight Memory
The static weight memory represents the baseline VRAM consumed when the model weights are loaded from disk into GPU memory before processing any user requests.
The General Formula
Where:
- is the total parameter count of the model (e.g., for an 8B model).
- is the storage bytes per parameter, dictated by the precision:
- FP32 (Single Precision):
- FP16 / BF16 (Half Precision):
- FP8 / INT8 (8-bit Quantized):
- INT4 / AWQ / GPTQ (4-bit Quantized):
- is the quantization metadata overhead factor ( for scaling factors and zero points).
Reference Weight Footprints Across Top Architectures
| Model Architecture | Parameter Count () | FP16/BF16 Size | FP8 Size | INT4 AWQ Size | Minimum GPU Hardware Target |
|---|---|---|---|---|---|
| Llama 3 8B | 16.06 GB | 8.03 GB | 4.02 GB | 1x NVIDIA RTX 4090 / L4 (24GB) | |
| Mistral 7B | 14.48 GB | 7.24 GB | 3.62 GB | 1x NVIDIA L4 / T4 (16GB–24GB) | |
| Mixtral 8x7B (MoE) | 93.40 GB | 46.70 GB | 23.35 GB | 1x NVIDIA A100 (80GB) @ INT4 | |
| Llama 3 70B | 141.20 GB | 70.60 GB | 35.30 GB | 2x A100 (80GB) or 1x H100 @ INT4 | |
| DeepSeek-V3 (MoE) | 1,342 GB | 671 GB | 335.5 GB | 8x H100 (80GB) @ FP8 | |
| Llama 3.1 405B | 810 GB | 405 GB | 202.5 GB | 8x H100 (80GB) @ FP8 |
2. Calculating KV Cache Memory Growth
The Key-Value (KV) Cache stores the past attention Key and Value tensor projections for all previous tokens across all layers. As context lengths expand to 32k, 64k, and 128k tokens, KV Cache memory rapidly surpasses the model weight memory itself.
The Mathematical Formula
For a standard Multi-Head Attention (MHA) or Grouped-Query Attention (GQA) model:
Where:
- : Multiplier accounting for two tensors (one Key tensor and one Value tensor).
- : Number of transformer layers in the model.
- : Number of Key-Value attention heads.
- In Multi-Head Attention (MHA): .
- In Grouped-Query Attention (GQA): (typically 8 heads).
- In Multi-Query Attention (MQA): .
- : Dimension per attention head ().
- : Total sequence length (Prompt Tokens + Generated Tokens).
- : Number of concurrent active requests (Batch Size).
- : Bytes per element in the KV cache ( for FP16/BF16, for FP8 KV cache).
Impact of Attention Mechanisms: MHA vs GQA
Let us compare the KV cache footprint for generating a 4,096-token context across 16 concurrent users () on a 70B model ():
Standard Multi-Head Attention (MHA, ):
(Exceeds two entire 80GB GPUs just for the KV cache!)
Grouped-Query Attention (GQA, , as used in Llama 3):
(An reduction in memory, fitting comfortably inside a single GPU's free cache pool!)
3. Activation Memory and System Overhead
A. Activation Memory
Activation memory is the temporary scratchpad VRAM required to store intermediate tensors produced during the forward pass (e.g., query-key product matrices, layer norm outputs, and feed-forward intermediate projections).
- During Token Decoding (), activation memory is negligible ().
- During Prompt Prefill (), standard attention without FlashAttention consumes quadratic memory:
With FlashAttention-2 / FlashAttention-3, intermediate attention score matrices are tiled into SRAM, reducing peak activation memory to linear:
For a prompt length of with on Llama 3 70B, peak activation memory requires .
B. CUDA Context and Driver Overhead
When the PyTorch or CUDA runtime initializes, it allocates:
- CUDA Runtime Context: ~600 MB to 1.2 GB per GPU.
- NCCL Inter-GPU Communication Buffers: ~500 MB to 1.0 GB per GPU when using Tensor Parallelism.
- PyTorch Caching Allocator Reserved Memory: ~1.0 GB baseline.
Total static runtime overhead: per GPU.
4. Production VRAM Calculation Script
Here is an enterprise-grade calculation engine written in Python that takes any Hugging Face model architecture config and computes exact capacity limits and maximum concurrent request concurrency.
5. Production Failure Modes and Troubleshooting Runbook
Failure Mode: CUDA OOM on Initial Batch Burst Despite Passing Weight Budget
- Symptom: The model loads into VRAM without errors, but the very first time a user submits a 16k context prompt, the server process crashes with
torch.cuda.OutOfMemoryError: CUDA out of memory. - Root Cause: The infrastructure engineer allocated 76 GB of an 80 GB GPU to model weights and KV cache pool, leaving only 4 GB for runtime operations. When the 16k prompt prefill arrived, the activation tensors during forward pass required 5.5 GB of intermediate VRAM, causing an unrecoverable out-of-memory exception.
- Resolution: In serving engines (like vLLM), set
gpu_memory_utilization = 0.85to0.90(never1.0). This guarantees a 10% to 15% dedicated headroom cushion for peak prefill activations and PyTorch allocator fragmentation.
6. Summary & Key Takeaways
- Total VRAM = Weights + KV Cache + Activations + Driver Overhead: Capacity planning must account for all four components simultaneously.
- Precision Directly Scales Weight Size: FP16 uses 2 bytes/param ( for 70B), FP8 uses 1 byte (), and INT4 uses 0.5 bytes ().
- Grouped-Query Attention (GQA) Saves the KV Cache: GQA reduces KV cache memory consumption by compared to standard Multi-Head Attention.
- Never Allocate 100% of VRAM to Weights and Caches: Always maintain a 10–15% buffer () on an 80GB GPU to absorb peak prompt prefill activations and CUDA context buffers.