Repository navigation
[Bugfix][Qwen3-Omni] Pass Thinker lm_head prefix so NVFP4 exclude-list is honored - #4528
Merged
hsliuustc0106 merged 1 commit intoJun 22, 2026
Conversation
YIHONG-JIN
requested review from
ZeldaHuang,
linyueqian,
princepride and
yuanheng-zhao
as code owners
June 18, 2026 07:11
…t is honored The custom Qwen3MoeLLMForCausalLM built lm_head via ParallelLMHead without the `prefix=maybe_prefix(prefix, "lm_head")` that vLLM's stock Qwen3MoeForCausalLM passes. vLLM 0.23.0 made ParallelLMHead quantizable by ModelOpt NVFP4 (0.22's get_quant_method only matched LinearBase, so the head was never a quant candidate and the missing prefix was harmless). On 0.23.0 the head is kept BF16 only via the prefix-based exclude-list (the W4A4 checkpoint ignores "*.lm_head"); with prefix="" that match fails, the head is wrongly NVFP4-quantized (FP4-packed -> hidden 1024), and the BF16 [vocab, 2048] lm_head weight fails to load (RuntimeError: size a(1024) must match b(2048)). Required for the W4A4 Qwen3-Omni checkpoint to load on the rebased vLLM 0.23.0 target. Latent since the original Qwen3-Omni port (vllm-project#55); surfaced by the 0.23.0 rebase. BF16 Qwen3-Omni is unaffected (no quant_config). Verified on B200 (sm_100) and RTX 5090 (sm_120): the W4A4 thinker loads and serves coherent text. Signed-off-by: Yihong Jin <yihongjin404@gmail.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
YIHONG-JIN
force-pushed
the
fix/qwen3-omni-lmhead-nvfp4-prefix
branch
from
June 18, 2026 07:25
c4c9ea1 to
26b19e9
Compare
Collaborator
|
Thanks, LGTM. |
hsliuustc0106
left a comment
Collaborator
There was a problem hiding this comment.
Bugfix looks correct.
Contributor
Author
|
@hsliuustc0106 Can you help approve this if everything looks fine? I suspect the impact is not limited to NVFP4 |
Collaborator
|
LGTM |
david6666666
approved these changes
Jun 22, 2026
david6666666
enabled auto-merge (squash)
June 22, 2026 02:40
1 task done
hsliuustc0106
disabled auto-merge
June 22, 2026 04:16
khairulkabir1661
pushed a commit
to khairulkabir1661/vllm-omni
that referenced
this pull request
Sep 25, 2026
…t is honored (vllm-project#4528) Signed-off-by: Yihong Jin <yihongjin404@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
6 tasks done
5 of 6 tasks
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.
What
Follow-up to #4025 (which landed the NVFP4 W4A4 NaN-clamp). Adds the
prefix=maybe_prefix(prefix, "lm_head")argument that the customQwen3MoeLLMForCausalLM(the Thinker text backbone) was missing when buildinglm_head, mirroring vLLM's stockQwen3MoeForCausalLM.Why
Without it, loading an NVFP4 W4A4 Qwen3-Omni checkpoint on vLLM 0.23.0 crashes at
load (in
vocab_parallel_embedding.py, loadinglm_head.weight):Root cause: on 0.23.0 the Thinker
lm_headis kept BF16 only via ModelOpt'sprefix-based exclude-list (the W4A4 checkpoint ignores
*.lm_head); withprefix=""that match fails, the head is wrongly NVFP4-quantized (FP4-packed →hidden 1024), and the BF16
[vocab, 2048]lm_head weight then fails to copy intothe 1024-wide param.
BF16 Qwen3-Omni is also unaffected on any version (no
quant_config, so thehead is never a quant candidate regardless of the prefix).
Reproduce
vLLM 0.23.0 + vllm-omni on Blackwell (B200 sm_100 / RTX 5090 sm_120), serving the
published W4A4 checkpoint:
The Thinker worker dies at weight load (
StageEngineCoreProc died during READY,worker traceback
qwen3_omni_moe_thinker.py:load_weights -> ... -> vocab_parallel_embedding.py) with the1024 vs 2048RuntimeError above. A debugprint at
Qwen3MoeLLMForCausalLM.__init__showslm_headbuilt as[152064, 1024](FP4-packed) instead of[152064, 2048]. With this PR it is[152064, 2048]and the model loads.Test
Verified on B200 (sm_100, FlashInfer Cutlass FP4) and RTX 5090 (sm_120): with the
fix the W4A4 Thinker loads (
embed_tokensandlm_headboth[152064, 2048])and serves coherent text (no
!!!!). Before the fix it crashes at load as above.🤖 Generated with Claude Code