Introduction
Running a 120-billion-parameter reasoning model on a single workstation GPU used to be impossible. In 2026, thanks to NVIDIA’s NVFP4 quantization and the Blackwell architecture’s native FP4 tensor cores, it is now a practical afternoon project. This article walks through the complete, end-to-end deployment of nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4 on a single RTX PRO 6000 Blackwell (96 GB) — every command, every pitfall, and the real benchmarks at the end.
We will cover: connecting to the server, choosing the right model artifact, installing the serving stack, fixing the four problems you will hit on Blackwell, and measuring throughput.
The Target Hardware
| Component | Specification |
|---|---|
| GPU | NVIDIA RTX PRO 6000 Blackwell Workstation Edition |
| VRAM | 96 GB (97,887 MiB) |
| Compute Capability | sm_120 (Blackwell) |
| Driver | 580.95.05 / CUDA 13.0 |
| System RAM | 147 GB |
| Storage | 485 GB NVMe |
| OS | Ubuntu 22.04 |
The Model: Nemotron-3-Super-120B-A12B
This is the star of the show. Nemotron-3-Super-120B-A12B is a hybrid Latent Mixture-of-Experts model:
- 120 billion total parameters, but only 12 billion active per token (22 experts routed out of 512 per layer). This is why it runs fast despite its size.
- Architecture: interleaved Mamba-2 state-space layers, MoE layers, and select attention layers. The Mamba layers have O(1) recurrent state — they do not grow a KV cache — which is exactly how the model supports a 1,048,576-token (1M) context on a single GPU.
- NVFP4 quantization: experts are stored in 4-bit floating point (group size 16); attention and shared layers remain FP8. This shrinks the weights to ~80 GB, fitting comfortably in 96 GB VRAM with room for a large KV cache.
- Capabilities: configurable reasoning/thinking mode (via the chat template’s
enable_thinkingflag), native tool calling, and a 1M-token context window.
On Hugging Face it lives at nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4. It is public and ungated — no token or license-acceptance gate is required to download it.
Important naming note: There is no model literally called “Nemotron 3 Super NVFP4.” The official repository id is
nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4. An older, unrelated family member (nvidia/Llama-3.3-Nemotron-Super-49B-v1) is a DeciLM/NAS model — make sure you grab the right one.
Step 1 — Create a Python Environment
We do not need a full CUDA toolkit on the host; vLLM ships with everything inside its Docker image. We do need a small venv on the host for downloading the model and running benchmark scripts.
python3 -m venv /opt/nemotron-venv
/opt/nemotron-venv/bin/pip install --upgrade pip wheel setuptools
/opt/nemotron-venv/bin/pip install "huggingface_hub[cli]" hf_transfer
Step 2 — Download the Model (80 GB)
export HF_HUB_CACHE=/opt/models
mkdir -p /opt/models
/opt/nemotron-venv/bin/python - <<'PY'
from huggingface_hub import snapshot_download
snapshot_download(
"nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4",
cache_dir="/opt/models",
max_workers=16,
)
PY
This pulls 17 safetensors shards (~80 GB) plus the chat template and a custom reasoning parser (super_v3_reasoning_parser.py). Copy the parser somewhere stable — we will mount it into the container:
MODEL_PATH=$(find /opt/models -type d -path "*Nemotron-3-Super*/snapshots/*" | head -1)
cp "$MODEL_PATH/super_v3_reasoning_parser.py" /opt/super_v3_reasoning_parser.py
Step 3 — Generate an API Key
API_KEY="nm-$(openssl rand -hex 24)"
echo "$API_KEY"
mkdir -p /opt/nemotron-serve
echo "API_KEY=$API_KEY" > /opt/nemotron-serve/.api_key
chmod 600 /opt/nemotron-serve/.api_key
Keep this key secret — every request to the server must carry it as a Bearer token.
Step 4 — Fix Docker GPU Passthrough (Pitfall #1)
The host had Docker installed but no nvidia-container-toolkit, so --gpus all failed with could not select device driver "" with capabilities: [[gpu]]. The NVIDIA apt repository was already configured, so the fix was a one-liner:
apt-get install -y nvidia-container-toolkit
nvidia-ctk runtime configure --runtime=docker
systemctl restart docker
Verify the GPU is visible inside a container:
docker run --rm --runtime=nvidia --gpus all ubuntu:22.04 \
nvidia-smi --query-gpu=name,memory.total --format=csv,noheader
# NVIDIA RTX PRO 6000 Blackwell Workstation Edition, 97887 MiB
Step 5 — Pull the vLLM Image
The model README pins vLLM 0.20.0 with a purpose-built Blackwell image. Do not be tempted by a newer pip install vllm — the pip path hit two more problems (see the pitfalls below). Use the official image, which bundles a matched CUDA 13.x toolkit:
docker pull vllm/vllm-openai:v0.20.0
Step 6 — Launch the Server
Create the launch script. The flags come straight from the model’s official README, with two critical additions discovered during bring-up (explained in the pitfalls section).
cat > /opt/nemotron-serve/launch_docker.sh <<'EOF'
#!/bin/bash
set -euo pipefail
API_KEY="$(grep -oP 'nm-[0-9a-f]+' /opt/nemotron-serve/.api_key)"
MODEL_PATH="/root/.cache/huggingface/models--nvidia--NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4/snapshots/4f0cf9daaeb7a4d5e23f80a00e7ed15f0e03caf6"
docker rm -f nemotron-serve 2>/dev/null || true
exec docker run --name nemotron-serve \
--runtime nvidia --gpus all \
--network host \
--shm-size 16g \
--restart unless-stopped \
-e VLLM_ALLOW_LONG_MAX_MODEL_LEN=1 \
-e HF_HUB_OFFLINE=1 \
-e HF_HOME=/root/.cache/huggingface \
-e HF_MODULES_CACHE=/root/.cache/hf_modules \
-v /opt/models:/root/.cache/huggingface:ro \
-v /opt/hf-cache/modules:/root/.cache/hf_modules:rw \
-v /opt/super_v3_reasoning_parser.py:/app/super_v3_reasoning_parser.py:ro \
vllm/vllm-openai:v0.20.0 \
--model "$MODEL_PATH" \
--served-model-name nvidia/nemotron-3-super \
--host 0.0.0.0 \
--port 20000 \
--api-key "$API_KEY" \
--async-scheduling \
--dtype auto \
--kv-cache-dtype fp8 \
--tensor-parallel-size 1 \
--trust-remote-code \
--gpu-memory-utilization 0.90 \
--enable-chunked-prefill \
--max-model-len 1048576 \
--max-num-seqs 32 \
--mamba-ssm-cache-dtype float16 \
--reasoning-parser-plugin /app/super_v3_reasoning_parser.py \
--reasoning-parser super_v3 \
--enable-auto-tool-choice \
--tool-call-parser qwen3_coder
EOF
chmod +x /opt/nemotron-serve/launch_docker.sh
# writable HF modules dir for trust-remote-code
mkdir -p /opt/hf-cache/modules
# launch
nohup /opt/nemotron-serve/launch_docker.sh > /opt/nemotron-serve/docker.log 2>&1 &
What each key flag does
--max-model-len 1048576+VLLM_ALLOW_LONG_MAX_MODEL_LEN=1— unlocks the full 1M-token context (the model’smax_position_embeddingsis 262144, but the Mamba/attention hybrid legitimately extends to 1M; the env var lets vLLM exceed the conservative default).--kv-cache-dtype fp8— FP8 KV cache, halving attention memory and fitting longer contexts in VRAM.--mamba-ssm-cache-dtype float16— the Mamba-2 recurrent state in fp16 (required for the hybrid layers).--reasoning-parser super_v3+--reasoning-parser-plugin— loads the custom parser that splits reasoning traces into thereasoning_contentfield.--enable-auto-tool-choice --tool-call-parser qwen3_coder— enables function-calling in the OpenAI-compatible API.--max-num-seqs 32— see Pitfall #4.
Startup takes about 90 seconds: ~25 s to load 80 GB of weights, then ~60 s for torch.compile and CUDA graph capture. The server is ready when the log shows:
INFO ... Application startup complete.
Step 7 — Verify It Works
API_KEY=$(grep -oP 'nm-[0-9a-f]+' /opt/nemotron-serve/.api_key)
# list models — confirms the 1M context
curl -s http://localhost:20000/v1/models \
-H "Authorization: Bearer $API_KEY" | python3 -m json.tool
# chat
curl -s http://localhost:20000/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nvidia/nemotron-3-super",
"messages": [{"role":"user","content":"What is 17 * 23?"}],
"max_tokens": 500,
"temperature": 1.0,
"top_p": 0.95
}'
The Four Pitfalls (and Their Fixes)
I hit all four of these. If you follow the script above you will avoid them — but they are worth understanding.
Pitfall #1 — Docker GPU passthrough missing
Symptom: could not select device driver "" with capabilities: [[gpu]].
Cause: nvidia-container-toolkit not installed.
Fix: apt-get install -y nvidia-container-toolkit && nvidia-ctk runtime configure --runtime=docker && systemctl restart docker.
Pitfall #2 — Read-only filesystem for trust-remote-code
Symptom: OSError: [Errno 30] Read-only file system: '/root/.cache/huggingface/modules'.
Cause: The model uses trust-remote-code, which writes its custom nemotron_h Python module into a cache directory. I had mounted the HF cache as :ro.
Fix: Keep the weights mount read-only, but add a separate writable volume for HF_MODULES_CACHE: -e HF_MODULES_CACHE=/root/.cache/hf_modules -v /opt/hf-cache/modules:/root/.cache/hf_modules:rw.
Pitfall #3 — max_num_seqs exceeds available Mamba blocks
Symptom: ValueError: max_num_seqs (1024) exceeds available Mamba cache blocks (685). Each decode sequence requires one Mamba cache block, so CUDA graph capture cannot proceed.
Cause: The hybrid Mamba-2 layers allocate one fixed-size state block per concurrent sequence. vLLM’s default max_num_seqs of 1024 was too high for the VRAM left after the 69 GB of weights.
Fix: Add --max-num-seqs 32 (the model README suggests 4 for DGX Spark, but 32 fits comfortably in the 685 available blocks and gives better batch throughput).
Pitfall #4 — Why not just pip install vllm?
I tried a native pip install vllm (which pulled v0.26.0 with torch 2.11 / CUDA 13). It hit two Blackwell-specific JIT problems that the Docker image avoids entirely:
- Missing
nvccat runtime: vLLM’s CUTLASS NVFP4 kernels need to JIT-compile. The host had no CUDA toolkit, only the driver. Fixable by pointingCUDA_HOMEat the pip-installednvidia/cu13package — but that led to problem #2. - CUDA compiler / header mismatch: FlashInfer’s sm_120 FP4/NVFP4 GEMM JIT (
gen_gemm_sm120) failed with#error "CUDA compiler and CUDA toolkit headers are incompatible". The pipnvidia-cuda-nvcc(13.3) disagreed with the bundled CCCL/libcudacxx headers.
The purpose-built vllm/vllm-openai:v0.20.0 image contains a coherently-matched CUDA 13.x toolchain, so all the NVFP4 kernels compile and load cleanly on the first try. Use the Docker image.
Benchmarks
Measured against the live server with a single concurrent request:
| Test | Prompt | Output | Wall time | Throughput |
|---|---|---|---|---|
| Short generation | 25 tok | 60 tok | 0.66 s | 90.3 tok/s |
| Medium generation | 28 tok | 300 tok | 3.20 s | 93.7 tok/s |
| Long generation | 38 tok | 800 tok | 8.51 s | 94.0 tok/s |
| Large prefill | 2,427 tok | 120 tok | 1.43 s | ~1,780 tok/s (prefill+decode) |
~94 tokens/second steady-state decode from a 120B-parameter model on a single workstation GPU. That is remarkable, and it comes from three things working together: NVFP4 weights (4× compression with minimal accuracy loss), Blackwell’s native FP4 tensor cores, and the 12B-active Mamba/MoE hybrid architecture that keeps the per-token FLOPs low. Throughput is flat across output lengths, confirming the KV and Mamba caches are healthy.
Using the Server
The server speaks the standard OpenAI API. Point any OpenAI-compatible client at it:
from openai import OpenAI
client = OpenAI(
base_url="http://175.28.230.22:20000/v1",
api_key="nm-<your-key>",
)
resp = client.chat.completions.create(
model="nvidia/nemotron-3-super",
messages=[{"role": "user", "content": "Design a REST API for a todo app."}],
max_tokens=2000,
temperature=1.0,
top_p=0.95,
)
print(resp.choices[0].message.content)
Tool calling works the same way — pass tools=[...] and the model emits structured function calls. Multi-turn conversations work as expected (pass the full message history).
Thinking mode
The model’s chat template defaults to enable_thinking=True. When thinking is on, the model first produces a reasoning trace inside <think>...</think> tags, then the final answer. The super_v3 reasoning parser splits these into the response’s reasoning_content and content fields. To toggle it per-request:
resp = client.chat.completions.create(
model="nvidia/nemotron-3-super",
messages=[{"role": "user", "content": "Prove the Pythagorean theorem."}],
extra_body={"chat_template_kwargs": {"enable_thinking": True}},
...
)
Operations Cheatsheet
# check container status
docker ps --filter name=nemotron-serve
# tail logs
docker logs -f nemotron-serve
# restart (picks up the launch script)
docker restart nemotron-serve
# GPU usage
nvidia-smi
# rotate the API key
API_KEY="nm-$(openssl rand -hex 24)"
echo "API_KEY=$API_KEY" > /opt/nemotron-serve/.api_key
docker restart nemotron-serve
Conclusion
The era of “a 120-billion-parameter model on one GPU” has arrived. The Nemotron-3-Super-120B-A12B design — LatentMoE with Mamba-2 hybrid layers, trained natively in NVFP4 — is purpose-built for exactly this hardware moment. With an RTX PRO 6000 Blackwell you get a 1M-context reasoning model at 94 tok/s, behind a standard OpenAI-compatible API, for the cost of the electricity to run one card.
The tricky parts are all infrastructure: getting Docker GPU passthrough working, matching the CUDA toolchain for the NVFP4 JIT kernels, and sizing the Mamba/sequence caches correctly. Once those are solved (and the launch script above solves them), the deployment is stable and fast.
Model: NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4, governed by the NVIDIA Nemotron Open Model License. Serving: vLLM 0.20.0. All benchmarks are real, measured live on the described hardware.