Local LLM Benchmark Results on DGX Spark & 96–128 GB Edge AI Workstations

October 2026 update. These are the earlier (April–September 2026) results with older images. The new same-hardware round with vLLM 0.31.0, 128K context and 4 concurrent users is in Benchmarks, with copy-paste recipes. Notably, Nemotron 3 Super 120B-A12B now runs on vLLM 0.31.0 (16.1 tok/s, 23.0 with MTP, ~95 GB), so the vLLM failure described below applies only to the older gemma4-0505-cu130 image.

For the quick start guide see Home. For the original Spanish log see Results in Spanish.

This document contains the full benchmark results and technical notes for running Gemma 4, Qwen 3.6 and NVIDIA Nemotron 3 locally on the NVIDIA DGX Spark and equivalent high-memory edge AI hardware.


Hardware / software base

ComponentValue
HardwareNVIDIA DGX Spark (GB10 Grace Blackwell)
CPU20 cores ARM64 (aarch64)
GPUNVIDIA GB10 (sm_121)
Memory128 GB LPDDR5x unified (~121 GB usable)
NVIDIA driver580.142
CUDA13.0
Docker29.2.1
NVIDIA Container Toolkit1.19.0

Critical GB10 limitation: no native FP4 compute. NVFP4 checkpoints run through the Marlin backend (--moe-backend marlin) in vLLM or the PyTorch backend in TensorRT-LLM, decompressing FP4 → BF16 at runtime. This limits throughput compared to FP4-native GPUs such as the B200.


Benchmark methodology

Text benchmarks used a ~120-token Spanish prompt, max_tokens=512, temperature 0.7 and streaming enabled. We report decode tok/s (excluding cold-start TTFT) and hot TTFT. Memory numbers reflect peak unified memory usage observed during the run.

Full results table

Total = parámetros totales del modelo · Activos = los que se ejecutan por token (clave para bandwidth del decode).

ModelParams (total/activos)CheckpointFramework / containerDecode tok/sHot TTFTMemoryNotes
Qwen3.8-Flash-Next NVFP4 hybrid176B / 6BRadixArk/Qwen3.8-Flash-Next-NVFP4qwen38-flash-dgx (vLLM release/qwen38next + 7 parches GB10)~37 warm / 117 @c=8~0.24 s~98 GBCurrent default (2026-09-01). MoE 176B (6B activos), GSM8K 97.27%, AIME26 98.75%. Recipe blazux/qwen3.8-Flash-DGX. NVFP4 experts + fp8 side layers. Cold start 14 min.
Qwen 3.8 27B NVFP4 + DSpark k=1427B / 27Bunsloth/Qwen3.8-27B-NVFP4vllm/vllm-openai:v0.27.1-aarch6413.93 fresh / 182 @c=8 warm / 253 @c=16~0.10 s~105 GBFallback lite. DSpark k=14 drafter externo, prefix caching obligatorio. Multimodal texto+imagen+video. Mejor concurrencia.
Qwen 3.6 35B-A3B35B / 3Bnvidia/Qwen3.6-35B-A3B-NVFP4vllm/vllm-openai:nightly~76~0.10 s~22 GBSingle-stream speed champion con long-context 262K. W4A16 NVFP4 (modelopt), flashinfer backend, FP8 KV cache, Marlin NVFP4 backend for SM121, qwen3_coder parser, 262K context, 1 sequence.
Gemma 4 26B-A4B IT26B / 4Bbg-digitalservices/Gemma-4-26B-A4B-it-NVFP4 + gemma4_patched.pyvllm/vllm-openai:gemma4-cu130~49.5~0.08 s~22 GBBest raw speed for agents. Requires community patch.
Qwen 3.6 35B-A3B35B / 3BRedHatAI/Qwen3.6-35B-A3B-NVFP4vllm/vllm-openai:gemma4-0505-cu130~42.2~0.10 s~22 GBcompressed-tensors format. Stable previous checkpoint.
Nemotron-3-Nano-Omni-30B-A3B30B / 3Bnvidia/NVIDIA-Nemotron-3-Nano-Omni-30B-A3B-Reasoning-NVFP4vllm/vllm-openai:gemma4-0505-cu130~40.0~0.10 s~40 GBOfficial multimodal: text + image work. Audio decoding still unresolved in this container.
Qwen 3.6 35B-A3B (n-gram speculative)35B / 3BRedHatAI/Qwen3.6-35B-A3B-NVFP4vllm/vllm-openai:gemma4-0505-cu130~34–37~0.10 s~22 GBWorse for non-repetitive text.
Qwen 3.6 35B-A3B TRT-LLM (MLP-only NVFP4)35B / 3BQuantized with Model Optimizer 0.44.0 from Qwen/Qwen3.6-35B-A3B BF16nvcr.io/nvidia/tensorrt-llm/release:1.3.0rc13~34.5~0.09 s~41 GBmodelopt NVFP4 MLP-only + FP8 KV. Works with TRT-LLM PyTorch backend. Chat template does not produce clean thinking output in our tests.
Gemma 4 26B-A4B IT (official)26B / 4Bnvidia/Gemma-4-26B-A4B-NVFP4vllm/vllm-openai:gemma4-0505-cu130~30.1~0.20 s~21 GBWorks without patch, but ~20 tok/s slower.
Nemotron-3-Nano-30B-A3B30B / 3Bnvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16nvcr.io/nvidia/tensorrt-llm/release:1.3.0rc13~28.8~0.22 s~118 GBDense-ish BF16. Uses almost all unified memory.
Nemotron-3-Nano-30B-A3B30B / 3Bnvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16vllm/vllm-openai:gemma4-0505-cu130~28.3~0.20 s~72 GBvLLM alternative. Stop other GPU services first.
Nemotron-3-Super-120B-A12B120B / 12Bnvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4nvcr.io/nvidia/tensorrt-llm/release:1.3.0rc13~14.7~0.29 s~110 GBOfficial NVFP4 checkpoint. Higher quality, lower speed due to more active experts.
Gemma 4 31B IT31B / 31Bnvidia/Gemma-4-31B-IT-NVFP4vllm/vllm-openai:gemma4-0505-cu130~6.7~1.8 s~31 GBDense, memory-bandwidth limited. Not recommended for fast interactive use.
Qwen 3.6 35B-A3B (MTP)35B / 3BRedHatAI/Qwen3.6-35B-A3B-NVFP4vllm/vllm-openai:gemma4-0505-cu130Load error––moe_backend='marlin' not supported by the non-quantized drafter.
Gemma 4 26B-A4B on TRT-LLM 1.3.0rc1326B / 4Bnvidia/Gemma-4-26B-A4B-NVFP4nvcr.io/nvidia/tensorrt-llm/release:1.3.0rc13Load error––Transformers in container does not recognize model_type: gemma4.
Qwen 3.6 35B-A3B on TRT-LLM 1.3.0rc1335B / 3Bnvidia/Qwen3.6-35B-A3B-NVFP4nvcr.io/nvidia/tensorrt-llm/release:1.3.0rc13Load error––AssertionError in quant_algo for modelopt NVFP4 checkpoint.
Nemotron-3-Super-120B-A12B120B / 12Bnvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4vllm/vllm-openai:gemma4-0505-cu130———Not viable: CUDA OOM on engine init; first attempt hung the Spark due to memory exhaustion.

Key takeaways


Why vLLM (with Marlin) and not TensorRT-LLM for Qwen 3.6

We tested two paths for Qwen 3.6 35B-A3B on the DGX Spark:

PathSpeedStabilityNotes
vLLM nightly + nvidia/Qwen3.6-35B-A3B-NVFP4 + Marlin~76 tok/sStable after the Marlin fixFastest option today.
TensorRT-LLM 1.3.0rc13 + custom MLP-only NVFP4 quant~34 tok/sStableRequires manual quantization; official NVIDIA checkpoint fails to load.

TensorRT-LLM worked, but it was almost 2× slower than vLLM. The reason vLLM had been failing earlier was not vLLM itself, but the default FP4/CUTLASS backend on GB10 (SM121). Switching to the Marlin backend for NVFP4 solved the crashes and memory saturation, letting us keep vLLM’s speed.

What is Marlin?

Marlin is a GPU kernel backend optimized for running quantized weights — especially 4-bit (INT4/FP4) — on NVIDIA GPUs. For MoE models like Qwen 3.6, vLLM exposes it via --moe-backend marlin.

The GB10 in the DGX Spark has no native FP4 compute (SM121 lacks a working FP4/CUTLASS path for these checkpoints). Marlin works around that by:

  1. Reading the FP4/quantized weights from disk.
  2. Decompressing them to BF16 at runtime inside optimized CUDA kernels.
  3. Using its own GEMM kernels instead of the broken CUTLASS FP4 kernels.

On newer GPUs with native FP4 (e.g. B200), the CUTLASS FP4 backend would be faster. On the Spark, Marlin is the only path that gives both speed and stability for the NVIDIA NVFP4 checkpoint.

The extra environment variables force vLLM to select Marlin-compatible kernels for FP8/Marlin fused ops and avoid atomic-add issues on this architecture:

-e VLLM_TEST_FORCE_FP8_MARLIN=1 \
-e VLLM_MARLIN_USE_ATOMIC_ADD=1

Without Marlin, vLLM falls back to CUTLASS FP4 kernels that crash or hang on SM121 — exactly the bmm_fp8 / CUDNN_STATUS_EXECUTION_FAILED_CUDA_DRIVER errors we saw earlier.


Why Nemotron-3 Super 120B-A12B fails on vLLM

Fixed in vLLM 0.31.0: see Benchmarks and the nemotron3-super-120b-nvfp4-mtp-v031 recipe.

We attempted twice to serve nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4 with vllm/vllm-openai:gemma4-0505-cu130.

First attempt

The container loaded all 17 checkpoint shards (~75 GB on disk) in ~8 minutes. The last logs showed:

Loading weights took 489.67 seconds
WARNING ... Your GPU does not have native support for FP4 computation ...
Using MoEPrepareAndFinalizeNoDPEPModular
Using uncalibrated q_scale 1.0 ...

Before the HTTP server came up, the Spark hung and had to be rebooted. Root cause: two llama-server processes running Qwen GGUF models were consuming ~76 GB of unified memory, leaving insufficient room for vLLM.

Second attempt (after freeing memory)

After stopping qwen27-local.service and qwen35-local.service, the system had ~117 GB free. However, vLLM failed immediately while initializing the EngineCore:

torch.AcceleratorError: CUDA error: out of memory
  File ".../vllm/utils/mem_utils.py", line 108, in measure
    self.free_memory, self.total_memory = current_platform.mem_get_info(device)

vLLM could not even query available memory without hitting an OOM.

Diagnosis

The model uses a hybrid Mamba-MoE architecture (NemotronHForCausalLM) with:

Although the checkpoint is ~75 GB on disk, decompressing FP4 → BF16 via Marlin, allocating KV cache under --gpu-memory-utilization 0.90, and compiling kernels with the vLLM V1 engine (torch.compile/inductor) exceeds the 128 GB unified-memory budget.

Why TensorRT-LLM works

The same checkpoint serves stably at ~14.7 tok/s and ~110 GB with:

trtllm-serve /models/nemotron --backend pytorch --max_seq_len 8192 --max_batch_size 1 --kv_cache_dtype fp8

TRT-LLM reserves a fixed memory budget (model + KV cache for the given seq_len/batch + activations) instead of vLLM’s percentage-based dynamic PagedAttention allocation.

Conclusion: on DGX Spark and equivalent 128 GB unified-memory hardware, Nemotron-3 Super 120B-A12B should only be used with TensorRT-LLM.


Extreme context scaling: Qwen 3.6 35B-A3B

For agentic workflows that ingest very long contexts (codebases, conversation history, RAG dumps, multi-turn agent traces) we tested how far nvidia/Qwen3.6-35B-A3B-NVFP4 can scale on the DGX Spark. We used vLLM nightly with:

--model /models/qwen3.6 \
--trust-remote-code \
--tensor-parallel-size 1 \
--attention-backend flashinfer \
--moe-backend marlin \
--gpu-memory-utilization 0.92 \
--max-model-len 262144 \
--max-num-seqs 1 \
--max-num-batched-tokens 32768 \
--enable-chunked-prefill \
--async-scheduling \
--enable-prefix-caching \
--load-format fastsafetensors \
--kv-cache-dtype fp8 \
--enable-auto-tool-choice \
--tool-call-parser qwen3_coder

Environment variables passed to the container:

-e VLLM_TEST_FORCE_FP8_MARLIN=1 \
-e VLLM_MARLIN_USE_ATOMIC_ADD=1

The 1-sequence/262K configuration is the recommended default because it uses the model’s full context window (262,144 tokens) with a single concurrent sequence. We reserve 237K tokens for input and 25K for output to avoid ContextWindowExceededError on long agent sessions. Earlier iterations ran 240K/1 seq to leave extra memory headroom; after measuring memory use we moved to the full 262K window while keeping --max-num-seqs 1.

Single-sequence context scaling

Input tokensOutput tokensTTFTDecode tok/sNotes
1,000320.28 s45.57Warm baseline.
50,0006427.1 s45.66First large-context call; includes some JIT warmup.
100,0006422.87 s39.80Faster TTFT than 50K because kernels are warm.
180,00064~50 s~35Stable within the 262K operational limit.
200,0006465.45 s33.17Stable, memory ~120 GB (historical data at 240K/1 seq).
250,00064––Near the current 262K operational limit; use for extreme long-context sessions.

Memory behavior

Practical guidance for agents


Launch scripts

Ready-to-run recipes are in scripts/:

ScriptModel / framework
scripts/run-gemma4-26b-a4b.shGemma 4 26B-A4B IT NVFP4 community patch on vLLM
scripts/run-qwen38-flash-next.shQwen3.8-Flash-Next NVFP4 hybrid on vLLM release/qwen38next (default 2026-09-01, recipe blazux/qwen3.8-Flash-DGX)
scripts/run-qwen38-27b-nvfp4-dspark.shQwen 3.8 27B NVFP4 + DSpark k=14 on vLLM 0.27.1 (fallback lite)
scripts/run-qwen36-35b-a3b.shQwen 3.6 35B-A3B nvidia NVFP4 on vLLM nightly (262K context, 1 seq, single-stream champion)
scripts/run-qwen36-35b-a3b-extreme-context-2seq.shAlias to run-qwen36-35b-a3b.sh (262K × 1 session)
scripts/run-qwen36-35b-a3b-trtllm.shQwen 3.6 35B-A3B custom MLP-only NVFP4 on TRT-LLM
scripts/run-gemma4-31b.shGemma 4 31B IT NVFP4 on vLLM
scripts/run-nemotron3-nano-30b-a3b-trtllm.shNemotron-3 Nano BF16 on TRT-LLM
scripts/run-nemotron3-nano-30b-a3b-vllm.shNemotron-3 Nano BF16 on vLLM
scripts/run-nemotron3-super-120b-a12b-trtllm.shNemotron-3 Super NVFP4 on TRT-LLM
scripts/run-nemotron3-nano-omni-vllm.shNemotron-3 Nano Omni NVFP4 multimodal on vLLM

Run a benchmark after the container reports healthy:

python3 benchmarks/bench_model.py gemma-4-26b-a4b 512

Important technical notes

  1. ARM64: always verify the Docker image has an arm64 manifest.
  2. Marlin is required for MoE NVFP4 on GB10: use --moe-backend marlin. Native FP4 backends (CUTLASS/FlashInfer) may fail or produce NaN on sm_121.
  3. FP8 KV cache saves memory but relies on checkpoint scaling factors; vLLM warns about accuracy if they are missing.
  4. Prefix caching speeds up requests with shared context or repeated long prompts.
  5. Tool calling: Qwen 3.6 requires --enable-auto-tool-choice --tool-call-parser qwen3_coder (the qwen3_coder parser is more robust for multi-turn than the older qwen3_xml); without a parser, vLLM returns XML in content and leaves the native tool_calls array empty. We omit --reasoning-parser for the nvidia/Qwen3.6-35B-A3B-NVFP4 checkpoint because it does not emit <think></think> tags; with the parser active, reasoning leaks into the reasoning field and content appears empty in agents.
  6. max-num-batched-tokens: for multimodal input (Gemma 4), must be >= max_tokens_per_mm_item (e.g. 2496 for Gemma 4, 4096 by default).
  7. TensorRT Model Optimizer on GB10: quantizing Qwen 3.6 from BF16 requires converting the VLM checkpoint to text-only and using total GPU memory (not free memory) because accelerate does not understand the 128 GB unified pool.
  8. TRT-LLM PyTorch backend reads hf_quant_config.json; use --backend pytorch and --kv_cache_dtype fp8 for HF NVFP4 checkpoints.
  9. Background services: stop VRAM consumers such as llama-server before launching large models. Two Qwen GGUF servers used ~76 GB in our tests and caused OOM/hangs.

Final recommendation

For agentic workflows on DGX Spark and similar 96–128 GB edge AI workstations:

Gemma 4 31B dense should be reserved only for tasks where the dense model quality justifies ~7 tok/s.

Choosing the right model:

EscenarioModeloPor qué
Default operativo (2026-09-01): agentic workflows, código, razonamiento, multimodalQwen3.8-Flash-Next hybridMejor balance calidad/concurrencia/multimodal
Single-stream long-context máximo (1 sesión × 262K, prioriza velocidad pura)Qwen 3.6 35B-A3B nvidia NVFP4~76 tok/s sustained con Marlin + flashinfer
Concurrencia máxima (8+ auxiliares Hermes/Opencode en paralelo)Qwen 3.8 27B + DSpark k=14253 tok/s @c=16
Velocidad pura en agente corto (< 128K ctx)Gemma 4 26B-A4B community~50 tok/s, baja VRAM
Calidad máxima + razonamiento pesadoQwen3.8-Flash-Next hybrid (GSM8K 97.27%)MoE 176B
Solo texto, sin multimodal, baja concurrenciaNemotron-3-Super 120B (TRT-LLM)Calidad máxima oficial