Repository navigation
Conversation
…keeps its BF16 linears The FP4 checkpoint quantizes the backbone and leaves the drafter in BF16, 181 MB that every draft pass reads. TF_FLASHNEXT_MTP_WEIGHTS=mxfp8 re-codes those linears to MXFP8 (E4M3 codes, one power-of-two scale a row of 32 inputs) as they load; checkpoint, the default, keeps the rows as stored and runs no new code. A draft is a proposal the verify forward checks, so a reply is unchanged and only the rounds it takes move.
Decode cells at 1, 2 and 4 streams on main, the branch unset and the branch with mxfp8, and the drafted, resumed and concurrent exactness table for the same three arms.
|
Sampled decode, and the drafter on against off, measured after the PR was opened. Same GB10, the PR's base 6c5cef8, bf16 KV, This family has no Drafter on against Greedy, drafter on: with the setting unset the PR is level with main, and with Sampled (temperature 1.0), drafter on, against the mean of 4 boots of main (3 boots each for the PR unset and with
Main's own boots spread by 1.6% to 2.0% in these cells, so the unset arm is inside main's range everywhere. So the last checklist box stays unticked: |
|
Thanks @BadAd84. The host tests pass, and keeping checkpoint as the default looks good. We will run the device check on our side with TF_FLASHNEXT_MTP_WEIGHTS unset, checkpoint and mxfp8. Each mode must preserve the plain target's complete generated tokens for greedy and seeded requests, including resumed turns and one and four streams. We will compare acceptance, resident memory, prompt speed and decode speed against main before merging.
|
What this changes
TF_FLASHNEXT_MTP_WEIGHTS=checkpoint|mxfp8says how the Flash Next MTP drafter's linears are kept in memory.checkpoint, the default, leaves the rows as stored and runs no new code.mxfp8re-codes the drafter's BF16 linears at load into the MXFP8 projection the mixers already use, so a draft pass walks about half their bytes. A draft is only a proposal the verify forward checks, so replies are the same and only the rounds a reply takes move.TF_FLASHNEXT_MTP_WEIGHTS) #3162 (the proposal; no maintainer decision on its gate yet, so this is a draft until one lands).atc overlap --base origin/main --jsonagainst main ata3aecd8:completeis false (pullFilesUnavailableandtimeLimit, so some pull requests areunknown). It lists textual conflicts with qwen27: serve the 27B pair, refuse what a pair cannot keep, and die with the peer #1434, DeepSeek-V4.1: read the pack's weight spans past the page cache (core/direct_io) #1924, Metal: serve the dense Qwen3.8-27B straight from a GGUF file (Q4_K_M, Q8_0) (#1920) #2078, deepseek_v41: reply logprobs normalize over all TP head columns (#1324) #2125 and CUDA admission: an integrated GPU under WSL2 reads the CUDA pool (RTX Spark N1X), plus an N1X receipt #2107. Each shares onlyCHANGELOG.mdand/orzig/src/platform/environment.zigwith this one (their changelog and registry additions land in the same places), and none touches the drafter's loader.Checks on this head
e16ca9d(basea3aecd8, the tip of main when I pushed). Two commits: the change and its receipt.python3 tools/zig/lean_check.py, base and head: 341 and 341, 0 new.python3 tools/pr_check.py --base origin/main --pr 9999reports 0 errors and 0 warnings.zig fmt --checkon the changed files rc 0;zig build compile-config-server -Dtarget=aarch64-linux-gnurc 0;zig build test-cuda-host --summary allon Windows with Zig 0.17.0: 383 of 383 build steps succeeded and 5,911 of 6,054 tests passed with 143 skipped, none failed;zig build test-environment-hostrc 0.platform/environment.zig's registry only); the completezig build test(macOS Metal tests need a Mac).Receipt
docs/receipts/flashnext-mtp-weights/, cells below. Same machine, checkpoint and settings for all four arms, fresh server per arm, alternatingmain, branch with the setting unset, branch withmxfp8,mainagain.mtp.*rows. A checkpoint whose drafter is not BF16 loads as stored whatever the setting says.TF_FLASHNEXT_MTP_WEIGHTS, defaultcheckpoint, acceptedcheckpointormxfp8(a registry row inplatform/environment.zig; any other word refuses to start by name).6c5cef8plus the same change (the branch was rebased ontoa3aecd8afterwards; onlyCHANGELOG.mdconflicted), Zig 0.17.0, CUDA 13.3, one DGX Spark (GB10, sm_121, 128 GB unified memory),nvidia/Qwen3.8-Flash-Next-FP4-Localat revisionb9ce18a6887e18c089fdea8509a33e63429a3300,--parallel 4, 131,072-token context, bf16 KV,MEM_CHECK=0.main, the branch with the setting unset and the branch withmxfp8, each booted fresh with the prompt cache on and again with--prompt-cache-gib 0,--parallel 4, bf16 KV:"draft": false:served_exactness.py, 8 prompts, token ids, 256 tokens, equal 8 of 8 in all three arms with the cache on and again with it off. The plain request drafted 0 tokens and the drafted ones accepted 13 to 237 a reply, so the two paths really differ.tools/bench_cache.pyrepeated and concurrent requests equal the first, 4 of 4.tools/bench_concurrent.py --alone --serialat 1, 2 and 4 streams, code and chat, greedy and temperature 1.0: 42 of 42 equal in each, 0 failed requests; the six golden prompts at 1, 2, 4 and 6 streams: 13 of 13 equal.mxfp8has the same token ids or hashes asmain's (16 of 16 concurrent, 6 of 6 golden, 8 of 8 drafted and plain, 7 of 7 turns).zig/tests/qwen35/serve_check.py: 15 ok and 0 failures in each arm.tools/bench_openai.pyandtools/bench_concurrent.py(greedy, 256 tokens, 3 reps), aggregate tok/s:mxfp8mxfp8against the mean of mainWith the setting unset the branch is level with main within the run-to-run spread (-0.5% to +0.2% against the mean of the two
mainarms). One chat cell at one stream is flat. Sampled decode (temperature 1.0) and--drafteroff were not run; this receipt is greedy only.--prompt-cache-gib 0, 8k 3.44 to 3.46 s and 32k 14.14 to 14.19 s in all arms; the change cannot reach prompt processing (the drafter runs only in decode).mtp.*(NVIDIA Open Model Agreement).Checklist
For a change that reaches inference:
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo. (Run onmain, the branch unset and the branch withmxfp8; see Exactness above.)mxfp8, which only changes which tokens it proposes.--drafter, no slower than without it, greedy and sampled. (Greedy decode at 1, 2 and 4 streams is measured above, and 4 is the widest this boot admits at a 131,072-token window; prompt speed is level. Not run: sampled decode speed, and--drafteragainst none.)