Skip to content
Friendly disclaimer: flozi00 TechHub is a solo side-project next to a full-time job — personal learning notes, no official statements. Verify critical steps yourself.

LLM Inference Math: From Theory to Hardware

The roofline math behind LLM inference: bytes per token, arithmetic intensity, and decode speed — worked examples with real GPU specs.

4 min readflozi00
aimachine-learninggpudatacenterdeep-learninghardware
Skip to the full article
Watch · explore · understand

Race the compute floor against the memory floor

Prefill reuses weights across prompt positions; small-batch decode has much less work per weight byte.

AI-assisted learning visualization · schematic article explanation

Step 1 / 4Choose the phase before estimating speed

During prefill, one loaded weight can serve many prompt positions. Small-batch decode uses it for far fewer positions, so the ratio of operations to weight bytes falls sharply.

AlgorithmCurrent stepSelect a block to explain it
Choose phase, batch and context
Prefill and decode have different shapes and data reuse.
Floating-point work F
Include linear layers and attention for the chosen phase.
Bytes that must move M
Weights, KV and intermediate data contribute traffic.
  1. Choose phase, batch and context Floating-point work F
    count operations
  2. Choose phase, batch and context Bytes that must move M
    count data movement
What to remember

A GPU has both a compute ceiling and a bandwidth ceiling; workload shape decides which one matters first.

These are ideal bounds for stated data movement and arithmetic. Peak specs, cache reuse, multimodal work and communication need consistent accounting.

Terms and the complete walkthrough
Arithmetic intensity
Floating-point operations performed per byte moved through the measured memory tier.
Roofline
An ideal performance ceiling set by compute rate and memory bandwidth.
  1. Choose the phase before estimating speed

    During prefill, one loaded weight can serve many prompt positions. Small-batch decode uses it for far fewer positions, so the ratio of operations to weight bytes falls sharply.

  2. Calculate two independent lower bounds

    Divide required operations by the applicable compute rate, and required bytes by memory bandwidth. Even with perfect overlap, execution cannot beat the larger of those two times.

  3. Read the roofline balance

    Arithmetic intensity is operations divided by moved bytes. Compare it with hardware compute divided by bandwidth: below that balance, bandwidth limits the ideal roof; above it, compute does.

  4. Add omitted traffic before predicting

    Weight-only arithmetic leaves out KV reads, activation movement and other work. First verify the configuration fits in memory, then measure the actual kernels; a theoretical token-rate ceiling is not a deployment forecast.

All connections

  • Choose phase, batch and context → Floating-point work F: count operations
  • Choose phase, batch and context → Bytes that must move M: count data movement
  • Floating-point work F → Compute time ≥ F ÷ compute rate: divide by FLOPS
  • Bytes that must move M → Memory time ≥ M ÷ bandwidth: divide by bytes/s
  • Compute time ≥ F ÷ compute rate → Overall time ≥ the larger floor: compute limit
  • Memory time ≥ M ÷ bandwidth → Overall time ≥ the larger floor: bandwidth limit
Set your own pace. Pause at any time or select a step directly.

Large Language Models (LLMs) have become foundational in modern AI, but running them efficiently requires a deep understanding of the interplay between model architecture and hardware capabilities. Simply choosing the most powerful GPU isn't always the most cost-effective solution. The key is to know whether your workload is compute-bound or memory-bound.

This guide walks through the essential math to profile an LLM for inference, helping you select the right hardware and optimize its performance. We will apply these principles to a real-world example: running the Qwen/Qwen3-VL-32B-Instruct model on the powerful NVIDIA RTX PRO 6000 Blackwell Edition workstation GPU.

This article is inspired by the mathematical approach detailed in the Baseten blog post, "A guide to LLM inference and performance."

For a measured example, the MI350P vLLM optimization case study audits 118 observations and follows state-write reduction, K/V reuse and small-row routing. It distinguishes logical byte counts from hardware traffic and complete deployment results from isolated kernel timings.

Step 1: Understanding Your Hardware's Capabilities

The first step is to analyze the key specifications of our GPU. These numbers define the theoretical limits of our hardware. For the NVIDIA RTX PRO 6000 Blackwell Edition, the critical specs are:

  • GPU Memory (VRAM): 96 GB GDDR7 ECC 1
  • GPU Memory Bandwidth: 1792 GB/s 1
  • FP16/BF16 Tensor Core Performance (dense): 503.8 TFLOPS 2

These three metrics—capacity, speed, and raw power—are the pillars of our analysis.

Step 2: Calculating the GPU's Operational Intensity (Ops:Byte Ratio)

A GPU's operational intensity, or ops:byte ratio, tells us how many computations it can perform for every byte of data it moves from VRAM. This is a crucial, hardware-specific ratio that reveals the balance between computation and memory access.

The formula is straightforward:

ops:byte Ratio = Compute Bandwidth (FLOPS) / Memory Bandwidth (Bytes/s)

Let's calculate it for our RTX PRO 6000:

  • Compute: 503.8 TFLOPS = 503,800,000,000,000 FLOPS
  • Memory: 1792 GB/s = 1,792,000,000,000 Bytes/s
ops_to_byte_ratio = 503,800,000,000,000 / 1,792,000,000,000
                  = 281.1 ops/byte

This means for our hardware to be fully utilized, our application must perform approximately 281.1 floating-point operations for every single byte it fetches from VRAM.

  • If our model performs fewer operations per byte, we are memory-bound.
  • If our model requires more operations per byte, we are compute-bound.

Step 3: Calculating the Model's Arithmetic Intensity

Next, calculate arithmetic intensity for the whole forward pass, separately for prefill and decode. Attention contributes work, but it is not the whole model: dense weight matrix multiplications dominate the simple linear term.

We'll use the parameters for the Qwen/Qwen3-VL-32B-Instruct model 3:

  • Sequence Length (N): 4096
  • Model Dimension (d_model): 5120
  • Number of Attention Heads (n_heads): 64
  • Number of KV Heads (n_kv_heads): 8 (GQA)
  • Dimension per Head (d_head): 128

For a 4,096-token prompt, the 33.357B-parameter checkpoint has about 66.7 GB of fp16 weights. The standard linear-layer approximation gives:

Linear FLOPs ≈ 2 × 33.357B parameters × 4,096 tokens ≈ 273.3 TFLOPs
Weight-read bytes ≈ 33.357B parameters × 2 bytes ≈ 66.7 GB
Linear arithmetic intensity ≈ 273.3 TFLOPs / 66.7 GB = 4,096 FLOPs/byte

This 4,096 FLOPs/byte counts linear-layer FLOPs divided only by weight reads. Attention adds FLOPs, while reading and writing activations adds bytes, so it is an illustration rather than a measured whole-model intensity. At batch-1 decode the same linear-layer ratio falls to about 1 FLOP per fp16 weight byte. Context-length-dependent attention reads add further traffic.

Step 4: Identifying the Bottleneck

Now we compare the two ratios:

  • GPU Ops:Byte Ratio: 281.1 ops/byte
  • Linear prefill illustration: 4,096 FLOPs/byte of weight traffic
  • Linear batch-1 decode illustration: 1 FLOP/byte of weight traffic

The simplified 4k-token prefill has more FLOPs per weight byte than the GPU's 281.1-FLOP/byte ridge, so its linear layers can be compute-bound. Batch-1 decode has much less arithmetic work per weight byte and is typically bandwidth-bound when the weights reside in VRAM. Actual bottlenecks also depend on attention, batch shape, kernels and cache behaviour; an attention-only intensity cannot classify the entire inference workload.

Step 5: VRAM and Performance Estimation

VRAM for Model Weights

A ~32.8-billion-parameter model (the Qwen3-32B text stack; the VL variant adds a vision tower for ~33.4B total) at half-precision (FP16) requires:

VRAM for Weights = 33.357 Billion Parameters * 2 Bytes/Parameter ≈ 66.7 GB

VRAM for the KV Cache

The KV cache size per token is:

KV Cache per Token = 2 * num_hidden_layers * n_kv_heads * d_head * 2 = 262,144 Bytes/token (Qwen3-VL-32B uses Grouped-Query Attention with 8 KV heads instead of 64, so the KV cache is 8× smaller than a full multi-head layout would need.)

With our 96 GB GPU, after loading the ~66.7 GB model, we have:

Spare VRAM = 96 GB - 66.7 GB ≈ 29.3 GB

This allows for a theoretical batch size of:

Batch Size = floor(29.285 GB / (262,144 B/token × 4,096 tokens)) = 27 sequences (before runtime, activation and allocator reservations)

Estimating Performance

Time Per Output Token (Decoding Latency):

Time/Token ≥ Model Size (Bytes) / Peak Memory Bandwidth (Bytes/s) ≈ 37.2 ms/token (weights only, batch 1)

This is a ~26.9 tok/s bandwidth ceiling before KV reads and other work, not a measured expectation.

Time to First Token (Prefill Latency): For a prompt of 512 tokens:

Linear compute time ≥ (512 tokens × 2 × 33.357e9 params) / 503.8 TFLOPS ≈ 67.8 ms

Conclusion

Our analysis shows:

  1. Bottleneck depends on phase: The linear part of a 4k-token prefill can be compute-bound; small-batch decode is usually bandwidth-bound.
  2. VRAM for batching: The 96 GB card has a raw capacity ceiling of 27 concurrent 4k-token KV sequences after the 66.7 GB checkpoint. Real capacity is lower once runtime and activation memory are reserved.
  3. Performance bounds: Weight streaming alone limits batch-1 decode to ~26.9 tok/s; linear compute alone sets a ~67.8 ms prefill floor for a 512-token prompt. Neither is a deployment forecast or full TTFT.

These calculations provide a solid foundation for understanding LLM inference performance and making informed hardware decisions.


References

Footnotes

  1. NVIDIA RTX PRO 6000 Blackwell Workstation Edition datasheet: 96 GB GDDR7 ECC and 1,792 GB/s peak bandwidth. ↩ ↩2

  2. Tensor core peak rates (503.8 TFLOPS FP16/BF16 dense = half of the 1007.6 TFLOPS FP8 dense rate), sourced from NVIDIA RTX PRO Blackwell GPU Architecture whitepaper, Table 4. Note: 126.0 TFLOPS is the non-tensor FP32/FP16 shader rate — LLM inference runs on tensor cores. ↩

  3. Qwen/Qwen3-VL-32B-Instruct model architecture parameters, sourced from Hugging Face Model Card. ↩