[NVFP4 4over6] Add the grouped-experts four-over-six converter - #14
Draft
wolfcomos wants to merge 1 commit into
Draft
[NVFP4 4over6] Add the grouped-experts four-over-six converter#14wolfcomos wants to merge 1 commit into
wolfcomos wants to merge 1 commit into
Conversation
This was referenced Aug 30, 2026
wolfcomos
force-pushed
the
4over6/titan1-dense
branch
from
August 30, 2026 11:16
04ce11d to
7652f2d
Compare
wolfcomos
force-pushed
the
4over6/titan2-grouped
branch
from
August 30, 2026 11:16
a690cca to
0614021
Compare
Add NVFP4GroupedExpertsConverter, applying four-over-six NVFP4 quantization to MoE routed-expert grouped GEMMs. The converter mirrors MXFP8GroupedExpertsConverter exactly: a class factory over the _grouped_mm seam plus swap_token_dispatcher(pad_multiple), with the quantized subclass calling torchao's _quantize_then_scaled_grouped_mm dispatcher with an NVFP4FourOverSixTrainingOpConfig. The torchao dispatcher branch owns tail handling, so there is no titan-side slice/pad glue and no per-forward int(offs[-1]) D2H sync. Like the dense converter, the config carries a recipe selector; recipe="four_over_six" is the only supported grouped value today -- torchao wires no RHT/SR grouped GEMM into its dispatcher, so there is no "default" grouped path, and the converter says so when asked for one. pad_multiple is validated as a multiple of 128 at converter build (the four-over-six grouped GEMM's swizzle contract; violating it produces silently wrong numerics), and row_scaled_activation together with model compile is rejected at config time because the row-scaled grouped forward host-reads offsets and loops dense GEMMs per group. Also add nvfp4_bf16_first_last_fqns (the miles NVFP4 RL recipes' --first-last-layers-bf16 analog), the deepseek_v3 debugmodel four-over-six recipes (high_precision base point and the dequantized first/last-bf16 variant), has_quantization coverage of the four-over-six experts cache and linear config, and CPU unit tests including the grouped recipe rejection. Requires a torchao build whose grouped GEMM dispatcher supports NVFP4FourOverSixTrainingOpConfig (the companion torchao PR). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
wolfcomos
force-pushed
the
4over6/titan1-dense
branch
from
August 31, 2026 02:01
7652f2d to
75ecab9
Compare
wolfcomos
force-pushed
the
4over6/titan2-grouped
branch
from
August 31, 2026 02:02
0614021 to
f38b8c4
Compare
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.
Stack (emulated ghstack, oldest at bottom):
Depends on the torchao grouped GEMM dispatcher PR: wolfcomos/ao#14.
Summary
Adds
NVFP4GroupedExpertsConverterwithrecipe="four_over_six", applying four-over-six NVFP4 quantization to MoE routed-expert grouped GEMMs. The NVFP4 RL recipes in the miles RL framework (https://github.com/radixark/miles) quantize only the routed-expert projections; with no Linear converter alongside, this converter alone reproduces that allow-list (attention, dense MLP, shared experts, router, embeddings, and the LM head all stay bf16).Also included:
nvfp4_bf16_first_last_fqns(the miles recipes'--first-last-layers-bf16analog), thedeepseek_v3_debugmodel_nvfp4_four_over_six{,_dequantized}debug recipes (high-precision-backward base point, and the dequantized-backward variant with first/last decoder layers kept bf16),has_quantizationcoverage of the four-over-six experts cache and linear config, and CPU unit tests.Design notes
recipe="four_over_six"is the only wired grouped recipe in torchao today: the config carries the samerecipeselector as the denseNVFP4LinearConverter([NVFP4 4over6] Add the dense four-over-six linear converter #13), but torchao wires no RHT/SR grouped GEMM into its dispatcher, so there is no "default" grouped path; any other value — including"default"— is rejected at converter build with aValueErrorexplaining exactly that.MXFP8GroupedExpertsConverterexactly: a class factory over the_grouped_mm(self, *, A, B_t, offs)seam plusswap_token_dispatcher(pad_multiple). The quantized subclass builds anNVFP4FourOverSixTrainingOpConfig(config object) and calls torchao's shared_quantize_then_scaled_grouped_mmdispatcher — identically to how the MXFP8 subclass calls it withMXFP8TrainingOpConfig. The torchao dispatcher branch owns tail handling, so the earlier titan-side slice/pad glue and its per-forwardint(offs[-1])D2H sync were deleted outright; nothing here reads offsets on the host.pad_multiplevalidated as a multiple of 128 at converter build: the four-over-six grouped GEMM's swizzle contract requires 128-row-aligned token groups, and violating it produces silently wrong numerics rather than an error, so it is rejected at config time.model_compile_enabledrejected unconditionally at converter build: torchao's dispatcher branch host-readsoffs[-1]in every configuration (the row-scaled loop adds more host reads), which fullgraph capture cannot handle; the copied "compile recommended for performance" warning was removed as it recommended an unsupported configuration.training.disable_cuda_graphs = True: the quantized grouped GEMM host-reads group offsets, which CUDA-graph capture forbids; the miles recipes likewise run with graphs off.NVFP4FourOverSixTrainingOpConfigand its_quantize_then_scaled_grouped_mmbranch ([nvfp4 training][rl] Add the four-over-six grouped GEMM and dispatcher wiring ao#14). Without it the converter raises an actionableImportErrorat build.Numerics evidence
Numerics live in the companion torchao PRs; parity results are maintained in a local TE harness (not in-tree): pure-torch quantizer 384/384 bitwise vs TE 2.17 kernels; CuTe DSL kernel 1920/1920 bitwise vs the torch oracle plus 12/12 vs TE; re-verified 2026-08-24 vs TE main.
Test plan
CPU-only (container without
--gpus; requires a torchao build providingNVFP4FourOverSixTrainingOpConfigonPYTHONPATH, otherwise the new tests skip):Import checks of every touched module pass (
torchtitan.components.quantization{,.nvfp4,.utils},torchtitan.models.deepseek_v3.config_registry). Lint: ufmt (black 22.12.0 / usort 1.0.5), flake8 with the repo plugin pins, pydoclint, and codespell all clean on the changed files.GPU results come from the assembled stack tip on GB200 (RL-parity phases A-D2 plus a 6-arm Qwen3 recipe ablation), since CI has no SM100 runner for the four-over-six kernels.
Draft on the fork to stage the upstream submission; supersedes the exploratory stack (#8)
Review pass (2026-08-30)
has_quantizationcoverage (utils.py hunk + test tail) moved down the stack into the dense PR; this PR keeps only the grouped-experts cache coverage.err_mode/e4m3_scale_bound/row_scaledthrough the shared helper.FourOverSixGroupedExperts.__init__importsNVFP4FourOverSixTrainingOpConfiglocally and raises an actionableImportErrorfor direct factory/config use (MXFP8-analog pattern).