Repository navigation
Conversation
…s idle A 16-row MXFP8 or BF16 lane call whose 64-column grid holds fewer than 96 blocks (TF_QMMF_HALF_BELOW, 0 never) takes a 32-column tile: half a packed tile's n8 tiles, contiguous in both formats' word and scale order, so each column's mma chain, K slices and cluster sum are the 64-column tile's and its bits the same, with twice the blocks. Flash Next's hyper-connection down projection ([324, 10240] BF16, 6 tiles x 8 slices) reads its weights at 183 GB/s instead of 158 (36.3 vs 42.0 us cold), the router and the shared expert's MXFP8 projections 4-8 % faster. The existing instances are untouched (their loads stay behind `if constexpr (BN == 64)`). tf-cuda-test lane-half: MXFP8 and BF16, fp32 and bf16 out, bytes equal to the 64-column tile at Flash Next's decode shapes and the column edges, FP64-bounded, timed on weights past the L2. Served (FP4-Local, no drafts): 23.95 / 23.83 tok/s one stream (main 23.58 / 23.66), replies equal.
…FP8 and BF16), a 1.5x-scale control, gate 5 records
… 0 for the released 64-column launches projection_f32_host_tests and the nemotron sm_89 host tests build a qmmf.Lane field by field; they now set its half tiles and half_below = 0, so their launch parameters stay the 64-column tile's they check.
|
Thanks @jschmied for the half tiles, and for keeping each column's K-slice order and cluster sum exactly as the 64-column tile's, with the 1.5x tensor-scale control to prove the replacement check bites. We are carrying all three commits onto current main ourselves, kept as yours, resolving the registry conflict you flagged, and a separate commit of ours will set - Synthema, Ash's AI Assistant. |
…, fp32-out half-tile contract entries - proposal_head_test.zig and flashnext_proposal_host.zig, added to main after the PR's base, build a qmmf.Lane from undefined; they now set half and half_below = 0, as the PR does for the other hand-built lanes, so matmulOut reads defined fields and launches the 64-column tile (both crashed on 0xaa... handles in Debug before). - contract_lane_half.zig: MXFP8 and BF16 half-tile entries writing fp32, and a 1.5x-scale fp32 control, since the FP32 projection contract's gate-4 shape (2560 x 10240) takes the 64-column tile and no gate 4 reached the fp32 half kernels.
|
Landed on main in 93a215b..35e46c0, with your records under your authorship plus the maintainer fix-ups. Thank you. Measured with the whole group (#1139, #1140, #1143, #1147, #1164, #1169, #1171 and #1170's Flash Next slice) against main on GB10s:
- Synthema, Ash's AI Assistant. |
What this changes
A 16-row MXFP8 or BF16 lane call (decode rows, verify windows) whose 64-column grid holds fewer than 96 blocks
(
TF_QMMF_HALF_BELOW, 0 for never) takes a 32-column tile: half a packed 64-column tile's n8 tiles, which arecontiguous in both formats' word order and in MXFP8's scale order. Each column's mma chain, its K slices and the
cluster sum are the 64-column tile's, so its bits are the same; the grid has twice the blocks. The existing instances'
loads stay behind
if constexpr (BN == 64).On Flash Next's ModelOpt checkpoint the hyper-connection down projection (
[324, 10240]BF16: 6 column tiles x 8K slices, one block an SM on a GB10) read its weights at 158 GB/s.
Receipt
Environment: TensorFold
maind1018b31plus this branch; one DGX Spark (GB10, sm_121, CUDA 13.0, nvcc 13.0.88);nvidia/Qwen3.8-Flash-Next-FP4-Local@b9ce18a6.Exactness:
tf-cuda-test lane-half: MXFP8 and BF16, fp32 and bf16 out, bytes equal to the 64-column tile at FlashNext's decode shapes (hyper-connection down with and without its 4 inject rows, the router, the shared expert's
gate/up and down), 1 to 16 rows, the 32- and 96-column edges; fp32 outputs within their float64 bound (worst 0.011).
Served, greedy, against
main: chats and ~8k contexts byte-identical.Kernel time on weights read from DRAM (copies past the L2, cycled):
Wider grids gain nothing (0.97-1.02x at 160 to 320 blocks), hence the threshold.
Decode speed (served,
--no-drafts, one stream, code / chat): 23.95 / 23.83 tok/s,main23.58 / 23.66; fourstreams 65.9 / 65.5 aggregate,
main65.6 / 65.1.Prompt speed: unchanged (prompt rows take the 64-row tiles).
Kernel contract,
tf-cuda-test kernel-contract(built-Dnvcc) on the GB10:SUMMARY 87 kernels: 87 pass gates 1-4, 0 fail, 0 known findings; 8 controls: 8 red as planted, 0 missed; 1533 limit problems(the limit problems are theoffline audit's on this nvcc, the same count as a main-based run; none in the new launches).
zig/tests/cuda/contract_lane_half.zig), MXFP8 and BF16, each replacing the 64-column 16-row tile:gate 1 against float64's classes, gate 3 bit-equal at 15 shapes (Flash Next's decode calls and the 32-, 64- and
K-edges), gate 4 exact (bf16 sums would miss 17,823-20,611x).
Tests run: full
zig build test -Dnvcc=/usr/local/cuda/bin/nvcc(exit 0),tf-cuda-test lane-halfandkernel-contract,zig fmt --check. Lean check (CI'slean_check.py+lean_new.pyagainstd1018b31): 0 new findings.Gotchas
qmmfis the lane matmul Nemotron uses too. Any 16-row MXFP8 or BF16 call with fewer than 96 blocks in its 64-column grid now takes the half tile, with the same bits. I measured speed on Flash Next only; Nemotron's bytes are covered by the contract, not by a served run.zig/src/core/contract/registry.zig: both add contract entries at the same place. Keep both lists.Checklist
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo. Measured with MTP drafts at--parallel 4: drafted == plain 8/8, concurrent == solo 8/8, and a two-turn prompt resumed from the cache (7,147 of 7,184 tokens restored) equals the same turn on a fresh server; each output equalsmain's.