Repository navigation
ggml-hrx: keep ADD_ID / SWIGLU_OAI with their MUL_MAT_ID (placement guard, engine #286) - #73
Merged
bong-water-water-bong merged 1 commit intoOct 2, 2026
Conversation
…uard) When gpt-oss's expert MUL_MAT_IDs run on the CPU while ADD_ID / SWIGLU_OAI run on HRX between those CPU splits, the result is wrong (KLD vs CPU 1.65, garbage text). The root cause is still open (engine ggml-org#286); this is a guard. moe-placement-guard.cpp (ours) claims ADD_ID / SWIGLU_OAI only when the MUL_MAT_ID they follow (directly or through ADD_ID) will run on HRX: HRX executes the op, and the expert weights sit in a buffer HRX can read. The second check matters for decode: when HRX declines the expert MUL_MAT_ID at load time, llama.cpp puts the experts in CPU_REPACK, and every MUL_MAT_ID then stays on the CPU, even the decode shapes that mul_mat_id.decode_f32_wave64 could run. One-line hook in device_supports_op. tests/test-hrx-moe-split.cpp: gpt-oss MoE block with MXFP4 experts in CPU_REPACK (and in a host buffer), biases and routing in HRX memory; checks the result against the CPU and the placement. Without the guard the CPU_REPACK pass gives nmse 0.058 at 1/3/12/40 tokens (the ggml-org#286 failure, reproduced in isolation); with it 1.5e-15. gpt-oss-20b MXFP4, KLD vs CPU (8 x 512): GGML_HRX_DISABLE_DISPATCH=mul_mat_id.f32_f32_wmma: 1.650 -> 0.031, greedy text correct default: 0.0294 before and after, same greedy text, pp512 / tg128 unchanged Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
|
Review (PR-Agent duty): approve; it merges first, then #72, then #68.
|
bong-water-water-bong
merged commit Oct 2, 2026
35027f7
into
1bit/hrx-vulkan-patched
10 of 24 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A placement guard for 1bit-MONSTER/engine#286. It is not a fix: the root cause stays open in 1bit-MONSTER/engine#286.
Problem
In gpt-oss, when the expert MUL_MAT_IDs run on the CPU and ADD_ID / SWIGLU_OAI (#67) run on HRX between those CPU splits, the output is wrong: KLD vs CPU 1.65 and garbage text. Each op is correct on its own.
Change
dispatch_registration/common/moe-placement-guard.{h,cpp}(our code, Apache-2.0 notice). HRX claims an ADD_ID or SWIGLU_OAI only when the MUL_MAT_ID it follows (directly or through ADD_ID) will also run on HRX. That needs two things:ggml_backend_dev_supports_buft).ggml-hrx.cpp: one include, and a one-line hook at the top ofdevice_supports_op.The buffer check is needed for decode. When HRX declines the expert MUL_MAT_ID at load time, llama.cpp puts the experts in CPU_REPACK. Every MUL_MAT_ID then stays on the CPU, including decode shapes that
mul_mat_id.decode_f32_wave64could run. With only an "HRX supports the op" check, prompt KLD was fine but generated text was still garbage, because decode-shaped MUL_MAT_IDs pass that check while staying on the CPU.tests/test-hrx-moe-split.cpp: the gpt-oss MoE block with MXFP4 experts in CPU_REPACK (the real layout) and in a host buffer, with biases and routing in HRX memory. It checks the result against a CPU-only run and checks placement. It also reproduces engine Understanding the basics ggml-org/llama.cpp#286 in isolation:Evidence (strixhalo, this exact tree ba0be9a, base 388290b)
gpt-oss-20b MXFP4,
llama-perplexity -c 512 -b 512 --chunks 8 -fa on, KLD vs CPU:GGML_HRX_DISABLE_DISPATCH=mul_mat_id.f32_f32_wmmaGreedy (
--temp 0 -n 48, three prompts: sky, primary colors, haiku):llama-bench, default, same box conditions:
The box was shared and in balanced power mode, so absolute numbers are below earlier runs. Before and after were measured the same way.
No regression: Qwen3.8-27B UD-Q4_K_XL and ZAYA1-8B Q4_K_M produce byte-identical greedy text on 388290b and on this PR (same three prompts).
Known limit, unchanged by this PR
gpt-oss with
-ub 4096fails loudly (graph_compute -1); it does not give wrong output.1bit serve(engine app/serve.cpp) passes no-ubfor chat models, so llama-server's default ubatch of 512 applies and users don't hit this. Only these serve paths set a large ubatch:--mmprojsets 4096 (vision models; gpt-oss has none);--embedding/--rerankset it to the context size.The one tuned recipe (
-ub 1024) is ROCm-only.🤖 Generated with Claude Code