
Tried running the 118B code-specialized MoE "Laguna S 2.1" on DGX Spark
This page has been translated by machine translation. View original
Introduction
Hello, I'm Morishige from Classmethod's Manufacturing Business Technology Department.
Poolside, an AI company specializing in agentic coding, released an open-weight MoE model called "Laguna S 2.1" on July 21, 2026. With a configuration of 117.6B total parameters and 8.5B active parameters, what catches the eye is the announcement specifically naming "runs on a single DGX Spark" as the target hardware. This may be the first time a code-specialized model exceeding 100B has officially listed DGX Spark as a supported target.
When the official announcement names specific hardware, it's only natural to want to verify whether it actually works as described. The day after the announcement, I loaded the official NVFP4 quantized version onto my DGX Spark and tested it across five dimensions: startup conditions, memory, speed, tool calling, and code correction quality. As a bonus, I also looked at Japanese language responses.
To state the conclusion upfront: the official NVFP4 version starts up as-is with vLLM v0.25.1 at 19.5 tok/s standalone, and adding DFlash speculative decoding pushed it up to a maximum of 31.2 tok/s. However, in my environment the results differed from the official recipe — the --moe-backend triton flag specified in the official recipe doesn't work as-is, and the optimal speculative depth was 3 rather than the official default of 15.
As part of the series searching for partner LLMs for DGX Spark, this follows the first article starting with Qwen3.6-27B (2026-07-06), the Qwen3.6-35B-A3B-NVFP4 matchup article (2026-07-13), and the Gemma 4 NVFP4 matchup article (2026-07-18).
This article presents the actual conditions for running Laguna S 2.1 NVFP4 on a single DGX Spark, along with measured performance showcasing the capabilities of this code-specialized model. I hope it resonates with those who use DGX Spark as a development companion.
What is Laguna S 2.1?
Laguna S 2.1 is an open-weight model specialized for code generation and agentic coding. The family also includes XS variants (33B/A3B) for local use and the flagship M.1 (225B/A23B), with S 2.1 sitting in between.
The architecture is a MoE that selects top-10 from 256 routed experts, with one shared expert attached. Of the 48 layers, 36 use sliding window attention (window 512) and 12 use global attention, a 3:1 hybrid arrangement. The native context length is 1M, but the NVFP4 model card used here sets it to 262,144.
The published benchmarks are 70.2% on Terminal-Bench 2.1 and 78.5% on SWE-bench Multilingual. Poolside's claim is that it's by far the best agentic coding model in its weight class. Since these are self-reported values, it's best to verify with tasks at hand.
The variety of distribution formats is a welcome point. In addition to BF16 (approximately 236GB), official FP8, NVFP4, INT4, GGUF, and MLX versions are available from the start, with the DGX Spark-targeted NVFP4 version weighing approximately 71GB. On my local disk it showed as 67GiB, which matches the published figure after unit conversion. Additionally, draft models for speculative decoding called "DFlash" (approximately 1B) are distributed in separate repositories by precision level. Since you don't need to create your own quantized versions, you can jump straight into testing after downloading.
The license is OpenMDW-1.1, a permissive license from the Linux Foundation ecosystem, allowing both commercial use and redistribution. This is the same one used by NVIDIA for the Nemotron family. Note that the flagship M.1 uses Apache 2.0, a different license within the family, so be careful not to confuse them.
Test Environment and Measurement Conditions
The test environment is as follows. Conditions are kept consistent with previous articles in the series.
| Item | Value |
|---|---|
| Hardware | DGX Spark (GB10, aarch64, 128GB unified memory) single unit |
| Inference Engine | vLLM v0.25.1 (vllm/vllm-openai:v0.25.1-aarch64 image) |
| Model | poolside/Laguna-S-2.1-NVFP4 (approximately 71GB, 67GiB on disk) |
| drafter | poolside/Laguna-S-2.1-DFlash-NVFP4 (2.1GiB) |
| KV cache | fp8 |
| max-model-len | 65,536 (262,144 for 262K verification only) |
| gpu-memory-utilization | 0.80 |
Speed is measured as single stream decode tok/s with output length fixed at 256 tokens (median of 3 runs), and aggregate tok/s with 8 concurrent requests. Since the official recipe explicitly states it was verified with vLLM 0.25.0 or later and speculative decoding with 0.25.1, I used the stable v0.25.1 image as-is.
Hit a Trap in the Official Recipe Right at Startup
First, the basic startup. Adding --tool-call-parser poolside_v1 --reasoning-parser poolside_v1 --enable-auto-tool-choice as per the official recipe, the server came up without any issues. The fact that the dedicated parser poolside_v1 is already included in stable v0.25.1 is evidence of tight release coordination, which makes a very positive impression. Japanese responses worked normally, and the tool call smoke test passed on the first try.
The stumbling block was speculative decoding. The speculative decoding command in the official recipe specifies --moe-backend triton, but adding this flag prevents startup.
ValueError: moe_backend='triton' is not supported for NvFP4 MoE. Expected one of
['cutlass', 'flashinfer_trtllm', 'flashinfer_cutlass', 'flashinfer_cutedsl',
'flashinfer_b12x', 'marlin', 'humming', 'emulation'].
The NVFP4 MoE path in vLLM v0.25.1 does not accept the triton backend, so pasting the recipe flag as-is results in immediate rejection for the NVFP4 version. The recipe was probably written with the BF16 or FP8 versions in mind and doesn't apply to the NVFP4 version. The fix is simple: remove the --moe-backend specification entirely and let vLLM auto-select, which allows normal startup including speculative decoding.
So which backend is fastest? I tested three configurations — auto, marlin, and explicitly specified triton — with the following results.
| moe-backend | single decode tok/s | Notes |
|---|---|---|
| auto | 19.87 | Internally selects FLASHINFER_CUTLASS |
| marlin | 19.86 | Tied with auto |
| triton | — | Cannot start due to the ValueError above |
Auto and marlin were essentially tied within margin of error. What's interesting is the auto resolution — looking at the serve logs, Laguna selects FLASHINFER_CUTLASS. When I ran the same auto with Qwen3.6-35B, it selected MARLIN, so the automatic selection result varies depending on the quantization format and expert configuration. All subsequent measurements use auto.
How 118B Fits in 128GB
Let me look at the memory side of "runs on a single DGX Spark." Measured immediately after startup with gpu-memory-utilization 0.80, of the 121GB total memory visible from the OS, 107GB was in use. The difference from the catalog's 128GB is due to unit conversion and reserved regions. In addition to the 67GiB of weights, vLLM allocated 27.11 GiB of KV cache. Combined with fp8 KV, this amounts to 977,533 tokens of cache capacity, enough to hold a maximum of 14.92 parallel 65,536-token requests.
Startup also succeeded with context extended to 262,144. Even in this configuration there's 1,114,602 tokens of KV capacity, allowing 4.25 full 262K requests to be held concurrently. The decode speed with short prompts is 19.39 tok/s, unchanged from the 65K setting, so regular use with long context in mind is practical. Community reports right after launch said "1M context is unrealistic, practical use up to 262K," and my conclusion is that 262K as the limit works with comfortable headroom.
DFlash Speculative Decoding Was Fastest at K=3
Here comes the main topic. Speculative decoding is a speedup technique where a small draft model predicts K tokens ahead in bulk, and the main model verifies them all in one step. If the prediction is correct, multiple tokens advance at once; incorrect ones are discarded, so effectiveness depends on the draft's accuracy and the choice of K.
Laguna comes with a dedicated draft model DFlash, and the official recipe presents num_speculative_tokens=15, i.e., K=15. On the other hand, on the NVIDIA Developer Forums on the day of the announcement, reports were flying that "spec 15 drops to 10~15 tok/s making it unusable, reducing to 7 gives 40~50 tok/s." To determine the truth, I swept K = 3 / 5 / 7 / 11 / 15 under identical conditions. The total acceptance rate in the table is the fraction of tokens proposed by the draft that were accepted by the main model; average accepted length is the number of tokens accepted per verification step.
| Configuration | single tok/s | vs base | 8-concurrent aggregate | Draft total acceptance rate | Average accepted length |
|---|---|---|---|---|---|
| base (no speculation) | 19.5 | — | 91.0 | — | — |
| DFlash K=3 | 31.15 | 1.60x | 121.9 | 52.1% | 1.56/3 |
| DFlash K=5 | 26.47 | 1.36x | 105.4 | 35.0% | 1.75/5 |
| DFlash K=7 | 30.42 | 1.56x | 106.7 | 29.0% | 2.03/7 |
| DFlash K=11 | 22.42 | 1.15x | 97.2 | 26.3% | 2.89/11 |
| DFlash K=15 (official) | 29.06 | 1.49x | 91.8 (≒base) | 13.6% | 2.04/15 |
Note that the base 19.5 tok/s is from a different serve run than the 19.87 in the backend verification, and this level of variation between serve runs is expected.

Single decode speed sweeping K from 3 to 15. Hatched bars indicate configurations where K+1 falls outside CUDA graph capture sizes causing padding; only K=5 and K=11 form valleys.
The results differed from both the forum reports and the official recipe. Three things can be said in summary.
First, the official default K=15 doesn't "collapse," but it's the worst choice among those tested. In single mode it maintains 29.06 tok/s at 1.49x base, but at 8 concurrent requests the aggregate is 91.8 tok/s — virtually identical to the 91.0 without speculation. Under parallel use, the benefit of speculative decoding disappears entirely. The 10~15 tok/s reported in the forum was not reproduced in my environment, so environmental factors seem significant.
Second, increasing K depth barely extends the accepted length. Looking at per-position acceptance rates from /metrics, at K=15 starting from 67.4% for the first token, it drops below 4.3% from the 8th onward, reaching 0.8% at the 15th. Average accepted length plateaus at around 2 tokens: 2.03 at K=7 versus 2.04 at K=15. K=11 fluctuated to 2.89 but ranked last in single speed, so it's not a counterexample. Meanwhile, the cost of one verification step scales proportionally with K, so paying a deeper K for negligible gain in accepted length is inefficient — increasing throughput with shallower K is better. This is the logic behind K=3 being fastest.

Per-position acceptance rate for K=7 and K=15. Both trace nearly the same curve, with almost no hits from position 8 onward. The structure where deeper K doesn't extend acceptance is clearly visible.
Third, only K=5 and K=11 dip unnaturally. The zigzag pattern 31.2 (K3) → 26.5 (K5) → 30.4 (K7) → 22.4 (K11) → 29.1 (K15) cannot be explained by acceptance rates alone. The hint was in the serve logs. CUDA graphs are a speedup mechanism that pre-records and replays computations of fixed sizes, and inputs that don't match a recorded size are padded up to the next size. vLLM runs these CUDA graphs in PIECEWISE mode during speculative decoding, with capture sizes following the sequence 1, 2, 4, 8, 16, 24…. The verification step processes draft K tokens + 1 main token = K+1 tokens, so K=3, 7, 15 land exactly on capture sizes, while K=5 and 11 waste computation with padding to the next size. This is an estimate from the config, but it cleanly matches the zigzag pattern.
So for using DFlash with Laguna on DGX Spark, it's best to choose K from values where "K+1 lands on a CUDA graph capture size." My recommended K is 3, and the startup flags take this form:
vllm serve poolside/Laguna-S-2.1-NVFP4 \
--speculative-config '{"method":"dflash","model":"poolside/Laguna-S-2.1-DFlash-NVFP4","num_speculative_tokens":3}' \
--tool-call-parser poolside_v1 --reasoning-parser poolside_v1 --enable-auto-tool-choice \
--kv-cache-dtype fp8 --max-model-len 65536 --gpu-memory-utilization 0.80
Placed among the models I've measured in the series, its position looks like this:

Comparison with models measured in the series. Laguna S 2.1 (★this time) goes from base 19.5 → DFlash K=3 at 31.1 tok/s. vLLM versions differ across measurement periods from v0.24.0 to v0.25.1.
poolside_v1 Tool Calling Was at Practical Level
For a model claiming agentic coding, tool calling is critical. I ran 6 single function call problems and 1 agentic task exploring a simulated filesystem with 3 tools, in both thinking and no-thinking modes.
| Evaluation Item | thinking | no-thinking |
|---|---|---|
| Minimal single call | ✅ | ✅ |
| Selection from 2 tools | ✅ | ❌ tag corruption |
| Nested arguments + enum + integer type | ✅ | ✅ |
| Parallel 2 calls in 1 turn | ❌ 1 only | ✅ |
| Japanese instructions + Japanese arguments | ✅ | ✅ |
| No excess calls when tool not needed | ✅ suppressed | ✅ suppressed |
| Agentic task (bug identification) | ✅ 4 turns | ✅ 4 turns |
Both modes scored 5 out of 6 on single calls. Tool calls returned as structured tool_calls had all valid argument JSON. The one failed case differed by mode: thinking mode reduced parallel 2 calls to 1, while no-thinking mode produced a format error where the calculation tool call tag corrupted and leaked into the body. The agentic task correctly reached the bug location in 4 turns in both modes. Since tool_calls arrive structured even in streaming, integration into agent frameworks should be straightforward.
One caveat about the reasoning parser: in non-streaming responses, there were cases where the thinking content wasn't separated into reasoning_content and instead mixed into content along with the </think> tag. Since tool call extraction works correctly the practical impact is limited, but applications that display content directly should add preprocessing to be safe.
Code Correction Matchup Against General-Purpose Champion Qwen 35B
Finally, the main specialty: code correction. Using existing OSS correction tasks risks the answers being in the training data, so I created a custom Python mini-repository for this evaluation. Starting from a 5-file inventory management CLI-like structure with 3 types of classic bugs planted (off-by-one boundary condition, mutable default argument, swallowed exception) totaling 4 fix locations, with 5 out of 12 pytest tests failing. Each model was given only 3 tools — read_file, write_file, run_tests — and allowed to run autonomously until all tests passed.
The opponent is Qwen3.6-35B-A3B-NVFP4, currently holding the partner LLM position in the series. I ran the same task on the same machine with the same vLLM. Speculative decoding was set to each model's fastest configuration: Laguna with DFlash K=3, Qwen with its bundled MTP 3-token lookahead enabled. Qwen showing only thinking mode in the table is because I focused on the representative configuration for comparison.
| Model | Result | Turns | Wall Time | Generated Tokens |
|---|---|---|---|---|
| Laguna S 2.1 (thinking) | 5/5 all fixed | 5 | 41.7 sec | 1,176 |
| Laguna S 2.1 (no-thinking) | 5/5 all fixed | 6 | 37.4 sec | 1,038 |
| Qwen3.6-35B-A3B (thinking) | 5/5 all fixed | 10 | 23.4 sec | 1,804 |
For bugs of this scale, both scored perfect. The difference was in approach. Laguna finished in 5 turns: run tests, read only the files relevant to failing tests, fix 3 bugs at once, retest — an efficient sequence with no wasted moves. Qwen used twice the turns (10), fixing one bug at a time in a cautious step-by-step style, but with decode speed of approximately 88 tok/s — nearly 3 times faster than Laguna — it was the fastest in wall time at 23.4 seconds.
The value of a code-specialized 118B appears in "fewer steps," while the value of a general-purpose 35B appears in "faster throughput" — a clear and instructive contrast. In this mini-repository, Qwen won in wall time, but the turn difference should matter more as tasks grow complex, and for heavy modifications surveying an entire repository, a reversal seems likely. This is something I'd like to verify in a follow-up by increasing the task scale.
Note that the infinite loop behavior reported by some immediately after the announcement never appeared in this evaluation. I had set up a guard of 20 turns and 15 minutes cutoff, but it was never needed.
Japanese Works Fine Too
I also confirmed Japanese capability with the 4 standard questions in the series: instruction compliance within 50 characters, free-form writing about remote work, code generation for deduplication sorting, and numerical reasoning about amounts.
Code generation and numerical reasoning were flawless. Free-form writing was in natural Japanese at a level usable as business writing as-is. For the instruction compliance question, it returned a 39-character answer "東京は日本の首都で、政治・経済の中心地です。世界的な都市として知られています。" and diligently appended "(49 文字)" (49 characters) on its own. The count is off, but it properly stayed within the 50-character instruction. However, due to the reasoning parser issue mentioned earlier, English thinking text mixed into the content before this correct answer, so mechanical character counting would produce false negatives. Japanese language ability itself is considerably better than you'd expect from the code-specialized label.
Summary
Laguna S 2.1 NVFP4 ran practically on a single DGX Spark as advertised. The day after the announcement, negative reports saying "DFlash acceptance rate is too low" were prominent, but actually getting hands on it revealed that the stumbling points were in the recipe details, and with the right configuration it's a model that can compete well — that's my honest assessment. There's something deeply gratifying about a 100B+ code-specialized model fitting on a local machine this easily.
What impressed me most during testing was the efficiency in code correction. Run the tests, read only the files that need reading, fix everything at once, done. This decisiveness is worthy of the code-specialized label, and it's become a realistic option to run as a permanent backend for an agent.
Next I'd like to increase the code correction task scale to find the reversal point against Qwen 35B, and try a comparison against current resident champion Hermes Agent in real-world use.
Reference Links
- Introducing Laguna S 2.1 | Poolside
- poolside/Laguna-S-2.1-NVFP4 | Hugging Face
- poolside/Laguna-S-2.1-DFlash-NVFP4 | Hugging Face
- vLLM recipes — Laguna-S-2.1
- OpenMDW License 1.1
- Laguna S 2.1 Config & Benchmarks - DGX Spark / GB10 | NVIDIA Developer Forums — Third-party benchmark thread from the day of announcement
- r0b0tlab/laguna-s-2.1-nvfp4-sm121-vllm | GitHub — Execution container and verification scripts for sm_121

