Skip to content

Fix Qwen3-VL (qwen3vl) mmproj not loaded: Krea2 / Qwen3-VL CLIP falls back to QWEN3_4B - #478

Open
allanmeng wants to merge 1 commit into
city96:mainfrom
allanmeng:fix-qwen3vl-mmproj
Open

Fix Qwen3-VL (qwen3vl) mmproj not loaded: Krea2 / Qwen3-VL CLIP falls back to QWEN3_4B#478
allanmeng wants to merge 1 commit into
city96:mainfrom
allanmeng:fix-qwen3vl-mmproj

Conversation

@allanmeng

Copy link
Copy Markdown

Problem

Loading a qwen3vl text encoder GGUF (e.g. Qwen3-VL-4B-Instruct-Q4_K_M.gguf

  • its mmproj) with type=krea2 fails at sampling time:

ValueError: Krea2 expects conditioning with 12x2560=30720 features but got 2560

Root cause is in loader.py:

if arch == "qwen2vl":          # qwen3vl never enters this branch
    vsd = gguf_mmproj_loader(path)

qwen3vl is present in TXT_ARCH_LIST but is excluded from the mmproj branch,
so the vision tower is never loaded. comfy.sd.detect_te_model() then cannot find
model.visual.deepstack_merger_list.0.norm.weight, falls back to QWEN3_4B, and
the text encoder emits a single 2560-dim layer instead of the 12 tapped layers
(KREA2_TAP_LAYERS) Krea2 needs.

This is backend-independent - it reproduces on CUDA/ROCm/XPU alike.

Fix

loader.py only (+52 / -3):

  1. gguf_clip_loader: if arch in ("qwen2vl", "qwen3vl") and pass arch through.
  2. New CLIP_VISION_SD_MAP_QWEN3VL for the Qwen3-VL vision tower. It differs from
    Qwen2-VL: merger is {norm, linear_fc1, linear_fc2} (not {ln_q, mlp.0, mlp.2}),
    blocks use a fused attn.qkv (not split attn_q/k/v) and mlp.linear_fc1/linear_fc2
    (not mlp.up_proj/down_proj). Keys are emitted in HF model.visual.* layout so that
    detect_te_model() identifies Qwen3-VL before the KREA2 branch rewrites the prefix.
  3. New qwen3vl_deepstack_remap(): GGUF indexes DeepStack mergers by source vision
    layer (4B: [5, 11, 17], 8B/32B: [8, 16, 24]) while ComfyUI expects a sequential
    list 0..N-1. Mapping is derived by sorting the layer ids found in the file, so it
    is not hardcoded per model size.

Verification

  • Key layout compared against the authoritative qwen3vl_4b_fp8_scaled.safetensors:
    315 vs 315 keys, missing=0 / unexpected=0 / shape mismatch=0.
  • Weight cosine similarity ~ +1.000 on all shared tensors; fused qkv split into
    Q/K/V blocks gives cos = 0.999988 / 0.999999 / 0.999995 (confirms [Q, K, V] order).
  • detect_te_model() simulated before/after: QWEN3_4B -> QWEN3VL_4B,
    so the KREA2 branch condition is satisfied.
  • Hardware run on Intel Arc B580 (Windows, XPU stack): Krea2 sampling completes
    at 2.85 s/it with Krea2RMSNorm shape=torch.Size([400, 12, 2560]) (before the fix
    only a single 2560 layer reached the DiT). Dequantization via Comfy Kitchen.

Notes

…EN3_4B

gguf_clip_loader only called gguf_mmproj_loader() when arch == "qwen2vl", so a
qwen3vl encoder never loaded its vision tower. Without the vision keys,
comfy.sd.detect_te_model() cannot find
"model.visual.deepstack_merger_list.0.norm.weight", falls back to QWEN3_4B and
the text encoder emits a single 2560-dim layer instead of the 12 tapped layers
that Krea2 requires ("expects conditioning with 12x2560=30720 features but got
2560"). Affects all backends, not XPU-specific.

- add CLIP_VISION_SD_MAP_QWEN3VL: Qwen3-VL differs from Qwen2-VL -- merger is
  {norm, linear_fc1, linear_fc2} (not {ln_q, mlp.0, mlp.2}), blocks use a fused
  attn.qkv (not split attn_q/k/v) and mlp.linear_fc1/linear_fc2 (not
  mlp.up_proj/down_proj). Keys are emitted in HF "model.visual.*" layout so
  detect_te_model() can identify Qwen3-VL before the KREA2 branch rewrites the
  prefix.
- add qwen3vl_deepstack_remap(): GGUF indexes DeepStack mergers by source vision
  layer (4B: [5, 11, 17]; 8B/32B: [8, 16, 24]) while ComfyUI expects a
  sequential list 0..N-1. Indices are derived by sorting the layer ids found in
  the file, so nothing is hardcoded per model size.
- gate on arch in ("qwen2vl", "qwen3vl") and pass arch through to the loader.
  qwen2vl behaviour is unchanged (arch defaults to None).

Verified against the authoritative qwen3vl_4b_fp8_scaled.safetensors layout
(315/315 keys, missing=0 / unexpected=0 / shape mismatch=0, cosine ~1.000) and
on hardware: Intel Arc B580, Krea2 sampling completes at 2.85 s/it with
Krea2RMSNorm shape=[400, 12, 2560].

Supersedes the Qwen3-VL mmproj part of city96#473 (see comment there: "v.deepstast."
typo and layer-index remap bound to a non-existent "ck." prefix).
Related: city96#464.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant