sgl-project/sglang · error · ValueError

qkv_proj weight {name}: unexpected shape {tuple(loaded_weigh

Error message

qkv_proj weight {name}: unexpected shape {tuple(loaded_weight.shape)}; expected sharded {tuple(param.shape)}

What it means

The qkv_proj weight tensor loaded from the checkpoint has a different number of dimensions or trailing dimensions than the target parameter after accounting for TP sharding. The loader cannot map such a tensor onto the fused-qkv parameter.

Source

Thrown at python/sglang/srt/models/mimo_v2.py:129

        raise ValueError(
            f"MiMoV2 fused qkv_proj checkpoint is TP={expected_fused_tp_size}-"
            f"interleaved; got attention tp_size={tp_size} while loading {name}."
        )

    is_scale_inv = "weight_scale_inv" in name

    if is_scale_inv and ckpt_tp != tp_size:
        if deferred_scale_inv is not None:
            deferred_scale_inv[name] = loaded_weight.clone()
            return
        raise ValueError(
            f"qkv_proj scale_inv {name}: shape mismatch "
            f"{tuple(loaded_weight.shape)} vs {tuple(param.shape)} "
            f"due to block quantization ceiling; pass deferred_scale_inv dict"
        )

    if loaded_weight.ndim != param.ndim or loaded_weight.shape[1:] != param.shape[1:]:
        raise ValueError(
            f"qkv_proj weight {name}: unexpected shape {tuple(loaded_weight.shape)}; "
            f"expected sharded {tuple(param.shape)}"
        )

    if tp_size == ckpt_tp:
        fused_shape = (param.shape[0] * tp_size, *param.shape[1:])
        if tuple(loaded_weight.shape) != fused_shape:
            raise ValueError(
                f"qkv_proj weight {name}: unexpected shape "
                f"{tuple(loaded_weight.shape)}; expected fused {fused_shape} "
                f"or sharded {tuple(param.shape)}"
            )
        default_weight_loader(param, loaded_weight.chunk(tp_size, dim=0)[tp_rank])
    else:
        shards_per_rank = ckpt_tp // tp_size
        shards = loaded_weight.chunk(ckpt_tp, dim=0)
        merged = torch.cat(
            shards[tp_rank * shards_per_rank : (tp_rank + 1) * shards_per_rank],

View on GitHub (pinned to 0132848349)

Solutions

  1. Verify checkpoint hidden_size matches the model config
  2. Re-convert/re-export the checkpoint so q/k/v weights are fused in the qkv_proj layout the model expects
  3. If the tensor is transposed/reshaped, fix the conversion script so ndim and trailing dims match param.shape[1:]
Defensive patterns

Strategy: validation

Validate before calling

w = checkpoints[name]
if w.ndim != param.ndim or w.shape[1:] != param.shape[1:]:
    raise SystemExit(f'bad tensor {name}: {tuple(w.shape)} vs {tuple(param.shape)}')

Type guard

def tensor_fits(w: torch.Tensor, param: torch.Tensor) -> bool:
    return w.ndim == param.ndim and w.shape[1:] == param.shape[1:]

Prevention

When it happens

Trigger: loaded_weight.ndim != param.ndim or loaded_weight.shape[1:] != param.shape[1:] in load_mimo_v2_qkv_proj_weight — e.g. a 3-D/transposed checkpoint tensor, or a checkpoint whose hidden dimension differs from config hidden_size.

Common situations: Loading a checkpoint fine-tuned or converted for a different config (hidden_size mismatch), corrupted safetensors, or a non-fused q/k/v layout fed into the fused-qkv loader.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/61ad60528640012c. Report an issue: GitHub.