Skip to content

opencl: Q6_K GEMM/GEMV fix for ne01 of weights that are not multiples of 128. #25464

Merged
max-krasnyansky merged 3 commits into
ggml-org:masterfrom
qualcomm:hq/adreno-q6k-smallk-fix
Jul 8, 2026
Merged

opencl: Q6_K GEMM/GEMV fix for ne01 of weights that are not multiples of 128. #25464
max-krasnyansky merged 3 commits into
ggml-org:masterfrom
qualcomm:hq/adreno-q6k-smallk-fix

Conversation

@wanghqc

@wanghqc wanghqc commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Overview

The Adreno no-shuffle (transposed-weight) Q6_K GEMM and GMMV require ne01 of weights to be multiple of 128 (ne01 % 128 == 0), which is generally fine for large models. This requirement is broken for models like granite-3.1-3b-a800m-instruct, in which the vocab size is an odd number and therefore the model produces gibberish output.

This PR fixes this by routing GEMM/GEMV with such weights to the general kernels.

Additional information

The bug only affects very small models.

Requirements

  • I have read and agree with the contributing guidelines: Yes
  • AI usage disclosure: Yes, for testing and prototyping.

wanghqc and others added 3 commits July 8, 2026 11:45
…dreno

Observed with granite-3.1-3b-a800m-instruct, whose vocab is an odd number.

Route Q6_K dense mul_mat with ne01 % 128 != 0 off the noshuffle path:
decode (ne1==1) uses the correct flat GEMV and the matching GEMM (ne1>1)
falls back to CPU (the flat convert has no verified small-batch GEMM kernel
for these shapes). All standard hidden/FFN/vocab dims are multiples of 128
and keep the noshuffle path.
…size

set_tensor carves quantized weights into per-component subbuffers (d/q,
ql/qh/s/d, ...) whose origins are each rounded up to the device base
address alignment. When a component's size is not a multiple of the
alignment, the carve extends past ggml_nbytes(tensor) and the last
subbuffer overlaps the next tensor in the pool -- e.g. q6_K [1536, 49155]:
size_s = 49155*96 ends 32 bytes past a 128-byte boundary, so the d
subbuffer ends 96 bytes past the tensor's allocation, and whichever of the
two neighboring tensors is uploaded last silently corrupts the other (here:
the last vocab rows' block scales). This affects any quant type whose
component sizes can be misaligned, on any shape with ne01 not a multiple of
the alignment granularity; standard power-of-two dims are unaffected.

Implement get_alloc_size for the OpenCL buffer type and reserve the
worst-case carve slack (4 aligned gaps; 5 components max, q5_K) for
quantized tensors. Costs at most 512 bytes per quantized tensor at the
observed 128-byte alignment.
@wanghqc wanghqc requested a review from a team as a code owner July 8, 2026 19:34
@github-actions github-actions Bot added ggml changes relating to the ggml tensor library for machine learning OpenCL Issues specific to the OpenCL backend labels Jul 8, 2026
@lhez lhez requested a review from max-krasnyansky July 8, 2026 21:12
@max-krasnyansky max-krasnyansky merged commit 92366df into ggml-org:master Jul 8, 2026
44 of 46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ggml changes relating to the ggml tensor library for machine learning OpenCL Issues specific to the OpenCL backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants