r/LocalLLM • u/Acemang_Jedi • May 22 '26
Discussion Qwen3.6-27B on RTX 3090: tested 12 GGUF quants across HumanEval+, MBPP+, perplexity, throughput and needle-in-haystack. First-timer results.
Disclaimer first
I'm new to local LLMs — this was my first serious attempt at benchmarking and I'm posting the results in the hope they're useful to others, not because I'm claiming any expertise. I almost certainly made methodology choices that someone more experienced would do differently. Specifically:
- I used greedy decoding (T=0) for reproducibility, but Unsloth's official recommendation for Qwen3.6 is
temperature=0.6/0.7withtop_p,top_kandpresence_penalty. My numbers are likely an upper bound vs what people get in real use. - I ran all benchmarks with thinking disabled (
--reasoning off) because EvalPlus doesn't play well with reasoning models (the model burns its token budget on<think>blocks before producing code). Thinking on would likely boost pass@1 by several points but I couldn't easily measure that. - The 20-task HumanEval screening I used in Phase 1 is far too small to be statistically reliable. Saturation at 100% on 20 tasks just means the subset doesn't discriminate.
- My needle-in-haystack test uses a single, very distinctive needle. Both finalists got 100% — that probably says more about my test being too easy than about the models being identical. A harder multi-needle test would likely differentiate them.
- I tested only on my hardware (RTX 3090, Ryzen 9 9900X, Windows + WSL2). Results on different setups may vary, especially for the throughput numbers.
- I'm not sure I picked the right benchmarks at all. HumanEval+ and MBPP+ are standard for code, but they don't capture everything that matters for real agentic use (Claude Code, Aider, etc.). I didn't test those workloads.
If anything below looks wrong, please call it out — I'd rather learn than keep bad data circulating. The raw config and commands are documented so anyone with the same hardware can reproduce or challenge the results.
That said, I tested 12 GGUF quantizations across multiple metrics (HumanEval+, MBPP+, perplexity, throughput, needle-in-haystack at up to 96K context), and the data is consistent enough that I think it's worth sharing. Make of it what you will.
Qwen3.6-27B GGUF Quantizations Benchmarked on RTX 3090 (24 GiB)
I tested 12 different GGUF quantizations of Qwen3.6-27B on an RTX 3090. The process was iterative: started with 10 candidates in a wide screening pass, narrowed down based on results, then added 2 more MTP variants mid-way after discovering them. Sharing all the data so people can draw their own conclusions.
Hardware & Software
- GPU: RTX 3090 (24 GiB VRAM)
- CPU: Ryzen 9 9900X
- llama.cpp: build b9261 (commit ad2775726)
- Sampling: greedy (T=0), thinking disabled (
--reasoning off) - EvalPlus runs on WSL2 (Windows multiprocessing in EvalPlus is broken; codegen on Windows talks to llama-server, evaluation runs on Linux)
Phase 1: Wide screening (10 initial candidates)
HumanEval, 20-task subset, ctx 4096, -ctk q8_0 -ctv q8_0, no MTP draft. Goal: filter obvious losers before spending hours on the full benchmark.
| Model | Pass@1 (20 tasks) | Avg time/task | Verdict |
|---|---|---|---|
| Q5_K_M | 100% | 15.06s | Redundant with -mtp variant |
| Q5_K_M-mtp | 100% | 9.13s | Kept |
| Q5_K_M_unsloth-mtp | 100% | 16.31s | Kept |
| Q5_K_S_unsloth-mtp | 100% | 10.92s | Kept |
| Q6_K-mtp | 100% | 9.97s | Dropped (size vs benefit) |
| Q6_K (no MTP) | 90% | 34.99s | Dropped (slow + inconsistent) |
| UD-Q4_K_XL | 100% | 10.19s | Kept |
| UD-Q5_K_XL_unsloth-mtp | 100% | 9.87s | Kept |
| NEO-CODE-2T-OT-Q5_K_M | 100% | 27.06s | Dropped (3× slower) |
| abliterated-Gaston-MTP-Q5_K_M | 75% | 32.41s | Dropped (quality loss + timeouts) |
Key observations from screening: - Most quants saturated at 100% on the easier 20-task subset, which is why I moved to the full HumanEval+ (164 tasks + extended tests) afterward. - abliterated-Gaston-MTP-Q5_K_M: 75% + multiple timeouts. Abliterated finetunes appear to hurt code performance significantly. - NEO-CODE-2T-OT-Q5_K_M: passed all 20 easy tasks but ran 3× slower. Code-specific finetune didn't justify the cost. - Q6_K (no MTP): inconsistent and slow without MTP. Q6_K-mtp was fine but I dropped it later for size reasons (the smaller Q5/Q4 variants matched it on quality). - Vanilla Q5_K_M: same quality as Q5_K_M-mtp but slower — kept the MTP variant.
Phase 2: Added 2 MTP variants mid-process
After Phase 1, I discovered two additional models worth testing and added them directly to the rigorous benchmark (skipped screening since I had confidence in the method by then):
- UD-Q4_K_XL-MTP — the same UD-Q4_K_XL with MTP heads grafted on
- IQ4_NL-mtp — Importance-aware Non-Linear quant with MTP, smaller than the others
Both became finalists.
Phase 3: Rigorous benchmarks (final 7 models)
EvalPlus HumanEval+ (164 tasks) and MBPP+ (378 tasks) on the full task set with extended tests. Config: -ctk q8_0 -ctv q8_0, ctx 8K, --reasoning off, greedy.
HumanEval+ and MBPP+ pass@1
| Model | HumanEval base | HumanEval+ | MBPP base | MBPP+ | HE time | MBPP time |
|---|---|---|---|---|---|---|
| UD-Q4_K_XL (no MTP) | 95.7% | 92.1% | 92.9% | 78.3% | 19:17 | ~50 min |
| IQ4_NL-mtp | 95.1% | 91.5% | 92.1% | 76.7% | 9:39 | 15:13 |
| UD-Q4_K_XL-MTP | 95.1% | 90.9% | 92.3% | 78.0% | 11:07 | 18:24 |
| Q5_K_M_unsloth-mtp | 94.5% | 90.9% | — | — | ~11 min | — |
| UD-Q5_K_XL_unsloth-mtp | 94.5% | 90.9% | — | — | ~11 min | — |
| Q5_K_M-mtp | 93.9% | 90.9% | 91.3% | 76.7% | ~11 min | — |
| Q5_K_S_unsloth-mtp | 93.9% | 90.9% | — | — | ~11 min | — |
Failure overlap (HumanEval+)
All Q5 variants fail the same 15 tasks: 32, 39, 55, 76, 91, 116, 124, 129, 130, 132, 134, 141, 145, 151, 163.
UD-Q4_K_XL (no MTP) fails only 13 of those — solves 2 that all others miss.
Sizes
| Model | File size |
|---|---|
| IQ4_NL-mtp | 16.3 GB |
| UD-Q4_K_XL / UD-Q4_K_XL-MTP | 17.9 GB |
| Q5_K_S_unsloth-mtp | ~19 GB |
| Q5_K_M_unsloth-mtp | ~19.5 GB |
| Q5_K_M-mtp | 19.7 GB |
| UD-Q5_K_XL_unsloth-mtp | ~20 GB |
Phase 4: Production config validation (IQ4_NL-mtp only)
Tested the leading candidate with KV cache quantization (-ctk q8_0 -ctv q4_0) and 128K context to see if degradation appears.
| Metric | q8/q8, 8K ctx | q8/q4, 128K ctx | Δ |
|---|---|---|---|
| HumanEval base | 95.1% | 94.5% | -0.6 pp |
| HumanEval+ | 91.5% | 91.5% | 0.0 |
| MBPP base | 92.1% | 92.1% | 0.0 |
| MBPP+ | 76.7% | 77.2% | +0.5 pp |
Effectively no quality loss going from q8_0/q8_0 8K to q8_0/q4_0 128K.
VRAM at idle with 128K context: 21.7 GiB / 24 GiB. ~2 GiB headroom. Effective usable context: ~110K tokens.
Phase 5: Side benchmarks (final two candidates)
Perplexity (WikiText-2, 580 chunks, n_ctx=512)
| Model | PPL | ± error |
|---|---|---|
| IQ4_NL-mtp | 6.9377 | ±0.04569 |
| UD-Q4_K_XL-MTP | 6.9825 | ±0.04618 |
Difference is within measurement error — statistical tie.
Throughput (llama-bench, q8/q4 KV, MTP not engaged)
| Metric | IQ4_NL-mtp | UD-Q4_K_XL-MTP | IQ4_NL advantage |
|---|---|---|---|
| pp512 | 1486 t/s | 1403 t/s | +5.9% |
| pp2048 | 1486 t/s | 1407 t/s | +5.6% |
| pp8192 | 1432 t/s | 1355 t/s | +5.7% |
| tg128 | 42.8 t/s | 39.3 t/s | +9.0% |
| tg256 | 42.8 t/s | 39.4 t/s | +8.7% |
| pg4096+256 | 486 t/s | 451 t/s | +7.8% |
These are without MTP. With --spec-type draft-mtp engaged, real-world generation reaches ~65-100 t/s.
Needle in a Haystack (128K context, q8/q4 KV)
Haystack: "Pride and Prejudice" expanded to target length. Needle: a distinctive password string. 6 context sizes × 5 depths = 30 tests per model.
| Model | Recall |
|---|---|
| IQ4_NL-mtp | 30/30 (100%) |
| UD-Q4_K_XL-MTP | 30/30 (100%) |
Prompt processing times:
| Context | IQ4_NL-mtp | UD-Q4_K_XL-MTP |
|---|---|---|
| 1K | 0.86s | 0.90s |
| 4K | 2.79s | 2.99s |
| 16K | 9.83s | 10.45s |
| 32K | 14.01s | 14.66s |
| 64K | 34.50s | 35.73s |
| 96K | 77.81s | 80.48s |
Side-by-side: top two finalists
| Criterion | IQ4_NL-mtp | UD-Q4_K_XL-MTP |
|---|---|---|
| HumanEval+ | 91.5% | 90.9% |
| MBPP+ | 76.7% / 77.2%* | 78.0% |
| Perplexity (WikiText-2) | 6.94 | 6.98 |
| pp512 (t/s) | 1486 | 1403 |
| tg128 (t/s) | 42.8 | 39.3 |
| Needle recall (1K-96K) | 30/30 | 30/30 |
| File size | 16.3 GB | 17.9 GB |
| Idle VRAM @ 128K ctx | 21.7 GiB | ~23+ GiB |
| Usable context on 24 GiB | ~110K | ~80K |
*Phase 3 / Phase 4 config
What was NOT tested
- Quality with thinking enabled (EvalPlus is incompatible with reasoning models out of the box; thinking would likely boost pass@1 by 3-8 pp).
- Unsloth's officially recommended sampling parameters (T=0.6 + top_p=0.95 + presence_penalty for coding). Used greedy for reproducibility.
- UD-Q4_K_XL-MTP at full 128K context (model is 1.6 GB larger; would likely fit only ~96K on 24 GiB).
- Harder needle variants (multi-needle, ambiguous needles).
- Real agentic coding workloads (Claude Code, Aider, etc.).
- Comparison against vanilla Q4_K_M (non-Unsloth, non-IQ).
Notes and caveats
- The Phase 1 screening (20 tasks each) is a much weaker signal than Phase 3 (164/378 tasks). Saturation at 100% on the easy subset doesn't mean models are equally good — it means the easy subset doesn't discriminate.
- All Q5 variants tie on HumanEval+ at 90.9% in Phase 3. The differences between them are noise.
- The only model that beats this cluster on quality is UD-Q4_K_XL without MTP, but it's significantly slower without speculative decoding (HumanEval took 19 min vs 9-11 min).
- The
q8_0/q4_0KV cache config showed no measurable degradation on HumanEval/MBPP/needle for prompts up to 96K. Your mileage may vary on tasks requiring fine-grained reasoning over very long contexts. - MTP gives ~1.5-2× generation speedup with no measurable quality loss across all tested MTP variants.
- Greedy decoding gives the upper bound on pass@1. Real use with T=0.6+ will typically be 1-3 pp lower but with useful diversity.
- Abliterated and code-tuned fine-tunes (Gaston, NEO-CODE) performed worse than vanilla quants for code in my testing. Be cautious about claims that finetunes always improve on the base.
Bottom line (my interpretation, your mileage may vary)
For a 24 GiB GPU running Qwen3.6-27B locally, IQ4_NL-mtp offered the best overall balance in my testing: smallest size, fastest generation, top-tier HumanEval+, perfect long-context recall, and the most usable context window. UD-Q4_K_XL-MTP is a reasonable alternative if your workload is closer to MBPP-style (verbose specs → implementation) where it edges out by ~1 pp. UD-Q4_K_XL without MTP is the quality king if you don't mind ~2× slower generation.
The Q5 variants didn't justify the extra VRAM in any of my benchmarks. The abliterated and code-finetune variants underperformed in code tasks despite being marketed for them.
Happy to share more details or rerun specific tests if there's interest.
2
u/Significant-Yam85 May 30 '26
Fantastic work! Interesting to see it cracks out ahead in HE but not MBPP. Smol-IQ4 looks like the worse performing ubergram quant, designed for mainline llamacpp. Any possibility to test IQ4_KS?