GPU Benchmarks

Real numbers measured on hardware in our lab — by us, not copied from vendor slides — with the exact methodology published below. Last updated 2026-10-09.

Results Tools & downloads →
Benchmark model:

One model, every card we’ve tested

Every card below ran the same test model: nemotron-3.5-lightning — a 31B-parameter hybrid-MoE reasoning model (~3.5B active parameters, Q4_K_M quantization, 23.68 GiB on disk), available in the Ollama library. Testing against the same model is what makes your numbers comparable to this table. Decode = tokens generated per second while streaming an answer, single request, model fully resident in VRAM.

GPUHostServing stackDecode tok/s
NVIDIA RTX 5090 32GBdesktop, internal PCIevLLM / NVFP4 4-bit377
NVIDIA RTX 5090 32GBdesktop, internal PCIeOllama / CUDA (Q4_K_M GGUF)≈240
NVIDIA DGX Spark (GB10, 128GB unified)DGX SparkvLLM / NVFP4 4-bit≈120
Intel Arc Pro B70 32GB (ASRock)desktop, internal PCIeOllama / Vulkan45.5
Intel Arc Pro B70 32GB (ASRock)mini PC + USB4 eGPU enclosureOllama / Vulkan40.9
Intel Arc Pro B70 32GB — experimentaldesktop, internal PCIellama.cpp / SYCL-on-OpenCL50.6

Warm figures, average of 3 runs, identical prompt. Full environment versions in Methodology (Tools tab).

Measured: the NVFP4 format is worth +57% on the same card. We predicted the 5090’s Q4-GGUF-via-Ollama number was leaving Blackwell performance on the table — then measured it. The same 30B model served as NVFP4 via vLLM (pip venv, FlashInfer decode auto-selected for sm120) on the same RTX 5090: 377 tok/s vs ≈240 — 360.8 / 376.7 / 379.5 across three 600-token streamed runs. Same silicon, same watts, different number format. If your GPU has a native low-precision path, generic quants are the expensive convenience.

Deep dive: a GPU in an external USB4 enclosure — what does it really cost?

We put an ASRock Arc Pro B70 32GB in a Razer Core X V2 Thunderbolt/USB4 enclosure, drove it from a Getorli mini PC (AMD Ryzen 7 8745HS, 16GB DDR5) over a single USB4 40 Gb/s cable, and benchmarked it against the same model of card in an ordinary internal PCIe slot — same driver, same Ollama 0.32.15, same model file.

Internal PCIe slotUSB4 eGPU (40Gb/s)eGPU cost
Warm decode46.3 / 45.5 / 44.7 tok/s40.1 / 40.9 / 41.6 tok/s−10%
Cold model load (25GB, caches dropped)11.1 s33.4 s3× slower
Prompt processingwithin noise of each other≈0

Why the tunnel barely hurts decode

LLM token generation is bound by the GPU’s own memory bandwidth — once the 25GB of weights are in VRAM, each generated token moves only kilobytes across the cable. USB4 tunnels PCIe at roughly 3 GB/s of usable bandwidth (the enclosure’s internal slot negotiated PCIe 4.0 x4), and decode simply doesn’t need it. The ~10% penalty we did measure comes from added latency on the small per-token host↔GPU round-trips — not bandwidth.

Where the tunnel does hurt

Loading the model. Weights stream disk → RAM → USB4 → VRAM, and on our platform the tunnel firmware only granted the card a 256MB CPU-visible window (no Resizable BAR — the mini PC’s BIOS has no Above-4G/ReBAR options, and a kernel-level resize returned -ENOSPC: the USB4 bridge windows are fixed at boot). Result: 25GB squeezes through a 256MB porthole and cold loads take 3× longer. A serving box keeps hot models resident, so this is a once-per-boot cost — but know it exists.

Small-BAR side effect worth knowing: Intel’s OpenCL runtime (NEO) refuses to initialize on a small-BAR device entirely — clinfo reports zero platforms even though Vulkan works perfectly. Anything that detects GPUs via OpenCL will think the card doesn’t exist — if your tooling relies on OpenCL detection, add a Vulkan fallback.

Verdict

An eGPU is a perfectly good inference box: ~90% of internal-slot decode, full VRAM usable, and it turns a mini PC into a GPU server. If you’re choosing hardware for a new build, an internal slot is ~10% free performance — but if the machine you have is small and the GPU you have is external, it works.

Backend bake-off on Intel Arc: Vulkan vs SYCL

Same card (internal-slot B70), same llama.cpp build (3f545be), same GGUF file — only the compute backend changed:

BackendPrompt (pp512)Decode (tg128)Notes
Vulkan (Mesa 25.2.8)864 ± 5 t/s43.4 ± 0.03 t/swhat Ollama ships; rock solid
SYCL over Level-Zerocrash — UR_RESULT_ERROR_UNSUPPORTED_FEATURE (OP SCALE)Level-Zero path not ready for Battlemage Pro
SYCL over OpenCL918 ± 4 t/s (+6%)50.6 ± 0.03 t/s (+17%)ONEAPI_DEVICE_SELECTOR=opencl:gpu

The headline: +17% decode on the same silicon, free, from a backend switch — if you route SYCL over the OpenCL runtime rather than Level-Zero. Caveats: it requires working OpenCL (so not on small-BAR eGPU setups, see above), and Intel’s IPEX-LLM distribution — the thing most “Ollama on Intel” containers wrap — still fails on Battlemage Pro (its Ollama fork is generations old and its custom XMX kernels assert).

Serving the +17%: llama.cpp’s llama-server

Ollama has no SYCL backend, so capturing this in production means serving the model with llama-server — llama.cpp’s built-in OpenAI-compatible HTTP server — built with -DGGML_SYCL=ON and launched with ONEAPI_DEVICE_SELECTOR=opencl:gpu. The neat part: llama-server can point directly at the GGUF blob Ollama already downloaded (Ollama’s model blobs are plain GGUF files), so there’s no second copy of a 25GB model. On our internal-slot B70 that turns a 45.5 tok/s Ollama setup into a ≈50 tok/s one — same card, same watts. Trade-offs: one model per llama-server process (Ollama’s multi-model juggling goes away), and you own the systemd unit. Worth it on a dedicated inference box; skip it on a machine that hops between models.

Can you overclock an Arc Pro B70? (No — and it wouldn’t help)

Measured during live inference: the card sits pinned at 2800 MHz — its rated maximum boost — for the entire generation, while drawing ~180W of its 230W budget. It isn’t clock-starved and it isn’t power-throttled; it’s waiting on memory. Linux exposes clock floors/ceilings only up to the rated max, and GDDR memory clocks (the thing that would actually move tok/s) aren’t adjustable on any OS. The performance ladder on Arc is backends (see above), not clocks.

Parallel serving: check your slots are real

Ollama’s OLLAMA_NUM_PARALLEL=2 verified with two simultaneous streams on an RTX 5090: both completed in 2.43s wall clock where serial execution takes ~3.7s, second stream’s first token in 1.4s. Without the setting, a “2-slot” server quietly queues one request behind the other. And a general tip: if a server dies mid-stream the response truncates silently, so robust clients always check finish_reason.

DGX Spark: getting a 4-bit NVFP4 model from 78 to 120 tok/s

The DGX Spark (GB10 Grace-Blackwell, 128GB unified memory) earns its keep on efficiency: we benchmarked the NVFP4 4-bit build of nemotron — the format Blackwell accelerates natively — via vLLM. Getting there was not a one-liner, and the traps are worth publishing:

  • No pip path. pip install vllm does not produce a working install on GB10 — NVIDIA’s NGC container (nvcr.io/nvidia/vllm) is the only sane route. There is no :latest tag; you have to enumerate tags via the registry API and pick a dated one.
  • Container age matters. Older images predate newer model architectures and refuse them outright; 26.07-py3 worked for ours.
  • The xgrammar trap. Tool-calling needed a newer xgrammar, but a bare pip install -U xgrammar inside the container upgrades transformers v4→v5 and bricks the whole environment. pip install --no-deps xgrammar is the fix. (We bricked it once so you don’t have to.)
  • Tuning flags are worth +53%. Out of the box the model served at 78.5 tok/s. With serving flags tuned for the hybrid-mamba architecture (notably --mamba-backend flashinfer among them), the same box serves the same model at ≈120 tok/s.

Why bother, when Ollama would have run a generic quant with zero effort? Because a generic 4-bit GGUF on this box throws away the NVFP4 hardware path — we measured the difference as the difference between second-string and first-class results. If your silicon has a native low-precision format, serve that format.

Methodology

Run this on your own GPU: Nbench (free)

Nbench is our benchmark as a single free binary. Run it plain for the CLI — or run nbench -ui for a browser panel that shows your detected hardware, lists every model your Ollama already has, streams the run live, and shows the model’s actual answer alongside the number. It — no install, no dependencies, no accounts, and it never phones home. It benchmarks your local Ollama with the exact methodology above (hardware detection, warm decode, model load, and the 2-stream parallel check), so the number it prints is directly comparable to every number on this page. Windows, Linux, and macOS.

PlatformInstall (one line, no admin needed)
Linux & macOSshow install command
Windows (PowerShell)show install command

The installer detects your system, puts nbench on your PATH (Windows also gets a Start Menu shortcut), and never needs administrator rights. Paste it into a terminal (PowerShell on Windows).

Advanced: raw binaries

For scripted or offline installs — same acceptance applies: linux-amd64 · linux-arm64 · windows · mac-apple-silicon · mac-intel

Installing or downloading requires accepting the as-is/no-warranty terms (one click). Needs a local Ollama. Default model is llama3.2:3b (a ~2GB one-time pull) so anyone can run it; to compare directly against the table above, run -model nemotron-3.5-lightning:latest (a ~25GB pull — needs a card with roughly 26GB+ of free VRAM); benchmark any other model with -model <name>, and -json - emits the full machine-readable result. A community leaderboard — opt-in submission of your score — is coming next.