GPU: PowerVR D-Series DXT-48-1536 MC1 (Google Tensor G5)
Driver: Vulkan 1.4.317, driverVersion 1.662.3024, VK_DRIVER_ID_IMAGINATION_PROPRIETARY
OS: Android 17 (API 37, Pixel 10 Pro), Bionic/Termux
In llama.cpp (b10055, commit e8f19cc0a), all k-quant compute shaders (Q2_K through Q6_K) produce
numerically incorrect results on this GPU. Non-k-quant types (Q4_0, Q5_0, Q8_0,
F16, F32) work correctly.
Affected shaders:
mul_mat_vec_q{2,3,4,5,6}_k_f32_f32and their_f16_f32variantsmatmul_q{2,3,4,5,6}_k_f32and their_f16accvariantsdequant_q{2,3,4,5,6}_k(in standalone form, likely affected as well)
Reproduction:
# Working:
./llama-simple -m model-q4_0.gguf -p "!!!!!!!!" -n 16
-> "!!!!!!!! !!!!!!!!" (correct)
# Broken:
./llama-simple -m model-q4_k_m.gguf -p "!!!!!!!!" -n 16
-> "!!iday !!(day !!(day" (garbled)
The error is deterministic (same garbled output every run), not random.
Additional observations:
-
Pipeline creation initially crashes with
SHADER_REDUCTION_MODE_SUBGROUP
for NUM_COLS >= 2. Changing toSHADER_REDUCTION_MODE_HYBRIDavoids the
crash but the output is still wrong (PR #20565 in llama.cpp). -
subgroupSize = 128. The k-quant shaders force a workgroup targeting 16-thread
subgroups (use_subgroups16), while non-k-quant shaders use the full 128.
VK_EXT_subgroup_size_controlis not exposed by the driver, so it is unclear
if the effective subgroup size is valid for reduced-size subgroup operations. -
Setting
GGML_VK_DISABLE_F16=1does not fix the issue — it only switches
between f16-accumulator and f32-accumulator variants of the same buggy
shader. Integer dot product (VK_KHR_shader_integer_dot_product) is not
supported on this device (int dot: 0), so the q8_1 code path is not used.
Suspected root cause: The k-quant block format uses complex hierarchical
bitfield packing — multiple 4-6 bit scale factors interleaved across uint32 words.
The working types (Q4_0 etc.) use simple contiguous 32-value blocks with one
scale factor. The driver’s shader compiler may have an optimization pass that
produces incorrect code for this more complex bit-extraction pattern.
Has anyone else seen this on PowerVR DXT or other recent PowerVR GPUs?
Is there a known driver bug with uint32 bitfield extraction in compute shaders?