Repository navigation
nemotron cuda: ModelOpt checkpoints below sm_90, the lane matmul's slices reduced through a per-stream buffer - #901
Open
BobClawblaw wants to merge 1 commit into
Open
BobClawblaw wants to merge 1 commit into
BobClawblaw wants to merge 1 commit into
Conversation
…reduced through a per-stream buffer The lane matmul already reduces its K slices through fp32 partials where a card has no clusters (qmmf.plan's reduce, qmmf.cu's reduce_kernel), and its FP4 and FP8 decode to bf16 for mma.sync, but the family passed it no partials buffer and refused sm_89 and below at load. Each stream's scratch now holds the most partials any dense shape writes at rows short of fusing, Ops carries it to decode and prompt rows, and the refusal goes. The reduce adds the slices in the cluster path's order, so the sums do not change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Nemotron's ModelOpt checkpoints (NVFP4, FP8, bf16 lane rows) now load on cards below sm_90. Before this, they were refused at load with
ModeloptNeedsSm90. One commit onmain.The kernels already had what these cards need. The lane matmul decodes FP4 and FP8 to bf16 for
mma.sync, and its cluster code is compiled out below sm_90 (qmmf.cu). Without clusters,qmmf.plansums the K slices through fp32 partials andreduce_kernel. The family never passed it a partials buffer, so the load refused those cards instead.cuda_state.zig: each stream's scratch getslane_part. It holds the most partials any dense shape writes at rows short of fusing (qmmf.fused_rows - 1), computed with the lane's ownplan. That is 22 MB a stream for Nemotron 3.5 Lightning, set byo_projat split-K 8.cuda_kernels.zig:Opscarries the buffer to decode rows (dense) and prompt rows (prefillDense, for the bf16 and FP8G rows the lane takes). The sm_90 refusal goes.cuda_engine.zig:Engine.ops()passes the bound buffers'lane_part.The bits.
reduce_kerneladds the slices in the cluster path's order, slice 0 and then 1 to SK − 1, before the tensor scale. So a card without clusters makes the same sums as one with them. On sm_90 and later nothing changes except a buffer each stream doesn't use.Receipt
-Dsm=89.maindoes not build on Windows yet, so the receipts ran this commit on Windows: the native CUDA server, and Qwen3.5-2B and Qwen3.8-27B on CUDA #836's branch (5e1c3fea); the Nemotron sources it touches are the same asmain's. Checkpoint:nvidia/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-NVFP4, with its MTP head drafting.the native CUDA engine cannot load … (ModeloptNeedsSm90).--context 16384 --parallel 2. Startup: model 19.51 GiB, two streams of 0.18 GiB, a 1.4 GiB prompt cache.bench_concurrent --levels 1,2 --alone --serial: 24 of 24 alone and 12 of 12 serial equal."draft": falseon five prompts, greedy and seeded T 0.7: 10 of 10 equal.bench_openai, 128 tokens): 468 code / 363 chat tok/s sampled, 553 / 414 greedy. Drafts accepted 3,977 of 6,153.bench_cache --require-cold, a cold 2,570-token prompt in 0.176 s (qualified).zig build test: 743 of 757 passed, 14 skipped, 0 failed.test-cuda-host: 469 of 474 passed, 5 skipped.tf-cuda-testquant-ref,modelopt,glueandsmokepass.quant-ref's NVFP4[320, 2560]takes split-K 4, so on this card it runs the reduce path: within float64 tolerance, and every row count's bits are equal.zig fmt --checkis clean. The lean check reports 528 problems, the same asmain.Another checkpoint it opens. #897's Nemotron 3.5 Bolt 74B-A9B stores its Mamba
in_projandout_projin NVFP4. With this change it serves on the 4090, text only, one stream:tools/zig/bolt_reference.py's fp32 forward.Checklist
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo.quant-ref's coverage on these cards, and before this change the load refused them.