Date: 2026-05-06
Reduce decode overhead in Qwen3.6 27B Q4_0 GGUF without changing weights, quantization, KV dtype, sampling, or GPU power. The target pattern is the FFN gate/up pair: two Q4_0 matvecs share the same activation and immediately feed split SwiGLU.
Added an opt-in SYCL path behind GGML_SYCL_FUSE_MMVQ2_SWIGLU=1.
ggml/src/ggml-sycl/mmvq.hpp: declared ggml_sycl_op_mul_mat_vec_q_fused2_swiglu.ggml/src/ggml-sycl/mmvq.cpp: added a reordered Q4_0/Q8_1 fused kernel that accumulates both matvecs and writes silu(gate) * up directly to the GLU output tensor.ggml/src/ggml-sycl/ggml-sycl.cpp: added the env gate, graph matcher, and safety checks.The matcher only accepts:
GGML_OP_GLU with GGML_GLU_OP_SWIGLU;Patch artifact: patches/llama-cpp-sycl-fused-mmvq2-swiglu-current-20260506.patch.gz.b64.
Greedy 8-token llama-completion stdout matched baseline byte-for-byte:
a7514e8196ec963459785822b3fcf25b1743096a4bdd5ec746225a7c9a29be19a7514e8196ec963459785822b3fcf25b1743096a4bdd5ec746225a7c9a29be19Single B70, 512 prompt / 512 output:
24.567164 tok/s24.657839 tok/s+0.37%Three B70 tensor split, SYCL2/SYCL1/SYCL3, -ts 1/1/1, 512 prompt / 512 output:
-ub 128: 45.745560 tok/s-ub 128: 46.804859 tok/s75.217668cmougm58m00dpld012rbm9rbsDefault -ub 512 now fails the 3-B70 512/512 graph reservation with GGML_ASSERT(buffer) failed in ggml_backend_buffer_get_size() while the meta backend allocates simple compute buffers. -ub 128 avoids the failure and should be used for 512-context 3-B70 validation until the meta-buffer sizing/null-buffer path is fixed.
The fusion is quality-preserving, but the single-card gain is small. This confirms FFN SwiGLU launch removal is useful but not enough to close the remaining single-B70 Linux gap to the Windows Q4_0 result. The next high-value target remains a broader same-activation GEMV fusion or a fused norm+projection path that reduces more launches and intermediate writes per layer.