Skip to content

HRX: follow AMD's live ggml-hrx, pinned to AMD's tested pair and kept current - #11

Merged
bong-water-water-bong merged 2 commits into
mainfrom
hrx-amd-live
Sep 23, 2026
Merged

bong-water-water-bong merged 2 commits into
mainfrom
hrx-amd-live

Conversation

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator

Moves the engine's llama.cpp to AMD's maintained HRX line, pinned to the pair AMD tests, with a daily job that keeps it current.

Why

The engine pinned bong-water-water-bong/llama.cpp@3b33c8a. That's AMD's hrx-v2 line (ggml-hrx2, device HRX20) plus our 33 commits. AMD abandoned that line in June, and it's 2455 commits behind ggml-org. AMD's live line is AMD-Ecosystem/llama.cpp hrx-graph-develop-v2, which has a single ggml-hrx backend (device HRX0), was updated yesterday, and is 915 behind. It's pinned, together with ROCm/hrx-system, by AMD's integration repo ROCm/ggml-staging-automation.

What

  • The llama.cpp source: third_party/llama.cpp now points at the new org fork 1bit-MONSTER/llama.cpp (fork of ggml-org/llama.cpp), branch 1bit/hrx-vulkan = AMD's f1a0aca.
  • The HRX runtime: third_party/hrx-system = fab1624, AMD's pin. The separate third_party/hrx (ROCm/hrx) submodule and patches/hrx/ are removed.
  • The build (cmake/hrx.cmake): a single external project. llama.cpp's ggml-hrx builds hrx-system itself (HRX_SOURCE_DIR) with TheRock's amdclang.
  • The HSA runtime: the distro's libhsa-runtime64 rejects gfx1151's PM4_EMULATION probe, so HRX then registers no device. CMake now finds TheRock's copy, and 1bit lemonade passes it to llama-server as IREE_HAL_AMDGPU_LIBHSA_PATH (unless you've set it yourself).
  • The device name: HRX20 → HRX0 in the app defaults, tests/hrx_lemonade_e2e.sh and the docs.
  • Keeping current: a new daily workflow, .github/workflows/bump-hrx.yml. When AMD moves its pair, it syncs the fork (master to ggml-org, 1bit/hrx-vulkan to AMD's pin) and opens a PR moving both submodules. It needs a secret HRX_BUMP_TOKEN: a fine-grained token with Contents read/write on 1bit-MONSTER/llama.cpp and 1bit-MONSTER/engine, and Pull requests read/write on 1bit-MONSTER/engine.
  • The previous build is kept as 1bit/hrx2-archive in the fork (our Q4NX kernels, zaya, MoE grouping) for a later port to ggml-hrx.

Verified on Strix Halo

  • End to end: tests/hrx_lemonade_e2e.sh PASS. Qwen3-0.6B Q4_0 answers "Paris" through both recipes, served by this build's llama-server on Vulkan0 and HRX0.
  • Speed: llama-bench, Qwen3-0.6B, pp512 / tg128:
previous build this PR
Vulkan0, Q4_K_M 10627 / 306 13905 / 338
HRX, Q4_K_M 1046 / 68 (HRX20) 21702 / 303 (HRX0)
HRX, UD-Q4_K_XL 837 / 83 18059 / 288

Lost until ported

Q4NX GGUFs on HRX: our Q4NX kernels lived in ggml-hrx2, which ggml-hrx doesn't have. GGUFs still route to Vulkan0.

🤖 Generated with Claude Code

bong-water-water-bong and others added 2 commits September 23, 2026 12:00
… current

third_party/llama.cpp moves to the org fork 1bit-MONSTER/llama.cpp (of ggml-org/llama.cpp),
branch 1bit/hrx-vulkan = AMD's hrx-graph-develop-v2 f1a0aca; third_party/hrx-system moves to
fab1624. That is the pair ROCm/ggml-staging-automation builds and tests. The previous build sat on
AMD's hrx-v2 line, abandoned in June and 2455 commits behind ggml-org; it is kept as
1bit/hrx2-archive in the fork, with our Q4NX kernels and zaya, for a later port to ggml-hrx.

- cmake/hrx.cmake: one external project. llama.cpp's ggml-hrx builds hrx-system itself
  (HRX_SOURCE_DIR) with TheRock's amdclang. The separate ROCm/hrx runtime, its three patches and
  the loom-link-only build are gone.
- The device is HRX0 (ggml-hrx), not HRX20 (ggml-hrx2): app defaults, the e2e test, docs.
- HRX dlopens the HSA runtime; the distro's rejects gfx1151's PM4-emulation probe and HRX then
  registers no device. CMake finds TheRock's libhsa-runtime64 and `1bit lemonade` passes it to
  llama-server as IREE_HAL_AMDGPU_LIBHSA_PATH (unless already set).
- .github/workflows/bump-hrx.yml: daily, when AMD moves its pair, syncs the fork and opens a PR
  moving both submodules (needs the HRX_BUMP_TOKEN secret).

Strix Halo, Qwen3-0.6B: tests/hrx_lemonade_e2e.sh PASS (Paris on Vulkan0 and on HRX0).
llama-bench pp512/tg128, previous -> now: Vulkan0 Q4_K_M 10627/306 -> 13905/338;
HRX Q4_K_M 1046/68 -> 21702/303.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bong-water-water-bong
bong-water-water-bong enabled auto-merge (squash) September 23, 2026 16:19
@bong-water-water-bong
bong-water-water-bong merged commit 5b38461 into main Sep 23, 2026
1 check passed
@bong-water-water-bong
bong-water-water-bong deleted the hrx-amd-live branch September 23, 2026 16:30
bong-water-water-bong added a commit that referenced this pull request Sep 26, 2026
…bit-MONSTER/llama.cpp #11) (#127)

The pin adds sliding-window attention and a second rope base for ZAYA1-74B-preview on top of
1e775cd (#119). ZAYA1-8B is unchanged: Q4_K_M perplexity 21.5731 on Vulkan before and after,
and test-llama-archs -a zaya passes. ZAYA1-74B-preview Q4_K_M passes serve_e2e through
1bit serve --device vulkan.

registry/architectures.json, regenerated: it records the new pin (it still named 5556bf2
after #119 moved the pin to 1e775cd without regenerating it).

Co-authored-by: bong-water-water-bong <bong-water-water-bong@1bit.gg>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
bong-water-water-bong pushed a commit that referenced this pull request Sep 26, 2026
…oints and three HRX fixes

Our llama.cpp #7 (HRX MoE router route-ids binding length), #9 (decode-split
flash-attention capacity bound), #11 (ZAYA sliding-window attention, ZAYA1-74B),
#12 (MoE router experts-per-wave launch geometry) and #14 (ZAYA legacy
checkpoints; --remote fetches chat_template.jinja).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bong-water-water-bong pushed a commit that referenced this pull request Oct 14, 2026
To run three probes back to back I wrote three scripts each shaped as 'while ps | grep <predecessor>; do sleep; done;
clean; launch the next one'. Three disc sessions then appeared at once, including two copies of 315lout4, and
315chain-run.log was empty - stage 1 never started - while stage 2 launched anyway, because the guard is 'wait WHILE
the predecessor is running', which is satisfied immediately when the predecessor does not exist at all. The guard
answers 'is it running now?' rather than 'did it ever run and finish?'. Two sessions then composed the regime
simultaneously, so neither arm's cell means what its label says and every arm in that window is unusable.

Why this is the same defect one layer up: it is defect #14 with the sign flipped. There, absence of output was read
as a clean result; here, absence of a process is read as completion. Both are a predicate on a proxy standing in for
the event of interest, and both silently proceed. The campaign now has four instances of this shape - #13, where an
EXTRA_ENV named a feature the build does not implement and absence of effect was read as absence of an effect; #14;
#16; and the pkill-on-name traps of #11/#12 where killing the wrapper was read as stopping the run.

Records the fix and what I did instead: the correct guard records evidence of the predecessor's completion via a
sentinel line written after its last arm, and additionally requires that it started, but chaining is not worth that
machinery here, so I abandoned it and ran the stages directly one at a time, verifying each launch by its own log
header before starting the next - slower, but it cannot silently skip a stage, which is the failure mode that cost
two composed regimes and about twenty minutes of box time this session is already over budget on. Cost: two
simultaneous compositions whose arms are discarded, the section-40 chain probe never ran and must be re-issued, and
one duplicate 315lout4 session, with no conclusions drawn from any arm in that window.
bong-water-water-bong pushed a commit that referenced this pull request Oct 20, 2026
…, G8 #12); --parallel on qwen35 family

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bong-water-water-bong added a commit that referenced this pull request Oct 20, 2026
…ily (#480)

* serve: the placement report covers every graph, not just the warmup

--placement-report passed GGML_HRX_REPORT=1, and the backend's 1 is the
first graph only, so serve printed a clean report for a model that leaves
nodes on the CPU in later graphs: the 20 Oct census found LFM2 --parallel 4
(20 nodes, 5 splits) and ZAYA1-8B (1-3 nodes) reading "all nodes on HRX".

Ask for every graph (2), keep the worst one instead of the last, and print
serve's line again whenever a graph is worse than every graph before it,
with the graph count. --strict-device reads the same worst graph. Without
--placement-report serve keeps 1, so no log volume is added by default.

tests/hrx_placement_test.cpp covers a clean warmup followed by a par4 graph
and a later clean graph.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* serve: --strict-device reads the report it needs

--strict-device only passed GGML_HRX_STRICT=1 to the backend. It did not pass GGML_HRX_REPORT=2 and it
did not add the -lv 4 that lets llama-server's log level carry the placement report through, so the graph
that would have been refused was never reported and serve fell through to "the backend printed no
placement line" while starting normally. Both flags are now treated the same way: GGML_HRX_REPORT=2 and
-lv 4 whenever either is set, so the refusal reads the same worst graph that --placement-report prints.

Found on device: `1bit serve ... --strict-device --parallel 4` (LFM2-1.2B) answered requests instead of
refusing, with that "no placement line" message in its log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* serve: --parallel on qwen35 / qwen35moe / qwen3next

These architectures were refused with "--parallel on --device hrx does not run <arch> yet (no
multi-sequence gated delta-net on HRX)". That was true when the HRX gated-delta-net matchers held
kMaximumSequences 3; they hold 8 now (llama.cpp 1bit/hrx-gdn-multi-sequence), and a four-sequence run keeps
every node on the device.

Measured on Qwen3.8-27B UD-Q4_K_XL, `--parallel 4`, four concurrent chats: 4 of 4 answered, placement "all
3655 nodes on HRX, 1 graph splits", zero error lines. The forced `-np 1` for these architectures when
--parallel is not given stays: llama-server's own default opens several slots, and that is a different
question from the explicit flag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Pin llama.cpp cefbfc07 (fork #117, G9) and gpu-kernels 421d7a4e (G7 #11, G8 #12); --parallel on qwen35 family

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* registry: regenerated at llama.cpp cefbfc07

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Pin llama.cpp dcf8c1ec (fork #118: narrower GDN claim) and gpu-kernels 449a809e (#13: v_f16 ABI + f16-V read fixes)

Fixes this PR's first hw-gate run (ops 618/649, Coder-30B HTTP 500).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* registry: regenerated at llama.cpp dcf8c1ec

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: bcloud <bcloud@localhost>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: bcloud <bcloud@1bit.local>
Co-authored-by: bong-water-water-bong <bong-water-water-bong@1bit.gg>
bong-water-water-bong added a commit that referenced this pull request Oct 21, 2026
…PU token (#484)

Three late-caught bugs of 2026-10-20 (gpu-kernels #11, #14) passed this gate.
It now covers the paths they broke:

- MODEL_TABLE takes a fifth column of llama-server arguments. Two new rows serve
  Qwen3-0.6B with -fa on -ctk q8_0 (V f16) and with -ctk q8_0 -ctv q8_0, with
  kat and the 7.1K-token needle. Their long prompts decode past 1,024 KV cells,
  where the add-on's split decode kernel fa_decode_q8_d128 takes over. Rows with
  server arguments skip kld (the bases are recorded per model file, f16 cache).
  Goldens recorded with the private kernels (gpu-kernels 449a809e, this pin):
  kat-qwen3-0.6b-kq8.json and kat-qwen3-0.6b-kvq8.json; both miss varied-720w
  ("25") exactly as the f16 golden does.
- The ops phase runs the add-on's ggml-hrx-fa-decode-bench on fa_decode_q8_d128
  with V f16 and V q8_0 (Hq/Hkv 16/8 and 32/8, n_kv 1031/2048/4103) against its
  double-precision reference; the build adds that target when the add-on is in.
  test-backend-ops has no FLASH_ATTN_EXT case with K and V of different types.
- The gate takes ~/GPU-TOKEN before its first GPU step: it waits up to
  HW_GATE_TOKEN_WAIT s (3600) logging the holder, writes "hw-gate [run N] pid P
  <time>", removes it on exit only if the content is still its own, and fails
  with exit 2 naming the holder on timeout. Two #481 gate runs died "server
  failed (rc 137)" while Hyperloom held the token. HW_GATE_TOKEN=none skips it.

Measured on strixhalo, performance mode:
- token: a fake holder with HW_GATE_TOKEN_WAIT=15 gives "gpu-token FAIL", exit 2;
  the recording run waited 960 s for Hyperloom's token, took it, released it
- fa-decode-q8: 6/6 PASS, NMSE 1.3e-13 to 2.3e-13, 5 repeats bit-identical

Co-authored-by: bong-water-water-bong <bong-water-water-bong@1bit.gg>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant