Repository navigation
ricursive: the publisher's DFlash2 drafter for Ripple-65B (stacked on #2231) - #2260
BobClawblaw wants to merge 7 commits into
Conversation
|
Thanks @BobClawblaw. Drafted equal to plain, the plain path's 53 hashes unchanged and ten planted controls red is a careful first drafter PR. Two things. The family itself still needs a decision on #2171, so this waits on that. And the drafter follows "SGLang's |
|
Thanks, and a fair catch: it's SGLang's own code. ricursiveAI's drafter release holds only
I'll redo the drafter and its float64 references from those, rerun drafted == plain, the kernel contract and the plain-path A/B, add z-lab to the notices for |
45685de to
904eb81
Compare
|
The rebuild is in ( On the full model: drafted == plain 12/12 and 12/12 under structured output, seeded sampling 9/9, soak 60/60, concurrent 12/12; speed and acceptance unchanged (48% of drafted tokens kept with one stream, 56% with two). Contract 75/75 with 25 controls red; the body has the details. Still a draft until #2171 is decided. |
|
Thanks @BobClawblaw for saying plainly where the first version came from, and for rebuilding it. The drafter now names only z-lab's A few things before it leaves draft. The family itself still waits on #2171.
With the stack on today's main, |
904eb81 to
df17d13
Compare
|
Thanks @ashhart. All six are answered on the new head,
Checks on this head (each exit 0): The suite ran on the same tree before its rebase over main's last two commits, a changelog line and |
|
/atc exchange 46d290cb7bf5b9c4f378215ac437fba71d39758355c048d08965f3db29e98aa2 |
|
/atc exchange a6621e0cf0281aea16665a2b398086be7563bcfde69edf6552af92206879e1c3 |
…ig stays at 600 lines or fewer
ricursiveAI's Ripple-65B-Preview (model_type ricursive) served from the publisher's own releases as published, read in place from their shards: the NVFP4 release (ModelOpt NVFP4 MLPs, bf16 attention, 53 GiB) and the bf16 release (121 GiB). - Family in zig/src/families/ricursive and kernels in zig/kernels/metal/ricursive: PeriNorm, q/k norms, RoPE on sliding layers (1,024-key window, 3,072-slot ring), NoPE global layers every fifth, fp32 sigmoid gate, value residual, clamped SwiGLU. - NVFP4 MLPs: E2M1 nibbles, E4M3 block scales and the fp32 global, applied exactly; activations stay bf16 (the publisher's SGLang serving is W4A4; disclosed in the doc). - Exact bf16 caches; prompt chunks planned on one 2,048-row grid, so resumed == fresh. - Every kernel registered with the kernel contract: 36 pass gates 1-4, 15 controls red. - Server: replies are always read for a think block when the model decides itself whether to think (Info.reasoning_optional); a thinking budget and logprobs are refused, since Ripple's think markers are spelled from several tokens. - tools/zig/ricursive_reference.py: the float64 / bf16-point CPU reference. - docs/recipes/ripple-65b-metal.md: correctness (KL), harness speed and serving checks.
…release code Longer contexts are refused by name until a run at that length qualifies them. THIRD_PARTY_NOTICES names modeling_ricursive.py and the release's SGLang model, which the family follows for its layer order and rounding points.
…ase through the harness
df17d13 to
938b8ae
Compare
What this changes
Adds the publisher's DFlash2 drafter for Ripple-65B on the native Metal engine:
ricursiveAI/Ripple-65B-Preview-DFlash2at35609b3be3dd08a822b3ba1257c1ea5dd6f87632(7.5 GiB, bf16), read in place as published.serve ... --drafter DIRon aricursivecheckpoint now drafts with it. Before,--drafterwas refused for this family.70c1867b5), one commit. It needs ricursive: Ripple-65B-Preview on native Metal (NVFP4 and bf16 releases) #2231 first.atc overlap --json: no conflict with main. idol: Idol's denoiser as a native Metal family #1766 would conflict in two shared hub files (ricursive: Ripple-65B-Preview on native Metal (NVFP4 and bf16 releases) #2231's family registration); whicheverlands second rebases.
Things to say up front
The harness checks this on the full model (below).
rounds tie plain ones except on lists, at seven they are slower on every kind, so with
--drafterthe server refuses--parallelabove 2 by name (table in the doc).over 4,096 keys, and the fifth (NoPE) over the release's 16,384-key draft window. Its 7.7 GiB (weights and rings)
comes out of the cache budget: 127.5 GiB instead of 135.2, seven 262,144-token streams instead of eight.
DFlash2DraftModelin z-lab/dflash'sdflash/model.pyat07ebd93db9f472af339b644bb70221ad8428328a(MIT): the taps'fcand norm, the layer order, the grouped dynamiccausal convolutions and the candidate selector, at its rounding points. z-lab imports its norms, rotary and MLP from transformers' Qwen3 module; ours follow the
release's own
RicursiveRMSNorm,RicursiveRotaryEmbeddingandRicursiveMLP(modeling_ricursive.py) instead. TheNoPE layer is
no_rope_layersin the drafter'sconfig.json, and the 16,384-token draft window is frominference/server/README.mdin Ripple-65B-Preview at240d5966. The first push followed SGLang'sdflash.py; this one was rechecked step by step against these twosources alone and changed where they differ (the convolution's and the selector's rounding). Both are in
THIRD_PARTY_NOTICES.md.dflash2_config.zigaccepts only this release's geometry beside Ripple-65B and refusesanything else by name.
Shared code
native/metal.zig:ricursiveis added to the--drafterfamily list and its refusal text.kernels/metal/sources.zig: one embed line.Everything else is in the family's folder (
families/ricursive/,kernels/metal/ricursive/dflash2.metal,native/ricursive.zig) and its contract files. On the plain path,forward.zigwrites the five taps only when adrafter asked for them. The A/B below shows plain Ripple unchanged.
Checks on this head
938b8aef0(on mainc3f64ca8a, ricursive: Ripple-65B-Preview on native Metal (NVFP4 and bf16 releases) #2231 at70c1867b5)zig build test --test-timeout 10m,test-kernel-contract,test-golden(322/335 equal to server goldens, 0 unexpected differences),
test-server-security test-pull-security(24 passed,0 failed, 0 skipped),
fuzz-cortheon, the build-options test,zig fmt --check build.zig zig.concurrency and speed; structured output, seeded sampling, the soak and resumed turns ran beside the NVFP4 release.
M1 to M4 Macs are refused at load, as for ricursive: Ripple-65B-Preview on native Metal (NVFP4 and bf16 releases) #2231.
Receipt
ricursiveAI/Ripple-65B-Preview-NVFP4at99eea4477a001a41b86914e41feb4b2ed86105e5, drafter at the revision above.b7ff7854f(this head's drafter code before the rebase; since then onlycomments changed, and
--parallelabove 2 is refused), the same results as on925ae9563:--context 262144 --parallel 2, greedy 256-token replies, no other modelbusy. "Before" is ricursive: Ripple-65B-Preview on native Metal (NVFP4 and bf16 releases) #2231 at
3a5954f38, measured on the same day.The speedup is 1.5-2.7× with one stream and 1.2-2.1× with two. A round keeps 2.65 tokens with one stream (48% of
drafted tokens accepted) and 2.65 with two (56%). Time to first token is 0.53-0.65 s with one stream.
--parallel 7, one binary with and without--drafter(e1d719275, this drafter'scode before the cap); tok/s for all streams, prose / code / structured / list:
So with
--drafter,--parallelabove 2 is refused by name.ricursiveAI/Ripple-65B-Previewat240d5966), onb7ff7854f: drafted == plain 12/12,concurrent 12/12.
--parallel 2; the plain rows are ricursive: Ripple-65B-Preview on native Metal (NVFP4 and bf16 releases) #2231's bf16 run:2.2-6.1× plain; a round keeps 2.93 tokens with one stream and 3.15 with two.
3a5954f38against45685de42, this PR before the z-lab rebuild, which changed onlydrafter-only kernels, tests, notices and docs; both without
--drafter): all 53 replies of the speed plan (rulers and aresumed turn) have the same hashes in the same order; one stream 10.2/10.2/10.3/10.2 tok/s and 98.2 ms a round on both,
two streams 106.0 ms a round against 106.1.
Kernel contract
dflash2.metal: the target's tap; the drafter's norms, embed, q/k prep, convolution, SiLU,attention, top-k and walk. Each has float64 references (
zig/tests/contract/metal_ricursive_dflash2*.zig).ricursive_records.zig.130 blocks.
tf-kernel-contract --only ricursive, M5 Ultra, exit 0, on this tree before its last rebase (see above):