Qwen3.8-27B · GGUF · ubatch 4096 + KV q8_0

Qwen3.8-27B GGUF on llama.cpp with ubatch 4096 + KV q8_0, 56.8 t/s warm, multi-variable run.

56.8
WARM DECODE (T/S)
60.3
COLD DECODE (T/S)
16.00
WARM TTFT (S)
93.65
COLD TTFT (S)
29.8
PEAK VRAM (GB)
1
CONCURRENT REQS
llm-servingllamacppggufb70multi-varASRock B70▲ +11.9 vs prev

Based on: https://huggingface.co/Greatjedi/Qwen3.8-27B-Intel-Arc-Tuned-GGUF

Multi-variable run vs run #4, three changes at once, so attribution is partial:

Changed From → To Affects
--ubatch-size 2048 → 4096 prefill speed
--kv-offload → --no-kv-offload off → on-GPU prefill write path, decode KV reads
--cache-type-k/v q4_0 → q8_0 quality (recall), VRAM (~2× KV bytes), maybe dequant overhead

Prefill gains can't be split between ubatch and offload; decode shifts could come from either offload or q8_0; the quality delta is attributable to q8_0 alone. Isolation follow-ups listed in Recommendations.

Status: Attempt 3 SURVIVED, --no-kv-offload identified as the crash culprit. Benchmark data below.

Crash history

Attempt ubatch kv-offload KV dtype Result
1 4096 off q8_0 CRASH (SYCL graph exception, flash-attn oneDNN SDPA)
2 4096 off f16 (default) CRASH (same)
3 4096 on f16 (default) OK

--no-kv-offload is the only variable present in both crashes and absent from the survivor → culprit. ubatch 4096 and f16 KV are safe. Exception text for the record:

W ggml_sycl_flash_attn_ext_onednn: oneDNN SDPA failed (Graph nodes cannot depend on events from outside the graph.); falling back to TILE kernel
Exception caught at file:/app/ggml/src/ggml-sycl/ggml-sycl.cpp, line:3240

Pitfall: don't use --no-kv-offload with this SYCL/flash-attn setup, long prefills crash-loop the container.

Config

Field Value
Model Greatjedi/Qwen3.8-27B-Intel-Arc-Tuned-GGUF → /models/Qwen3.8-27B-GSQ-RCO-IQ3_S-Intel-Arc-Tuned-MTP-Q4_K.gguf (IQ3_S ≈3.5 bpw, MTP draft head Q4_K)
Inference platform llama.cpp ghcr.io/ggml-org/llama.cpp:full-intel, SYCL/Level-Zero, single B70 (card2/renderD129)
Port / host your-LAN-IP:9932
Context --ctx-size 163840 (unchanged)
Layers / fit --n-gpu-layers all, --fit-target 256, flash-attn on
KV cache q8_0 K/V (was q4_0), --kv-unified, --no-kv-offload (was default-on offload)
Prefill batching --batch-size 16384, --ubatch-size 4096 (was 2048)
Speculative decoding unchanged: ngram-mod (match 24, min 1, max 3) + draft-mtp (max 3, p-min 0.5)
CPU threads 8 / threads-batch 12; OMP_NUM_THREADS=12
Prompt caching --cache-prompt --cache-reuse 2048 --cache-ram 2048 (unchanged)
Concurrency --parallel 1, --n-predict -1
Sampling defaults temp 0.7, top-p 0.9, top-k 40, repeat 1.05, client overrides to greedy-equivalent for comparability
Reasoning / tools --reasoning on; same 6 tools; --jinja + qwen-sharp.jinja (from the model repo's chat_templates/); alias Qwen3.8-27B
SYCL env unchanged incl. SYCL_CACHE_PERSISTENT=0

Stats (attempt 3: ubatch 4096 + kv-offload + f16 KV)

Metric Cold (req #1) Warm (APC hit)
Prompt tokens 64,501 64,501
TTFT (s) client 93.65 / server prompt eval 62.26 s client 16.00 / server prompt eval 0.35 s (4 tokens re-prefilled)
Prefill (tok/s) 1,036.07 (server; run #4 was 1,013.59 → ubatch 4096 made no difference) cache-served (cached_tokens 64,497/64,501)
Decode (tok/s, generated) client 60.3 (1,158 tok / 19.19 s); server windows ~29.5–30.5 client 56.8 (1,254 tok / 22.09 s); server windows ~33–49, declining
Completion tokens 1,158 1,254
E2E (s) client 112.84 / server total 101.51 client 38.09 / server total 38.01
VRAM (GB) 29.2 at start (user) 29.8 peak (user)
Spec decode draft accept 0.744 (694/933), mean len 2.81 draft accept 0.785 (796/1,014), mean len 3.02

Baseline to beat (run #4: ubatch 2048 + kv-offload + q4_0 KV): prefill 1,013.59 tok/s, warm decode 44.9 tok/s, cold decode 30.1, VRAM peak 20.9 GB.

Findings

Recommendations

Quality variant

  1. f16 KV is now active (attempt 3), compare summary output vs runs #4/#2/#3 (same corpus, greedy; note trajectory diverged due to KV numerics).
  2. q8_0 was never actually tested, both q8_0 attempts crashed (culprit was no-kv-offload, not q8_0). If a middle ground between q4_0 and f16 is wanted, test q8_0 with kv-offload ON.
  3. Draft KV stays f16 (default).

Speed variant

  1. Resolved: --no-kv-offload crashes (SYCL graph exception), keep --kv-offload.
  2. Isolate the decode gain cleanly: rerun run #4 config with only ubatch 4096 (keep q4_0 KV), splits the +26 % warm decode gain between ubatch and f16 KV.
  3. ctx-size → 262144, confirmed NOT to fit with f16 KV (only ~2.8 GB headroom at 163k ctx, needs ~+5 GiB); fits at q4_0 (~+2 GiB). Pick the KV dtype first.
  4. SYCL_CACHE_PERSISTENT=1, still pending from run #4.
  5. SSE first-token delay, verify with curl -N before trusting llama.cpp TTFT numbers (open since run #4).

Appendix: docker-compose (verbatim, as provided 2026-10-21, attempt 3, the running config)

Attempts 1–2 (both crashed) used --no-kv-offload; attempt 1 additionally had --cache-type-k/v q8_0 active.

services:
  llamacpp:
    container_name: b70
    image: ghcr.io/ggml-org/llama.cpp:full-intel
    restart: unless-stopped
    ports:
      - "9932:9932"
    volumes:
      - ./models:/models
      - ./cache/llamacpp:/root/.cache/llamacpp:Z
      - ./cache/sycl:/root/.cache/sycl:Z
      - ./cache/huggingface:/root/.cache/huggingface:Z
    devices:
      - /dev/dri
    group_add:
      - "992"
    environment:
      GGML_SYCL_ENABLE_GRAPH: 1
      UR_LOADER_USE_LEVEL_ZERO_V2: 0
      ZE_AFFINITY_MASK: 0
      SYCL_DEVICE_FILTER: level_zero:0
      ONEAPI_DEVICE_SELECTOR: level_zero:0
      SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS: "1"
      GGML_SYCL_ENABLE_COPY: "1"
      GGML_SYCL_F16: "1"
      ZES_ENABLE_SYSMAN: "1"
      OMP_NUM_THREADS: "12"
      HF_HOME: /root/.cache/huggingface
      HUGGINGFACE_HUB_CACHE: /root/.cache/huggingface
      LLAMA_CPP_CACHE: /root/.cache/llamacpp
      SYCL_CACHE_PERSISTENT: "0"
      SYCL_CACHE_PATH: /root/.cache/sycl
      SYCL_USE_XMX: 1
    command:
      - --server
      - --model
      - /models/Qwen3.8-27B-GSQ-RCO-IQ3_S-Intel-Arc-Tuned-MTP-Q4_K.gguf
      - --spec-type 
      - "ngram-mod,draft-mtp"
      - --spec-ngram-mod-n-match 
      - "24"
      - --spec-ngram-mod-n-min
      - "1"
      - --spec-ngram-mod-n-max
      - "3"
      - --spec-draft-n-max
      - "3"
      - --spec-draft-p-min
      - "0.5" 
      - --jinja 
      - --chat-template-file 
      - /models/qwen-sharp.jinja
      - --alias 
      - "Qwen3.8-27B"
      - --host
      - 0.0.0.0
      - --port
      - "9932"
      - --n-gpu-layers
      - "all"
      - --flash-attn
      - "on"
      - --fit-target
      - "256"
      - --ctx-size
      - "163840"
      - --n-predict 
      - "-1"
      - --temp 
      - "0.7"
      - --top-p 
      - "0.9"
      - --top-k 
      - "40"
      - --repeat-penalty
      - "1.05"
      - --repeat-last-n
      - "256"
      - --presence-penalty
      - "0.0"
      - --dry-penalty-last-n
      - "512"
      - --threads
      - "8"
      - --threads-batch
      - "12"
      - --batch-size
      - "16384"
      - --ubatch-size
      - "4096"
      - --cors-origins
      - "*"
      - --cache-prompt
      - --cache-reuse
      - "2048"
      - --cache-ram
      - "2048"
      - --parallel
      - "1"
      - --kv-unified
      - --kv-offload
      - --reasoning
      - "on"
      - --tools
      - "read_file,file_glob_search,grep_search,write_file,edit_file,get_info"
      - --metrics
      - --slots
      - --warmup
      - --perf
RELATED
2026-10-17 · llama.cpp SYCL/XPU · 1x B70 · ctx 163840