Skip to content

opencl: fix Q4_0 SOA rows and Adreno paths#1561

Open
happyyzy wants to merge 1 commit into
ggml-org:masterfrom
happyyzy:agent/opencl-q4-adreno-correctness-upstream
Open

opencl: fix Q4_0 SOA rows and Adreno paths#1561
happyyzy wants to merge 1 commit into
ggml-org:masterfrom
happyyzy:agent/opencl-q4-adreno-correctness-upstream

Conversation

@happyyzy

@happyyzy happyyzy commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix OpenCL Q4_0 correctness issues seen when GGML_OPENCL_SOA_Q and Adreno OpenCL kernels are enabled:

  • allow GET_ROWS(Q4_0) to read SOA quant buffers instead of assuming an AoS block_q4_0 buffer
  • handle Adreno-transposed and Adreno-MoE Q4_0 layouts in GET_ROWS(Q4_0)
  • avoid a shared static temporary buffer in transpose_2d()
  • fix the fused RMSNorm/MUL offset to use src1->view_offs
  • preserve F32 activation/accumulation for selected Adreno Q4_0 GEMM paths that otherwise produce invalid diffusion output

The same fix was also prepared for the older leejet/ggml fork used by stable-diffusion.cpp, but this branch was re-applied and build-checked against upstream master.

Image evidence

The image-level reproduction was run through stable-diffusion.cpp using ggml OpenCL, because the observed failure requires full diffusion-model execution.

Test device/config:

QUALCOMM Adreno 830, OpenCL 3.0 QUALCOMM build: 0800.71 Compiler E031.47.18.49
GGML_OPENCL_SOA_Q=ON
GGML_OPENCL_USE_ADRENO_KERNELS=ON
VAE conv direct enabled
Diffusion flash attention disabled

Individual images:

Case Before After
Flux.2 Klein Q4_0, 512x512 Klein before Klein after
Z-Image Turbo Q4_0, 512x512 Z-Image before Z-Image after

Reproduction commands

The same model files and generation parameters were used before and after the patch.

Flux.2 Klein Q4_0, before

git checkout 3af5f5760e19a96427f5f7a93b79cbdf3d4b265b
./bin/sd-cli \
  --diffusion-model "$KLEIN_Q4_0_GGUF" \
  --llm "$QWEN_3_4B_Q4_0_GGUF" \
  --vae "$FLUX2_VAE_SAFETENSORS" \
  -p "a lovely cat" \
  --cfg-scale 1.0 \
  --steps 4 \
  --seed 42 \
  -W 512 -H 512 \
  --vae-conv-direct \
  -o klein_before.png \
  -v

Result: command completes and saves an image, but the output is blank.

Flux.2 Klein Q4_0, after

git checkout e30fbfe5
./bin/sd-cli \
  --diffusion-model "$KLEIN_Q4_0_GGUF" \
  --llm "$QWEN_3_4B_Q4_0_GGUF" \
  --vae "$FLUX2_VAE_SAFETENSORS" \
  -p "a lovely cat" \
  --cfg-scale 1.0 \
  --steps 4 \
  --seed 42 \
  -W 512 -H 512 \
  --vae-conv-direct \
  -o klein_after.png \
  -v

Result: valid image output.

Z-Image Turbo Q4_0, before

git checkout 3af5f5760e19a96427f5f7a93b79cbdf3d4b265b
./bin/sd-cli \
  --diffusion-model "$Z_IMAGE_TURBO_Q4_0_GGUF" \
  --llm "$QWEN_3_4B_Q4_0_GGUF" \
  --vae "$Z_IMAGE_AE_SAFETENSORS" \
  -p "a lovely cat" \
  --cfg-scale 1.0 \
  --steps 8 \
  --seed 42 \
  -W 512 -H 512 \
  --vae-conv-direct \
  -o zimage_before.png \
  -v

Result: command completes and saves an image, but the output is blank.

Z-Image Turbo Q4_0, after

git checkout e30fbfe5
./bin/sd-cli \
  --diffusion-model "$Z_IMAGE_TURBO_Q4_0_GGUF" \
  --llm "$QWEN_3_4B_Q4_0_GGUF" \
  --vae "$Z_IMAGE_AE_SAFETENSORS" \
  -p "a lovely cat wearing black sunglasses, studio photo" \
  --cfg-scale 1.0 \
  --steps 4 \
  --seed 42 \
  -W 512 -H 512 \
  --vae-conv-direct \
  -o zimage_after.png \
  -v

Result: valid image output.

Checks

git diff --check ggmlorg/master..HEAD

cmake -S . -B /tmp/ggml_opencl_upstream_pr_build -G Ninja \
  -DCMAKE_BUILD_TYPE=Release \
  -DGGML_OPENCL=ON \
  -DGGML_OPENCL_USE_ADRENO_KERNELS=ON \
  -DGGML_OPENCL_EMBED_KERNELS=ON \
  -DGGML_NATIVE=OFF

cmake --build /tmp/ggml_opencl_upstream_pr_build --target ggml -j

The OpenCL-enabled ggml target builds successfully on this branch.

@happyyzy
happyyzy marked this pull request as ready for review July 11, 2026 08:20
@happyyzy
happyyzy force-pushed the agent/opencl-q4-adreno-correctness-upstream branch from e30fbfe to 7d92e51 Compare July 12, 2026 15:05
@happyyzy

Copy link
Copy Markdown
Contributor Author

Could @lhez @max-krasnyansky @shaofeiqi help review or route this Adreno OpenCL Q4_0 correctness fix when you have a chance?

@akleine

akleine commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

The author has done an excellent job here !

I have succesful tested this PR using a different (older) sd.cpp commit and different models, e.g NitroFusion and Diff-InstructStar. For both I earlier noticed similar mono-color image problems as mentioned for Flux and Z-Image.

It should be emphasized that this PR now allows the use of multiple threads to use during computation in sd.cpp when using OpenCl / Adreno and Q4_0. (I had to use the -t 1 option beforehand.)

Please merge as soon as possible @lhez @max-krasnyansky @shaofeiqi
Thank You

@lhez

lhez commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@happyyzy Thank you for bringing this up.

I wonder if we can move this PR (and your xmem FA PR #1562) to llama.cpp repo since currently almost all development happens there and this way we can have all updates in the same place.

By the way, I think you can have a separate PR for fix the fused RMSNorm/MUL offset to use src1->view_offs and we can quickly merge it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants