Does MoE on vLLM make sense? Qwen3.8-Flash-Next vs dense Qwen3.8-27B on two DGX Sparks
Qwen3.8-Flash-Next computes 6B of its 180B parameters per token and is 98.0 GiB in NVFP4. At the same 32–64K tokens of context per request, it decodes 53.0 tok/s vs 27.6 for dense Qwen3.8-27B at 1 request and 159.7 vs 69.4 at 9–12 requests.
| Flash-Next (MoE) | Qwen3.8-27B (dense) | |
|---|---|---|
| Active / stored params | 6B / 180B | 27B / 27B |
| Weights | 98.0 GiB, 51.98 GiB per rank | — |
| Decode, 1 request, 32–64K context | 53.0 tok/s | 27.6 tok/s |
| Decode, 9–12 requests, 32–64K context | 159.7 tok/s | 69.4 tok/s |
| Faster, by concurrency band | 6 of 6 | 0 of 6 |
| Qwen’s 12 text benchmarks | wins 12 of 12 | — |
Specs: Qwen3.8-Flash-Next, Qwen3.8-27B. Checkpoints: hibrid48 and nvidia/Qwen3.8-27B-NVFP4. Speeds: our measurements on 2× DGX Spark, vLLM TP=2.
Stored vs computed
Each token goes to 10 of 512 routed experts plus 1 shared expert. That is 6B parameters of arithmetic out of 180B held in memory. On these Sparks only ~37 of 6,144 CUDA cores multiply in a Flash-Next decode step, so routing saves weight bytes read per token, not compute time.
98.0 GiB resident
Every expert must stay resident, because the next token can be routed to any of them. vLLM’s expert parallelism shards experts across ranks (EP_SIZE = TP × DP). With TP=1 there is one rank, so the whole 98.0 GiB sits on it.
Routed experts are 64.6% of the checkpoint (67.95 GB of 105.24 GB). Per token, each MoE layer uses 10 of 512 of them.
Decode speed at equal context
Both models ran on one pair of DGX Sparks, vLLM TP=2 over ConnectX, with MTP speculative decoding, on production traffic. The load balancer logs a perf window every ~60 s with tokens generated, requests running and KV-cache usage. Context per request = KV tokens in use (usage × pool size) ÷ requests running; shared prefix blocks count once. Decode speed falls as context grows, and the two models saw different contexts: Flash-Next 61–114K tokens per request on average, the 27B 28–75K. So the comparison uses only windows at 32–64K per request, the range both models have in every band. Each figure is Σ tokens ÷ Σ seconds over those windows.
| Requests running | Flash-Next MoE | 27B dense | MoE ÷ dense | Minutes (MoE / dense) |
|---|---|---|---|---|
| 1 | 53.0 | 27.6 | 1.92× | 32 / 11 |
| 2 | 70.6 | 33.5 | 2.11× | 4 / 1 |
| 3–4 | 89.9 | 49.8 | 1.81× | 6 / 1 |
| 5–8 | 121.7 | 64.1 | 1.90× | 68 / 7 |
| 9–12 | 159.7 | 69.4 | 2.30× | 24 / 4 |
| 13–16 | 149.5 | 86.5 | 1.73× | 219 / 3 |
Without the context match, the 27B looked faster at 9–12 (89.0 vs 74.8 tok/s). That was context, not the model: in that band Flash-Next spent 139 min at 64–128K per request, decoding 34.5 tok/s, against 159.7 tok/s at 32–64K. The dense side has only 1–11 min per band, all from one day.
Flash-Next ran MTP 4 for 93% of its logged time (MTP 2–6 otherwise) at 6–24 seats; the 27B ran MTP 4 at 16 and 32 seats.
A controlled Flash-Next run (2026-09-30): 100 requests × 512 output tokens at 24 seats, 304.9–305.3 tok/s over 3 reps, 0 errors; prefill on 16 real ~32K-token prompts, 3,073 tok/s.
No published benchmark pairs these two models on 2× DGX Spark under the same settings. The two-node entries on Spark Arena run Flash-Next with MTP and the 27B with DFlash or a draft model.
Qwen’s 12 text benchmarks: +0.8 to +22.3 points
TL;DR
TL;DR: At the same 32–64K tokens of context per request on 2× DGX Spark, Flash-Next decodes 1.7–2.3× faster than dense Qwen3.8-27B in all 6 concurrency bands with data, and scores higher on all 12 of Qwen’s text benchmarks.