← Back to posts

Running Qwen3.6 27B on Intel Arc Pro B70: The Full Recipe

Every config that works for running Qwen3.6 27B dense on Intel Arc Pro B70 with llama.cpp SYCL — Q4/Q5/Q6 quant comparison, MTP-4 speculative decoding (+35-50%), q8_0 K + q4_1 V KV cache with measured KL-divergence, and the exact VRAM context ceiling for each quant. Validated on build b10222 with llama-bench.

Case Snapshot

Situation

Qwen 3.8 27B is launching next week. I needed the definitive B70 recipe for 27B-class dense models — which quant, which context, which KV config, and what decode speed to expect — so the answer is ready before the launch wave hits.

Issue:

The 27B dense model is VRAM-hungry (16-21 GB weights + 7-14 GB KV at high context), making the quant/context/KV trade-off non-obvious. The previous fleet used q5_0-q4_1 KV cache, but KL-divergence analysis showed q8_0 K + q4_1 V is near-lossless. The context ceiling per quant was unknown.

Solution:

Tested all three quants (Q4_K_M, Q5_K_M, Q6_K) at every context length (128K-512K) with q8_0 K + q4_1 V KV cache. Measured VRAM boundaries, decode speed, and prefill with llama-bench. MTP-4 speculative decoding adds +35-50% decode. The KV insight: dense models use 3.8x more KV cache than MoE — so a 16 GB dense model can't pass 256K while a 25 GB MoE reaches 512K.

Used In:

Production inference on Intel Arc Pro B70 32GB, serving ThinkingCap-Qwen3.6-27B via llama-server SYCL build b10222. Used daily through a Telegram bot bridge on Radxa ROCK 5B+.

Impact:

Q5_K_M at 200K context runs at ~24 t/s with MTP-4 (base 16.2 t/s + 50% spec gain). Q4_K_M reaches 256K. MoE 35B reaches 512K at 70 t/s. Prefill hits 1621 t/s on the B70's XMX engines. Full VRAM boundary map provided for every config.

Situation

With Qwen 3.8 27B launching next week, the question is simple: what’s the best way to run a 27B dense model on a single Intel Arc Pro B70 32GB?

Not “can it run” — we know it can. The real questions are:

  • Which quant fits, and at what context?
  • Does Q5_K_M work at 200K, or are we stuck with Q4?
  • Does Q6_K fit at all?
  • How much does MTP-4 speculative decoding actually help?
  • What KV cache config gives near-lossless quality without wasting VRAM?

I tested all three quants (Q4_K_M, Q5_K_M, Q6_K) at every context length from 128K to 512K, measured the exact VRAM boundary for each, and benchmarked with llama-bench on build b10222. This is the full recipe.

Hardware reference: Intel Arc Pro B70 on Amazon.

The VRAM problem (and why dense 27B is harder than MoE 35B)

The B70 has 32,656 MiB visible VRAM. A 27B dense model eats most of it in weights alone:

QuantWeightsVRAM left for KV + buffers
Q4_K_M15.6 GB~17 GB
Q5_K_M18.2 GB~14.5 GB
Q6_K20.9 GB~11.8 GB

The remaining VRAM must hold the KV cache (which scales with context length) plus ~2 GB of fixed compute buffers (SYCL JIT, attention workspace, etc.).

Here’s the non-obvious insight: KV cache scales with the attention layer size, not total parameter count. Dense 27B runs full-size attention on all 27B params, consuming ~6,960 MiB KV per 128K context. MoE 35B-A3B has tiny attention (only 3B active), consuming just ~1,847 MiB per 128K — 3.8x less.

This means a 25 GB MoE model reaches 512K context, while a 16 GB dense model can’t pass 256K. The bigger model goes further because its attention is smaller.

KV cache: q8_0 K + q4_1 V (near-lossless, ~50% VRAM savings)

The fleet standard is asymmetric KV quantization:

--cache-type-k q8_0 --cache-type-v q4_1 --flash-attn on

Why asymmetric? In attention (softmax(Q·Kᵀ / √d) · V), the K matrix determines which tokens to attend to (routing), while V is averaged across attended tokens. K is sensitive to quantization noise; V tolerates it. So: spend bits on K (q8_0), save bits on V (q4_1).

Measured KL-divergence (from llama.cpp discussion #23470, cross-referenced with my own KL-divergence analysis):

K cacheV cacheKL-divergenceSame top-pVerdict
q8_0q4_1~0.003~97%Fleet standard
q8_0q8_0~0.003~97%Conservative (more VRAM)
q5_0q4_1~0.006-0.008~93%Acceptable trade-off
q4_0any~5.5~11.6%Catastrophic — never use

The q4_0 K cliff is not gradual — it’s catastrophic (KL-divergence ~5.5, only 11.6% of top-p tokens match). The model output is destroyed. This is why we use q8_0 for K: it’s the safest option that still saves ~50% VRAM vs FP16.

Context ceilings per quant (measured)

I loaded each quant at progressively higher context until VRAM ran out. These are measured values from llama-bench on build b10222, not estimates:

Quant128K200K256K512K
Q4_K_M8.1 GB free ✅4.2 GB free ✅0.9 GB free ⚠️OVER ❌
Q5_K_M3.3 GB free ✅2.7 GB free ✅OVER ❌OVER ❌
Q6_K0.7 GB free ⚠️OVER ❌OVER ❌OVER ❌

(Values = MiB free after model + KV + compute buffers. ✅ >1 GB, ⚠️ <1 GB tight.)

Key finding: Q5_K_M at 200K works with 2.7 GB headroom — better than linear VRAM models predicted. This means Q5 quality at 200K context is a viable production config, not just Q4.

Q6_K at 128K is the absolute quality ceiling: it fits with only 687 MiB free. Pure text only — no room for a vision projector or extra context.

Decode speed (llama-bench, build b10222)

Prefill throughput at multiple prompt sizes

Configpp512pp4096Δ vs Q4
Q4_K_M @ 256K567 t/s700 t/s
Q5_K_M @ 128K614 t/s706 t/s+0.9%
Q5_K_M @ 200K616 t/s706 t/s+0.9%
Q6_K @ 128K585 t/s715 t/s+2.1%

Build b10222, q8_0-q4_1 KV, FA on, 150W, llama-bench 3 reps.

Prefill is flat across dense quants (~700-715 t/s at pp4096) — same bandwidth constraint as decode. The B70’s XMX engines (via oneDNN flash attention) push prefill well beyond what the raw 608 GB/s bandwidth suggests.

Token generation (decode) with MTP-4 delta

ConfigBase decode (tg128)With MTP-4 (est.)Δ vs base
Q4_K_M @ 256K18.4 t/s~29 t/s+58%
Q5_K_M @ 200K16.2 t/s~24 t/s+48%
Q6_K @ 128K16.0 t/s~24 t/s+50%

Base from llama-bench tg128 (no speculative). MTP-4 estimate from measured +35-50% gain (93-94% draft acceptance, build b10222, 165-180W).

Decode speed is quant-independent (~16-18 t/s base across all quants). The B70 is bandwidth-bound on weights — the quant only affects quality and VRAM, not decode speed. The choice between Q4/Q5/Q6 is purely about quality vs context ceiling.

Cross-hardware comparison: 27B dense class

HardwareVRAMModelDecode (base)Prefill (pp4K)Max ctxSource
Arc Pro B70 32GB32 GBThinkingCap 27B Q516.2 t/s706 t/s200Kthis post
Arc Pro B70 32GB32 GBThinkingCap 27B Q5 + MTP~24 t/s706 t/s200Kthis post
RX 7800 XT 16GB16 GBGLM-4.7-REAP-23B IQ459.8 t/s81.7 t/s32Kmy bench
RTX 4090 24GB24 GBQwen 27B Q4 (est.)~35 t/s~1000 t/s128Kcommunity

The B70’s advantage is VRAM capacity (32 GB → 200K context) not raw speed. Consumer GPUs with less VRAM cap at 32-128K. The 7800 XT is faster per-token on smaller models but can’t fit a 19 GB 27B at 200K — it tops out at 32K for a 23B model.

MTP-4 speculative decoding: +35-50% decode

Multi-Token Prediction (MTP) is Qwen’s built-in speculative decoding. The model has a draft head that proposes multiple tokens per forward pass, which are then verified in parallel. On dense 27B:

ConfigBase decodeWith MTP-4Gain
Q4_K_M @ 128K, 180W~18 t/s~29 t/s+50%
Q5_K_M @ 200K, 165W~16 t/s~24 t/s+35%

Draft acceptance rate: 93-94% (measured 0.933-0.938). This is on the high end for self-draft speculative decoding — MTP shares the model’s own distribution, so acceptance is naturally high.

Power matters for dense MTP. At 165W you get ~24 t/s with MTP-4; at 180W it rises to ~29 t/s. The B70’s power scaling helps dense models because higher GPU frequency increases effective memory bandwidth utilization. MoE models don’t benefit from power scaling — they self-limit to ~130-140W draw regardless of the cap.

# MTP-4 flags (add to the server launch below)
--spec-type draft-mtp --spec-draft-n-max 4 --spec-draft-p-min 0.75

The full recipe: Q5_K_M @ 200K with MTP-4

This is the production config running daily through the Telegram bot bridge:

source /opt/intel/oneapi/setvars.sh --force > /dev/null 2>&1

export SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0
export SYCL_CACHE_PERSISTENT=0
export SYCL_DEVICE_FILTER=level_zero
export ZE_FLAT_DEVICE_HIERARCHY=COMPOSITE
export ONEAPI_DEVICE_SELECTOR=level_zero:0
export ZE_AFFINITY_MASK=0

# Set power cap (165W = efficiency sweet spot for dense MTP)
echo 165000000 | sudo tee /sys/class/hwmon/hwmon4/power1_cap

# Launch
~/llama.cpp/build-sycl-0801/bin/llama-server \
  -m ~/models2/ThinkingCap-Qwen3.6-27B-Q5_K_M-MTP.gguf \
  --host 0.0.0.0 --port 8765 \
  -ngl 99 -ncmoe 0 \
  -fa on -ctk q8_0 -ctv q4_1 \
  -c 204800 -b 8192 -ub 4096 \
  --spec-type draft-mtp --spec-draft-n-max 4 --spec-draft-p-min 0.75 \
  -t 8 --no-mmap \
  --mmproj ~/models/gguf/mmproj-ThinkingCap-Qwen3.6-27B-f16.gguf

Expected: ~24 t/s decode with MTP-4, 706 t/s prefill, 200K context, 2.7 GB VRAM free.

For pure text (no vision projector), add 889 MiB headroom — use this for the Q4_K_M @ 256K config.

Runtime flags handbook

FlagValueWhy
-ngl 99All layers on GPUFull GPU offload, no CPU fallback
-ncmoe 0All MoE experts on GPU(For dense models, this is a no-op but harmless)
-fa onFlash attentionRequired for quantized KV cache to work
-ctk q8_0K cache = 8-bitNear-lossless (KL ~0.003). Never use q4_0 for K — catastrophic (KL ~5.5)
-ctv q4_1V cache = 4-bitV tolerates aggressive quantization (averaged in attention)
-c 204800200K contextMax safe context for Q5_K_M. Q4 can reach 256K
-b 8192Batch sizeOptimal for SYCL prefill throughput
-ub 4096Micro-batchDo NOT reduce — smaller values hurt prefill significantly
-t 88 CPU threadsFor prompt processing and CPU-side ops
--no-mmapKeep in VRAMDon’t page model to disk
--spec-type draft-mtpMTP speculative decoding+35-50% decode on dense. 93-94% acceptance
--spec-draft-n-max 4Max 4 draft tokensBest acceptance/speed trade-off
--spec-draft-p-min 0.75Min acceptance probabilityBelow this, fall back to standard decode

MoE comparison: when to use 35B instead of 27B

For reference, the Qwen3.6-35B-A3B MoE on the same B70:

ConfigDecodePrefillMax contextVRAM free
MoE Q4_K_XL @ 512K70.2 t/s1659 t/s512K1.6 GB
MoE Q5_K_M @ 256K~68 t/s~1621 t/s256K2.2 GB
Dense Q5_K_M @ 200K (MTP)~24 t/s706 t/s200K2.7 GB

The MoE is 3x faster in decode and 2.3x faster in prefill, with 2.5x more context. Use MoE for throughput and long context; use dense for reasoning quality and tool use. Dense 27B with MTP is better for agentic workloads where reasoning chains matter more than raw t/s.

What changed since the original B70 posts

If you read the earlier B70 posts, three things have changed:

  1. KV cache upgraded from q5_0-q4_1 to q8_0-q4_1. The old config is still acceptable (KL ~0.006-0.008), but q8_0 K halves the KL-divergence to ~0.003 at only ~6% more VRAM. This is now the fleet standard, validated against llama.cpp #23470.

  2. Build advanced from b9853 to b10222 (+6-13% improvement). The upstream SYCL commits (oneDNN XMX flash attention #25222, fused top-k MoE #25217, RMS_NORM fusion #26015) are real and measurable. Prefill improved up to 12.8% at long context; decode improved 12.5%.

  3. Model switched to ThinkingCap-Qwen3.6-27B. This is a token-efficient finetune of Qwen3.6-27B that keeps full accuracy with ~46% fewer thinking tokens. The MTP draft head is built into the weights — no separate draft model needed.

Benchmark methodology

All numbers from llama-bench (synthetic prompts, immune to HTTP API quoting bugs):

llama-bench \
  -m ThinkingCap-Qwen3.6-27B-Q5_K_M-MTP.gguf \
  -ngl 99 -ncmoe 0 -fa 1 -ctk q8_0 -ctv q4_1 \
  -p 512,4096 -n 128 -r 5 -d 0 \
  -b 8192 -ub 4096 -t 8 -dev SYCL0
  • pp4096 = prefill throughput at 4096-token synthetic prompt
  • tg128 = decode throughput generating 128 tokens
  • 5 repetitions per test, coefficient of variation < 0.5%
  • 150W power cap, 54-66°C temperature range
  • Build b10222 (a7a6d0d26, build-sycl-0801, IntelLLVM 2026.0.0)

MTP-4 numbers measured via llama-server HTTP API (llama-bench doesn’t support speculative decoding). Decode rate from timings.predicted_per_second in the JSON response.

What to expect with Qwen 3.8 27B

Qwen 3.8 27B should drop into this recipe with minimal changes — same architecture class, same VRAM profile, same MTP support. The Q5_K_M quant will likely be ~19 GB (same as 3.6), fitting at 200K with q8_0-q4_1 KV.

If the 3.8 model includes the MTP draft head (Qwen has been shipping MTP since 3.0), the speculative decoding flags will work unchanged. If not, you’ll need a separate draft model or can use ngram speculation as a fallback.

The B70’s XMX engines (via oneDNN flash attention) are the key enabler — they push prefill to 700+ t/s on dense and 1600+ t/s on MoE, which is what makes long-context agentic workflows practical on a single 32 GB card.

Buy on Amazon

As an Amazon Associate I earn from qualifying purchases.