Skip to content

Zyphra BlackMamba on Vulkan - #118

Merged
bong-water-water-bong merged 1 commit into
mainfrom
blackmamba
Sep 26, 2026
Merged

bong-water-water-bong merged 1 commit into
mainfrom
blackmamba

Conversation

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator

Next step of Zyphra-family support. third_party/llama.cpp-vulkan → 1bit/vulkan-upstream f6261222 (the current ee6e4e0d + one commit of ours): model: BlackMamba (Zyphra/BlackMamba-1.5B, -2.8B), our code in src/models/blackmamba.cpp / conversion/blackmamba.py.

  • Mamba-1 layers alternate with a Switch MoE: router (with bias) → sigmoid → top-1 expert, scaled by its probability; experts are gated erf-GELU MLPs (ggml_geglu_erf_split; the config says swiglu but the activation is F.gelu).
  • RMSNorm per layer, a biased LayerNorm at the end, output tied to the embeddings.
  • No transformers implementation exists: the checkpoint is Megatron-style ({"model": state_dict}, config.json without architectures), so conversion/base.py routes on mamba_moe_layers (next to the existing ssm_cfg case) and the converter uses the built-in GPT-NeoX vocab.
Check (Strix Halo) Result
Teacher-forced top-1 vs Zyphra's own PyTorch code (FP32, CPU; Triton/CUDA ops swapped for plain PyTorch) 96/96
Greedy text and prompt tokens vs the reference identical
BlackMamba-1.5B F16 pp256 7180, tg64 250 tok/s
BlackMamba-1.5B Q8_0 pp256 10136, tg64 369 tok/s

Registry: BlackMambaForCausalLM → vulkan. It is a base model, so there is no registry_check row (that check asks a chat question).

🤖 Generated with Claude Code

third_party/llama.cpp-vulkan -> 1bit/vulkan-upstream f6261222 (ee6e4e0d + one
commit of ours): model: BlackMamba (Zyphra/BlackMamba-1.5B, -2.8B). Mamba-1
layers alternate with a Switch MoE (router with bias -> sigmoid -> top-1,
scaled by its probability; gated erf-GELU experts); RMSNorm per layer, a biased
LayerNorm at the end, output tied. The converter reads the Megatron-style
checkpoint and uses the built-in GPT-NeoX vocab.

BlackMamba-1.5B on Strix Halo: teacher-forced top-1 vs Zyphra's own PyTorch
code (FP32, CPU) 96/96, identical greedy text and prompt tokens; Q8_0 pp256
10136, tg64 369 tok/s. registry: BlackMambaForCausalLM -> vulkan.

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

context7 Bot commented Sep 26, 2026

Copy link
Copy Markdown

Docs7 for 1bit-monster/engine

Result Status Action
Deployment ➖ Not used —
Content review ➖ Did not run. This site has no agent runs available this month. Wait for the monthly reset or check your Docs7 plan. —

Commit b66994a

@github-actions

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing Performance Benchmark Details

The PR description includes performance benchmarks for BlackMamba on Vulkan, but the specific hardware and conditions under which these benchmarks were measured are not clearly stated. This makes it difficult to assess the validity and reproducibility of the claimed performance numbers (e.g., pp256 7180, tg64 250 tok/s).

BlackMamba (`f6261222`), `Zyphra/BlackMamba-1.5B`: teacher-forced top-1 vs Zyphra's own PyTorch code (FP32, CPU) **96/96** on three prompts, identical greedy text and prompt tokens; F16 pp256 7180 / tg64 250 tok/s, Q8_0 pp256 10136 / tg64 **369** tok/s. No HF `architectures` in its config.json: the converter routes on `mamba_moe_layers`.
Architecture Registry Update

The registry update adds BlackMambaForCausalLM to the Vulkan backend, but there is no corresponding entry in the architectures section for BlackMambaForCausalLM in the src/models/blackmamba.cpp file or any other model-specific code. This could lead to inconsistencies in how the model is handled across different parts of the system.

"BlackMambaForCausalLM": {
 "gguf": "blackmamba",
 "backends": [
  "vulkan"
 ]
},

@bong-water-water-bong
bong-water-water-bong merged commit 54aa1f7 into main Sep 26, 2026
5 checks passed
@bong-water-water-bong
bong-water-water-bong deleted the blackmamba branch September 26, 2026 07:14
bong-water-water-bong pushed a commit that referenced this pull request Oct 20, 2026
…s 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>
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant