Skip to content

opencl: ragged-tile MoE prefill FP16 GEMM optimization (skip padded expert tiles)#25433

Merged
max-krasnyansky merged 3 commits into
ggml-org:masterfrom
qualcomm:hq/moe-ragged-fp16
Jul 8, 2026
Merged

opencl: ragged-tile MoE prefill FP16 GEMM optimization (skip padded expert tiles)#25433
max-krasnyansky merged 3 commits into
ggml-org:masterfrom
qualcomm:hq/moe-ragged-fp16

Conversation

@wanghqc

@wanghqc wanghqc commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Overview

  1. The MoE prefill GEMM groups tokens into 32-wide per-expert tiles; at low tokens-per-expert most tiles are mostly padding and the computation is not needed and hurt performance.
  2. This PR is to skip the fully-padding skip-groups and pad in the quarter granularity, dotx8_reduce4, across all eight *_f32_ns MoE GEMMs (q4_0/q4_1/q5_0/q5_1/q4_k/q5_k/q6_k/mxfp4) to save unnecessary computations.
  3. Default on and opt out with GGML_OPENCL_MOE_RAGGED_FP16=0.
  4. Granularity can be set via GGML_OPENCL_MOE_RAGGED_GRAN={8,16,32}
  5. Numerically identical.
  6. Only for prefill: token generation untouched.

Additional information

Gains on X2 GPU: Qwen3-30B-A3B Q4_K_M pp128 +24% / pp512 +10%; Q4_0 pp128 +26%; gpt-oss-20b MXFP4 pp128 +20%

Requirements

Tested with Adreno GPUs on Windows on Snapdragon (WoS) X1 and X2 devices.

  • 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 7, 2026 20:37
The MoE prefill GEMM groups tokens into TILESIZE_N=32 per-expert tiles; at low
tokens-per-expert most tiles are mostly padding. When a tile's upper 16 slots
are all padding (router index 0xFFFFFFFF), skip the second dotx16_reduce8 half.
Numerically identical (skipped lanes are padding). Applied to all eight *_f32_ns
MoE GEMMs; default on, opt out with GGML_OPENCL_MOE_RAGGED_FP16=0.
Replace the two half-tile dotx16_reduce8 calls in the 8 *_f32_ns MoE GEMMs with
four dotx8_reduce4 (8-column) calls, skipping each empty trailing skip-group
independently. Padding is always trailing, so the kernel rounds the valid count
up to the skip granularity and skips fully-padding groups. Byte-identical to the
non-skipped path. New env GGML_OPENCL_MOE_RAGGED_GRAN={8,16,32} (quarter/half/
off); default quarter.
@wanghqc
wanghqc requested a review from a team as a code owner July 8, 2026 05:03
@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 06:51
@lhez

lhez commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

X2-90

With longer prompts.

gpt-oss-20b-mxfp4

this PR

0.39.915.472 I common_perf_print: prompt eval time =   16561.96 ms /  4294 tokens (    3.86 ms per token,   259.27 tokens per second)
0.39.915.473 I common_perf_print:        eval time =    8623.09 ms /   256 runs   (   33.68 ms per token,    29.69 tokens per second)

master

0.52.023.673 I common_perf_print: prompt eval time =   18061.53 ms /  4294 tokens (    4.21 ms per token,   237.74 tokens per second)
0.52.023.674 I common_perf_print:        eval time =    8658.40 ms /   256 runs   (   33.82 ms per token,    29.57 tokens per second)

Qwen3.6-35B-A3B-MXFP4_MOE

this PR

1.26.138.227 I common_perf_print: prompt eval time =   15552.92 ms /  4677 tokens (    3.33 ms per token,   300.72 tokens per second)
1.26.138.228 I common_perf_print:        eval time =   13101.59 ms /   256 runs   (   51.18 ms per token,    19.54 tokens per second)

master

1.19.758.016 I common_perf_print: prompt eval time =   18391.06 ms /  4677 tokens (    3.93 ms per token,   254.31 tokens per second)
1.19.758.017 I common_perf_print:        eval time =   13185.33 ms /   256 runs   (   51.51 ms per token,    19.42 tokens per second)

@max-krasnyansky
max-krasnyansky merged commit 167d057 into ggml-org:master Jul 8, 2026
34 of 40 checks passed
wanghqc added a commit to qualcomm/llama.cpp that referenced this pull request Jul 15, 2026
The ragged MoE GEMM change (ggml-org#25433) added two kernel args
(adreno_use_moe_ragged, adreno_moe_ragged_skip_gran) to the ns MoE GEMM
paths, set unconditionally. When GGML_OPENCL_USE_ADRENO_BIN_KERNELS is
enabled and the prebuilt kernel library is present, these paths select
the prebuilt *_ns_bin kernels, whose signatures do not include the
ragged args, so clSetKernelArg fails with CL_INVALID_ARG_INDEX and any
MoE model aborts on GGML_ASSERT.

Only set the ragged args when the built-in source kernel is selected
(q4_0, q4_1, q4_K, mxfp4 - the four paths with prebuilt variants; the
prebuilt kernels have no ragged support). Verified on Adreno X2-90 with
and without the prebuilt library on gpt-oss-20b MXFP4, Qwen3-30B-A3B
Q4_K_M and Q4_0.
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