All posts
DGX SparkLocal LLMvLLMBenchmarks

Which LLM should you run on a DGX Spark? gpt-oss-120B vs Qwen3.6-35B vs Gemma-4 26B

Three model stacks, one DGX Spark, a month of benchmarks: why Qwen3.6-35B with thinking off beats Gemma-4 26B and gpt-oss-120B on this box.

Daniel Voyce··9 min read

I ran three LLM stacks on one DGX Spark for a month. Same box, same 128 GB on the sticker, same documents going in. Here's the ranked verdict: gpt-oss-120B, the model I expected to win, came third.

The hardware is an NVIDIA GB10 Grace Blackwell (mine is the ASUS GX10, same silicon, different case, so I'll call it "DGX Spark" here). It has roughly 121 GiB of unified LPDDR5X shared between CPU and GPU, fed by about 260 to 273 GB/s of bandwidth, with no discrete VRAM. The model, its KV cache, the embedding model, the reranker and the OCR model all come out of the same pool, and when that pool runs out the box doesn't get slow: it OOM-kills you.

All three landed within 14 points of each other on the same 49-question set, and the biggest accuracy gain in the study came from fixing my own pipeline, not from swapping models. What separated them was speed, memory headroom and moving parts. Ranked: Qwen3.6-35B with thinking off for most of what most people do, Gemma-4 26B if you want one model doing every job, and gpt-oss-120B only when you can hand it the whole machine.

Verdict cards for the three models: Qwen3.6-35B at 2,805 tok/s batched with 28-30 GiB free, Gemma-4 26B consolidating chat, OCR and rerank, and gpt-oss-120B at 2,621 tok/s but only 1-7 GiB free
The verdict on one GB10: Qwen3.6-35B is the fast default (2,805 tok/s batched, 28-30 GiB free), Gemma-4 26B folds OCR and reranking into the LLM, gpt-oss-120B batches hardest but leaves 1-7 GiB free.

Accuracy didn't pick the winner

All three extracted a graph from the same corpus of enterprise agreements, scored by the same deterministic scorer.

Model Overall (49 Q) Multi-hop cross-doc Refused the unanswerable
gpt-oss-120B 79.6% (39/49) 83% (10/12) 100% (5/5)
Qwen3.6-35B (thinking off) 93.9% (46/49) 92% (11/12) 100% (5/5)
Gemma-4 26B (end-to-end) 91.8% (45/49) 100% (12/12) 100% (5/5)

The gpt-oss and Qwen rows isolate extraction, with a common answer model reading both graphs; Gemma's row extracts and answers, the harder test, so 91.8% is a floor. The gap to gpt-oss is pure recall: its sparser graph drops facts that are in the documents.

Gemma's first run scored 42.9%, from a three-week-stale bundle image that predated three fixes we'd already shipped. Rebuilding the app layer from current source took the same model on the same corpus to 91.8%. One fix, where OCR read tables perfectly but the values never reached the chunk stream, was worth 40% to 97% on table-heavy questions by itself.

1. Qwen3.6-35B-A3B, the default for most people

35B total, about 3B active per token, NVFP4 on vLLM. Single-stream it does 119.9 tok/s with thinking off; at 128 concurrent requests it reaches 2,805 tok/s, the highest batched ceiling of the three, a 23.4x gain. The useful knee comes earlier: aggregate throughput hits roughly 533 tok/s near concurrency 32, and per-stream latency collapses past it. Set max-num-seqs 32, with a worker fan-out to match.

Turn thinking off

Thinking on, graph extraction ran at about 20 minutes per document. Thinking off, 1.4 minutes, a 12x difference, and the slow mode was also worse, yielding roughly 43 raw entities per document against 58. It spends its budget on around 3,000-token reasoning traces, truncated and retried instead of extracting. I capped the thinking-on run at two documents.

It fits with room to work

Qwen's 49 GiB of weights and KV, plus the embedding model, reranker and GLM-OCR, come to roughly 91 GiB used and 28 to 30 GiB free. Extraction here is memory-bound, not compute-bound: 16 extraction workers is the sweet spot at around 106 GiB, 24 brushes the ceiling, 32 plateaus. More on the tuning in Seven levers that took a DGX Spark from "won't boot" to 2,800 tokens a second.

2. Gemma-4 26B-A4B, the consolidation play

26B total, only 3.8B active, FP8-Dynamic on a vLLM nightly. One server here does four jobs: chat, extraction, reranking and vision OCR are all the same /v1/chat/completions call with a different prompt or an image attached.

Diagram contrasting the separate-services architecture, LLM plus dedicated OCR, embedding and reranker models, with the consolidated architecture where one Gemma-4 model serves chat, OCR and reranking
Two architectures on one box: a stack of specialised models versus one Gemma-4 26B serving chat, vision/OCR and reranking, which is what leaves around 55 GiB free at idle.

Speculative decoding pays for itself here: MTP at k=4 took single-stream from 39.4 to 56.2 tok/s, a free 43% gain, lossless, at around 47% draft acceptance. Two caveats: MTP is FP8-only today (vLLM's NVFP4 path lacks the tie_weights the draft needs), and vision costs nothing at decode, 56.3 tok/s with images on versus 56.2 without. Batched it tops out near 1,011 tok/s at 128 concurrent, but the comfortable knee is 64, where p95 time-to-first-token is still sub-second.

The OCR trade-off

Gemma's built-in vision OCR reads a page in roughly 18 seconds, against 0.42 seconds for dedicated GLM-OCR, forty times slower. For months I quoted that as the reason to keep a dedicated OCR model for bulk ingest.

Measuring the phase instead of the page reversed the conclusion. On the same 100-document, 392-page corpus the consolidated path finished OCR at 339 docs/hr against the dedicated path's around 139: dropping the layout model removed a per-fork memory wall pinning both GLM-OCR runs to two OCR workers, and Gemma's vision path batches on the GPU instead. It loses 40x per page and wins 2.4x per phase, finishing 100 documents in 70.4 minutes, 85.2 docs/hr, measured. The gpt-oss and Qwen equivalents (roughly 5.5 and 24 to 32 docs/hr) are projections, not completed runs.

3. gpt-oss-120B, the whole-machine model

120B total, about 5B active, MXFP4 on SGLang. It's the most bandwidth-starved of the three single-stream at 61.4 tok/s, so it recovers most from batching: 2,621 tok/s at 128 concurrent, a 42.7x gain on identical silicon. That argument in full is Your DGX Spark isn't slow. You're testing it wrong.

Grafana panels during document ingest on the gpt-oss stack, showing three separate model services running concurrently: glm-ocr, Qwen3-Embedding-4B and Qwen3-Reranker-0.6B
The standard stack mid-ingest: three separate services, glm-ocr, Qwen3-Embedding-4B, Qwen3-Reranker-0.6B, each holding a slice of the same 121 GiB pool.

One model per job means four resident models, and with gpt-oss underneath them the box sits at 111 to 114 GiB used, 1 to 7 GiB free. Getting it to ingest at all took seven attempts; the fix was shutting off the admin UI, chatbox, sandbox, ml_worker, flower and the reranker (15 to 20 GiB of services), after which it managed six documents in 33 minutes. That's 0.18 docs/min, four times slower than Qwen, and two concurrent ingests is enough to risk an OOM.

gpt-oss-120B leaves 1 to 7 GiB free with the full stack up. That's not something you can tune around; it just OOMs. On this box, usability comes down to memory headroom more than tokens per second.

What actually ranks them: active params and free memory

Single-stream decode here is arithmetic: tok/s ≈ bandwidth ÷ active bytes per token. Active parameters matter, total ones don't: all three models above are Mixture-of-Experts designs activating 3 to 5B out of 26 to 120B. The one dense model I tried, a 31B Gemma activating all 30.7B every token (around 15.4 GB of reads per token at 4-bit), measured around 7 tok/s and was disqualified on the spot. The MoE variant runs 4 to 5.5x faster on the same box.

Chart of the roughly 121 GiB unified memory pool showing how each stack fills it: gpt-oss-120B at 111-114 GiB used, Qwen3.6 at about 91 GiB, and Gemma-4 at about 66 GiB idle
The same 121 GiB pool, three ways of filling it: 1-7 GiB free under gpt-oss-120B, 28-30 under Qwen3.6, around 55 under consolidated Gemma-4. Model choice on this box is a memory decision with a speed consequence, not the other way round. See "128GB of VRAM" is the most misread spec on the DGX Spark.
Component gpt-oss-120B Qwen3.6-35B Gemma-4 26B
LLM weights + KV cache 67-74 GiB 49 GiB 54.5 GiB
Embedding model 6.8 GiB 11.9 GiB 11.4 GiB
Reranker 2.4 GiB 4 GiB folded into the LLM
OCR 3.3 GiB 5-6 GiB folded into the LLM
Total used 111-114 GiB ~91 GiB ~66 GiB idle / ~102 peak
Free 1-7 GiB 28-30 GiB ~55 GiB idle

Where the memory goes, by stack, measured at idle and peak on the same box.

What I'd actually set

Use case Model Configuration
Accuracy-critical batch gpt-oss-120B Offload non-essential services, extraction workers at 8, ordered model load on boot, memory fraction tuned to 0.64
Production default (serve + extract) Qwen3.6-35B Thinking OFF, max-num-seqs 32, extraction workers at 16, OCR workers at 8, merge worker at 1 (overlapping data) or 4 (diverse)
Full consolidation (one model) Gemma-4 26B FP8+MTP max-num-seqs 64, OCR workers 8x8, extraction workers at 6, vision OCR on, pin a specific vLLM build

The Qwen recipe I actually run:

--max-num-seqs 32   # match your worker fan-out
rag_worker=16       # ~106 GiB sweet spot; 24 brushes the ceiling
ocr_worker=8
graph_merge_worker=1            # 4 only for diverse/multi-tenant data
MAX_ASYNC=8                     # merge fan-out: 59 s -> ~15 s
GLMOCR_PIPELINE_MAX_WORKERS=8   # any batching vision-OCR server
swap >= 48 GiB                  # a 61 GB model double-buffers to ~115 GB on load

Two of those look wrong until you've been bitten. Merge concurrency of 1 seems absurd until you ingest a corpus where every document says "Base Salary": four merge workers produced 217 lock timeouts, one produced zero. Pushing max-num-seqs past the sweet spot, 64 to 160, thrashed OCR roughly 3x too, because the GPU was already saturated on prefill (more in Most people tuning local LLMs optimise the wrong half of the problem).

How this was measured

One box, no cluster: a single GB10 with Prometheus, node-exporter and the DCGM GPU exporter feeding a Grafana dashboard, plus a benchmark script running five prompts at temperature 0, with warmup and repeats. The accuracy test set was held constant across stacks, same corpus, same 49 questions, same deterministic scorer, so the ranking turns on speed, memory and ops. Documents-per-hour is the shakiest row: only the Gemma run was driven to completion on current code, so treat that figure as directional and the rest as measured.

Certant is built so deployment follows the compliance team: cloud, your own infrastructure, or fully air-gapped, and a DGX Spark is the shape of box a regulated customer can put in their own rack. Qwen3.6-35B with thinking off is my pick for 90% of cases: it serves a team, ingests their documents, answers with citations, and never touches a network.

Build a brain for your business.

Certant turns your documents, data and processes into agents, dashboards and assistants you can actually trust.