Repository navigation
feat(weights): sparse deltas for MXFP8 engines - #4373
Draft
faresobeid wants to merge 6 commits into
Draft
faresobeid wants to merge 6 commits into
faresobeid wants to merge 6 commits into
Conversation
Engines that quantize online to MXFP8 (vLLM quantization=mxfp8, Blackwell's
native format) report their tensors as "mxfp8". The trainer quantizes old and
new weights with vLLM's mxfp8_e4m3_quantize and sends fp8 byte diffs plus
changed e8m0 scales as {name}_mx_scale ([rows, cols/32]); 1x32 blocks never
straddle row shards, so nothing is gathered. The engine finds each layer's
uint8 weight_scale, records the scales in the kernel's layout (row-major, or
FlashInfer's F8_128x4 swizzle through offset tables) and checks one tensor per
param against vLLM's quantization of the checkpoint. MoE kernel layouts
(Marlin, TRTLLM) still raise.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MXFP8 params try candidate kernel layouts (row-major and F8_128x4-swizzled scales, and for expert params the FlashInfer TRT-LLM MoE layouts: w13 swapped, gate/up interleaved and shuffled, w2 shuffled, scales interleaved) and keep the first whose positions hold vLLM's quantization of the checkpoint byte for byte. The TRT-LLM tables come from running vLLM's swap_w13_to_w31 and _shuffle_mxfp8_moe_weights (FlashInfer's block_scale_interleave included) on byte-planes of index probes, so they follow the engine's code exactly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lashinfer_utils Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in the boot layout check (match_boot). MXFP8 params are left to fp8_layout, which probes their kernel layouts byte for byte already; the worker marks them (uint8 `_scale` next to the weight, no `_scale_inv`) before match_boot, and row ranges align to 128-row blocks only for per-block fp8 params. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Sparse weight deltas for engines that quantize online to MXFP8 (vLLM
quantization = "mxfp8"), Blackwell's native format. Stacked on #4085; until now such engines were refused (no_scale_inv, unknown layouts).What changes
"mxfp8". The trainer quantizes old and new weights with vLLM's ownmxfp8_e4m3_quantize(FlashInfer on SM100+, torch elsewhere: the same bytes for bf16 inputs) and sends the fp8 byte diffs plus the changed e8m0 scales as{name}_mx_scale([rows, cols / 32], uint8). 1x32 blocks never straddle row shards, so nothing is gathered. The fp8 encoder's block geometry is now per mode (fp8_block): 128x128 forfp32/ue8m0, 1x32 formxfp8.fp8_layoutfinds each MXFP8 layer's uint8weight_scaleand tries candidate kernel layouts for every fp8 param, keeping the first whose recorded positions hold vLLM's MXFP8 quantization of the checkpoint byte for byte (weights and scales):swizzle_mxfp8_scale; FlashInfer Cutlass/CuteDSL/torch linear kernels), as row/column offset tables;swap_w13_to_w31and_shuffle_mxfp8_moe_weights(FlashInfer'sblock_scale_interleaveincluded) on byte-planes of index probes, so they follow the engine's code exactly.An unknown layout raises instead of patching the wrong bytes.
load_rowsquantizes anchors and full checkpoints the same way.Validation
FlashInferCutlassMxfp8LinearKernel, 196 tensors held in MXFP8 with swizzled scales), sparse deltas, anchor every 3 steps: 8/8 deltas applied and verified against the trainer's checksums, 0 mismatches; reward 0.24 -> 0.36-0.41.swap_w13_to_w31+_shuffle_mxfp8_moe_weightsoutput for w13 and w2.swizzle_mxfp8_scale(padded shapes included);_probe_permutation/_separablerecover a known permuted, padded layout and reject non-permutations; 556 passed across the sparse test set; ruff clean.Not covered
configs/advanced/deepseek-v4-flash/swe_mxfp8.toml.gptq_marlin_repackis a byte permutation). NVFP4 (online NVFP4 is SM100-only; its per-expert global scale makes an expert dense when its amax moves) is next.🤖 Generated with Claude Code