feat(qwen3_5_moe): support compressed-tensors NVFP4 experts with block-fp8 dense side - #296
Open
JIAQI13 wants to merge 1 commit into
Open
feat(qwen3_5_moe): support compressed-tensors NVFP4 experts with block-fp8 dense side#296JIAQI13 wants to merge 1 commit into
JIAQI13 wants to merge 1 commit into
Conversation
…k-fp8 dense side llm-compressor mixed-precision exports (e.g. kyaky/Qwen3.6-35B-A3B-Uncensored-NVFP4 and the sakamakismile abliterated checkpoint in FlashML-org#263) store routed experts as compressed-tensors NVFP4 (weight_packed/weight_scale/weight_global_scale) while the dense side is 128x128 block FP8. Add a CT NVFP4 expert bank loader for offload, detect the format from config_groups, and route the dense pass through the existing block-fp8 loader (gating shared-expert/GDN block-fp8 modules on dense_quant/attn_quant). Fixes FlashML-org#263, addresses FlashML-org#236.
This was referenced Aug 30, 2026
Open
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.
Fixes #263
Also addresses #236 (uncensored/abliterated Qwen3.6-35B-A3B NVFP4 support). Related: #165, #252, #274.
Problem
Community abliterated/uncensored Qwen3.6-35B-A3B NVFP4 checkpoints exported with llm-compressor (
quant_method: compressed-tensors,format: mixed-precision) cannot be converted:weight_packed(uint8) +weight_scale(fp8-e4m3 block) + scalarweight_global_scale.weight_scale, W8A8)FreeToken only recognized the nvidia-modelopt NVFP4 expert layout (
weight/weight_scale/weight_scale_2), so:ValueError: Missing MoE expert source layersreported in [Bug] ft checkpoint fails on Qwen3.6-35B-A3B abliterated NVFP4 checkpoints: Missing MoE expert source layers #263 on v0.2.0-beta.14), andmain, the dense block-FP8 weights hit the per-tensor FP8 dequant path and crash withRuntimeError: The size of tensor a (2048) must match the size of tensor b (16)(a 128×128 block scale fed to the per-tensor dequant).The official
nvidia/Qwen3.6-35B-A3B-NVFP4(modelopt layout) and block-FP8 checkpoints are unaffected.Changes
models/nvfp4_banks.py: addload_nvfp4_ct_expert_source_banks/..._parallel— a compressed-tensors NVFP4 expert source builder for the offload banks. Parsesweight_packed/weight_scale/weight_global_scale(the stored global is the quant-side scale; the dequant global is its reciprocal, broadcast per output row — same convention vLLM uses), and builds the single-file safetensors weight map from the safetensors header when nomodel.safetensors.index.jsonis present.models/qwen3_5_moe/config.py: add_compressed_tensors_mixed_fp8block()detection (8-bitblockgroup + 4-bitgroup_size=16 tensor_groupgroup inconfig_groups); when matched, route experts to NVFP4 banks and the dense side (attn/GDN/shared expert) to native 128×128 block FP8 (attn_quant/dense_quant = "fp8_block").models/qwen3_5_moe/weight.py: register the CT expert key pattern/source spec; route the dense pass of these checkpoints through the existing block-FP8 loader (_iter_weights_fp8), renaming the block scale suffix.weight_scale→.weight_scale_invand skipping dynamic-activation scales.models/qwen3_5_moe/moe.py,gdn.py: enable the block-FP8 modules for the shared expert and GDN whendense_quant/attn_quant == "fp8_block"(previously gated on the experts being block-FP8).tests/models/test_qwen3_5_moe_ct_mixed_detect.py: detection tests — mixed CT flagged, pure-CT-NVFP4 / per-channel-FP8 / modelopt mixed / no-quant not flagged.Pure modelopt NVFP4, block-FP8, dense NVFP4, and pure compressed-tensors NVFP4 paths are unchanged.
Tested on (real hardware)
kyaky/Qwen3.6-35B-A3B-Uncensored-NVFP4(compressed-tensors mixed-precision, single 23 GBmodel.safetensors)ft checkpoint --model <HF dir> --out <out> --dtype bfloat16 --moe-backend offload --shard-gib 8:main: conversion fails (dense block-FP8 dequantRuntimeError: tensor size 2048 vs 16; [Bug] ft checkpoint fails on Qwen3.6-35B-A3B abliterated NVFP4 checkpoints: Missing MoE expert source layers #263 reports the equivalent bank-buildValueError: Missing MoE expert source layerson the Desktop build)653 weight + 240 experts_banktensorsft serve --model-path <FTW> --moe-backend offload --moe-cache-auto: loads via the FTW fast path (3.25 GiB dense + 16.9 GiB expert banks),API server is ready,/v1/chat/completionsreturns correct generations.Scope note
This covers the compressed-tensors expert layout (also used by
sakamakismile/Huihui-...-abliterated-NVFP4in #263). The other failing checkpoint in that report,joshebbs/qwen3.6-35b-abliterated-nvfp4-modelopt, uses an unusual doubled key prefix (language_model.model.layers.N.mlp.experts.*) that neither the existing modelopt regex nor this change matches — that looks like a separate export bug and is not handled here.