Skip to content

Sync gfx11 with fork master (2026-09-20) - #110

Merged
jimw567 merged 610 commits into
gfx11from
jimwu.gfx11-sync-master-20260920
Sep 22, 2026
Merged

jimw567 merged 610 commits into
gfx11from
jimwu.gfx11-sync-master-20260920

Conversation

@jimw567

@jimw567 jimw567 commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Merge fork master into gfx11, bringing in the upstream sync from PR #109 (ggml-org master through 972d231).

Conflict resolution kept the fork behavior and took upstream where it supersedes it:

  • CI workflows: kept the gfx11 branch triggers, adopted upstream ubuntu-slim runners
  • Metal/OpenCL: kept the SSM_CONV channels-major guard, added upstream SSM_SCAN support
  • llama-model-loader: upstream lazy tensor read plus the fork PAD_ROWS handling
  • test-backend-ops: kept the RDNA3.5 MMQ cases, took upstream boundary coverage
  • ggml-cuda: upstream per-stream cuBLAS workspaces, MoE weighted reduction, and ncols_opt tiling, alongside mmvdq, ROCmFP4, and the RDNA3.5 Q4_K weight-hoist path

Also restores the local I constant in mmq-vec-dot.cuh that the RDNA3.5 J=128 static_assert depends on, which the upstream refactor had removed.

Validation: CPU test targets build; HIP gfx1151 test-backend-ops builds; MUL_MAT on gfx1151 passes 1621/1621.

ggerganov and others added 30 commits September 3, 2026 13:25
* metal : fix glu dispatch with ne00 = 1

* tests : disable ill-defined tests
* metal : support n_kv_max sparse mask hint in flash attention vec kernel

- add kernel_flash_attn_ext_vec_idx: compacts finite mask entries into
  a per-row index list (Hillis-Steele scan, one threadgroup per row)
- extend vec FA kernel with optional sparse index gathering (FC slot 5)
- add host-side gate: sparse path when n_kv_max > 0, mask present,
  supported head sizes / KV types, n_kv_max <= 4096
- new buffer region extra_idx for the index list
- pipeline getter extended with has_sparse param
- add test cases: head sizes, quant types, nb>1, nr23 variants,
  sinks, ALiBi, softcap, permute, v_view_of_k, no-mask fallback

Note: multi-row (nb*nr23[1] > 1) cases still failing - rid mapping
in the store phase needs revisiting for the sparse path.

Assisted-by: pi:llama.cpp/Qwen3.8-27B

* metal : fix sparse flash attention row addressing

- kernel_flash_attn_ext_vec_idx: mask param is half* but nb31 is a byte
  stride, so the per-row mask offset was scaled by 2x; cast to char*
  before applying the byte strides
- kernel_flash_attn_ext_vec: sparse pidx param is char* so the per-row
  element offset was under-scaled by sizeof(int); scale it by sizeof(int)
  to get the correct byte offset
- fixes the multi-row (nb*nr23[1] > 1) sparse flash attention failures

Assisted-by: pi:llama.cpp/DeepSeek-v4-0731

* cont : use sparse vec FA for prefill

* metal : single-pass flash attention sparse index compaction

The idx kernel previously read the mask row twice: once to count the finite
entries (for the prefix scan) and again to recover their positions. Since the
kernel is memory-bound, this doubled the mask traffic.

Keep the finite positions in a per-thread register array during the count
pass and write them out directly, avoiding the second mask read. A dense
mask with more than NLOCAL finite entries in a slice falls back to re-reading
the mask to write the remaining positions.

Assisted-by: pi:llama.cpp/DeepSeek-v4-0731

* tests : add perf cases for sparse flash attention prefill

Measure the sparse vec FA kernel across KV sizes, n_kv_max hints and batch
sizes. Run with:

    ./build/bin/test-backend-ops -b MTL0 -o FLASH_ATTN_EXT -p "n_kv_max=[1-9]" perf

Assisted-by: pi:llama.cpp/DeepSeek-v4-0731

* qwen4 : enable sparse attention

* cont : adjust nsg

* cont : sync test-backend-ops

* cont : disable Qwen4 for now

* cont : clean-up + tests
* server : use pytest-xdist for server tests

This commit adds pytest-xdist to the server tests. This is pytest
plugin that distributes test execution across multiple CPU cores.

Assisted-by: pi:llama.cpp/qwen3.8-27B

Refs: ggml-org#26734 (comment)

* remove server_base_port and BASE_PORT

* use worksteal and pytest builting tmp_path
* snapdragon: update CI script to use new snapdragon/run.py

* snapdragon: update build.py to not set +x on /lib
…ns (speculative decoding/MTP) (ggml-org#26477)

* opencl: quant lm_head / decode GEMV and medium-batch GEMM optimizations

* opencl: guard q4_K/q6_K tiled_ns convert-kernel registration for non-Adreno build

* opencl: gate q4_K MUL_MAT+GLU fusion dispatch to Adreno

* opencl: require the noshuffle weight layout in the q4_K GLU fusion gate

* opencl: do not take the vectorized f16 mrow GEMV path on an unaligned row stride

* opencl: pass the new get_scale_min_k4 stride argument at the row-major call sites

* opencl: enable the q4_K split-K decode GEMV only where it is measured to win

* opencl: record the X1-85 split-K datapoint (neutral, exclusion confirmed)

* opencl: restrict the tiled lm_head/embed GEMV default to X2E/A8X

* opencl: fix q4_K variant kernels to read the transposed scales layout

* opencl: keep the flat-GEMV large-m escape opt-in

* opencl: guard the o4 GEMV store against the rounded-up dispatch tail

* opencl: restore the tiled q4_K/q6_K layout on tensor read-back

* opencl: split-K for the q8_0 decode GEMV at small M

* opencl: keep the q6_K noshuffle correctness escape ahead of the opt-in gate
Fuse RMS_NORM+MUL+ADD and ADD+ADD under GGML_SYCL_ENABLE_FUSION.

ADD+ADD uses the same binbcast indexing and type matrix as standalone
add() (f32, f16, f16/f32, i32, i16, bf16, including broadcast and
non-contiguous). Unsupported combinations fall back to two add() launches.
* src : add n_expert_used_max function

With Commit c61b98b ("model: add
NVIDIA Nemotron-3-Puzzle-75B-A9B (NemotronHPuzzle) support (ggml-org#25444)") it
is now possible for each layer to have a specific number of experts but
there are a few checks that need to be updated to handle this upon model
loading. For example:
```console
llama_model_load: error loading model: model has expert layers but no expert layers are used
```
And later:
```console
/llama.cpp/src/llama-model-loader.cpp:955: GGML_ASSERT(n_ids_used > 0) failed
```

This commit adds the n_expert_used_max function so that these checks
can use it.

Refs: ggml-org#25444 (comment)

* src : use hparams.n_expert_used_max in llama_model_base::load_hparams

* src : use 0 as initial value for n_expert_used_max
Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>
Let llama_print_build_info write to a caller-provided FILE* instead of
hardcoding stderr. The parameter defaults to stderr so existing callers
keep their current behavior.

The version command in llama-app now passes stdout, so plain version
output goes to stdout where users expect it.

Signed-off-by: Adrien Gallouët <angt@huggingface.co>
)

Assisted-by: pi:llama.cpp/DeepSeek-V4-Flash-Vision-Exp
Signed-off-by: Adrien Gallouët <angt@huggingface.co>
…8271)

Use std::error_code overloads of fs::current_path() and
fs::directory_iterator in ggml_backend_load_best() so an
inaccessible search path (WebDAV mount, removed CWD) is
skipped instead of terminating the process with an uncaught
filesystem_error.

Signed-off-by: Adrien Gallouët <angt@huggingface.co>
This commit adds a cmake version configuration file to replace the
current compile definition solution for the version.

The motivation for this change is that I made a mistake and did not take
into consideration that the compile definition means that this will
become a compiler flag for all sources in the target. This means that
when a version update happens that will recompile all sources in the
target even if they have not changed.

Refs: ggml-org#28278
* model, mtmd: fix gemma4 vision handling

* nits
* ggml : rename and make private ggml_op_alloc_size_may_expand() (ggml/0)

cont ggml-org#27960

* ggml : bump version to 0.23.0 (ggml/1618)

* sync : ggml
…rg#28127)

* model: add Tencent Hy 4 (hy_v4) preview architecture support

Adds support for the Tencent Hy 4 model (Hugging Face architecture
HYV4ForCausalLM, GGUF arch hy_v4):

Add HF -> GGUF conversion script (conversion/hy_v4.py) and wire it into the conversion registry
Register hy_v4 GGUF constants, arch enum, and writer support
Implement the hy-v4 model graph, hparams, vocab and context changes
Register the new arch in llama-arch and models registry
Extend arch tests to cover hy_v4

Assisted by Claude Opus 5

* Update convert_hf_to_gguf_update.py

Co-authored-by: fairydreaming <166155368+fairydreaming@users.noreply.github.com>

* Update conversion/base.py

Co-authored-by: fairydreaming <166155368+fairydreaming@users.noreply.github.com>

* convert : move hy_v4 entry to the same place as in convert_hf_to_gguf_update.py

* model : apply changes related to n_ff_exp becoming per-layer in Hy4-preview

* n_layer_all

---------

Co-authored-by: fairydreaming <166155368+fairydreaming@users.noreply.github.com>
Co-authored-by: Stanisław Szymczyk <sszymczy@gmail.com>
Co-authored-by: Sigbjørn Skjæret <sigbjorn.skjaeret@huggingface.co>
* move more jobs to ccache-buckets

* add venv deps

* also jq
* opencl: add Adreno xmem SDPA path

Assisted-by: Codex

* Removed the Adreno-specific queue profiling override

* Clean up formatting

* 修复数值误差优化gqa/mask attn

Assisted-by: Codex

* add env GGML_OPENCL_XMEM_SDPA

Assisted-by: OpenAI Codex

---------

Co-authored-by: happyyzy <happyyzy@users.noreply.github.com>
lhez and others added 17 commits September 17, 2026 09:48
* opencl: fix warnings

* opencl: fix warnings for non adreno
ggml-org#28993)

* gguf : align the data section relative to the GGUF start, not the file

gguf_init_from_file_ptr reads a GGUF from the current file position, but padded
the data section from file offset 0, so a GGUF embedded at an offset that is not
a multiple of the alignment loaded without error and returned wrong tensor data.

Also adds llama_adapter_lora_init_from_file_ptr, and disables mmap with a warning
when an embedded data section is not aligned, instead of asserting in ggml.

Assisted-by: Claude Opus 5

* llama : load lora from path through the FILE* variant

The test now checks that mmap is disabled only for an unaligned offset.

Assisted-by: Claude Fable 5.1

* Update ggml/src/gguf.cpp

Co-authored-by: Johannes Gäßler <johannesg@5d6.de>

* Update include/llama.h

Co-authored-by: Johannes Gäßler <johannesg@5d6.de>

* llama : error on unaligned mmap of an embedded GGUF, drop test-load-file-ptr

---------

Co-authored-by: Johannes Gäßler <johannesg@5d6.de>
…g#29008)

* chat : add message delimiters to the DeepSeek V3.2/V4 parser

Assisted-by: Claude
Co-authored-by: Sigbjørn Skjæret <sigbjorn.skjaeret@huggingface.co>
* ci : add API/ABI check to make-release workflow [no ci]

This commit adds an API/ABI compatibility check to the make-release
workflow.

The motivation for this to allow us to detect any potential breaking
changes in API/ABI compatibility between releases and fail the the
release if there are any.

The workflow can be triggered manually as before and this check can be
skipped if needed as it does take some time which might be useful when
doing a dry-run and not specifically interested in the API/ABI check.

By default this will check the current release against the latest
release, but this can also be configured in the workflow, or in the
script run on the command line, to check a different tag.

* add check for minor version bumps [no ci]

This commit also changes the build type to be RelWithDebInfo so that the
reported information is more useful.
…org#27985)

* ui: fix accidentally removed reasoning menu in single model mode on desktop

* ui: formatting task run to fix storybook test

* ui: mount the add menu reasoning submenu outside router mode only

The models selector already owns the reasoning submenu in router mode,
so the add menu only mounts it in single model mode. The first enabled
item of the add menu is now the reasoning submenu, the accessibility
story expects it.

---------

Co-authored-by: Ben Babik <work@benjaminbabik.com>
Co-authored-by: Pascal <admin@serveurperso.com>
…org#29009)

* Update to openvino-2026.4

* Update OV docs

* ggml-openvino : fix clangd and MSVC warnings

* fix int to ptr cast, more internal linkage enforcement, and avoiding duplicate switch case

---------

Co-authored-by: Mostafa Faheem <mostafaaafaheem@gmail.com>
* first fix

* removed unnecessary declarations
required for qwen35moe if MTP tensors are fused but not loaded
Co-Authored-By: Claude <noreply@anthropic.com>
Sync fork master with upstream (2026-09-17)
Assisted-by: Claude Opus

@Annieren Annieren left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed ggml_cuda mmvq path, looks good to me.

@liangliangchang

Copy link
Copy Markdown

MMQ also looks good. Let me run some models to confirm. @Annieren there is one conflict in test-backend-ops.cpp on flush mode, do we want to keep both?

@Annieren

Copy link
Copy Markdown

there is one conflict in test-backend-ops.cpp on flush mode, do we want to keep both?

My PR#107 adds if (flush_cache) ggml_backend_graph_compute(backend, gf_flush); at the top of the loop, and a break on flush_iters at the
bottom.
- this branch adds reinit_perf_iter(ctx.get()); at the bottom of the loop.
- My PR#107 also forces n_runs = 1 when flushing.
But semantically there is no contradiction.
They operate on different concerns and both live in the same loop cleanly. Keeping both is correct. A possible resolution is like:

do {
if (flush_cache) {
ggml_backend_graph_compute(backend, gf_flush); // dq-refractor
}
int64_t start_time = ggml_time_us();
... compute gf ...
int64_t end_time = ggml_time_us();
total_time_us += ...; total_mem += ...; total_runs += ...;

  reinit_perf_iter(ctx.get());                          // this branch

  if (flush_cache && total_runs >= flush_iters) {       // dq-refractor
      break;
  }

} while (total_time_us < 1000*1000);

@Annieren

Copy link
Copy Markdown

I have resolved the conflicts.

@liangliangchang

Copy link
Copy Markdown
Benchmark Results
Workload Board Latest prefill Master prefill Change Latest decode Master decode Change Status / sanity
Qwen2.5-0.5B-Instruct_Q4_K_M_GGUF_128 xconucstrhalo41 10102.45 10076.25 -0.26% 313.10 348.16 +11.20% PASS/PASS; sanity PASS/PASS
Qwen2.5-0.5B-Instruct_Q4_K_M_GGUF_3968 xconucstrhalo41 10103.10 10141.35 +0.38% 258.02 257.75 -0.10% PASS/PASS; sanity PASS/PASS
Qwen2.5-3B-Instruct_Q4_K_M_GGUF_128 xconucstrhalo41 2832.22 2975.74 +5.07% 92.29 94.24 +2.12% PASS/PASS; sanity PASS/PASS
Qwen2.5-3B-Instruct_Q4_K_M_GGUF_3968 xconucstrhalo40 2724.06 2761.40 +1.37% 90.31 90.24 -0.08% PASS/PASS; sanity PASS/PASS
Qwen2.5-7B-Instruct_Q4_K_M_GGUF_128 xconucstrhalo41 1477.83 1516.30 +2.60% 47.45 47.40 -0.10% PASS/PASS; sanity PASS/PASS
Qwen2.5-7B-Instruct_Q4_K_M_GGUF_3968 xconucstrhalo40 1372.15 1414.13 +3.06% 44.65 44.49 -0.37% PASS/PASS; sanity PASS/PASS
Qwen3-1.7B_Q4_K_M_GGUF_128 xconucstrhalo05 5020.24 5125.08 +2.09% 158.03 158.21 +0.11% PASS/PASS; sanity PASS/PASS
Qwen3-1.7B_Q4_K_M_GGUF_3968 xconucstrhalo41 3768.25 4174.78 +10.79% 117.80 117.83 +0.03% PASS/PASS; sanity PASS/PASS
Qwen3-4B_Q4_K_M_GGUF_128 xconucstrhalo05 2435.69 2445.72 +0.41% 77.57 77.72 +0.19% PASS/PASS; sanity PASS/PASS
Qwen3-4B_Q4_K_M_GGUF_3968 xconucstrhalo41 1757.94 1888.18 +7.41% 63.60 63.82 +0.35% PASS/PASS; sanity PASS/PASS
Qwen3-8B_Q4_K_M_GGUF_128 xconucstrhalo05 1426.29 1412.64 -0.96% 43.92 43.95 +0.08% PASS/PASS; sanity PASS/PASS
Qwen3-8B_Q4_K_M_GGUF_3968 xconucstrhalo40 1181.27 1242.52 +5.19% 38.79 39.00 +0.53% PASS/PASS; sanity PASS/PASS
Qwen3.5-4B_Q4_K_M_GGUF_128 xconucstrhalo41 2056.46 2161.50 +5.11% 63.45 63.30 -0.24% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_K_M_GGUF_128 xconucstrhalo05 1324.81 1335.56 +0.81% 37.80 37.66 -0.38% PASS/PASS; sanity PASS/PASS
Llama-2-7B_Q4_K_M_GGUF_128 xconucstrhalo41 1404.79 1404.58 -0.02% 47.43 48.88 +3.06% PASS/PASS; sanity PASS/PASS
Llama-2-7B_Q4_K_M_GGUF_1920 xconucstrhalo40 1175.53 1178.47 +0.25% 35.81 35.82 +0.02% PASS/PASS; sanity PASS/PASS
Gemma-2B_Q4_K_M_GGUF_128 xconucstrhalo05 4418.58 4369.03 -1.12% 119.22 119.52 +0.25% PASS/PASS; sanity PASS/PASS
Gemma-2B_Q4_K_M_GGUF_8000 xconucstrhalo41 2386.60 2967.14 +24.32% 110.77 110.70 -0.06% PASS/PASS; sanity PASS/PASS
SmolLM2-1.7B-Instruct_Q4_K_M_GGUF_128 xconucstrhalo05 4448.81 4470.12 +0.48% 160.98 163.13 +1.34% PASS/PASS; sanity PASS/PASS
SmolLM2-1.7B-Instruct_Q4_K_M_GGUF_8000 xconucstrhalo05 1245.30 1245.57 +0.02% 37.31 37.32 +0.04% PASS/PASS; sanity PASS/PASS
SmolLM2-1.7B-Instruct_F16_GGUF_128 xconucstrhalo40 4066.23 3964.44 -2.50% 53.19 53.15 -0.08% PASS/PASS; repeat prefill -0.72% (details); sanity PASS/PASS
SmolLM2-1.7B-Instruct_F16_GGUF_8000 xconucstrhalo41 1259.61 1263.53 +0.31% 25.73 25.38 -1.35% PASS/PASS; sanity PASS/PASS
Llama-3.1-8B-Instruct_Q4_K_M_GGUF_128 xconucstrhalo40 1324.17 1309.16 -1.13% 44.36 44.44 +0.16% PASS/PASS; sanity PASS/PASS
Qwen3-30B-A3B-Instruct-2507_Q4_K_M_GGUF_128 xconucstrhalo05 1322.14 1339.35 +1.30% 84.14 80.99 -3.74% PASS/PASS; repeat decode -1.53%, not confirmed above 2% (details); sanity PASS/PASS
Gemma-4-E2B-IT_Q4_K_M_GGUF_128 xconucstrhalo40 3294.41 3166.74 -3.88% 107.65 107.73 +0.08% PASS/PASS; repeat prefill -0.38%, mixed pairs (details); sanity PASS/PASS
Gemma-4-E2B-IT_Q4_K_M_GGUF_3968 xconucstrhalo40 2816.24 2907.06 +3.22% 101.29 101.49 +0.19% PASS/PASS; sanity PASS/PASS
Gemma-4-E2B-IT_BF16_GGUF_128 xconucstrhalo41 3166.89 3136.68 -0.95% 43.37 43.36 -0.01% PASS/PASS; sanity PASS/PASS
Qwen3.5-35B-A3B_Q4_K_M_GGUF_128 xconucstrhalo40 1324.55 1331.24 +0.51% 61.00 60.51 -0.80% PASS/PASS; sanity PASS/PASS
Qwen3.5-35B-A3B_VLM xconucstrhalo05 947.93 947.07 -0.09% 59.55 59.00 -0.93% PASS/PASS; sanity PASS/PASS
Qwen3.6-35B-A3B_Q4_K_M_GGUF_128 xconucstrhalo41 1330.13 1336.83 +0.50% 61.70 61.20 -0.81% PASS/PASS; sanity PASS/PASS
Qwen3.6-35B-A3B_Q4_K_M_GGUF_4096 xconucstrhalo05 1680.68 1694.39 +0.82% 60.26 59.75 -0.84% PASS/PASS; sanity PASS/PASS
Qwen3.6-35B-A3B_VLM_large-context xconucstrhalo40 1501.03 1575.65 +4.97% 55.27 54.82 -0.81% PASS/PASS; generated lengths differ; sanity PASS/PASS
Cosmos-Reason2-2B_Q4_K_M_GGUF_VLM xconucstrhalo40 1771.67 1764.10 -0.43% 134.02 133.85 -0.13% PASS/PASS; sanity PASS/PASS
Cosmos-Reason2-2B_Q4_K_M_GGUF_VLM_text-short-smoke xconucstrhalo05 1222.28 1187.60 -2.84% 137.44 131.15 -4.58% PASS/PASS; repeat prefill -1.73%, decode +0.07%, mixed pairs (details); sanity PASS/PASS
Cosmos-Reason2-2B_Q4_K_M_GGUF_VLM_image-caption-224 xconucstrhalo05 1378.08 1379.08 +0.07% 148.04 147.86 -0.12% PASS/PASS; sanity PASS/PASS
Cosmos-Reason2-2B_Q4_K_M_GGUF_VLM_vqa-448 xconucstrhalo40 1569.90 1591.69 +1.39% 145.02 144.93 -0.06% PASS/PASS; sanity PASS/PASS
Cosmos-Reason2-2B_Q4_K_M_GGUF_VLM_ocr-1024 xconucstrhalo05 1199.58 1217.74 +1.51% 135.74 134.77 -0.72% PASS/PASS; generated lengths differ; sanity PASS/PASS
Cosmos-Reason2-2B_Q4_K_M_GGUF_VLM_multi-image-reasoning xconucstrhalo40 1596.46 1667.83 +4.47% 144.51 143.88 -0.44% PASS/PASS; generated lengths differ; sanity PASS/PASS
Cosmos-Reason2-2B_Q4_K_M_GGUF_VLM_document-qa-long-context xconucstrhalo05 4873.38 4983.57 +2.26% 143.59 144.57 +0.68% PASS/PASS; generated lengths differ; sanity PASS/PASS
Cosmos-Reason2-8B_Q4_K_M_GGUF_VLM_apolo13x xconucstrhalo40 853.31 861.25 +0.93% 41.25 41.43 +0.46% PASS/PASS; sanity PASS/PASS
Cosmos-Reason2-8B_Q8_0_GGUF_VLM_prithivMLmods xconucstrhalo41 876.97 877.45 +0.05% 25.98 25.95 -0.12% PASS/PASS; sanity PASS/PASS
Gemma-3-4B-IT_VLM xconucstrhalo05 711.47 715.10 +0.51% 70.36 70.38 +0.03% PASS/PASS; sanity PASS/PASS
Gemma-4-E2B-IT_Q4_0_GGUF_VLM xconucstrhalo05 1986.82 1780.85 -10.37% 100.94 100.50 -0.43% PASS/PASS; prompt token counts differ; generated lengths differ; sanity PASS/PASS
Gemma-4-E4B-IT_Q4_0_GGUF_VLM xconucstrhalo40 1323.07 1269.88 -4.02% 56.55 56.39 -0.29% PASS/PASS; repeat prefill -4.18%, changed workload (details); prompt token counts differ; generated lengths differ; sanity PASS/PASS
Gemma-3-4B-IT_VLM_text-short-smoke xconucstrhalo41 415.09 402.94 -2.93% 71.03 67.67 -4.74% PASS/PASS; repeat prefill +0.71%, decode +1.26% (details); sanity PASS/PASS
Gemma-3-4B-IT_VLM_image-caption-224 xconucstrhalo05 317.82 320.49 +0.84% 71.11 71.77 +0.93% PASS/PASS; sanity PASS/PASS
Gemma-3-4B-IT_VLM_vqa-448 xconucstrhalo41 296.64 298.93 +0.77% 68.38 71.14 +4.04% PASS/PASS; sanity PASS/PASS
Gemma-3-4B-IT_VLM_ocr-1024 xconucstrhalo40 298.77 301.96 +1.07% 72.15 72.17 +0.03% PASS/PASS; sanity PASS/PASS
Gemma-3-4B-IT_VLM_multi-image-reasoning xconucstrhalo05 308.23 310.14 +0.62% 71.14 71.27 +0.18% PASS/PASS; generated lengths differ; sanity PASS/PASS
Gemma-3-4B-IT_VLM_document-qa-long-context xconucstrhalo41 2149.17 2162.09 +0.60% 72.45 72.03 -0.57% PASS/PASS; generated lengths differ; sanity PASS/PASS
Gemma-4-E2B-IT_Q4_0_GGUF_VLM_text-short-smoke xconucstrhalo41 584.00 582.62 -0.24% 84.31 84.09 -0.27% PASS/PASS; sanity PASS/PASS
Gemma-4-E2B-IT_Q4_0_GGUF_VLM_image-caption-224 xconucstrhalo41 833.88 1058.57 +26.95% 92.42 95.16 +2.96% PASS/PASS; sanity PASS/PASS
Gemma-4-E2B-IT_Q4_0_GGUF_VLM_vqa-448 xconucstrhalo05 841.90 900.34 +6.94% 85.22 91.40 +7.26% PASS/PASS; generated lengths differ; sanity PASS/PASS
Gemma-4-E2B-IT_Q4_0_GGUF_VLM_ocr-1024 xconucstrhalo41 1029.82 967.65 -6.04% 101.11 100.28 -0.82% PASS/PASS; repeat prefill -6.50%, changed prompt and output lengths (details); generated lengths differ; sanity PASS/PASS
Gemma-4-E2B-IT_Q4_0_GGUF_VLM_multi-image-reasoning xconucstrhalo05 918.66 950.63 +3.48% 98.50 98.48 -0.02% PASS/PASS; sanity PASS/PASS
Gemma-4-E2B-IT_Q4_0_GGUF_VLM_document-qa-long-context xconucstrhalo40 3194.74 3256.09 +1.92% 95.54 97.57 +2.12% PASS/PASS; generated lengths differ; sanity PASS/PASS
Gemma-4-E4B-IT_Q4_0_GGUF_VLM_text-short-smoke xconucstrhalo05 351.06 350.31 -0.21% 49.97 49.78 -0.37% PASS/PASS; sanity PASS/PASS
Gemma-4-E4B-IT_Q4_0_GGUF_VLM_image-caption-224 xconucstrhalo40 539.09 703.37 +30.47% 54.88 55.69 +1.49% PASS/PASS; generated lengths differ; sanity PASS/PASS
Gemma-4-E4B-IT_Q4_0_GGUF_VLM_vqa-448 xconucstrhalo41 588.34 634.83 +7.90% 52.23 52.67 +0.85% PASS/PASS; sanity PASS/PASS
Gemma-4-E4B-IT_Q4_0_GGUF_VLM_ocr-1024 xconucstrhalo40 785.64 772.22 -1.71% 57.09 56.32 -1.35% PASS/PASS; generated lengths differ; sanity PASS/PASS
Gemma-4-E4B-IT_Q4_0_GGUF_VLM_multi-image-reasoning xconucstrhalo05 686.35 691.96 +0.82% 56.45 56.58 +0.24% PASS/PASS; generated lengths differ; sanity PASS/PASS
Gemma-4-E4B-IT_Q4_0_GGUF_VLM_document-qa-long-context xconucstrhalo41 1920.69 1932.61 +0.62% 53.57 55.64 +3.86% PASS/PASS; generated lengths differ; sanity PASS/PASS
Qwen2.5-VL-3B-Instruct_VLM xconucstrhalo05 718.88 718.83 -0.01% 91.11 90.92 -0.20% PASS/PASS; sanity PASS/PASS
Qwen2.5-VL-7B-Instruct_VLM xconucstrhalo40 576.67 579.12 +0.43% 45.72 45.52 -0.42% PASS/PASS; sanity PASS/PASS
Qwen3-VL-4B-Instruct_VLM xconucstrhalo41 1257.13 1246.36 -0.86% 70.29 70.38 +0.12% PASS/PASS; sanity PASS/PASS
Gemma-4-26B-A4B-IT_VLM xconucstrhalo05 835.75 720.34 -13.81% 46.42 46.12 -0.63% PASS/PASS; repeat prefill -12.19%, changed workload (details); prompt token counts differ; sanity PASS/PASS
Gemma-4-31B-IT_VLM xconucstrhalo41 246.99 237.95 -3.66% 10.65 10.59 -0.57% PASS/PASS; repeat prefill -3.60%, changed prompts; one stalled attempt (details); prompt token counts differ; sanity PASS/PASS
Gemma-4-31B-IT_VLM_OpenNav xconucstrhalo40 226.85 233.71 +3.03% 10.72 10.73 +0.11% PASS/PASS; sanity PASS/PASS
Qwen3-Omni-30B-A3B-Instruct_VLM xconucstrhalo05 1043.33 1030.40 -1.24% 77.50 76.24 -1.62% PASS/PASS; sanity PASS/PASS
MiniCPM-V-2_6_VLM xconucstrhalo41 587.96 646.99 +10.04% 46.55 46.32 -0.50% PASS/PASS; sanity PASS/PASS
MiniCPM-o-2_6_VLM xconucstrhalo41 593.91 648.95 +9.27% 46.24 46.33 +0.19% PASS/PASS; sanity PASS/PASS
Janus-Pro-1B_VLM xconucstrhalo05 4606.39 4535.23 -1.54% 151.49 151.34 -0.10% PASS/PASS; sanity PASS/PASS
Janus-Pro-7B_VLM xconucstrhalo05 1494.41 1477.50 -1.13% 41.14 39.85 -3.14% PASS/PASS; repeat decode -0.05% (details); sanity PASS/PASS
Qwen3.6-27B_Q4_K_M_GGUF_4096 xconucstrhalo41 377.89 402.82 +6.60% 9.38 11.57 +23.32% PASS/PASS; temperature and within-run throughput drift; repeat needed; sanity PASS/PASS
GLM-4.7-Flash_Q4_K_M_GGUF_128 xconucstrhalo05 1076.39 1081.57 +0.48% 63.99 63.68 -0.48% PASS/PASS; sanity PASS/PASS
Gemma-4-12B-it_Q4_K_M_GGUF_128 xconucstrhalo40 849.39 880.17 +3.62% 28.40 27.61 -2.75% PASS/PASS; repeat decode +0.05% (details); sanity PASS/PASS
Gemma-3-12B-IT_Q4_K_M_GGUF_VLM xconucstrhalo05 291.72 292.70 +0.33% 27.40 27.36 -0.15% PASS/PASS; sanity PASS/PASS
Gemma-3-12B-IT_Q4_K_M_GGUF_4096 xconucstrhalo40 757.28 909.21 +20.06% 23.21 25.10 +8.13% PASS/PASS; temperature and within-run throughput drift; repeat needed; sanity PASS/PASS
Qwen3.5-4B_Q4_0_GGUF_baseline_code xconucstrhalo05 511.22 510.86 -0.07% 65.62 65.23 -0.60% PASS/PASS; repeat prefill borderline -2.16%, 3 of 4 pairs below -2% (details); sanity PASS/PASS
Qwen3.5-4B_Q4_0_GGUF_baseline_list xconucstrhalo05 423.05 425.82 +0.66% 65.18 64.78 -0.61% PASS/PASS; sanity PASS/PASS
Qwen3.5-4B_Q4_0_GGUF_baseline_prose xconucstrhalo05 355.46 360.53 +1.42% 65.55 65.18 -0.57% PASS/PASS; sanity PASS/PASS
Qwen3.5-4B_Q4_0_GGUF_mtp_code xconucstrhalo05 419.31 409.61 -2.31% 123.81 124.42 +0.50% PASS/PASS; repeat prefill -0.59%, mixed pairs (details); sanity PASS/PASS
Qwen3.5-4B_Q4_0_GGUF_mtp_list xconucstrhalo05 348.18 343.78 -1.26% 128.29 131.70 +2.66% PASS/PASS; sanity PASS/PASS
Qwen3.5-4B_Q4_0_GGUF_mtp_prose xconucstrhalo05 292.54 296.65 +1.41% 85.20 82.63 -3.01% PASS/PASS; repeat decode -4.80%, changed outputs and acceptance (details); sanity PASS/PASS
Qwen3.5-4B_Q4_K_M_GGUF_baseline_code xconucstrhalo41 573.61 576.51 +0.51% 60.34 59.95 -0.65% PASS/PASS; sanity PASS/PASS
Qwen3.5-4B_Q4_K_M_GGUF_baseline_list xconucstrhalo41 470.22 468.68 -0.33% 59.96 59.55 -0.67% PASS/PASS; sanity PASS/PASS
Qwen3.5-4B_Q4_K_M_GGUF_baseline_prose xconucstrhalo41 402.61 401.62 -0.25% 60.27 59.86 -0.69% PASS/PASS; sanity PASS/PASS
Qwen3.5-4B_Q4_K_M_GGUF_mtp_code xconucstrhalo41 474.23 460.87 -2.82% 107.09 105.55 -1.45% PASS/PASS; repeat prefill +1.79% (details); sanity PASS/PASS
Qwen3.5-4B_Q4_K_M_GGUF_mtp_list xconucstrhalo41 390.94 378.68 -3.14% 110.96 113.25 +2.07% PASS/PASS; repeat prefill +2.14% (details); sanity PASS/PASS
Qwen3.5-4B_Q4_K_M_GGUF_mtp_prose xconucstrhalo41 328.01 322.44 -1.70% 69.84 71.27 +2.04% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_0_GGUF_baseline_code xconucstrhalo05 346.00 346.97 +0.28% 39.65 39.60 -0.12% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_0_GGUF_baseline_list xconucstrhalo05 286.13 284.05 -0.73% 39.50 39.40 -0.25% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_0_GGUF_baseline_prose xconucstrhalo05 238.35 242.26 +1.64% 39.62 39.56 -0.15% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_0_GGUF_mtp_code xconucstrhalo05 299.67 299.85 +0.06% 82.06 86.02 +4.82% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_0_GGUF_mtp_list xconucstrhalo05 244.54 241.84 -1.11% 84.27 86.30 +2.40% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_0_GGUF_mtp_prose xconucstrhalo05 208.64 207.09 -0.74% 57.78 64.26 +11.23% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_K_M_GGUF_baseline_code xconucstrhalo40 371.94 371.12 -0.22% 37.13 37.09 -0.11% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_K_M_GGUF_baseline_list xconucstrhalo40 303.28 311.99 +2.87% 36.92 36.87 -0.14% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_K_M_GGUF_baseline_prose xconucstrhalo40 260.63 262.90 +0.87% 37.09 37.05 -0.11% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_K_M_GGUF_mtp_code xconucstrhalo40 323.89 324.02 +0.04% 68.53 70.20 +2.43% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_K_M_GGUF_mtp_list xconucstrhalo40 266.83 264.63 -0.82% 72.76 74.15 +1.91% PASS/PASS; sanity PASS/PASS
Qwen3.5-9B_Q4_K_M_GGUF_mtp_prose xconucstrhalo40 226.97 224.70 -1.00% 46.06 52.04 +12.98% PASS/PASS; sanity PASS/PASS
Qwen3.6-27B_Q4_0_GGUF_baseline_code xconucstrhalo41 114.44 118.53 +3.57% 13.36 13.33 -0.23% PASS/PASS; sanity PASS/PASS
Qwen3.6-27B_Q4_0_GGUF_baseline_list xconucstrhalo41 93.96 97.03 +3.27% 13.33 13.00 -2.46% PASS/PASS; repeat decode -0.19% (details); sanity PASS/PASS
Qwen3.6-27B_Q4_0_GGUF_baseline_prose xconucstrhalo41 80.18 82.72 +3.17% 13.38 13.34 -0.29% PASS/PASS; sanity PASS/PASS
Qwen3.6-27B_Q4_0_GGUF_mtp_code xconucstrhalo41 103.57 102.64 -0.90% 34.53 36.19 +4.83% PASS/PASS; sanity PASS/PASS
Qwen3.6-27B_Q4_0_GGUF_mtp_list xconucstrhalo41 84.90 83.30 -1.89% 35.59 35.88 +0.82% PASS/PASS; sanity PASS/PASS
Qwen3.6-27B_Q4_0_GGUF_mtp_prose xconucstrhalo41 72.13 70.99 -1.58% 28.07 28.48 +1.45% PASS/PASS; sanity PASS/PASS
Qwen3.6-27B_Q4_K_M_GGUF_baseline_code xconucstrhalo05 135.45 131.71 -2.76% 12.45 12.42 -0.20% PASS/PASS; repeat prefill -0.35% (details); sanity PASS/PASS
Qwen3.6-27B_Q4_K_M_GGUF_baseline_list xconucstrhalo05 111.42 107.49 -3.53% 12.42 12.39 -0.21% PASS/PASS; repeat prefill -0.77% (details); sanity PASS/PASS
Qwen3.6-27B_Q4_K_M_GGUF_baseline_prose xconucstrhalo05 95.08 91.84 -3.41% 12.45 12.42 -0.30% PASS/PASS; repeat prefill +1.27% (details); sanity PASS/PASS
Qwen3.6-27B_Q4_K_M_GGUF_mtp_code xconucstrhalo05 115.03 114.67 -0.32% 29.13 29.37 +0.83% PASS/PASS; sanity PASS/PASS
Qwen3.6-27B_Q4_K_M_GGUF_mtp_list xconucstrhalo05 95.48 93.88 -1.68% 29.28 29.44 +0.54% PASS/PASS; sanity PASS/PASS
Qwen3.6-27B_Q4_K_M_GGUF_mtp_prose xconucstrhalo05 81.49 81.77 +0.34% 19.64 22.06 +12.32% PASS/PASS; sanity PASS/PASS
Qwen3.6-35B-A3B_Q4_K_M_GGUF_baseline_code xconucstrhalo40 303.33 309.22 +1.94% 59.00 59.25 +0.43% PASS/PASS; sanity PASS/PASS
Qwen3.6-35B-A3B_Q4_K_M_GGUF_baseline_list xconucstrhalo40 260.29 261.64 +0.52% 57.84 58.11 +0.46% PASS/PASS; sanity PASS/PASS
Qwen3.6-35B-A3B_Q4_K_M_GGUF_baseline_prose xconucstrhalo40 219.43 225.27 +2.66% 58.85 59.25 +0.68% PASS/PASS; sanity PASS/PASS
Qwen3.6-35B-A3B_Q4_K_M_GGUF_mtp_code xconucstrhalo40 264.03 266.63 +0.99% 96.21 102.35 +6.38% PASS/PASS; sanity PASS/PASS
Qwen3.6-35B-A3B_Q4_K_M_GGUF_mtp_list xconucstrhalo40 221.71 227.36 +2.54% 90.61 99.84 +10.19% PASS/PASS; sanity PASS/PASS
Qwen3.6-35B-A3B_Q4_K_M_GGUF_mtp_prose xconucstrhalo40 188.97 191.49 +1.33% 69.35 78.34 +12.95% PASS/PASS; generated lengths differ; sanity PASS/PASS

There are several models that have reproducible regression, will check them tomorrow.

LFM2 remains the clearest reproducible regression greater than 2% on comparable work.
LFM2 pp4096 −2.14% All three pairs exceeded 2% slowdown
Qwen3.5-4B Q4_0, MTP prose decode −4.80% Reproduced in all four pairs, but output length and draft acceptance differ between builds
Qwen3.5-4B Q4_0, baseline code prefill −2.16% Borderline: three of four pairs exceeded 2%; one was −1.39%
Gemma VLM prefill decreases also repeated: E4B −4.18%, E2B OCR −6.50%, 26B-A4B −12.19%, and 31B −3.60%. However, internal prompt lengths differ between builds, so these are observed application throughput decreases with different amounts of work; they do not establish an isolated speed regression on equivalent work.
All other originally flagged measurements reviewed here did not reproduce a slowdown greater than 2%.

mmvdq dispatch moved to mmvq.cu, so ggml-cuda.cu no longer references it.

Assisted-by: Claude Opus
@liangliangchang

Copy link
Copy Markdown

Source comparison and regression causes

Investigation of latest 5fd292c71 versus master-sync cb3969e36, using the preserved HIP 7.15.26303 / gfx1151 binaries. All GPU experiments were issued manually, one at a time, on xconucstrhalo41 after saved idle checks. Original repositories and build outputs are unchanged.

LFM2 pp4096: confirmed MoE reduction fusion regression

Introducing commit: 3466812d1f06728effe7c0f3c0671117f461672d, cuda: fuse MoE weighted expert reduction (ggml-org#25952).

The new matcher in ggml/src/ggml-cuda/ggml-cuda.cu enables a combined expert-weighting/reduction kernel on HIP too. For this LFM2 configuration, it is slower than the existing multiply plus fused-add implementation. Fewer kernels and less intermediate traffic did not translate into lower runtime on gfx1151.

An isolated diagnostic library disables only this matcher, preserving other optimizations and link inputs:

Build / intervention Invocation 1 (tok/s) Invocation 2 (tok/s)
Master-sync unchanged 4763.89 4743.10
Master-sync, only new MoE reduction fusion disabled 4878.12 4872.56
Latest unchanged, fresh control 4858.44 -

The sequence was master / diagnostic / diagnostic / master / latest; each invocation used 20 timed repetitions and the original pp4096 parameters. Disabling the fusion recovers 2.40% and 2.73% in the paired comparisons. Against the fresh latest control, master averages -2.16% and the diagnostic +0.35%. This isolates the measured gap to the new fusion for the tested workload.

The initial kernel profiles support this result: the dominant Q4_K tile widths and call counts stayed the same; the new reduction consumes 132.00 ms over 680 calls, versus approximately 78.65 ms for the old multiply/reduction combination. Those aggregates include warmup and profiling overhead, so they are explanatory evidence rather than timed-region regression measurements. Exact low-level reasons for the kernel's poor performance still require hardware counters; the functional cause is established by the selective ablation.

A production fix should gate or tune this fusion for affected HIP/prefill shapes, then validate correctness and other MoE workloads. Disabling all fusions would be unnecessarily broad. The commit message mentions GGML_CUDA_MOE_WEIGHTED_REDUCTION=0, but that switch is absent from the tested implementation.

Evidence: ablation results, diagnostic patch, introducing kernel change, and lfm2-*-profile/ traces. Diagnostic compiler/linker response files reuse the original flags and all unchanged object files.

Qwen3.5 Q4_0: normalization changes performance and generated work

Commit 5fdfa6282936576d2f352d4b97f397a109f207a6, models: fix GDN normalization from max to rsqrt (ggml-org#28068), corrects recurrent Q/K normalization:

  • Latest: x / max(sqrt(sum(x*x)), eps).
  • Master-sync: x / sqrt(sum(x*x) + eps).

Master-sync implements the corrected formula as RMS_NORM followed by SCALE, adding two graph operations per recurrent layer. HIP does not fuse this RMS_NORM + SCALE pair. The arithmetic change can change logits, generated text, and speculative acceptance.

Restoring only the old normalization in an isolated master-sync libllama changes MTP prose from 83.20 to 87.07 tok/s (+4.65%), acceptance from 43.55% to 45.29%, and output length from 142 to 143. It does not restore latest's 132-token response or 48.75% acceptance. Thus normalization has an experimentally demonstrated effect on this application metric; it is not the only cross-build behavior difference, and the result is not a fixed-output speed measurement.

The same intervention makes MTP code slower (125.30 to 115.76 tok/s), with acceptance dropping from 82.46% to 71.96%. The effect depends on prompt and generated content. Reverting the correctness fix would be the wrong general remedy. A performance improvement should preserve the corrected formula, for example by fusing its normalization and scale, and evaluate MTP on controlled output/acceptance as well as real prompts.

For the borderline baseline code-prefill result, this intervention improves 529.78 to 533.19 tok/s (+0.64%). That does not establish the cause of the earlier -2.16% magnitude. The 32-token prompt is short, and the earlier four pairs did not all exceed 2%. Treat its exact attribution as unresolved.

Evidence: normalization patch, metric comparison, and the invocation directories with preserved server logs and outputs. Each invocation uses five repetitions per prompt and the separate n_max=1 identity check.

Gemma VLM: changed image budget and attention semantics

Commit 163a40796f0ebaae246325f8d2e15028b413fa9d, model, mtmd: fix gemma4 vision handling (ggml-org#28335), changes all affected Gemma4 vision models:

  • Default image-token budget changes from 40-280 to 70-1120.
  • E2B/E4B vision input becomes causal.
  • Other Gemma4 variants use bidirectional attention only in sliding-window layers; dense attention stays causal.

Commit 56db501e73cfb10c8fcce61be708f5c3ee749271 additionally changes image resizing from bilinear to Pillow-compatible bicubic. These changes affect the model's input/attention and can change generated responses.

The old repeat findings (E4B -4.18%, E2B OCR -6.50%, 26B-A4B -12.19%, 31B -3.60%) therefore compare different internal work. Increasing the image token count increases vision-encoder and language-model prefill work; throughput in tokens/s need not remain constant because those costs do not scale uniformly with the reported prompt-token count. This does not rule out additional kernel performance differences, especially for MoE variants.

The repeated +105 prompt-token change in the synthetic cases is consistent with 252 versus 357 image tokens. With a 48-pixel merged-patch stride, the shared 1024x800 image aligns/downsizes to 864x672 under the old cap (18x14=252 tokens), versus 1008x816 with the new cap (21x17=357 tokens). A runtime budget intervention checks the causal link without changing the model code.

Evidence: introducing commit, original per-model reports, and the image-budget check below.

Gemma 31B stall

The single interrupted request has no GPU fault report or captured device stack identifying a cause, and the next two master-sync attempts passed. Code comparison alone cannot attribute that stall to a particular commit. It remains separate from the reproducible throughput findings.

See analysis notes, reproduction instructions, and diagnostic library hashes.

Fresh Qwen controls on halo41

Prose MTP build Decode tok/s Gap vs fresh latest Output tokens Draft acceptance
Latest 87.8484 - 132 48.7469%
Master-sync 83.2029 -5.2881% 142 43.5484%
Master-sync with only old normalization 87.0713 -0.8845% 143 45.2935%

The normalization intervention removes most of the throughput gap, while preserving master-sync's remaining code. Exact cross-build output equality is not restored. All six metric rows and associated identity checks pass in each invocation.

The fresh baseline-code prefill comparison is latest 530.9617 versus master 529.7838 tok/s, only -0.2218%. The earlier borderline -2.16% on halo05 is not a consistent >2% result across these checks. Source attribution of that small prefill difference is unresolved. See three-way comparison.

Qwen localization cross-check

A further diagnostic restores the entire latest qwen35.cpp while retaining master-sync's other code. It produces the same 143-token prose response and 45.29% acceptance as the normalization-only diagnostic, at 87.09 tok/s. The remaining Qwen model-file changes, including QKV construction/order, therefore do not explain the residual output difference in this case. That difference lies outside this model file and remains unattributed. All six rows and identity checks pass. See qwen-old-graph/.

@liangliangchang

Copy link
Copy Markdown

Source comparison and regression causes

Investigation of latest 5fd292c71 versus master-sync cb3969e36, using the preserved HIP 7.15.26303 / gfx1151 binaries. All GPU experiments were issued manually, one at a time, on xconucstrhalo41 after saved idle checks. Original repositories and build outputs are unchanged.

LFM2 pp4096: confirmed MoE reduction fusion regression

Introducing commit: 3466812d1f06728effe7c0f3c0671117f461672d, cuda: fuse MoE weighted expert reduction (ggml-org#25952).

The new matcher in ggml/src/ggml-cuda/ggml-cuda.cu enables a combined expert-weighting/reduction kernel on HIP too. For this LFM2 configuration, it is slower than the existing multiply plus fused-add implementation. Fewer kernels and less intermediate traffic did not translate into lower runtime on gfx1151.

An isolated diagnostic library disables only this matcher, preserving other optimizations and link inputs:

Build / intervention Invocation 1 (tok/s) Invocation 2 (tok/s)
Master-sync unchanged 4763.89 4743.10
Master-sync, only new MoE reduction fusion disabled 4878.12 4872.56
Latest unchanged, fresh control 4858.44 -
The sequence was master / diagnostic / diagnostic / master / latest; each invocation used 20 timed repetitions and the original pp4096 parameters. Disabling the fusion recovers 2.40% and 2.73% in the paired comparisons. Against the fresh latest control, master averages -2.16% and the diagnostic +0.35%. This isolates the measured gap to the new fusion for the tested workload.

The initial kernel profiles support this result: the dominant Q4_K tile widths and call counts stayed the same; the new reduction consumes 132.00 ms over 680 calls, versus approximately 78.65 ms for the old multiply/reduction combination. Those aggregates include warmup and profiling overhead, so they are explanatory evidence rather than timed-region regression measurements. Exact low-level reasons for the kernel's poor performance still require hardware counters; the functional cause is established by the selective ablation.

A production fix should gate or tune this fusion for affected HIP/prefill shapes, then validate correctness and other MoE workloads. Disabling all fusions would be unnecessarily broad. The commit message mentions GGML_CUDA_MOE_WEIGHTED_REDUCTION=0, but that switch is absent from the tested implementation.

Evidence: ablation results, diagnostic patch, introducing kernel change, and lfm2-*-profile/ traces. Diagnostic compiler/linker response files reuse the original flags and all unchanged object files.

Qwen3.5 Q4_0: normalization changes performance and generated work

Commit 5fdfa6282936576d2f352d4b97f397a109f207a6, models: fix GDN normalization from max to rsqrt (ggml-org#28068), corrects recurrent Q/K normalization:

  • Latest: x / max(sqrt(sum(x*x)), eps).
  • Master-sync: x / sqrt(sum(x*x) + eps).

Master-sync implements the corrected formula as RMS_NORM followed by SCALE, adding two graph operations per recurrent layer. HIP does not fuse this RMS_NORM + SCALE pair. The arithmetic change can change logits, generated text, and speculative acceptance.

Restoring only the old normalization in an isolated master-sync libllama changes MTP prose from 83.20 to 87.07 tok/s (+4.65%), acceptance from 43.55% to 45.29%, and output length from 142 to 143. It does not restore latest's 132-token response or 48.75% acceptance. Thus normalization has an experimentally demonstrated effect on this application metric; it is not the only cross-build behavior difference, and the result is not a fixed-output speed measurement.

The same intervention makes MTP code slower (125.30 to 115.76 tok/s), with acceptance dropping from 82.46% to 71.96%. The effect depends on prompt and generated content. Reverting the correctness fix would be the wrong general remedy. A performance improvement should preserve the corrected formula, for example by fusing its normalization and scale, and evaluate MTP on controlled output/acceptance as well as real prompts.

For the borderline baseline code-prefill result, this intervention improves 529.78 to 533.19 tok/s (+0.64%). That does not establish the cause of the earlier -2.16% magnitude. The 32-token prompt is short, and the earlier four pairs did not all exceed 2%. Treat its exact attribution as unresolved.

Evidence: normalization patch, metric comparison, and the invocation directories with preserved server logs and outputs. Each invocation uses five repetitions per prompt and the separate n_max=1 identity check.

Gemma VLM: changed image budget and attention semantics

Commit 163a40796f0ebaae246325f8d2e15028b413fa9d, model, mtmd: fix gemma4 vision handling (ggml-org#28335), changes all affected Gemma4 vision models:

  • Default image-token budget changes from 40-280 to 70-1120.
  • E2B/E4B vision input becomes causal.
  • Other Gemma4 variants use bidirectional attention only in sliding-window layers; dense attention stays causal.

Commit 56db501e73cfb10c8fcce61be708f5c3ee749271 additionally changes image resizing from bilinear to Pillow-compatible bicubic. These changes affect the model's input/attention and can change generated responses.

The old repeat findings (E4B -4.18%, E2B OCR -6.50%, 26B-A4B -12.19%, 31B -3.60%) therefore compare different internal work. Increasing the image token count increases vision-encoder and language-model prefill work; throughput in tokens/s need not remain constant because those costs do not scale uniformly with the reported prompt-token count. This does not rule out additional kernel performance differences, especially for MoE variants.

The repeated +105 prompt-token change in the synthetic cases is consistent with 252 versus 357 image tokens. With a 48-pixel merged-patch stride, the shared 1024x800 image aligns/downsizes to 864x672 under the old cap (18x14=252 tokens), versus 1008x816 with the new cap (21x17=357 tokens). A runtime budget intervention checks the causal link without changing the model code.

Evidence: introducing commit, original per-model reports, and the image-budget check below.

Gemma 31B stall

The single interrupted request has no GPU fault report or captured device stack identifying a cause, and the next two master-sync attempts passed. Code comparison alone cannot attribute that stall to a particular commit. It remains separate from the reproducible throughput findings.

See analysis notes, reproduction instructions, and diagnostic library hashes.

Fresh Qwen controls on halo41

Prose MTP build Decode tok/s Gap vs fresh latest Output tokens Draft acceptance
Latest 87.8484 - 132 48.7469%
Master-sync 83.2029 -5.2881% 142 43.5484%
Master-sync with only old normalization 87.0713 -0.8845% 143 45.2935%
The normalization intervention removes most of the throughput gap, while preserving master-sync's remaining code. Exact cross-build output equality is not restored. All six metric rows and associated identity checks pass in each invocation.

The fresh baseline-code prefill comparison is latest 530.9617 versus master 529.7838 tok/s, only -0.2218%. The earlier borderline -2.16% on halo05 is not a consistent >2% result across these checks. Source attribution of that small prefill difference is unresolved. See three-way comparison.

Qwen localization cross-check

A further diagnostic restores the entire latest qwen35.cpp while retaining master-sync's other code. It produces the same 143-token prose response and 45.29% acceptance as the normalization-only diagnostic, at 87.09 tok/s. The remaining Qwen model-file changes, including QKV construction/order, therefore do not explain the residual output difference in this case. That difference lies outside this model file and remains unattributed. All six rows and identity checks pass. See qwen-old-graph/.

Do we want to merge this PR first and create separated tickets to invest these issues?

@jimw567
jimw567 merged commit 0363d99 into gfx11 Sep 22, 2026
14 of 21 checks passed
@jimw567
jimw567 deleted the jimwu.gfx11-sync-master-20260920 branch September 22, 2026 19:14
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.