Repository navigation
Muse Spark Open on CUDA, on two GB10s - #1295
ajensenwaud wants to merge 21 commits into
Conversation
|
Thank you for this. Bringing Muse Spark Open up on two GB10s with drafts and exact repeats is serious work. To fit how we land things, it needs splitting before we can run it:
After that, the family PR will just be the Muse Spark family, and we'll run it on two GB10s. - Synthema, Ash's AI Assistant. |
ashhart
left a comment
There was a problem hiding this comment.
Thanks @ajensenwaud. We rebased it onto current main (conflicts in chat.zig next to #1298's cut tool calls, build lists and the CUDA registry; all kept). Host suites and both Linux CUDA compiles pass, and lean adds no findings. Before a device run:
TF_MUSE_KV8and the e4m3 attention mode are still here (forward.zig,engine.zig,ops.zig,kept.zig,attention.cu, the recipe). The engine takes no lossy KV, even opt-in, so please remove them. The served exactness results were taken with int8 KV on, so they need rerunning with fp16.- Please drop the recipient-replies and sampler-race commits now that they're #1336 and #1337, and stack on #1336.
- Register the
muse_*kernels with the CUDA kernel contract. - Where the shared EXL3 operators cover a shape, please use them instead of the vendored copies (
muse_spark/exl3_linear.cu,exl3_experts*.cu,experts_grouped.cuh,decode.cuh). memory_reserve_gib = 3lowers the OS reserve from about 12.8 GB to 3 GB by default on a shared GB10. We'd rather this be the operator's explicit choice, with measured per-rank peak footprint showing the headroom, than a family default.- Please give the full revisions of the pack and the DFlash2 drafter, and add host tests for the lane backend's verify/keep/draft.
Then we'd run, on our GB10 pair: shared fatbins identical, the contract SUMMARY, drafted vs plain (greedy and seeded), concurrent vs solo, resumed vs fresh, graphed vs eager, and a GLM control.
85420d6 to
9168996
Compare
|
Thanks. All four done:
Output is byte-identical to before, so the parity numbers stand. The branch is just the family now, rebased on main. Happy to run anything on our two GB10s. |
9168996 to
9b33491
Compare
9b33491 to
e2231f5
Compare
|
Re-review of e2231f5 against main 3f408b6. Thank you, every point from the earlier review is addressed: the fp8/int8 KV is gone, the vendored EXL3 copies are replaced by the shared operators (registered as
|
|
Thanks Ash. All six from your review are addressed on the branch (
Host suites pass on the new head ( |
e2231f5 to
7db0640
Compare
|
The |
|
Please let me know what more is pending. |
951d536 to
92e7cae
Compare
|
Thanks @ajensenwaud. The Muse Spark family files are byte-for-byte what we re-reviewed on 26 Oct. Only the registration lists and #1336's two newer commits changed, so that review stands. Rebased on main Three small things, then our GB10 run:
On our pair we'll |
92e7cae to
aa9588a
Compare
|
Thanks @ashhart. All three are done. The branch is rebased on main
Every miss on the four short texts, with both sides' top 5, margins and gapsEnglish prose (4 misses of 157)
Chinese prose (1 misses of 138)
Code (2 misses of 214)
Agent turn (9 misses of 239)
|
|
Thanks @ajensenwaud. The licence paragraph, the per-miss tables and the concurrent-alone runs answer our three asks, and the family's code is unchanged since 26 Oct apart from the recipe. We merged aa9588a onto main a1e6d34 (clean). fmt and lean are clean, and the server changes are byte-for-byte #1336's, which pass Three things before our GB10 run:
Then on our pair, with the 1.8 bpw pack and a 3 GiB reserve on both ranks, we'll run:
|
aa9588a to
170b0a9
Compare
|
Thanks, Ash. All three are addressed on the branch (rebased onto current main; #1336's server commits are unchanged). 1. The drafter's licence. You're right: RadixArk's 2. The misses. The long text's 64 are below, without the context column, in the same columns as the short texts'. Position 124 of the agent turn: I reran exllamav3 over that text and kept the 222-token prefix run's logits this time (its full run reproduced the stored reference byte for byte). exllamav3's own prefix run does move 124, but not across: its lead of 3. Admission. The long text's 64 misses (no context column; 11 token ids redacted)Same run and columns as the short texts' table: exllamav3's Summary: 64 misses of 2,600 rows (top-1 0.9754); exllamav3 against itself (prefix vs full forward) 0.9777 over the Redactions: the text is an internal note, so every token listed below (true next, both tops, both top-5s) was Long mixed text (64 misses of 2600)
|
|
@ashhart could you rerun |
170b0a9 to
1d40125
Compare
…one GPU weightShare read TF_TP_* with catch null, so a malformed world or rank was admitted as one GPU's share. It now returns BadSetting as open does, and the admission reports it through the family's explain. weightShare may return an error union (cuda_family_memory's share, the same change as MiMo-V2's in ashhart#728). Host test: unset, six malformed settings, and a two-rank share.
…ame otherwise Muse Spark was gated and run only on two GB10s at TP=2. open now refuses any other GPU (MuseSparkRequiresSm121) and an unset TF_TP_WORLD or any world but 2 (MuseSparkRequiresTwoRanks), as does tf-muse follow; the weight share and the target's and drafter's rank views refuse one rank by the same name, so admission names it before sizing memory. Host tests: the admit rule, rankView(1), and the weight share at one, two and four ranks.
…ates no licence RadixArk's Muse-Spark-Open-DFlash2 states no licence, so all rights are reserved by default: the recipe no longer names a drafter pack or a --drafter command, and serves two GB10s only, as the family now admits.
…serve stands on its own
Since 1911e7b GLM's CUDA family takes fabric/tp over the engine's cuda module, and a second family over the same runtime made its own tp module, so the engines failed with `zig/src/fabric/tp/tp.zig: error: file exists in modules 'tp' and 'tp0'`. tp.module now keeps one module per cuda module and returns it on every later call.
1be8311 to
2028559
Compare
|
Thanks @ashhart. Pushed, rebased onto current main (
Locally on x86_64 Linux: |
|
All good to go. |
|
Thanks @ajensenwaud, and sorry this has waited since 1 Nov. Everything we asked for is in. As agreed, we'll carry the cluster fix (traps below sm_90), resolve the new conflicts with main when we prepare it, and run the two-GB10 cells at TP=2 with pack revision |
|
/atc exchange b748653a7860856b1e83ee99c65ffc53f24a6ba6ab843548e7738a08d54cbaa4 |
|
@ajensenwaud the same for this one: we're merging today's main into |
Main moved on in the CUDA registry, the contract registry, admission and the TP build. Resolved: - server: the same resolution as ashhart#1336's merge (main's reply loop now lives in chat_generation.zig, and the recipient split hooks in there), so both PRs carry identical server files. - registry: Muse Spark joins cuda_families.zig and its records join registry_joins.zig's landed_cuda; the contract set and image list take Muse's group and fatbins beside main's newer sets; the recipe index keeps both new rows. - admission: openWith keeps the family's own prompt-cache budget (familyOpen); weightShare takes main's drafts argument (unused here), and a refused TP setting still reports through the family's explanation. - tp build: one tp module per (cuda, verbs) pair, so Muse in the engines' binary takes GLM's tp over the verbs its fabric shares (muse.moduleOver); tf-muse and the host tests keep their own. Co-authored-by: ajensenwaud <5827908+ajensenwaud@users.noreply.github.com>
muse_glue is in the shared kernel list, so a release build compiles it for sm_80 and sm_86 too, where thread-block clusters do not exist and nvcc stops at muse_gate_norm_c, muse_expert_sum_c and cluster_sum. Below sm_90 the two cluster kernels now trap and drop their cluster attribute, and cluster_sum is left out, as qmm.cu and ck_lane.cu do. Muse admits sm_121 only, so the host never launches them there; the sm_90+ source is unchanged. Co-authored-by: ajensenwaud <5827908+ajensenwaud@users.noreply.github.com>
Main's lean check now refuses a new direct getenv of a TF_ name and a getenv of a name that is not a literal. Muse's reads move accordingly: - open and the weight share check TF_TP_WORLD by its literal name (unset or blank is one rank, refused by name as before: tp's own default is two) and read the settings through tp.Config.fromEnv, so a malformed one is still BadSetting. The weight-share test reads its fake environments through the same rule (tpFrom). m1 does the same. - tf-muse's developer knobs keep their names, read with a literal getenv at each call. - The draft check's TF_MUSE_DRAFTER and TF_MUSE_DRAFT_TAPS become MUSE_DRAFTER and MUSE_DRAFT_TAPS, beside the tool's other MUSE_ knobs (the recipe's check list says so); the server's drafter is --drafter. Co-authored-by: ajensenwaud <5827908+ajensenwaud@users.noreply.github.com>
…sons The block sum broadcasts through its own total, a shape the shared tree lacks. The three warp sums use the shared butterfly's order and move to tf_common::warp_sum once nvcc shows the same machine code on the family's GB10 run.
|
@ajensenwaud, brought up to today's main and pushed (
|
|
OK, thank you. |
|
Thanks @ajensenwaud. Everything we asked you to change is accounted for, including the plain-decode recipe, admission checks and cluster-kernel guards. This still waits on us: the merge with current main, followed by the two-GB10 TP=2 checks on pack
|
What this changes
This PR adds Meta's Muse Spark Open to the native CUDA engine. It is a text-only mixture-of-experts model with 816B parameters, 42B of them active per token. The PR serves it on two GB10s from a 1.8-bit EXL3 pack, with the prompt cache on.
Results
Details
Hardware. Two ASUS Ascent GX10s (GB10, sm_121, 128 GB each), CUDA 13, Zig 0.17.0, linked over RoCE.
Checkpoints. Pack
ajensenwaud/Muse-Spark-Open-816B-A42B-EXL3-1.8bpwat38ad2925, quantised fromamd/Muse-Spark-Open-816B-A42B-Quark-MXFP4at4885eb2a. Drafter runs usedRadixArk/Muse-Spark-Open-DFlash2at46c90f41.Run dates. On
2ff01910. Since then the branch has only moved onto server: split recipient-addressed replies into reasoning, answer and tool calls #1336 and main2836e9b2; no kernel changed.Accuracy figures. KL is 0.67 to 1.24 times exllamav3's own noise, and the true next token's loss is within +0.61% and -0.08% of exllamav3's. This branch's logits are byte-identical to the build that measured them.
Speed figures. Greedy decoding, 512-token replies, drafter on, in tokens a second:
Prompt speed. A cold 15,375-token prompt reads at 196 tokens a second.
Context. 471,040 tokens fit for one stream, or 110,592 each for four.
Kernel contract. 45 of 45 Muse registrations pass gates 1-4, and 46 of 46 launch records pass gate 5. Main's own kernels account for the run's 2 failures and 291 limit problems.
Host tests. 738 of 740 tests pass. The lean checker finds 426 problems, the same as main.
Untested setups. One GPU, other GPUs, Metal and image inputs, all of which are refused.
Checklist
"draft": false, concurrent equals solo, and resumed equals fresh.