Test record: I qualified Muse Glimmer 30B on a 128GB GMKtec EVO-X3 with a Ryzen AI MAX+ 395 / Radeon 8060S (
gfx1151). I built the samellama.cppb10362 commit for ROCm 7.14 and Vulkan. ROCm processed a 2,048-token prompt at 434.59 tok/s and reached 42.38 tok/s on a favourable DFlash workload. Vulkan was much slower at prompt processing, but it was the only backend to pass the fresh 8K passkey test. I kept Vulkan without speculative decoding for the correctness-first text service and retained ROCm plus DFlash as the next short-context candidate to qualify.
For the first half of this test, ROCm looked like the easy choice. It was roughly twice as fast as Vulkan at prompt processing on the dynamic quant, and DFlash could push a favourable generation task beyond 40 tokens/s.
Then I moved the passkey beyond roughly 4,000 tokens. ROCm stopped returning the right value; Vulkan returned it exactly at 8,000 tokens. That one failure changed the deployment decision.
Muse Glimmer is a dense 29.6B-parameter multimodal model with tool calling, a 131,072-token context window and a separate DFlash draft model. Both published quants and the vision projector fit comfortably in the EVO-X3’s 128GB unified memory. Fit was not the problem. The test was about how much speed I could use without narrowing the model’s working context by accident.
The numbers that shaped the decision
| Requirement | Retained configuration | Result |
|---|---|---|
| Highest prompt-processing rate | ROCm, dynamic quant, no HIP graphs | 434.59 tok/s at pp2048 |
| Highest target-only baseline decode | Vulkan, 17GB quant | 12.96 tok/s at tg128 |
| Highest favourable speculative result | ROCm, 17GB quant, DFlash n-max=15 |
42.38 tok/s mean |
| More representative ROCm DFlash set | ROCm, 17GB quant, three 512-token tasks | 23.46 tok/s mean |
| Qualified longer-context route | Vulkan, dynamic quant, no DFlash | exact 8K passkey returned |
| Vision and tool use | ROCm, dynamic, DFlash 15, projector / Jinja tool parser | passed in that feature check; not retested on Vulkan |
The distinction between “highest favourable result” and “representative set” is deliberate. Speculative decoding accelerates accepted draft tokens; its benefit changes with the prompt and output. A single arithmetic loop is useful for tuning the ceiling, but it is not an honest forecast for coding, explanation and operational writing.
The exact build I tested
The test host was the same evox3 workstation used throughout this series:
| Component | Tested state |
|---|---|
| Host | GMKtec EVO-X3, Ryzen AI MAX+ 395, Radeon 8060S (gfx1151), 128GB installed / 124GiB visible |
| Operating system | Ubuntu 24.04, kernel 6.17.0-40 |
| ROCm | 7.14.0 |
llama.cpp |
b10362, commit 4801e3c567d5131dd41b387df5f2d4b1370d92be |
| Model revision | a0532f7263ee67f1e0a5f5c5fdcd50dd62fc9aa4 |
| Attention | flash attention enabled |
| Prompt batch / micro-batch | 8,192 / 2,048 |
| Parallel slots | one |
I tested both model quants published in the official repository rather than treating the filename as provenance:
| Artefact | Size | SHA-256 | Model-card quality note |
|---|---|---|---|
muse-glimmer-30B-kquant-17gb.gguf |
16.76GB | 7e9b74b7c8875e9e265695df9613bf6290f2392e479ce740495a129019c488d8 |
about 1.0% degradation |
muse-glimmer-30B-kquant-dynamic.gguf |
19.65GB | 513109c8319115f69eb09fb7b118c97c8167d15bc014fd7670d2e30489bf106c |
about 0.2% degradation |
mmproj-kquant.gguf |
1.40GB | f48b452316f9b213758e8659444029b961a24a07f99a1abb2a9f88b06f7c00c6 |
vision projector |
dflash-kquant.gguf |
1.63GB | 27d9a805fa29b943cfb6ad4843367cd4eaaaf06bd452d8cc3e00a2cd18a677bc |
DFlash drafter |
The dynamic quant is the quality-first choice because this machine has ample capacity. The 17GB quant remains useful for a speed profile: it decoded 17% faster than dynamic under the ROCm target-only baseline and leaves more memory for other services.
Muse Glimmer support landed through llama.cpp PR #26841. The model card requires b10353 or newer; using b10362 keeps the model architecture, chat parser, vision path and DFlash integration on one exact source revision for both backends.
Building both backends
The ROCm build targets the APU explicitly and disables HIP graphs, because the graph-enabled control was fractionally slower in every retained benchmark:
cmake -S . -B build-rocm \
-DGGML_HIP=ON \
-DGGML_HIP_GRAPHS=OFF \
-DAMDGPU_TARGETS=gfx1151 \
-DCMAKE_BUILD_TYPE=Release
cmake --build build-rocm --config Release -j
The Vulkan build uses the same source tree and release mode:
cmake -S . -B build-vulkan \
-DGGML_VULKAN=ON \
-DCMAKE_BUILD_TYPE=Release
cmake --build build-vulkan --config Release -j
The common benchmark shape was pp2048 and tg128, repeated three times with all layers on the GPU, flash attention enabled, an 8,192-token batch and 2,048-token micro-batch. Model loading was excluded from the timed result.
ROCm won prefill; Vulkan narrowly won baseline decode
| Quant | Backend | HIP graphs | pp2048 | tg128 |
|---|---|---|---|---|
| 17GB | ROCm 7.14 | off | 427.94 ± 2.64 | 12.428 ± 0.003 |
| 17GB | ROCm 7.14 | on | 424.57 | 12.416 |
| 17GB | Vulkan | n/a | 240.51 | 12.961 |
| dynamic | ROCm 7.14 | off | 434.59 ± 1.79 | 10.594 ± 0.001 |
| dynamic | ROCm 7.14 | on | 433.54 | 10.577 |
| dynamic | Vulkan | n/a | 216.12 | 10.779 |
ROCm was 78% faster than Vulkan in 17GB-quant prompt processing and just over twice as fast with the dynamic quant. Vulkan reversed the target-only generation result, but only narrowly: 4.3% on the 17GB quant and 1.8% on dynamic.
HIP graphs did not create a useful ROCm win. Disabling them improved prompt processing by 0.8% on the 17GB quant and 0.2% on dynamic; generation changed by around one tenth of one percent. I retained the simpler graph-disabled build rather than adding a moving part for a negative result.
These are microbenchmarks, not complete chat-request rates. They isolate prompt processing and autoregressive generation so the backend differences are visible; the later correctness and feature tests decide whether a configuration is deployable.
DFlash made ROCm much faster on the right output
The official DFlash model is not plug-and-play with the current GGUF metadata. Its muse-glimmer.attention.sliding_window_pattern is encoded as an array of booleans, while the current DFlash binding expects the scalar pattern. That mismatch is tracked in llama.cpp issue #26894 and can terminate model loading with a vector::_M_range_check exception.
The non-destructive workaround is an explicit metadata override:
--override-kv muse-glimmer.attention.sliding_window_pattern=int:4
That scalar represents the published local/local/local/global attention cycle. DFlash also needs an explicit speculation type in this build:
-md dflash-kquant.gguf
--spec-type draft-dflash
--spec-draft-n-max 15
-ngld 99
The last tuning control was decisive. The default maximum of three draft tokens left most of the opportunity unused. Seven was slower on the coding control, while 15 matched the DFlash block shape and won clearly.
| ROCm 17GB workload | DFlash maximum | Generation rate | Draft counters where retained |
|---|---|---|---|
| target-only tg128 baseline | off | 12.428 tok/s | n/a |
| favourable integer set, three runs | 3 | 19.84 tok/s mean | not retained |
| favourable integer set, three runs | 15 | 42.38 tok/s mean | not retained |
| 512-token coding task | 15 | 34.85 tok/s | 411 accepted / 1,480 drafted |
| 512-token B-tree explanation | 15 | 17.38 tok/s | 309 / 2,996 |
| 512-token PostgreSQL checklist | 15 | 18.14 tok/s | 318 / 2,823 |
The three representative 512-token tasks averaged 23.46 tok/s, 1.89 times the target-only baseline. The favourable integer set averaged 42.38 tok/s, 3.41 times baseline. Both are true; only the first is a reasonable planning number for mixed work.
Dynamic plus DFlash showed the same shape. A favourable integer run reached 43.87 tok/s, coding reached 31.03 and the B-tree explanation reached 17.68. With seed 123, the speculative and target-only paths also returned identical final content for an exact addition check: 12345 + 67890 = 80,235.
This is the strongest ROCm performance result in the study. I still did not make it the default, because it only helps inside the context range that returns the right answer.
The context test changed the deployment decision
I inserted a unique passkey at the start of progressively longer prompts and asked for that exact value at the end. Each important boundary was repeated from a fresh server so the result did not depend on a reused slot cache.
| Backend and mode | Approximate prompt tokens | Result |
|---|---|---|
| ROCm, dynamic, no DFlash | 1,086 | pass |
| ROCm, dynamic, no DFlash | 2,586 | pass |
| ROCm, dynamic, no DFlash | 4,086 | pass |
| ROCm, dynamic, no DFlash | 6,037 | repeated output followed by parser HTTP 500 |
| ROCm, dynamic, no DFlash | 8,086 | failed to retrieve passkey |
| ROCm, dynamic, no DFlash | 32,089 | failed to retrieve passkey |
| Vulkan, dynamic, no DFlash | 8,000 | exact passkey returned |
| Vulkan, dynamic, DFlash 15 | 8,000 | exact passkey returned |
The ROCm slot really had a 131,072-token context and processed the full prompt; this was not a server-side truncation. Turning flash attention off did not repair the 8K result. The override is also equivalent to the model’s repeated local/local/local/global metadata, so the evidence does not point to a changed attention pattern.
I am describing this narrowly as a current b10362 / ROCm 7.14 / gfx1151 long-context correctness regression. The test does not prove a universal ROCm fault or identify the kernel responsible. It does establish a deployment boundary on this exact machine: I will not expose the ROCm route as a long-context endpoint until a newer build passes the same retrieval gate.
Vulkan returned HALO-MUSE-VULKAN-8000 exactly without speculation. At that depth it processed the prompt at 198.59 tok/s and generated at 10.71 tok/s. DFlash also returned its passkey, but generation fell to 6.96 tok/s because acceptance was poor. On a favourable short integer task, Vulkan DFlash improved dynamic generation by only about 15%. Those controls make the Vulkan choice straightforward: run the target model alone.
I tested 8K retrieval, not the model’s full advertised 131K window. The server can be configured for 131,072 tokens, but that is capacity rather than a published correctness claim. I would qualify 16K, 32K, 64K and 128K before promising the full window to users.
Vision and tool calling
The feature checks used the dynamic quant on ROCm with DFlash 15. They did not use the Vulkan/no-DFlash profile that passed the 8K retrieval test.
With mmproj-kquant.gguf, Muse Glimmer correctly identified a supplied GitHub icon. Loading the first image increased GPU-visible GTT by about 346MiB. I then compared two 10,016-token prefill controls before and after the image: 390.52 and 400.91 tok/s. That does not reproduce the first-image prefill collapse reported for CUDA in llama.cpp issue #26873, although the extra retained memory was visible.
The Jinja tool path also returned a valid OpenAI-compatible tool_calls response for a weather lookup, with the expected get_weather function and {"city":"Paris"} arguments. Reasoning appeared separately from final content, and the ordinary arithmetic smoke test returned 391 for 17 × 23.
Those results establish that the features worked on the tested ROCm route. They do not establish multimodal or tool-call support on Vulkan merely because both backends came from the same source revision. I would repeat the image and tool checks on the exact Vulkan profile before exposing either feature there.
What I would run next
Correctness-first text service
The retained default is the dynamic quant on Vulkan, without DFlash. This text-only command exposes loopback, keeps one slot and caps the qualified retrieval endpoint at 8K:
./build-vulkan/bin/llama-server \
-m muse-glimmer-30B-kquant-dynamic.gguf \
-ngl 99 -fa on \
-c 8192 -np 1 \
-b 8192 -ub 2048 \
--load-mode none --no-host --fit off \
--jinja --temp 1.0 --top-p 0.95 --top-k 64 \
--host 127.0.0.1 --port 18090
The model supports a 131,072-token context, so the context can be raised after
each longer retrieval and multi-turn compaction gate passes. Keeping -np 1
avoids silently dividing the configured context across slots. A public or
LAN-facing service also needs authentication and a deliberate network policy;
loopback is the safe baseline. The projector is deliberately absent here:
adding images or publishing tool calls requires a fresh check on this exact
Vulkan/no-DFlash profile.
Fast short-context candidate
The 17GB ROCm quant plus DFlash produced the useful speed result, but the retained passkey checks used the dynamic target without DFlash. I would use the following command as a qualification canary, not yet as a service profile:
./build-rocm/bin/llama-server \
-m muse-glimmer-30B-kquant-17gb.gguf \
-md dflash-kquant.gguf \
--spec-type draft-dflash \
--spec-draft-n-max 15 \
--override-kv muse-glimmer.attention.sliding_window_pattern=int:4 \
-ngl 99 -ngld 99 -fa on \
-c 4096 -np 1 \
-b 8192 -ub 2048 \
--load-mode none --no-host --fit off \
--jinja --temp 1.0 --top-p 0.95 --top-k 64 \
--host 127.0.0.1 --port 18091
The 4K cap is a conservative test ceiling, not a validated safety boundary for this configuration. The 4,086-token pass in the dataset belongs to the dynamic quant without DFlash. Before serving the 17GB/DFlash combination, I would run a fresh 4K retrieval gate on that exact command and only then repeat the 8K and longer tests.
The profile I kept and the candidate I did not promote
ROCm is the quicker option in the shallow, well-tested lane. Its dynamic-quant prefill was twice as fast as Vulkan, and DFlash lifted the mixed 512-token set from a 12.43 tok/s target-only baseline to 23.46 tok/s. On favourable output it exceeded 40 tok/s.
I kept Vulkan as the text default because it returned the exact 8K passkey where the current ROCm path did not. It is slower at prompt processing and only slightly faster at target-only decode. DFlash adds too little on Vulkan—and can make generation substantially slower when acceptance is poor—so the correctness-first text route uses the dynamic target model by itself.
That leaves one qualified text profile and one benchmark candidate:
- Vulkan / dynamic / no DFlash for text retrieval up to the currently qualified 8K context. Multimodal and tool use remain unqualified on this exact profile.
- ROCm / 17GB / DFlash 15 as the next short-context candidate. It is not a deployment recommendation until the exact combination passes the 4K retrieval gate.
The complete retained measurements are available as CSV. The production DeepSeek service was unloaded for the isolated tests and restored afterwards; the benchmark server was not left competing for unified memory.
Benchmark date: 11 August 2026. All figures were measured locally on the same EVO-X3. No backend failure is represented as zero throughput, speculative results are labelled separately from target-only generation, and the 8K Vulkan pass is not presented as a 131K qualification.