Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions tests/model_executor/layers/test_linear_missing_param.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project

import pytest
import torch
import torch.nn as nn

from vllm.model_executor.layers.linear import MergedColumnParallelLinear


class DummyLayer(nn.Module):
"""A dummy layer to test weight loading without distributed GPU state."""

def __init__(self):
super().__init__()
self.prefix = "dummy_layer"

def validate_shard_id(self, shard_id: int | None) -> None:
pass


def test_linear_missing_parameter_raises_clear_error():
"""Verify loading an undeclared weight triggers ValueError."""
layer = DummyLayer()

# Bind the actual vLLM method to our dummy layer to test its logic safely
layer.load_weights = MergedColumnParallelLinear.load_weights.__get__(layer)

# Simulate a checkpoint carrying an unexpected tensor
fake_weights = [("unexpected_scale", torch.tensor([1.0, 2.0]))]

with pytest.raises(ValueError, match="no such parameter, got DummyLayer instead"):
list(layer.load_weights(fake_weights))
20 changes: 20 additions & 0 deletions vllm/model_executor/layers/linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,16 @@ def load_weights(
param = getattr(self, name, self)
if param is None and name == "bias":
continue

if not isinstance(param, torch.nn.Parameter):
raise ValueError(
f"{self.prefix}: cannot load {name!r} — no such "
f"parameter, got {type(param).__name__} instead. "
f"This usually means the checkpoint carries a "
f"tensor the layer does not declare, e.g. a "
f"quantization scale on an unquantized layer."
)

param.weight_loader(param, loaded_weight, shard_id)
logger.debug(
"Loaded shard %s with shape %s into %s.%s",
Expand Down Expand Up @@ -1318,6 +1328,16 @@ def load_weights(
param = getattr(self, name, self)
if param is None and name == "bias":
continue

if not isinstance(param, Parameter):
raise ValueError(
f"{self.prefix}: cannot load {name!r} — no such "
f"parameter, got {type(param).__name__} instead. "
f"This usually means the checkpoint carries a "
f"tensor the layer does not declare, e.g. a "
f"quantization scale on an unquantized layer."
)

param.weight_loader(param, loaded_weight, shard_id)
logger.debug(
"Loaded shard %s with shape %s into %s.%s",
Expand Down
Loading