Qwen3.5-9B-MXFP4-QAD-s4000
MXFP4 QAD (W4A16-trained (weight-only)) checkpoint of Qwen/Qwen3.5-9B @ c202236235762e1c871ad0ccb60c8ee5ba337b9a, optimizer step 4000 of 4000.
Stage-1 arm at the recipe's original lr 1e-6. The held-out eval barely moved (-0.2% over 4000 steps): at this dose the movement budget is a fraction of one E2M1 quantization cell, so the quantized student is effectively frozen ("homeopathic-lr" regime). Kept for the record; superseded by the lr 1e-5 arm (Qwen3.5-9B-MXFP4-QAD-LR1e-5-s4000, picked by a measured lr sweep).
How this checkpoint was produced
| item | value |
|---|---|
| training repo | QATFactory branch weili/mxfp4 @ 86b72a2 (PR) — scripts/train_llm_qat.py |
| method | QAD (quantization-aware distillation): student trains with fake-quantized forward; frozen BF16 teacher = the base model itself |
| objective | pure KL at temperature 1.0 (distill_weight 1.0, hard_label_weight 0.0), loss on assistant tokens only |
| base model / teacher | Qwen/Qwen3.5-9B @ c202236235762e1c871ad0ccb60c8ee5ba337b9a |
| dataset | openperfectblend_100k_Qwen3.5-9B_think — ~100K ChatML conversations (OpenPerfectBlend-derived prompts with Qwen3.5-9B think-mode responses; native <think> spans in the assistant turns), prepared in the QATFactory project. Train file from togethercomputer/Qwen3.5-9B-reasonmix @ b88c109 (940,793,581 bytes, md5 0406bb3a7a482352360716a1bc5e9e04; ~84.3k train conversations by the trainer's epoch accounting). Held-out eval = a disjoint 256-conversation split (md5 af10c8c304c146a81ddc35e439d7ac4b), 818,944 scored positions — the same corpus used for the serving-KL rows below |
| preprocessing | model chat template (ChatML), assistant-only loss mask, max_seq_len 8192, right-truncated |
| this checkpoint | optimizer step 4000 of 4000 (32,000 conversations consumed ~= 0.38 epoch, no data repetition) |
| batch per weight update | 8 sequences = 1/GPU x 8 GPUs x grad-accum 1 (<= 8 x 8192 = 65,536 tokens/update) |
| learning rate | peak 1.0e-6, cosine decay to 0 over 4000 steps, linear warmup 1% (40 steps) — recipe default, carried from the NVFP4 recipe; later shown ~10x too small by the stage-1.5 sweep |
| optimizer | AdamW (adamw_torch, beta1 0.9 / beta2 0.999), weight_decay 0.0, max_grad_norm 1.0 |
| precision / parallelism | bf16, FSDP2 full_shard on jbom 8xB200 (single node), gradient checkpointing (non-reentrant), sdpa attention |
| fake-quantized modules | all linear projections (q/k/v/o_proj, gate/up/down_proj, GatedDeltaNet in/out projections); embeddings, lm_head, norms and the vision tower stay BF16 |
| quantization config | quant_format: mxfp4, fused_runtime_scales: false (MXFP4 rejects fused scales by design) |
| seed / bookkeeping | seed 42; held-out eval every 100 steps; checkpoint every 1000 steps; step time |
| in-loop held-out eval KL | 0.05203 (s100) -> 0.05192 (s4000) — essentially flat |
| W&B | i4taulo6 (project qatfactory-qat, public) |
Training mode: W4A16 (weight-only fake-quant). Weights are fake-quantized in the forward pass; activations stay BF16 during training. The exported artifact can still be served W4A4 — the tables below measure both.
Serving
compressed-tensors format mxfp4-pack-quantized (FP4 E2M1 weights, block-32 E8M0 scales).
One artifact serves both modes in vLLM >= 0.25.1:
- W4A4 (default on SM100+/Blackwell): FlashInfer FP4 kernel, activations quantized
dynamically per-token to MXFP4 at runtime. First load runs a one-time
fp4_gemmautotune (~10-20 min; cached underVLLM_CACHE_ROOT). - W4A16 (any Marlin-capable GPU, or forced on Blackwell):
--linear-backend marlin(CLI) orLLM(..., linear_backend="marlin").
vllm serve weili-0234/Qwen3.5-9B-MXFP4-QAD-s4000 --max-model-len 24576
Evaluation (step 4000)
| model | KL vs BF16 | GSM8K | GPQA-D | MMLU-Pro |
|---|---|---|---|---|
| BF16 teacher | — (reference) | 83.8 | 67.68 | 77.0 |
| this ckpt, A16 (W4A16 serving) | 0.0827 | 76.8 | 55.0 | 66.9 |
| this ckpt, A4 (W4A4 serving) | 0.1802 | 65.8 | 54.5 | 56.1 |
MXFP4 PTQ baselines on the same harness (same base, same lattice): RTN A16 KL 0.0827 / A4 0.1805; GPTQ (512-sample calib) A16 0.0333 / A4 0.1239 — see MXFP4-RTN and MXFP4-GPTQ.
All rows come from one frozen harness: vLLM 0.25.1 on B200 (SM100), temperature 0; KL = top-20 + residual-bucket KL vs the BF16 teacher's next-token distribution over 818,944 held-out positions (nats, lower is better; pipeline validated by a BF16-self run at 0.0002); GSM8K test[:500] 0-shot CoT; GPQA-Diamond n=198 (single seed — treat deltas < ~6 points as noise); MMLU-Pro 1000-question subset.
Related checkpoints
- Other steps of this arm: s1000, s2000, s3000
- QAD-trained BF16 master weights (pre-export): Qwen3.5-9B-MXFP4-QAD-s4000-BF16
- Higher-dose arms: MXFP4-QAD-LR1e-5, MXFP4-QAD-LR8e-6
Part of a monitored QAD experiment series with full bookkeeping (pre-registered predictions, exact SHAs/configs/seeds per run). Produced with AI assistance (Claude).
- Downloads last month
- -