Qwen3-Omni-30B-A3B-Instruct — NVFP4 W4A4 (full thinker, MSE) — Preview

ModelOpt NVFP4 W4A4 quantization of Qwen/Qwen3-Omni-30B-A3B-Instruct. The entire thinker language model is FP4: attention QKV/O, MoE experts, all Linears in the thinker. Embeddings, norms, MoE router, multimodal encoders, talker, and code2wav stay BF16.

This is a legacy preview checkpoint that pre-dates the ModelOpt 0.44 NaN regression fix (see below). For production W4A4 serving with this same quantization scope, prefer:

⚠️ This checkpoint contains NaN bytes — requires vllm-omni#4025

This checkpoint was exported with vanilla nvidia-modelopt==0.44.0 before the calibration-side fix was available. Its on-disk weight_scale tensors contain literal NaN bytes (E4M3 encoding 0x7F / 0xFF). Loaded on stock vllm-omni main, those NaN bytes propagate through the FlashInfer FP4 GEMM and the model collapses to !!!!.

The mitigation is the load-time clamp from vllm-project/vllm-omni#4025. Until that PR is merged, install from the branch:

git clone -b feat/qwen3-omni-modelopt-nvfp4-w4a4 https://github.com/YIHONG-JIN/vllm-omni
cd vllm-omni && pip install -e . --no-deps

With the clamp installed, this checkpoint serves coherently (Daily-Omni n=50 = 0.70, see below).

Accuracy vs BF16 baseline (with vllm-omni#4025 clamp)

Benchmarked on RTX PRO 6000 Blackwell WS, Daily-Omni n=50 via the vllm-omni harness.

Variant Daily-Omni n=50 Δ vs BF16
Qwen/Qwen3-Omni-30B-A3B-Instruct (BF16) 0.72
W4A4 experts-only 0.72 0
W4A4 experts + o_proj (with clamp) 0.70 -2 pp
W4A4 full thinker (this, with clamp) 0.70 -2 pp

Adding qkv_proj to the FP4 scope (going from experts+o_proj to full-thinker) costs ~zero additional accuracy under the load-time clamp on this n=50 slice.

Daily-Omni breakdown (full-thinker)

Task type n Score
Reasoning 11 1.000
AV Event Alignment 3 1.000
Inference 4 0.750
Comparative 9 0.667
Context understanding 10 0.600
Event Sequence 13 0.462

Reasoning and AV Event Alignment still 100%. The full-thinker-awqclip production sibling lifts the headline number further to BF16 parity at n=1197 (0.675 vs 0.694 = -1.9 pp).

Quantization scope

Layer State
thinker.model.*.self_attn.{q,k,v}_proj (fused qkv_proj at runtime) NVFP4 W4A4
thinker.model.*.self_attn.o_proj NVFP4 W4A4
thinker.model.*.mlp.experts.* (gate_up_proj, down_proj) NVFP4 W4A4
thinker.model.* embeddings, norms BF16
thinker.model.*.mlp.gate (MoE router) BF16
thinker.audio_tower.*, thinker.visual.*, thinker.lm_head BF16
talker, code2wav BF16

Calibration recipe

  • Base model: Qwen/Qwen3-Omni-30B-A3B-Instruct in bfloat16
  • ModelOpt: nvidia-modelopt==0.44.0 (vanilla — without the FP8-cast clamp fix; this is what produces the NaN bytes documented above)
  • Config: mtq.NVFP4_DEFAULT_CFG + algorithm mse (with fp8_scale_sweep=True) — no per-projection attention exclusions
  • Samples: 512 from HuggingFaceH4/ultrachat_200k train_sft (chat-templated), truncated to 512 tokens
  • Calibration time: ~70 min on a single RTX PRO 6000 Blackwell WS
  • Excluded patterns: *audio_tower*, *visual*, *talker*, *code2wav*, *lm_head*, *mlp.gate*

Inference (with vllm-omni#4025 clamp)

from vllm_omni import Omni
omni = Omni(model="YihongJin/Qwen3-Omni-30B-A3B-Instruct-NVFP4-W4A4-full-thinker-mse-preview")

OpenAI-compatible server:

vllm serve YihongJin/Qwen3-Omni-30B-A3B-Instruct-NVFP4-W4A4-full-thinker-mse-preview \
    --omni --port 8000

Compute requirement: sm_100+ (Blackwell — B100, B200, RTX 5090, RTX Pro 6000) for native FP4 tensor cores.

Do not pass --enforce-eager for benchmarks. CUDA graphs amortize kernel launch overhead and unlock the FP4 throughput wins; with --enforce-eager set, W4A4 TPOT degrades ~10x relative to the CUDA-graph configuration.

ModelOpt 0.44 NaN regression — two mitigation paths

ModelOpt 0.44's float32 -> torch.float8_e4m3fn cast of per-block weight_scale occasionally emits literal NaN bytes (E4M3 encoding 0x7F / 0xFF) when the pre-cast scale rounds above the FP8 max of 448 after the global-scale division. A single NaN byte in any weight_scale propagates through the FlashInfer FP4 GEMM into the residual stream and collapses the served model output to !!!!. Two complementary fixes:

  1. Calibration-time (ModelOpt-side): clamp the pre-cast values to torch.finfo(torch.float8_e4m3fn).max before every .to(torch.float8_e4m3fn) at the two cast sites in modelopt/torch/quantization/qtensor/nvfp4_tensor.py and modelopt/torch/export/quant_utils.py. This produces a clean checkpoint at calibration time. This preview checkpoint was exported BEFORE that fix was applied, so it carries NaN bytes on disk. An upstream PR to NVIDIA/TensorRT-Model-Optimizer is in progress.

  2. Load-time (vllm-omni-side): vllm-project/vllm-omni#4025 installs a defensive override of ModelOptNvFp4LinearMethod.process_weights_after_loading that scans weight_scale for NaN bytes and clamps them to FP8 E4M3 max at worker init. This is the fix that lets this preview checkpoint serve coherently without re-calibrating. Self-extinguishes once vllm-omni's vllm pin includes the corresponding upstream vLLM fix; can be disabled with VLLM_OMNI_SKIP_NVFP4_NAN_CLAMP=1 for diagnostics.

Sample output (with clamp)

"The sky appears blue during the day because of Rayleigh scattering, a phenomenon where shorter blue wavelengths of sunlight are scattered more than longer red wavelengths by air molecules. This scattered blue light is what we see from all directions, giving the sky its blue hue."

Related

License

Apache-2.0 (inherits from the base Qwen3-Omni-30B-A3B-Instruct model).

Downloads last month
7
Safetensors
Model size
20B params
Tensor type
BF16
·
F8_E4M3
·
U8
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for YihongJin/Qwen3-Omni-30B-A3B-Instruct-NVFP4-W4A4-full-thinker-mse-preview

Quantized
(31)
this model