Fuse nested 4-bit scale reconstruction on SM103 - #2051
Open
heiheiha798 wants to merge 5 commits into
Open
Conversation
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.
Summary
Default compressed 4-bit state reconstructs per-block FP32 scales in three CUDA launches: General8 scale dequantization, an offset add, and NF4/FP4 value dequantization. This change adds a private nested NF4/FP4 dequantization kernel that performs the same separately rounded FP32 multiply and add while decoding values, eliminating the intermediate FP32 scale tensor and two launches.
The new path is intentionally narrow:
state2.blocksize == 256;functional.dequantize_4bitin eager mode and the existing CUDA dequantize-plus-linear fallback.Non-SM103 CUDA devices, HIP/non-CUDA backends, nonnested states, unsupported nested metadata, and
torch.compiletracing retain the legacy registered-op chain. This does not change GEMM dispatch, fallback selection, launch geometry, quantization formats, schemas, serialization, or public APIs.Implementation
__fmul_rnfollowed by__fadd_rn; no FMA contraction or relaxed correctness oracle is used..outshape/dtype validation before any native call.torch.compiler.is_compiling()is true so fullgraph backward remains traceable.The CUDA library built with the official-compatible target list grew from 3,922,064 to 4,053,448 bytes, an increase of 131,384 bytes.
Validation
Kernel and performance validation was recorded in Slurm job 5140 at commit
4c7e1f54cab5dffeb9e308ab958e6aa38d051813. Review fixes were validated in Slurm job 5157 at the final headfe35f68b46c9a285e96cf9488513c7b15a17f056. Both jobs ran on one NVIDIA B300 SXM6 AC (CC 10.3, 148 SMs), driver 580.126.09, CUDA 13.0.88, and PyTorch 2.13.0+cu130. Candidate builds used CUDA targets75-real;80-real;86-real;89-real;90-real;100-real;120, and each process asserted that it loaded the library from its isolated source tree..outbehavior and architecture guards were covered separately by focused pytest.compute-sanitizer --tool racecheck: 0 hazards, 0 errors, 0 warnings.compute-sanitizer --tool synccheck: 0 errors..outrejection before the native kernel.MatMul4Bitautograd passes (384 CUDA and 384 CPU).2883b3873ffd32953c1c32620fdd8d3f6e0bb600:uvx --from pre-commit pre-commit run --all-files --show-diff-on-failureandgit diff --check upstream/main...HEADpass.Job 5126 stopped before configuration because CMake was absent from the inherited
PATHand is setup-failure evidence only. Job 5127 is a successful baseline-transform pilot and supporting evidence only. Job 5140 is the authoritative committed kernel/build/correctness/sanitizer/performance/profile run. Job 5157 is the authoritative exact-final-head.out, eager-route, and fullgraph compatibility run.B300 Performance
Both variants used the same allocation and inputs. Timings used CUDA events, 20 alternating warmups, seven interleaved timed batches, and size-scaled repetitions of up to 100 per batch. Every recorded cell includes all round samples plus median, p10, and p90.
The 24-cell direct matrix covers four realistic matrix shapes, NF4/FP4, and FP16/BF16/FP32 at block size 64:
All direct outputs were raw-bit equal. Every direct cell improved by more than 10%; per-round ratio dispersion remained below the observed effect. An independently executed tracked CLI reproduced a 1.1976x geomean and 1.1099x minimum across the same 24 cells.
Public-path controls, with quantization/setup excluded from steady-state timing:
The fallback cells assert the selected runtime path rather than inferring it from M alone. The final review fix changes only invalid-
.outvalidation and compile-time routing; the native kernel and eager selected implementation are unchanged, so the native performance matrix was not rerun after that fix.Nsight Systems shows the legacy General8 scale-dequantization, FP32 offset-add, and 4-bit value-dequantization sequence becoming one
kDequantizeBlockwiseNestedlaunch, with the full FP32 scale temporary removed. NCU on the candidate kernel reports 33.95 us duration, 69.15% compute-memory throughput, 65.08% SM throughput, 66.17% active warps, 40 registers per thread, and 2.66 KiB static shared memory.Reproduction
After building the candidate with CUDA 13 and target input
75;80;86;89;90;100;120, load that isolated package and run the benchmark on one B300:The CLI gates on one B300 SM103 with 148 SMs, records the loaded native library and environment in JSONL, alternates measurement order, reports complete samples/medians/p10/p90/effective bandwidth, and checks raw-bit equality against the legacy launch chain.
Limits
hipcc. This PR makes no HIP behavior or performance claim; downstream HIP compilation is required before merge.Tracking