Home / Intel's flash-attention prefill kernel on Arc (llama.cpp PR #29357)

Intel's flash-attention prefill kernel on Arc (llama.cpp PR #29357)

Summary

On Intel Arc, stock llama.cpp Vulkan reads prompts quickly when the conversation is short, then slows sharply as context grows. Prompt reading drops from 589 tok/s on an empty context to 118 tok/s at 32K tokens. That is exactly what hurts coding agents, which re-send a 20–40K token conversation on every turn.

Intel's FA prefill kernel (PR #29357, commits 61cc4c2 and 1a5137a from sliu39/llama.cpp, branch intel/fa-prefill) fixes this, but only when the KV cache is f16. The PR was closed unmerged upstream, so this repo ships the two commits itself: see Upstream status.

Prompt processing, pp2048 (tok/s)empty16K deep32K deep
Stock b11524, f16 KV589198118
Intel FA, f16 KV653513420
Stock b11524, q4_0 KV584182101
Intel FA, q4_0 KV584182101

Generation speed (tg32, no drafter, llama-bench) is the same on both engines: 16.0 tok/s on an empty context, falling to 14.5 tok/s at 32K. That is the figure to quote for "stock" decode speed: it is not the 42.3 tok/s eval-suite throughput (wall-clock, prompt processing included), which also uses the DFlash2 drafter. Raw data: compare-f16.txt, compare-q4.txt.

In a real agent loop (three turns, each adding about 3K tokens to a 30–37K conversation and writing 400 tokens), total wall time fell from 201 s† to 55–57 s.

The trade-off: f16 KV costs memory

The profiles therefore have two variants:

VariantKV cacheContext on 24GBBest for
qwen3.8-27b (default)f16~57–64KCoding agents, anything that re-reads long context
qwen3.8-27b-bigq4_0~150–200KHuge documents read once
qwen3.8-27b-longq4_0, no drafter262KWhole-codebase questions, about 15 tok/s

Upstream status and the vendored patches

ItemStatus
Intel Xe flash-attention decode kernels, PR #24406Merged 2026-09-22. Already in stock b11524.
Intel GDN tuning, PR #29476Merged 2026-09-29.
FA prefill shader, PR #29357Closed unmerged by its author on 2026-09-25. The branch was force-pushed afterwards. This is the 118 to 420 tok/s change.
SYCL backend work, PR #25025Merged 2026-07-31 (a different backend; the prefill shader is Vulkan-only).

Because the prefill shader never reached mainline and its branch can change, the two commits are vendored in engine/patches/ with SHA256 checksums, the original author lines and a README on provenance and licence. The build applies them to llama.cpp b11524. The previous method (fetch the branch and cherry-pick) is kept as a fallback only.

The engine we ran is llama.cpp build 11526 (commit c85e6c598), which is upstream b11524 (86a283532, tag dated 2026-10-09) plus those two commits. The stock engine we compare against is plain b11524. Versions of everything else are in the README.

Build it (portable, no admin)

engine/build.ps1 downloads a portable GCC toolchain (w64devkit), CMake and Ninja. It then builds glslc from shaderc, which needs cooperative-matrix and integer-dot support, and builds llama.cpp b11524 with the two vendored patches applied (it checks their checksums first). It installs to C:\AI\llama.cpp\vulkan-intelfa and never touches your existing build. On Linux, engine/build-linux.sh does the equivalent; patch application is verified, but the script has not been run end to end on a Linux machine with an Arc GPU.

Check the configure log for:

GL_KHR_cooperative_matrix supported by glslc
GL_EXT_integer_dot_product supported by glslc

Building with Visual Studio Build Tools also works. See engine/BUILD-INTEL-FA.md.

Verify on your card

powershell -ExecutionPolicy Bypass -File bench\compare-f16.ps1   # stock vs Intel FA, f16 KV, 0/16K/32K depth
powershell -ExecutionPolicy Bypass -File bench\server-test.ps1   # agent-style 3-turn test + coding/tool checks

Then switch with qwen engine intelfa (and back with qwen engine stock).

Gotchas