vadery/Qwen3.5-27B-W8A8
Qwen3.5-27B W8A8 (INT8 weights + INT8 dynamic activations) — MTP-preserved
W8A8 INT8 quantization of Qwen/Qwen3.5-27B, produced with llm-compressor (SmoothQuant + GPTQ). The built-in MTP (Multi-Token Prediction) head is preserved as BF16 and works at 93 % acceptance under vLLM ≥ 0.17.
Quick start
pip install "vllm>=0.17"
huggingface-cli download vadery/Qwen3.5-27B-W8A8 --local-dir ./Qwen3.5-27B-W8A8
vllm serve ./Qwen3.5-27B-W8A8 \
--max-model-len 262144 \
--dtype bfloat16 \
--gpu-memory-utilization 0.92 \
--trust-remote-code \
--enable-auto-tool-choice --tool-call-parser qwen3_coder \
--reasoning-parser qwen3 \
--speculative-config '{"method":"qwen3_5_mtp","num_speculative_tokens":1}'No additional patches required — both config.json.quantization_config.ignore (covers MTP Linear modules) and actorder field are already fixed.
Performance (single H200 SXM, vLLM 0.17.1, temperature=0)
Same quantization recipe as the GRM-2.6-Plus fine-tune (vadery/qwen36-27b-ft-grm-w8a8) — performance numbers are within noise.
Architecture preserved
Quantization recipe
SmoothQuantModifier(smoothing_strength=0.8, mappings=SQ_MAPPINGS,
ignore=[...vision, mtp, linear_attn, embed, lm_head...])
GPTQModifier(targets="Linear", scheme="W8A8",
ignore=[same as above],
dampening_frac=0.01)SmoothQuant mappings explicitly cover only the 16 full-attention layers (indices 3, 7, …, 63 out of 64) plus MLP on every layer — to avoid SmoothQuant trying to fuse into the linear_attn projections which have non-standard shapes.
Calibration: 512 samples × 2048 tokens from HuggingFaceH4/ultrachat_200k.
Post-process steps (already applied; documented for reproducers)
llm-compressor 0.10 drops the MTP tensors from the saved state and writes a quantization_config.ignore that doesn't cover MTP Linear modules. We post-process:
- Restore MTP tensors — copy 15
mtp.*tensors from the BF16 sourcemodel-*.safetensorsshards into the W8A8 single-shard safetensors. - Patch `config.json` — add 8 MTP Linear module names to
quantization_config.ignoreand clear the spuriousactorder=staticfield, so vLLM treats the MTP head as un-quantized BF16 on load.
Without these two steps, vLLM either drops the MTP head (0 % acceptance) or loads garbage values (also 0 % acceptance after weights are corrupted on load).
File size
Reasoning + tool calling
Same parser flags as the BF16 source:
--reasoning-parser qwen3— separates<think>segments intoreasoningfield--tool-call-parser qwen3_coder+--enable-auto-tool-choice— OpenAI tool-call API
Notes
- vLLM ≥ 0.17 required (
qwen3_5_mtpspeculative method only landed there). transformers≥ 5.x is required forqwen3_5model_type.- Tested on H200 (compute capability 9.0). H100 should also work.
- The Qwen3.5 series emits
<think>blocks by default — givemax_tokens >= 4096or pass"chat_template_kwargs": {"enable_thinking": false}to skip.
License
Inherits Apache 2.0 from the base model.
