# W8A8 MXFP8 Quantization ## Overview W8A8 MXFP8 (Microscaling FP8) quantizes both weights and activations to FP8 using the OCP MX format: groups of 32 K-dimension elements share a single `float8_e8m0fnu` exponent scale. This gives better accuracy than channel-wise FP8 while keeping the same 8-bit weight footprint. This method supports three modes: | Mode | Description | |------|-------------| | **Online** | BF16 weights are quantized to MXFP8 at load time — no pre-processing needed | | **Offline (Native)** | msModelSlim-exported MXFP8 weights converted to diffusers format via `merge_mxfp8_checkpoint.py` — weights and scales are loaded directly from the preprocessed checkpoint | | **Offline (AutoRound)** | AutoRound MXFP8 checkpoints with `data_type="mx_fp"` — auto-detected from `config.json` | ## Hardware Support | Device | Online | Offline (Native) | Offline (AutoRound) | |--------|--------|------------------|---------------------| | NVIDIA Blackwell GPU (SM 100+) | ⭕ | ⭕ | ⭕ | | NVIDIA Ada/Hopper GPU (SM 89+) | ⭕ | ⭕ | ⭕ | | NVIDIA Ampere GPU (SM 80+) | ⭕ | ⭕ | ⭕ | | AMD ROCm | ⭕ | ⭕ | ⭕ | | Intel XPU | ✅ | ❌ | ✅ | | Ascend NPU (Atlas 950 A5) | ✅ | ✅ | ⭕ | Legend: `✅` supported, `❌` unsupported, `⭕` not verified in this guide. **Note**: Intel XPU only supports AutoRound MXFP8 for offline mode. Use AutoRound quantized checkpoints or online mode for XPU. ## Model Type Support ### Diffusion Model (Wan2.2) | Model | Mode | Notes | |-------|------|-------| | Wan2.2-T2V-A14B | Online + Offline | MoE cascade; quantizes two transformers (`transformer` + `transformer_2`) | | Wan2.2-I2V-A14B | Online + Offline | MoE cascade; quantizes two transformers (`transformer` + `transformer_2`) | | Wan2.2-TI2V-5B | Online + Offline | Single transformer | ### Multi-Stage Omni/TTS Model (Qwen3-Omni, Qwen3-TTS) | Model | Status | Notes | |-------|--------|-------| | Qwen3-Omni | Not validated | — | | Qwen3-TTS | Not validated | — | ### Multi-Stage Diffusion Model (BAGEL, GLM-Image) | Model | Status | Notes | |-------|--------|-------| | BAGEL | Not validated | — | | GLM-Image | Not validated | — | ## Configuration ### Online Mode Online mode requires no pre-processing. vLLM-Omni quantizes BF16 weights to MXFP8 at load time. Python API: ```python from vllm_omni import Omni from vllm_omni.inputs.data import OmniDiffusionSamplingParams omni = Omni(model="", quantization="mxfp8") outputs = omni.generate( "A cat sitting on a windowsill", OmniDiffusionSamplingParams(num_inference_steps=50), ) ``` CLI: ```bash python text_to_video.py --model --quantization mxfp8 # Online serving vllm serve --omni --quantization mxfp8 ``` ### Offline Mode (Native) Native offline mode loads a pre-quantized checkpoint from msModelSlim. A preprocessing step converts the raw quantized output to the diffusers format expected by vLLM-Omni and injects the quantization config into `transformer/config.json` so that vLLM-Omni auto-detects the offline path without a `--quantization` flag. #### Step 1 — Quantize with msModelSlim ```bash msmodelslim quant \ --model_path /path/to/Wan2.2-TI2V-5B-Diffusers \ --save_path /path/to/wan2_2_ti2v_quantized_raw \ --device npu \ --model_type Wan2_2 \ --config_path /path/to/wan2_2_w8a8f8_mxfp.yaml \ --trust_remote_code True ``` After this step, `--save_path` contains the raw quantized safetensors files and a metadata JSON (`quant_model_description*.json`). For cascade MoE models (T2V-A14B, I2V-A14B), msModelSlim outputs two subdirectories: `high_noise_model/` and `low_noise_model/`. #### Step 2 — Preprocess with merge_mxfp8_checkpoint.py The script (`vllm_omni/quantization/tools/merge_mxfp8_checkpoint.py`): 1. Copies the original diffusers model to `--output-path` (VAE, text encoder, scheduler, etc. are preserved). 2. Remaps tensor names from msModelSlim convention to diffusers convention. 3. Saves the converted weights as `diffusion_pytorch_model.safetensors`. 4. Copies the original `transformer/config.json` and injects `quantization_config` so that vLLM-Omni auto-detects offline MXFP8. For cascade MoE models, steps 2–4 run separately for `high_noise_model/` → `transformer/` and `low_noise_model/` → `transformer_2/`. ```bash python vllm_omni/quantization/tools/merge_mxfp8_checkpoint.py \ --model-type Wan2.2-TI2V-5B \ --original-model /path/to/Wan2.2-TI2V-5B-Diffusers \ --quant-path /path/to/wan2_2_ti2v_quantized_raw \ --output-path /path/to/Wan2.2-TI2V-5B-MXFP8 ``` | Argument | Description | |----------|-------------| | `--model-type` | Model variant: `Wan2.2-T2V-A14B`, `Wan2.2-I2V-A14B`, or `Wan2.2-TI2V-5B` | | `--original-model` | Root directory of the original BF16 diffusers model | | `--quant-path` | Root directory of the msModelSlim quantized output | | `--output-path` | Output directory for the merged model (created by the script) | The script outputs a complete diffusers model directory at `--output-path`, with each transformer subfolder containing: - `diffusion_pytorch_model.safetensors` — converted FP8 weights - `config.json` — original transformer config with `quantization_config` injected - `quant_model_description.json` — renamed quantization metadata (reference only) #### Step 3 — Serve ```bash python text_to_video.py --model /path/to/Wan2.2-TI2V-5B-MXFP8 # Online serving vllm serve /path/to/Wan2.2-TI2V-5B-MXFP8 --omni ``` Python API: ```python omni = Omni(model="/path/to/Wan2.2-TI2V-5B-MXFP8") ``` !!! note No `--quantization` flag is needed for native offline mode. The preprocessing script injects `quantization_config` into each `transformer/config.json`, which vLLM-Omni reads automatically to activate the offline MXFP8 method. ### Offline Mode (AutoRound) AutoRound MXFP8 checkpoints declare `quant_method="auto-round"` with `data_type="mx_fp"` in their `config.json`. These are automatically detected and use the `IncMxfp8OfflineLinearMethod` backend. To use an AutoRound MXFP8 checkpoint: ```bash python text_to_video.py --model # Online serving vllm serve --omni ``` Python API: ```python omni = Omni(model="") ``` !!! note AutoRound MXFP8 checkpoints are auto-detected from `config.json` and do not require a `--quantization` flag. The config must include: ```json { "quantization_config": { "quant_method": "auto-round", "data_type": "mx_fp", ... } } ``` ## Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `method` | str | — | Must be `"mxfp8"` | | `is_checkpoint_mxfp8_serialized` | bool | `False` | `True` for offline pre-quantized checkpoints; auto-set from `config.json` when using the preprocessing script | | `ignored_layers` | list[str] | `[]` | Layer name substrings to keep in BF16 (e.g. `"to_out"` matches `blocks.0.attn1.to_out.0`) | ## Validation and Notes 1. Online mode quantizes BF16 weights at load time using `npu_dynamic_mx_quant`. This adds a one-time overhead on the first load but requires no checkpoint preparation. 2. Offline mode loads FP8 weights directly from the checkpoint. Scales are stored as `uint8` bytes in safetensors (same bit layout as `float8_e8m0fnu`) and are reinterpreted at load time without a dtype conversion. 3. If the offline checkpoint was produced with the old `merge_mxfp8_checkpoint.py` interface (arguments `--quant-dir`, `--orig-dir`, `--meta-json`, `--output-dir`), regenerate it with the current script. The old script wrote a separate `quantization_config.json` that is not read by vLLM-Omni; the current script injects the config directly into `transformer/config.json`.