NVFP4 vs FP8 on an RTX PRO 6000 Blackwell (vLLM 0.24): sadly, FP4 is still not faster than FP8 - Qwen3.6‑27B
TL;DR
Same model, two quantizations — nvidia/Qwen3.6-27B-NVFP4 (4‑bit) vs Qwen/Qwen3.6-27B-FP8 (8‑bit) — head‑to‑head, each on its own RTX PRO 6000 Blackwell (96 GB), with vLLM and MTP speculative decoding (3 tokens) on both.
Even today, on the latest vLLM (0.24.0) and Blackwell, NVFP4 is not faster than FP8. FP8 is ~8–12 % faster on decode in every single‑stream and high‑concurrency scenario; the two only draw level on prefill‑bound big‑context concurrent load. Warm TTFT is identical.
Quality is effectively tied on everything with an objective answer (logic puzzle, edge‑case Python, strict‑schema long‑context JSON). Czech is native and artifact‑free on both, with FP8 a hair cleaner and better‑behaved in "thinking" mode. No catastrophic degradation on either.
Caveat: the endpoints ran different vLLM builds (NVFP4 0.24.0, FP8 0.23.1rc1‑dev). That plausibly favors NVFP4 — and it still doesn't win.
Setup
| NVFP4 | FP8 | |
|---|---|---|
| Model | nvidia/Qwen3.6-27B-NVFP4 |
Qwen/Qwen3.6-27B-FP8 |
| GPU | 1× RTX PRO 6000 Blackwell, 96 GB | 1× RTX PRO 6000 Blackwell, 96 GB |
| vLLM | 0.24.0 | 0.23.1rc1.dev233+g635c38338 |
| Weights | NVFP4 (4‑bit) | FP8 (8‑bit) |
| Spec. decoding | MTP, num_speculative_tokens=3 |
MTP (qwen3_next_mtp), num_speculative_tokens=3 |
| KV cache / max‑len / gpu‑util / max‑seqs | fp8_e4m3 / 262k / 0.92 / 128 | fp8_e4m3 / 262k / 0.92 / 128 |
| Extra | flashinfer attention, marlin/triton MoE, fastsafetensors | vLLM defaults |
| Prefix caching / chunked prefill / async scheduling | on | on |
Verified via nvidia-smi: each quant on its own GPU (NVFP4→GPU0, FP8→GPU1), so both were benchmarked in parallel without competing for compute. OpenAI‑compatible streaming endpoints. Non‑thinking mode unless noted.
Methodology
Client‑side streaming, timed send→[DONE], tokens from the server usage block. Four throughput scenarios + a 7‑prompt quality suite (Czech poem, reklamace e‑mail, HTML to‑do, HTML Snake, logic→JSON, merge_intervals, 59 KB→JSON analysis) in both modes.
| Scenario | What | Concurrency | Prompt size |
|---|---|---|---|
single_tale |
one ~2000‑word Czech tale | 1 | ~130 tok |
big_prompt |
one ~59 KB doc → synthesis | 1 | ~22 300 tok |
par_tale |
16× the tale at once | 16 | tiny |
par_big |
4× the big prompt at once | 4 | ~22 300 tok |
Total wall‑clock: ~20 min end‑to‑end (both GPUs in parallel).
Throughput (non‑thinking, MTP=3) — decode tok/s, higher is better
| Scenario | metric | NVFP4 | FP8 | winner |
|---|---|---|---|---|
| single, small | decode tok/s | 77.1 | 84.7 | FP8 +10 % |
| TTFT (warm) | 0.09 s | 0.09 s | tie | |
| big (~22.3k in) | decode tok/s | 98.7 | 111.0 | FP8 +12 % |
| prefill tok/s / TTFT | ~5 700 / 3.9 s | ~7 000 / 3.2 s | FP8 | |
| 16× concurrent | aggregate tok/s | 891.7 | 963.3 | FP8 +8 % |
| per‑request decode tok/s | 67.4 | 68.5 | ~tie | |
| e2e p95 | 58.6 s | 55.6 s | FP8 | |
| 4× concurrent, big | aggregate tok/s | 358.9 | 342.5 | NVFP4 +5 % |
| per‑request decode tok/s | 100.4 | 103.7 | ~tie |
No failures or truncation at concurrency 16. FP8 wins the decode‑bound scenarios by a consistent ~8–12 %; the only place NVFP4 draws level (and edges ahead) is heavy prefill‑bound concurrent load (par_big), where both are limited by chewing through 22k‑token prompts rather than by weight bandwidth. Warm TTFT is identical.
The first NVFP4 request showed ~3.7 s TTFT — one‑time vLLM warm‑up (CUDA‑graph capture), not the quant; warm value is 0.09 s.
Per‑prompt answer latency (non‑thinking)
| Prompt | NVFP4 latency / tok/s | FP8 latency / tok/s |
|---|---|---|
| Czech poem (~2000 words) | 49.3 s / 74.4 | 36.8 s / 87.3 |
| HTML to‑do app | 16.3 s / 104 | 15.9 s / 116 |
| HTML Snake game | 17.6 s / 124 | 15.8 s / 141 |
| Logic puzzle → JSON | 2.75 s / 104 | 2.6 s / 129 |
Python merge_intervals |
1.78 s / 122 | 1.87 s / 129 |
| Czech reklamace e‑mail | 11.0 s / 60.5* | 6.0 s / 110* |
| 59 KB → JSON analysis | 20.0 s / 103 | 25.2 s / 103 |
* short outputs → tok/s is noisy on those two rows.
Quality (code & JSON actually executed/parsed)
| Task | NVFP4 | FP8 | verdict |
|---|---|---|---|
| Logic puzzle (known solution) | 5/5 correct | 5/5 correct | tie |
merge_intervals (non‑thinking) |
6/6 edge cases, ValueError, no mutation | 6/6 edge cases, ValueError, no mutation | tie |
| 59 KB → strict JSON | valid, severity high, 5–6 items |
valid, severity high, 6–7 items |
~tie |
| HTML to‑do & Snake | valid single‑file, APIs present | valid single‑file, APIs present | tie |
| Czech reklamace e‑mail | all facts + 5 legal terms; ~3 minor grammar slips | all facts + terms; ~1 slip; auto‑computed the "19‑day delay" | slight FP8 edge |
| Czech poem | native; one Slovak‑ish coinage ("nájdení") | native, better arc/register | slight FP8 edge |
Thinking mode: both over‑reason on the trivial Python task, but NVFP4 is less disciplined — it never finished the function even at a 16k‑token budget (12 139 reasoning tokens), while FP8 finished correctly. For deterministic work, non‑thinking is the sane choice on both.
Bottom line: no measurable gap in reasoning correctness or instruction‑following; no gibberish, broken diacritics, or language switching on either. FP8 keeps a small edge in Czech polish and thinking‑mode restraint. 4‑bit NVFP4 does not noticeably "get dumber."
Caveats
- vLLM builds differ (0.24.0 vs 0.23.1rc1‑dev) + different attention/MoE backends — a confound that plausibly favors NVFP4, making "FP8 is faster" the conservative read.
- Single run per scenario, not averaged; short‑output tok/s is noisy.
- One 27B MoE model, one Blackwell card, MTP=3 — don't extrapolate to dense models / other GPUs / non‑speculative serving.
- HTML judged structurally (valid single file, inline JS, required APIs present), not by driving it in a browser.
- MTP=3 is on for both, so decode tok/s already bakes in speculative acceptance.
Legend
- TTFT — time to first token (prefill + queue proxy).
- decode tok/s — per‑request output tokens/sec after the first token (excludes prefill).
- aggregate tok/s — total output tokens/sec across all concurrent requests (
total_completion_tokens / wall). - prefill tok/s — input tokens/sec before first output (
prompt_tokens / TTFT); meaningful only on the ~22.3k‑token big‑prompt rows (≈ a 59 KB Czech document). - e2e p50/p95 — end‑to‑end request‑latency percentiles across the concurrent batch.
Good empirical analysis and we observed the same. I think the "problem" is that they made a choice to not quantize the activations which are still W4A16. So the main benefit of this NVFP4 ends up being less memory usage and almost same accuracy as the fp8. There are other checkpoints that also quantize the MLP and end up running significantly faster on blackwell than the fp8 and faster than this particular NVFP4, specifically on prefill heavy agentic coding workloads. One example would be https://huggingface.co/sakamakismile/Qwen3.6-27B-MTP-pi-tune-NVFP4
Could be a deliberate trade-off they made to keep the accuracy.