Local AI infrastructure

Memory bandwidth and speed limits

How fast can this model possibly decode on this GPU?

See why memory bandwidth, not compute, limits LLM decoding, compare GPUs for the same setup, and read a measurement against its limit.

Size unit

1 · Model

Parameters
8.19B
Layers
36
Heads
32 query, 8 KV
Head dimension
128
Maximum context
40,960 tokens
KV cache per token, 16 bit
147.46 KB/token
Hidden size
4,096
Vocabulary
151,936

Values read from the config.json on Hugging Face on October 30, 2026.

These values come from Hugging Face and cannot be edited. Customize to change them.

2 · Precision

How many bits store each parameter.

›Published quantizations

Applies to quantized formats only.

Set apart from the weights. FP8 halves the cache.

3 · Workload

Tokens per sequence, prompt and generated text together.

tokens

Requests processed at the same time, the batch.

4 · Hardware

RTX PRO 6000 Blackwell Server Edition

NVIDIA · Blackwell

Data center

Memory

96 GB

GDDR7 · counted as 96 GiB

Bandwidth

1,597 GB/s

Max power

300 to 600 W

Configurable.

Bars compare each figure with the largest GPU in the catalogue.

NVLink
None
MIG instances
4
NVLink group
None, PCIe only
GPUs per server
up to 8

How it is built into servers

Dividing this GPU

MIG

Divides into 4 memory slices and 4 compute slices, up to 4 instances on one GPU. The profiles:

  • 1g.24gb
  • 2g.48gb
  • 4g.96gb

Where an instance may start:Derived

vGPU for Compute

10 types with 8 to 96 GB of framebuffer, up to 12 vGPUs on one GPU. It needs an NVIDIA AI Enterprise licence and a hypervisor.

Sharing without dividing

Time-slicing works on any GPU, with no memory or fault isolation between the replicas. MPS shares a whole GPU, not a MIG instance.

Number formats

FP4FP8FP16BF16TF32FP32
›Specifications and sources
Memory
96 GB[1]
Type
GDDR7[1]
Bandwidth
1,597 GB/s[1]
Max power
300 to 600 W[2]Configurable.
NVLink
0[3]Not supported.
MIG instances
4[4]
FP4
4,000 TFLOPS[1]NVIDIA does not say dense or sparse.
FP8
2,000 TFLOPS[1]NVIDIA does not say dense or sparse.
FP16 / BF16
1,000 TFLOPS[1]NVIDIA does not say dense or sparse.
TF32
234 TFLOPS[1]NVIDIA does not say dense or sparse.

Number formats: FP4, FP8, FP16, BF16, TF32, FP32

Tensor figures are peak values from datasheets. They are not application performance.

Sources

Loading sources

GPUs in all. They share the model by tensor parallelism, pipeline stages and replicas, as the layout below sets.

1 server of 8 GPUs, the last one with 1

How the GPU is used

Divide each GPU into slices or share it between replicas instead of using more GPUs. Slices and shares run replicas of the model: they cannot be joined into a tensor-parallel group.

Share a device between replicas

Several replicas on one device, each with its own part of the memory.

Compute instances exist only inside a MIG instance.
›Deployment layout

How the GPUs share the model. The memory per GPU, the KV cache room and the GPU counts follow from it, the way vLLM divides them.

Pipeline stages

Splits the layers into runs on different GPUs. Little data crosses between stages, so it suits GPUs without a fast link and servers joined by a network.

Replicas

Independent copies of the model, each with its own KV cache. They share the sequences. A mixture-of-experts model spreads its experts over all of them.

Tensor parallel size: 1, the GPUs divided by the stages and the replicas.

GPUs per server

Tensor parallelism stays inside a server. Beyond it the GPUs become pipeline stages.

Decode context parallel size

Splits the KV cache of every sequence by token over the tensor-parallel GPUs. It adds no GPUs and slows decoding.

Only for mixture-of-experts models.

Measurement

Optional: the inter-token latency you measured for this setup, in milliseconds.

ms
Runtime assumptions›3.22 GB overhead per GPU, 90 % usable, 10 % headroom

Memory for the CUDA context, activations and graphs, in the unit of the page. A heuristic.

GB

Share of the GPU memory the serving engine may use. vLLM's default is 92 percent.

%

Share of the usable memory that should stay free for a comfortable fit.

%

This model has no sliding window layers.

Theoretical limit, not expected speed

Shortest decode step

13.28 ms

21.21 GB read per GPU over 1.6 TB/s.

Speed limit of one sequence

75.28 tok/s

Tokens per second it cannot exceed, without speculative decoding.

All 4 sequences

301.13 tok/s

Tokens per second together.

Weight read time

10.26 ms

The weights one GPU holds, read once at full bandwidth.

Break-even batch

313

Where compute takes over from memory. Latency rises earlier.

What one GPU reads in a step

  • Weights read16.38 GB77.22 %
  • KV cache read4.83 GB22.78 %

Step time as the batch grows

Every extra sequence adds its own cache to the bytes a step reads, while the weights are read once for all of them. The same limits at a context of 8,192 tokens.

  • 1 sequence

    11.01 ms

  • 2 sequences

    11.77 ms

  • 4 sequences

    13.28 ms

  • 8 sequences

    16.31 ms

  • 16 sequences

    22.36 ms

  • 32 sequences

    34.46 ms

  • 64 sequences

    58.67 ms

  • 128 sequences

    107.08 ms

  • 256 sequences

    203.89 ms

The same setup on other GPUs

The same bytes over each GPU's bandwidth. A GPU where the setup does not fit is marked, and its figure is what it would give if it did.

  • GB200 NVL72

    377 tok/s

  • GB300 NVL72

    377 tok/s

  • B200 HGX

    363 tok/s

  • B300 HGX

    363 tok/s

  • GH200 144 GB HBM3e

    231 tok/s

  • H200 SXM

    226 tok/s

  • H200 NVL

    226 tok/s

  • GH200 96 GB HBM3

    189 tok/s

  • H100 NVL

    186 tok/s

  • H100 SXM

    158 tok/s

  • A100 80GB SXM4

    96 tok/s

  • H100 PCIe

    94 tok/s

  • RTX PRO 6000 Blackwell Server EditionSelected

    75 tok/s

  • Note: The maker prints this GPU's peak without saying whether it includes sparsity. The figure used is half of it, as for the GPUs of the same generation that do say.

Deploy this setup

These commands are written for the setup you sized above and the choices you make here, and change with either. Nothing is changed for you: a choice that stops working is kept and marked, with ways to fix it.

The server

Run it with

Runtime

The server that loads the model.

GPUs

The indices of the GPUs on the machine, as nvidia-smi lists them, separated by commas. The setup uses 1 GPU.

Identify the GPUs by

An index depends on the order the driver finds the GPUs. A UUID is tied to the card.

Endpoint

The port the endpoint answers on. 8000 (default)

Listen on

The default keeps the endpoint on this machine.

The endpoint answers only to requests that carry a key. The key is made on your machine and is never written in a command or a link.

More options

Where the downloaded weights are kept. A directory that exists already saves the download.

The default is the release these commands were written for. latest follows the newest.

What will run

DocumentedConfiguration YSTVGT

vLLM · Docker · 1 GPU, RTX PRO 6000 Blackwell

Worth a look

  • You sized a fp16 KV cache for bf16 weights. A 16 bit cache takes the same room in either type, and vLLM stores it in the model's own type unless told otherwise, so the commands do not force fp16.

16 steps in 5 phases. Open one at a time, or all of them.

1Check the hardware

Look at what the machine or cluster offers before you change anything.
  1. Step 1

    Check the driver

    Confirm that the NVIDIA driver is installed and new enough for the software below.

    nvidia-smi

    What you should see

    • A table with the driver version and a CUDA version of at least 13.0, which the image needs.
    Help and sources

    If it does not work

    • If the CUDA version is lower than the software needs, update the driver and check again.

    Where the values come from

    • The GPU you chose: RTX PRO 6000 Blackwell.
  2. Step 2

    Check the GPUs

    Confirm that the machine lists the GPU at index 0.

    nvidia-smi -L

    What you should see

    • One line for each GPU, each naming RTX PRO 6000 Blackwell the way the machine spells it.
    Help and sources

    If it does not work

    • If a GPU you chose is missing, it is not in this machine or the driver cannot see it.
    • If the names do not match what you expect, the indices are not what you think. Identify the GPUs by UUID, which does not depend on the order.

    Where the values come from

    • The calculator uses 1 GPU.
    • The GPU you chose: RTX PRO 6000 Blackwell.
  3. Step 3

    Check that the memory is free

    The calculator expects 22.76 GiB on each GPU, of the 86.40 GiB the engine may use. Check that the memory of the GPU at index 0 is free.

    nvidia-smi --query-gpu=index,name,memory.total,memory.used,memory.free --format=csv -i 0

    What you should see

    • Nearly all the memory of the GPU is free, at least 22.76 GiB on each.

    Keep in mind

    • Other work may already use these GPUs. If their memory is not free, stop that work or choose other GPUs before you start.
    Help and sources

    Where the values come from

    • The calculator: 22.76 GiB needed of 86.40 GiB usable on each GPU.

2Prepare

Get access to the model, install what the server needs and fetch it. A divided GPU is made here too.

Install the tools

  1. Step 4

    Check Docker

    Confirm that Docker Engine is installed.

    docker --version

    What you should see

    • A Docker version.
    Help and sources
  2. Step 5

    Install the NVIDIA Container Toolkit

    Needs administrator rights

    It lets containers use the GPUs. These commands are for Ubuntu and Debian, and the page linked below has the other distributions.

    Comes after step 1

    sudo apt-get update && sudo apt-get install -y --no-install-recommends ca-certificates curl gnupg2
    curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
      && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
        sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
        sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
    sudo apt-get update
    export NVIDIA_CONTAINER_TOOLKIT_VERSION=1.20.1-1
    sudo apt-get install -y \
      nvidia-container-toolkit=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
      nvidia-container-toolkit-base=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
      libnvidia-container-tools=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
      libnvidia-container1=${NVIDIA_CONTAINER_TOOLKIT_VERSION}

    What you should see

    • The packages install without errors.
    Help and sources
  3. Step 6

    Connect Docker to the GPUs

    Needs administrator rights

    Register the NVIDIA runtime with Docker and restart it.

    sudo nvidia-ctk runtime configure --runtime=docker
    sudo systemctl restart docker

    What you should see

    • No errors, and Docker comes back up.

    Keep in mind

    • Restarting Docker stops the containers that are running.
    Help and sources
  4. Step 7

    Check that a container sees the GPUs

    Run nvidia-smi in a container that is given the GPU at index 0. Only that GPU should appear.

    docker run --rm --runtime=nvidia --gpus '"device=0"' \
      ubuntu nvidia-smi

    What you should see

    • A table with one GPU, the ones you chose.
    Help and sources

    If it does not work

    • If Docker cannot start with the GPUs, the toolkit is not configured or the indices do not exist on this machine.
    • If the names do not match what you expect, the indices are not what you think. Identify the GPUs by UUID, which does not depend on the order.

    Where the values come from

    • --gpus '"device=0"'

      Default The first GPUs, counted from 0.

Get the server

  1. Step 8

    Download the image

    Download vllm/vllm-openai:v0.32.0 before the first start, so that the start only has to load the model.

    docker pull vllm/vllm-openai:v0.32.0

    What you should see

    • The download completes and the last line names the image.

    Keep in mind

    • The image is several gigabytes.
    Help and sources

3Start the server

Start it with the setup you sized.
  1. Step 9

    Start the server

    Start vllm-qwen3-8b with the setup you sized: the model Qwen/Qwen3-8B, the parallelism, the context and the memory it was given. The first start downloads the model and takes a few minutes.

    Comes after step 3

    # config YSTVGT
    docker run -d --name vllm-qwen3-8b \
      --runtime nvidia --gpus '"device=0"' \
      --ipc=host \
      -v "$HOME/.cache/huggingface":/root/.cache/huggingface \
      -p 127.0.0.1:8000:8000 \
      vllm/vllm-openai:v0.32.0 \
      --model Qwen/Qwen3-8B \
      --max-model-len 8192 --max-num-seqs 4 \
      --gpu-memory-utilization 0.90

    What you should see

    • A container id.

    Keep in mind

    • The first start downloads the model and prepares the kernels, which takes minutes. The server is not ready before that.
    Help and sources

    If it does not work

    • If it stops with an out of memory message, the setup needs more than the GPU holds. Lower the context or the sequences, give the engine more of the GPU, or use more GPUs. The calculator shows by how much.
    • If vLLM says the context is longer than the KV cache can hold, lower the context or the number of sequences.
    • If vLLM says the attention heads cannot be divided by the tensor parallel size, use a size that divides them.
    • If the port is taken, choose another one in your choices.
    • If Docker cannot start with the GPUs, the toolkit is not configured or the indices do not exist on this machine.

    Where the values come from

    • -d

      Default How you chose to run it.

    • --name vllm-qwen3-8b

      From the calculator The repository of the model you chose.

    • --runtime nvidia

      Default How you chose to run it.

    • --gpus '"device=0"'

      Default The first GPUs, counted from 0.

    • --ipc=host

      Default How you chose to run it.

    • -v "$HOME/.cache/huggingface":/root/.cache/huggingface

      Default Where the downloaded weights are kept.

    • -p 127.0.0.1:8000:8000

      Default The port the endpoint answers on.

    • --model Qwen/Qwen3-8B

      From the calculator The repository of the model you chose.

    • --max-model-len 8192

      From the calculator The context length you set: 8,192 tokens.

    • --max-num-seqs 4

      Worked out 4 sequences shared by 1 replica.

    • --gpu-memory-utilization 0.90

      Worked out The usable share you set, 90 percent, divided between 1 replica on the device, rounded down so the shares never add up to more than the device.

    • The repository of the model you chose.
    • The context length you set: 8,192 tokens.
    • The usable share you set, 90 percent, divided between 1 replica on the device, rounded down so the shares never add up to more than the device.

4Check that it works

Wait until it answers, ask it something, and compare the memory with the calculator.

Check the endpoint

  1. Step 10

    Wait until it is ready

    The server answers /health once the model is loaded.

    timeout 900 bash -c 'until curl -fs http://127.0.0.1:8000/health >/dev/null; do sleep 5; done' && echo ready

    What you should see

    • The word ready, after a minute or more while the model loads.
    Help and sources

    If it does not work

    • If it does not become ready, read the last log lines: the model is still loading, or the server stopped with an error.
    • If it stops with an out of memory message, the setup needs more than the GPU holds. Lower the context or the sequences, give the engine more of the GPU, or use more GPUs. The calculator shows by how much.
  2. Step 11

    Check that the model is served

    Ask the server which models it serves.

    curl -sS http://127.0.0.1:8000/v1/models

    What you should see

    • A list with Qwen/Qwen3-8B in it.
    Help and sources

    If it does not work

    • If the answer is 401, the key in this shell is not the one the server was started with.
  3. Step 12

    Ask it something

    One request through the endpoint your applications will use.

    curl -sS http://127.0.0.1:8000/v1/chat/completions \
      -H 'Content-Type: application/json' \
      -d '{"model": "Qwen/Qwen3-8B", "messages": [{"role": "user", "content": "Say hello in five words."}], "max_tokens": 32}'

    What you should see

    • A JSON answer with a message from the model.
    Help and sources

    If it does not work

    • If the answer is 401, the key in this shell is not the one the server was started with.
    • If it does not become ready, read the last log lines: the model is still loading, or the server stopped with an error.

Look at the machine

  1. Step 13

    Look at the GPUs

    See the memory in use and the work on the GPU at index 0 while the server runs.

    nvidia-smi --query-gpu=index,name,memory.used,memory.total,utilization.gpu --format=csv -i 0

    What you should see

    • Memory in use close to what the engine was given.
    Help and sources
  2. Step 14

    Look at the server

    See that vllm-qwen3-8b is running, and what it last said.

    Comes after step 12

    docker ps --filter name=vllm-qwen3-8b --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
    docker logs --tail 20 vllm-qwen3-8b

    What you should see

    • The server is running, and its last log lines show no errors.
    Help and sources

Compare with the calculator

  1. Step 15

    Compare with the calculator

    The calculator expected 22.76 GiB on each GPU, with 90 percent of the GPU given to the engine. The server's own log says what it took for the weights and what is left for the KV cache.

    Comes after step 12

    docker logs vllm-qwen3-8b 2>&1 | grep -E 'Model loading took|Available KV cache memory|GPU KV cache size'

    What you should see

    • Lines with the memory the weights took, the memory left for the KV cache and how many tokens it holds.
    Help and sources

    Where the values come from

    • The calculator: 22.76 GiB needed of 86.40 GiB usable on each GPU.

5Clean up

Stop the server and remove what these steps made.
  1. Step 16

    Stop it

    Can stop or remove things

    Stop vllm-qwen3-8b and free the GPUs.

    Comes after step 9

    docker stop vllm-qwen3-8b && docker rm vllm-qwen3-8b

    What you should see

    • No output, and the GPUs are free.

    Keep in mind

    • The endpoint stops answering.
    Help and sources

Calculation

  • Your input
  • Official specification
  • Calculated result
  • Estimate
  • Heuristic
  • Theoretical limit
›Weights
  1. Raw weight size

    Calculated result

    Raw weight size = parameters × nominal bits per parameter ÷ 8

    = Your input: 8.19B parameters × Official specification: 16 bit/param ÷ 8

    = 16.38 GB

  2. Weights in memory

    Calculated result

    Weights in memory = parameters × effective bits per parameter ÷ 8

    = Your input: 8.19B parameters × Official specification: 16 bit/param ÷ 8

    = 16.38 GB

›KV cache
  1. KV cache per token

    Calculated result

    KV cache per token = 2 × layers with a KV cache × KV heads × head dimension × KV cache bits per value ÷ 8

    = 2 × Your input: 36 × Your input: 8 × Your input: 128 × Your input: 16 bit ÷ 8

    = 147.46 KB/token

  2. KV cache per sequence

    Calculated result

    KV cache per sequence = KV cache per token × context length

    = Calculated result: 147.46 KB/token × Your input: 8,192 tokens

    = 1.21 GB

  3. KV cache

    Calculated result

    KV cache = KV cache per sequence × concurrent sequences

    = Calculated result: 1.21 GB × Your input: 4

    = 4.83 GB

›Memory per GPU and in total
  1. Required memory per GPU

    Estimate

    Required memory per GPU = Weights in memory + KV cache + Runtime overhead

    = Calculated result: 16.38 GB + Calculated result: 4.83 GB + Heuristic: 3.22 GB

    = 24.43 GB

  2. Model with runtime overhead

    Estimate

    Model with runtime overhead = Weights in memory + Runtime overhead

    = Calculated result: 16.38 GB + Heuristic: 3.22 GB

    = 19.6 GB

›One decode step and its limits
  1. Weights read per GPU in one step

    Calculated result

    Weights read per GPU in one step = Weights in memory

    = Calculated result: 16.38 GB

    = 16.38 GB

  2. Bytes read per GPU in one step

    Calculated result

    Bytes read per GPU in one step = Weights read per GPU in one step + KV cache

    = Calculated result: 16.38 GB + Calculated result: 4.83 GB

    = 21.21 GB

  3. Time to read the weights once

    Theoretical limit

    Time to read the weights once = Weights in memory ÷ GPU memory bandwidth

    = Calculated result: 16.38 GB ÷ Official specification: 1.6 TB/s

    = 10.26 ms

  4. Shortest time of one step

    Theoretical limit

    Shortest time of one step = Bytes read per GPU in one step ÷ GPU memory bandwidth

    = Calculated result: 21.21 GB ÷ Official specification: 1.6 TB/s

    = 13.28 ms

  5. Speed limit of one sequence

    Theoretical limit

    Speed limit of one sequence = 1 ÷ Shortest time of one step

    = 1 ÷ Theoretical limit: 13.28 ms

    = 75.28 tok/s

  6. Speed limit of all sequences

    Theoretical limit

    Speed limit of all sequences = concurrent sequences ÷ Shortest time of one step

    = Your input: 4 ÷ Theoretical limit: 13.28 ms

    = 301.13 tok/s

›Break-even points
  1. Batch where compute takes over

    Theoretical limit

    Batch where compute takes over = (Peak compute, dense × 1,000,000,000,000 ÷ GPU memory bandwidth) × effective bits per parameter ÷ 8 ÷ 2

    = (Estimate: 500 TFLOPS × 1,000,000,000,000 ÷ Official specification: 1.6 TB/s) × Official specification: 16 bit/param ÷ 8 ÷ 2

    = 313.09

Assumptions

  • Assumption: The KV cache is stored in blocks (16 tokens in vLLM), so the real capacity is slightly below the number shown.
  • Heuristic: Runtime overhead is 3.22 GB per GPU for the CUDA context, activations and graphs. It is a heuristic: vLLM measured 2.57 GiB for an 8B model, and it varies with engine and settings. Change
  • Assumption: Only 90 % of the GPU memory is given to the model. Serving engines reserve the rest: vLLM's default is 92 percent (documentation of version 0.32). Change
  • Assumption: A fit counts as comfortable when at least 10 % of the usable memory stays free. Change
  • Assumption: NVIDIA prints GPU memory in GB, and the hardware holds that many GiB: an H100 80 GB has 80 GiB, and nvidia-smi shows 79.6. The few percent that ECC and the driver keep back are covered by the usable share.
  • Assumption: The KV cache precision is set apart from the weight precision. Quantizing the weights does not shrink the KV cache or the overhead. Change
  • Assumption: Every sequence is assumed to use the full context at the same time, the worst case. Real traffic is usually shorter. Change
  • Assumption: Several GPUs are assumed to share the model with tensor parallelism, as vLLM does: weights and KV heads are split, and every GPU pays the runtime overhead.
  • Theoretical limit: These are limits, not forecasts. Real engines add kernel, scheduling and network time: published vLLM measurements ran 30 to 270 percent slower than the same formula, and the workshop's single-GPU runs 10 to 15 percent.
  • Assumption: No speculative decoding. It can produce several tokens in one step and beat a limit per sequence.
  • Assumption: Every weight outside the experts counts as read in each step. Embedding lookups read only a few rows of the input table, so the true minimum is a few percent lower for small models.
  • Theoretical limit: The batch where the compute of a step equals its memory time, from the dense peak of the format the weights compute in. Latency starts to rise before it. For a mixture of experts every expert needs this many tokens of its own.

Continue with

Your model and settings are carried over.

13.28 ms75.28 tok/sSpeed limit of one sequence

Why it matters

Every decoding step reads the weights it needs and the cache of every running sequence once, so a step cannot be shorter than those bytes over the memory bandwidth. That makes bandwidth the number that sets how fast a model answers, long before the compute of the GPU does. The limits here are physics. Real engines are slower, and a measurement tells you by how much.

How to read the result

The shortest step is the bytes one GPU reads in a step over its bandwidth, and the speed limits follow from it. They are limits, never forecasts: published vLLM measurements ran 30 to 270 percent slower. Enter your own measured time per token to see how close you are. The break-even batch is where compute starts to matter. For a mixture of experts the bytes grow with the batch, because more experts are touched.

Local AI and sovereignty

Running a model on hardware you control is one input to a sovereignty decision. It does not by itself make a deployment sovereign, GDPR compliant or EU AI Act compliant.

These tools come from the AI Without the Cloud workshop.

← All tools