diff --git a/tests/models/test_utils.py b/tests/models/test_utils.py index 8d47b4436575..9efbba8eb77a 100644 --- a/tests/models/test_utils.py +++ b/tests/models/test_utils.py @@ -89,82 +89,6 @@ def weight_generator(): assert new_mod.nested_mod.bn.num_batches_tracked.item() == 1 -@pytest.mark.cpu_test -def test_module_skip_prefix(): - """Ensure the auto weight loader can skip prefix.""" - mod = ModuleWithNestedBatchNorm() - # Run some data through the module with batchnorm - mod(torch.Tensor([[1, 2], [3, 4]])) - - # Try to load the weights to a new instance - def weight_generator(): - # weights needed to be filtered out - redundant_weights = { - "prefix.bn.weight": torch.Tensor([1, 2]), - "prefix.bn.bias": torch.Tensor([3, 4]), - } - yield from (mod.state_dict() | redundant_weights).items() - - new_mod = ModuleWithNestedBatchNorm() - - assert not torch.all( - new_mod.nested_mod.bn.running_mean == mod.nested_mod.bn.running_mean - ) - assert not torch.all( - new_mod.nested_mod.bn.running_var == mod.nested_mod.bn.running_var - ) - assert new_mod.nested_mod.bn.num_batches_tracked.item() == 0 - - loader = AutoWeightsLoader(new_mod, skip_prefixes=["prefix."]) - loader.load_weights(weight_generator()) - - # Ensure the stats are updated - assert torch.all( - new_mod.nested_mod.bn.running_mean == mod.nested_mod.bn.running_mean - ) - assert torch.all(new_mod.nested_mod.bn.running_var == mod.nested_mod.bn.running_var) - assert new_mod.nested_mod.bn.num_batches_tracked.item() == 1 - - -@pytest.mark.cpu_test -def test_module_skip_substr(): - """Ensure the auto weight loader can skip prefix.""" - mod = ModuleWithNestedBatchNorm() - # Run some data through the module with batchnorm - mod(torch.Tensor([[1, 2], [3, 4]])) - - # Try to load the weights to a new instance - def weight_generator(): - # weights needed to be filtered out - redundant_weights = { - "nested_mod.0.substr.weight": torch.Tensor([1, 2]), - "nested_mod.0.substr.bias": torch.Tensor([3, 4]), - "nested_mod.substr.weight": torch.Tensor([1, 2]), - "nested_mod.substr.bias": torch.Tensor([3, 4]), - } - yield from (mod.state_dict() | redundant_weights).items() - - new_mod = ModuleWithNestedBatchNorm() - - assert not torch.all( - new_mod.nested_mod.bn.running_mean == mod.nested_mod.bn.running_mean - ) - assert not torch.all( - new_mod.nested_mod.bn.running_var == mod.nested_mod.bn.running_var - ) - assert new_mod.nested_mod.bn.num_batches_tracked.item() == 0 - - loader = AutoWeightsLoader(new_mod, skip_substrs=["substr."]) - loader.load_weights(weight_generator()) - - # Ensure the stats are updated - assert torch.all( - new_mod.nested_mod.bn.running_mean == mod.nested_mod.bn.running_mean - ) - assert torch.all(new_mod.nested_mod.bn.running_var == mod.nested_mod.bn.running_var) - assert new_mod.nested_mod.bn.num_batches_tracked.item() == 1 - - class raise_if_cuda_sync: def __enter__(self): self.previous_debug_mode = torch.cuda.get_sync_debug_mode() diff --git a/tests/v1/shutdown/test_startup_error.py b/tests/v1/shutdown/test_startup_error.py index 03982aa48e71..617fa6439c0e 100644 --- a/tests/v1/shutdown/test_startup_error.py +++ b/tests/v1/shutdown/test_startup_error.py @@ -61,7 +61,7 @@ def test_async_llm_startup_error( pytest.skip(reason="Not enough CUDA devices") # Monkeypatch an error in the model. - monkeypatch.setattr(LlamaForCausalLM, failing_method, evil_method) + monkeypatch.setattr(LlamaForCausalLM, failing_method, evil_method, raising=False) engine_args = AsyncEngineArgs( model=model, enforce_eager=True, tensor_parallel_size=tensor_parallel_size diff --git a/vllm/distributed/weight_transfer/ipc_engine.py b/vllm/distributed/weight_transfer/ipc_engine.py index f1b6070893bf..3736f026605e 100644 --- a/vllm/distributed/weight_transfer/ipc_engine.py +++ b/vllm/distributed/weight_transfer/ipc_engine.py @@ -20,6 +20,7 @@ WeightTransferInitInfo, WeightTransferUpdateInfo, ) +from vllm.model_executor.model_loader.utils import autoload_weights if TYPE_CHECKING: from vllm.config import VllmConfig @@ -274,7 +275,7 @@ def receive_weights(self, update_info: IPCWeightTransferUpdateInfo) -> None: weight = rebuild_cuda_tensor(*list_args) weights.append((name, weight)) - self.model.load_weights(weights) + autoload_weights(self.model, weights) def shutdown(self) -> None: pass diff --git a/vllm/distributed/weight_transfer/nccl_engine.py b/vllm/distributed/weight_transfer/nccl_engine.py index 5838a8ba8a1d..7551bfa02e2e 100644 --- a/vllm/distributed/weight_transfer/nccl_engine.py +++ b/vllm/distributed/weight_transfer/nccl_engine.py @@ -27,6 +27,7 @@ DEFAULT_PACKED_NUM_BUFFERS, packed_nccl_broadcast_consumer, ) +from vllm.model_executor.model_loader.utils import autoload_weights # Re-exported for backward compatibility; canonical home is nccl_common. __all__ = [ @@ -177,11 +178,14 @@ def state_dict_info_iterator(): dtype = getattr(torch, dtype_name) yield (name, (shape, dtype)) + def load_weights(w: list[tuple[str, torch.Tensor]]) -> None: + autoload_weights(self.model, w) + packed_nccl_broadcast_consumer( iterator=state_dict_info_iterator(), group=self.model_update_group, src=0, - post_unpack_func=self.model.load_weights, + post_unpack_func=load_weights, buffer_size_bytes=update_info.packed_buffer_size_bytes, num_buffers=update_info.packed_num_buffers, device=self.device, @@ -196,7 +200,7 @@ def state_dict_info_iterator(): self.model_update_group.broadcast( weight, src=0, stream=torch.cuda.current_stream() ) - self.model.load_weights([(name, weight)]) + autoload_weights(self.model, [(name, weight)]) del weight def shutdown(self) -> None: diff --git a/vllm/model_executor/layers/linear.py b/vllm/model_executor/layers/linear.py index c0dbc776acb1..1438f3e00da7 100644 --- a/vllm/model_executor/layers/linear.py +++ b/vllm/model_executor/layers/linear.py @@ -973,6 +973,9 @@ class QKVParallelLinear(ColumnParallelLinear): (e.g. model.layers.0.qkv_proj) return_bias: If true, return bias together with outputs in forward pass. disable_tp: If true, weights matrix won't be sharded through tp rank. + v_head_size: size of each attention value head. + If None, assume v_head_size = head_size. + fused_qkv_interleaved: If true, QKV weights are fused and interleaved on disk. """ def __init__( @@ -990,10 +993,12 @@ def __init__( return_bias: bool = True, disable_tp: bool = False, v_head_size: int | None = None, + fused_qkv_interleaved: bool = False, ): self.hidden_size = hidden_size self.head_size = head_size self.v_head_size = v_head_size if v_head_size is not None else head_size + self.fused_qkv_interleaved = fused_qkv_interleaved self.total_num_heads = total_num_heads if total_num_kv_heads is None: total_num_kv_heads = total_num_heads @@ -1054,6 +1059,27 @@ def _get_shard_size_mapping(self, loaded_shard_id: str): } return shard_size_mapping.get(loaded_shard_id) + def _deinterleave_fused_qkv(self, loaded_weight: torch.Tensor) -> torch.Tensor: + """De-interleave a per-KV-group fused qkv weight/bias to [Q|K|V]. + + The on-disk layout groups each KV head's query heads, key and value + together: ``[q_0..q_{g-1}, k, v]`` repeated per KV head, where + ``g = total_num_heads // total_num_kv_heads``. This reorders it to the + block-contiguous ``[Q_all | K_all | V_all]`` that the fused split below + expects. Operates on the output dim (0); trailing dims (hidden, or none + for a bias) are preserved. Assumes a uniform head size across q/k/v. + """ + heads = self.total_num_heads + kv_heads = self.total_num_kv_heads + hs = self.head_size + groups = heads // kv_heads + rest = loaded_weight.shape[1:] + x = loaded_weight.reshape(kv_heads, groups + 2, hs, *rest) + q = x[:, :groups].reshape(heads * hs, *rest) + k = x[:, groups : groups + 1].reshape(kv_heads * hs, *rest) + v = x[:, groups + 1 : groups + 2].reshape(kv_heads * hs, *rest) + return torch.cat((q, k, v), dim=0) + def _load_fused_module_from_checkpoint( self, param: BasevLLMParameter, loaded_weight: torch.Tensor ): @@ -1066,6 +1092,8 @@ def _load_fused_module_from_checkpoint( An example of a model with these fused layers: https://huggingface.co/microsoft/Phi-3-mini-4k-instruct """ + if self.fused_qkv_interleaved: + loaded_weight = self._deinterleave_fused_qkv(loaded_weight) shard_offsets = [ # (shard_id, shard_offset, shard_size) ("q", 0, self.total_num_heads * self.head_size), @@ -1173,6 +1201,8 @@ def weight_loader( assert param_data.shape == loaded_weight.shape param_data.copy_(loaded_weight) return + if self.fused_qkv_interleaved: + loaded_weight = self._deinterleave_fused_qkv(loaded_weight) shard_offsets = [ # (shard_id, shard_offset, shard_size) ("q", 0, self.total_num_heads * self.head_size), diff --git a/vllm/model_executor/model_loader/bitsandbytes_loader.py b/vllm/model_executor/model_loader/bitsandbytes_loader.py index cc9af05af726..fd1625d1c120 100644 --- a/vllm/model_executor/model_loader/bitsandbytes_loader.py +++ b/vllm/model_executor/model_loader/bitsandbytes_loader.py @@ -31,7 +31,7 @@ RowParallelLinear, ) from vllm.model_executor.model_loader.base_loader import BaseModelLoader -from vllm.model_executor.model_loader.utils import ParamMapping +from vllm.model_executor.model_loader.utils import ParamMapping, autoload_weights from vllm.model_executor.model_loader.weight_utils import ( download_safetensors_index_file_from_hf, download_weights_from_hf, @@ -336,9 +336,8 @@ def _unquantized_generator( global_tp_size = get_tensor_model_parallel_world_size() global_tp_rank = get_tensor_model_parallel_rank() - check_match = ( - lambda weight_name, module_name: weight_name.removesuffix(".weight") - == module_name + check_match = lambda weight_name, module_name: ( + weight_name.removesuffix(".weight") == module_name ) for ( org_weight_name, @@ -524,12 +523,6 @@ def _verify_model_compatibility( """ Verify that the model is compatible with BitsAndBytes quantization. """ - if not hasattr(model, "load_weights"): - raise AttributeError( - "The required method 'load_weights' is not defined in class" - f" {type(model).__name__}." - ) - if not hasattr(model, "packed_modules_mapping"): raise AttributeError( f"Model {type(model).__name__} does not support BitsAndBytes " @@ -808,7 +801,7 @@ def load_weights(self, model: nn.Module, model_config: ModelConfig) -> None: model_config.revision, ) weights_to_load = {name for name, _ in model.named_parameters()} - loaded_weights = model.load_weights(qweight_iterator) + loaded_weights = autoload_weights(model, qweight_iterator) # Some models may have weights loading tracker unimplemented. if loaded_weights is not None: weights_not_loaded = weights_to_load - loaded_weights diff --git a/vllm/model_executor/model_loader/default_loader.py b/vllm/model_executor/model_loader/default_loader.py index 3ea76f4d9b3a..6c57da8514c7 100644 --- a/vllm/model_executor/model_loader/default_loader.py +++ b/vllm/model_executor/model_loader/default_loader.py @@ -19,6 +19,7 @@ from vllm.model_executor.model_loader.ep_weight_filter import ( compute_local_expert_ids, ) +from vllm.model_executor.model_loader.utils import autoload_weights from vllm.model_executor.model_loader.weight_utils import ( download_safetensors_index_file_from_hf, download_weights_from_hf, @@ -424,7 +425,8 @@ def load_weights(self, model: nn.Module, model_config: ModelConfig) -> None: self._init_ep_weight_filter(model_config) - loaded_weights = model.load_weights(self.get_all_weights(model_config, model)) + weights = self.get_all_weights(model_config, model) + loaded_weights = autoload_weights(model, weights) self.counter_after_loading_weights = time.perf_counter() logger.info_once( diff --git a/vllm/model_executor/model_loader/runai_streamer_loader.py b/vllm/model_executor/model_loader/runai_streamer_loader.py index 3f30a42fe406..d41810de548c 100644 --- a/vllm/model_executor/model_loader/runai_streamer_loader.py +++ b/vllm/model_executor/model_loader/runai_streamer_loader.py @@ -10,6 +10,7 @@ from vllm.config import ModelConfig from vllm.config.load import LoadConfig from vllm.model_executor.model_loader.base_loader import BaseModelLoader +from vllm.model_executor.model_loader.utils import autoload_weights from vllm.model_executor.model_loader.weight_utils import ( download_safetensors_index_file_from_hf, download_weights_from_hf, @@ -135,6 +136,5 @@ def load_weights(self, model: nn.Module, model_config: ModelConfig) -> None: model_weights = model_config.model if model_weights_override := model_config.model_weights: model_weights = model_weights_override - model.load_weights( - self._get_weights_iterator(model_weights, model_config.revision) - ) + weights = self._get_weights_iterator(model_weights, model_config.revision) + autoload_weights(model, weights) diff --git a/vllm/model_executor/model_loader/tensorizer_loader.py b/vllm/model_executor/model_loader/tensorizer_loader.py index 338f9eac072a..9c10cfa0d059 100644 --- a/vllm/model_executor/model_loader/tensorizer_loader.py +++ b/vllm/model_executor/model_loader/tensorizer_loader.py @@ -20,6 +20,7 @@ tensorizer_weights_iterator, ) from vllm.model_executor.model_loader.utils import ( + autoload_weights, get_model_architecture, initialize_model, ) @@ -83,7 +84,7 @@ def _load_model_serialized_cpu( with torch.device(device_config.device): model = initialize_model(vllm_config=vllm_config, prefix=prefix) - model.load_weights(self._get_weights_iterator()) + autoload_weights(model, self._get_weights_iterator()) return model.eval() def download_model(self, model_config: ModelConfig) -> None: @@ -110,7 +111,7 @@ def load_weights(self, model: nn.Module, model_config: ModelConfig) -> None: tensorizer_config = self._patch_tensorizer_config(model_config) deserialize_tensorizer_model(model, tensorizer_config) else: - model.load_weights(self._get_weights_iterator()) + autoload_weights(model, self._get_weights_iterator()) def load_model( self, vllm_config: VllmConfig, model_config: ModelConfig, prefix: str = "" diff --git a/vllm/model_executor/model_loader/utils.py b/vllm/model_executor/model_loader/utils.py index 3367f4833e6c..233db1b35e21 100644 --- a/vllm/model_executor/model_loader/utils.py +++ b/vllm/model_executor/model_loader/utils.py @@ -4,6 +4,7 @@ import inspect import warnings +from collections.abc import Iterable from contextlib import contextmanager from dataclasses import dataclass, field from typing import Any @@ -310,3 +311,23 @@ def configure_quant_config( quant_config.apply_vllm_mapper(hf_to_vllm_mapper.get_unstacked_mapper()) if packed_mapping is not None: quant_config.packed_modules_mapping = packed_mapping + + +def autoload_weights( + model: nn.Module, weights: Iterable[tuple[str, torch.Tensor]] +) -> set[str]: + """Load `weights` into `model` via its `load_weights`, or AutoWeightsLoader. + + Models whose loading is fully handled by `AutoWeightsLoader` (mapper as a + class attribute, tied lm_head auto-skipped) need not define a trivial + `load_weights`. This is the single entry point every caller should use so + such models load correctly whether or not the method exists. + """ + # Imported lazily to avoid a circular import: `AutoWeightsLoader` lives in + # `models.utils`, which imports from `model_loader`. + from vllm.model_executor.models.utils import AutoWeightsLoader + + model_load_weights = getattr(model, "load_weights", None) + if callable(model_load_weights): + return model_load_weights(weights) + return AutoWeightsLoader(model).load_weights(weights) diff --git a/vllm/model_executor/models/AXK1.py b/vllm/model_executor/models/AXK1.py index 7818200dff5d..faa7d447137f 100644 --- a/vllm/model_executor/models/AXK1.py +++ b/vllm/model_executor/models/AXK1.py @@ -77,7 +77,6 @@ from .interfaces import MixtureOfExperts, SupportsEagle, SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, get_spec_layer_idx_from_weight_name, is_pp_missing_parameter, @@ -1140,7 +1139,3 @@ def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: num_experts=self.config.n_routed_experts, num_redundant_experts=0, ) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/adapters.py b/vllm/model_executor/models/adapters.py index cccd849681f2..1e3ea95b7306 100644 --- a/vllm/model_executor/models/adapters.py +++ b/vllm/model_executor/models/adapters.py @@ -219,7 +219,8 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): def default_load_weights(weights): loader = AutoWeightsLoader(self) - return loader.load_weights(weights) + mapper = getattr(self, "hf_to_vllm_mapper", None) + return loader.load_weights(weights, mapper=mapper) load_weights = getattr(super(), "load_weights", default_load_weights) return load_weights(mapped_weights) diff --git a/vllm/model_executor/models/afmoe.py b/vllm/model_executor/models/afmoe.py index 0122d019588a..e606f572fb0a 100644 --- a/vllm/model_executor/models/afmoe.py +++ b/vllm/model_executor/models/afmoe.py @@ -2,7 +2,6 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project """Inference-only AfMoE model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -43,7 +42,6 @@ ) from vllm.model_executor.models.llama import LlamaMLP as AfmoeMLP from vllm.model_executor.models.utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, extract_layer_index, @@ -591,7 +589,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/aimv2.py b/vllm/model_executor/models/aimv2.py index bc4b3e8cd080..a5d5fe0d3bab 100644 --- a/vllm/model_executor/models/aimv2.py +++ b/vllm/model_executor/models/aimv2.py @@ -225,13 +225,11 @@ def forward(self, pixel_values: torch.Tensor) -> torch.Tensor: return x def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - # post_trunk_norm is optional (absent for clip-skip backbones). - skip_prefixes=( - ["trunk.post_trunk_norm."] - if self.trunk.post_trunk_norm is None - else None - ), + # post_trunk_norm is optional (absent for clip-skip backbones). + drop = WeightsMapper( + orig_to_new_prefix={"trunk.post_trunk_norm.": None} + if self.trunk.post_trunk_norm is None + else {} ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) + loader = AutoWeightsLoader(self) + return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper | drop) diff --git a/vllm/model_executor/models/apertus.py b/vllm/model_executor/models/apertus.py index b997e153a994..12176dd63e40 100644 --- a/vllm/model_executor/models/apertus.py +++ b/vllm/model_executor/models/apertus.py @@ -25,7 +25,6 @@ # limitations under the License. """Inference-only Apertus model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -64,7 +63,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, extract_layer_index, @@ -489,10 +487,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/arcee.py b/vllm/model_executor/models/arcee.py index c32a903bba8b..e5accf34574d 100644 --- a/vllm/model_executor/models/arcee.py +++ b/vllm/model_executor/models/arcee.py @@ -8,7 +8,6 @@ # Inference-only Arcee (AFM) model – adds support for ReLU^2 feed-forward # activation. -from collections.abc import Iterable from itertools import islice from typing import Any @@ -36,7 +35,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, make_empty_intermediate_tensors_factory, @@ -280,12 +278,13 @@ class ArceeForCausalLM( runtime.""" hf_to_vllm_mapper = WeightsMapper( + orig_to_new_substr={"gate_proj": None}, orig_to_new_stacked={ # weight_name: (param_name, shard_id) ".q_proj": (".qkv_proj", "q"), ".k_proj": (".qkv_proj", "k"), ".v_proj": (".qkv_proj", "v"), - } + }, ) # Map fused module names to their submodule components # (for quantization and LoRA) @@ -352,15 +351,3 @@ def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None: def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor: return self.model.embed_input_ids(input_ids) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - """Load weights into the model (delegates to inner model and handles - tied embeddings).""" - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - skip_substrs=["gate_proj"], - ) - # AutoWeightLoader handles weight name remapping, including fusing - # separate q_proj, k_proj, v_proj into qkv_proj - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/arctic.py b/vllm/model_executor/models/arctic.py index fee9eaaac8d7..99d32cfc984b 100644 --- a/vllm/model_executor/models/arctic.py +++ b/vllm/model_executor/models/arctic.py @@ -44,7 +44,6 @@ from .interfaces import SupportsPP, SupportsQuant from .utils import ( - AutoWeightsLoader, extract_layer_index, is_pp_missing_parameter, make_empty_intermediate_tensors_factory, @@ -587,10 +586,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/aria.py b/vllm/model_executor/models/aria.py index 5117f541cfd0..480a1c6100ea 100644 --- a/vllm/model_executor/models/aria.py +++ b/vllm/model_executor/models/aria.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Literal import torch @@ -40,11 +40,7 @@ ) from .interfaces import MultiModalEmbeddings, SupportsMultiModal, SupportsQuant from .llama import LlamaDecoderLayer, LlamaMLP, LlamaModel -from .utils import ( - AutoWeightsLoader, - WeightsMapper, - maybe_prefix, -) +from .utils import WeightsMapper, maybe_prefix class AriaImagePixelInputs(TensorSchema): @@ -86,18 +82,15 @@ def __init__( self.post_layernorm = nn.Identity() hf_to_vllm_mapper = WeightsMapper( + # NOTE: post_layernorm is not used in Aria. + orig_to_new_substr={"post_layernorm": None}, orig_to_new_stacked={ ".q_proj": (".qkv_proj", "q"), ".k_proj": (".qkv_proj", "k"), ".v_proj": (".qkv_proj", "v"), - } + }, ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - # NOTE: post_layernorm is not used in Aria. - loader = AutoWeightsLoader(self, skip_substrs=["post_layernorm"]) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class AriaProjectorMLP(nn.Module): def __init__( @@ -534,7 +527,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader(self) - loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/audioflamingo3.py b/vllm/model_executor/models/audioflamingo3.py index e03baeda0cdb..7d21385f6ccc 100644 --- a/vllm/model_executor/models/audioflamingo3.py +++ b/vllm/model_executor/models/audioflamingo3.py @@ -17,7 +17,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Any, Literal, TypeAlias import torch @@ -62,11 +62,7 @@ SupportsMultiModal, SupportsPP, ) -from .utils import ( - AutoWeightsLoader, - init_vllm_registered_model, - maybe_prefix, -) +from .utils import init_vllm_registered_model, maybe_prefix class AudioFlamingo3FeatureInputs(TensorSchema): @@ -671,7 +667,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/bagel.py b/vllm/model_executor/models/bagel.py index 97cfe75e67de..32f7deed7c04 100644 --- a/vllm/model_executor/models/bagel.py +++ b/vllm/model_executor/models/bagel.py @@ -337,14 +337,28 @@ class BagelForConditionalGeneration( The image generation part is not supported in vLLM. """ - # Weight mapping from HF to vLLM hf_to_vllm_mapper = WeightsMapper( + # Skip generation-related weights since we only support text2text and image2text + # Filter out all image generation components: + # - 'moe_gen': MoE generation weights + # - 'latent_pos_embed': Latent position embeddings for VAE + # - 'llm2vae', 'vae2llm': LLM-VAE projections + # - 'time_embedder': Timestep embeddings for diffusion + # - VAE encoder/decoder: Use specific prefixes to avoid matching vision encoder + orig_to_new_substr={ + "moe_gen": None, + "latent_pos_embed": None, + "llm2vae": None, + "vae2llm": None, + "time_embedder": None, + }, orig_to_new_prefix={ - "language_model.": "language_model.", - "vit_model.": "vit_model.", - "connector.": "connector.", - "vit_pos_embed.": "vit_pos_embed.", - } + # VAE encoder/decoder, not vision encoder + "decoder.": None, + "encoder.": None, + # Skip vit_pos_embed.pos_embed as it's handled by PositionEmbedding module + "vit_pos_embed.pos_embed": None, + }, ) @classmethod @@ -539,33 +553,8 @@ def compute_logits( return self.language_model.compute_logits(hidden_states) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - """Load weights from checkpoint.""" - # Skip generation-related weights since we only support text2text and image2text - # Filter out all image generation components: - # - 'moe_gen': MoE generation weights - # - 'latent_pos_embed': Latent position embeddings for VAE - # - 'llm2vae', 'vae2llm': LLM-VAE projections - # - 'time_embedder': Timestep embeddings for diffusion - # - VAE encoder/decoder: Use specific prefixes to avoid matching vision encoder - generation_keywords = [ - "moe_gen", - "latent_pos_embed", - "llm2vae", - "vae2llm", - "time_embedder", - ] - vae_prefixes = [ - "decoder.", - "encoder.", - ] # VAE encoder/decoder, not vision encoder filtered_weights = [] for name, tensor in weights: - # Skip generation-related keywords - if any(skip in name for skip in generation_keywords): - continue - if any(name.startswith(prefix) for prefix in vae_prefixes): - continue - if "patch_embedding.weight" in name and tensor.ndim == 2: out_channels = tensor.shape[0] in_features = tensor.shape[1] @@ -579,6 +568,5 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: filtered_weights.append((name, tensor)) - # Skip vit_pos_embed.pos_embed as it's handled by PositionEmbedding module - loader = AutoWeightsLoader(self, skip_prefixes=["vit_pos_embed.pos_embed"]) + loader = AutoWeightsLoader(self) return loader.load_weights(filtered_weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/bailing_moe.py b/vllm/model_executor/models/bailing_moe.py index 642d07ee659d..4dab085370a9 100644 --- a/vllm/model_executor/models/bailing_moe.py +++ b/vllm/model_executor/models/bailing_moe.py @@ -474,10 +474,6 @@ def forward( hidden_states, _ = self.norm(hidden_states, residual) return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class BailingMoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA): packed_modules_mapping = { @@ -558,10 +554,7 @@ def _normalize_lm_head( yield name, loaded_weight def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.tie_word_embeddings else None), - ) + loader = AutoWeightsLoader(self) return loader.load_weights(self._normalize_lm_head(weights)) diff --git a/vllm/model_executor/models/bailing_moe_linear.py b/vllm/model_executor/models/bailing_moe_linear.py index 5cc057c3b458..271a513eaa98 100644 --- a/vllm/model_executor/models/bailing_moe_linear.py +++ b/vllm/model_executor/models/bailing_moe_linear.py @@ -55,7 +55,6 @@ from .interfaces import HasInnerState, IsHybrid, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, is_pp_missing_parameter, make_layers, @@ -813,9 +812,5 @@ def get_mamba_state_dtype_from_config( def get_mamba_state_copy_func(cls) -> tuple: return MambaStateCopyFuncCalculator.linear_attention_state_copy_func() - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: return self.model.get_expert_mapping() diff --git a/vllm/model_executor/models/bert.py b/vllm/model_executor/models/bert.py index 225f6c2bda7b..e86fa2b3d320 100644 --- a/vllm/model_executor/models/bert.py +++ b/vllm/model_executor/models/bert.py @@ -2,7 +2,9 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project from collections.abc import Iterable, Set +from dataclasses import replace +import regex as re import torch from torch import nn from transformers import BertConfig @@ -37,6 +39,7 @@ ) from vllm.model_executor.layers.quantization import QuantizationConfig from vllm.model_executor.layers.vocab_parallel_embedding import VocabParallelEmbedding +from vllm.model_executor.model_loader.utils import autoload_weights from vllm.sequence import IntermediateTensors from vllm.tasks import PoolingTask from vllm.v1.pool.metadata import PoolingMetadata @@ -370,6 +373,7 @@ class BertModel(nn.Module, SupportsQuant): packed_modules_mapping = {"qkv_proj": ["query", "key", "value"]} hf_to_vllm_mapper = WeightsMapper( + orig_to_new_prefix={"pooler.": None}, # Original google-bert checkpoints use the legacy `gamma`/`beta` # LayerNorm names; rename to vLLM's `weight`/`bias`. orig_to_new_substr={ @@ -414,13 +418,10 @@ def forward( return self.encoder(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["pooler."]) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class BertPoolingModel(BertModel): is_pooling_model = True + hf_to_vllm_mapper = replace(BertModel.hf_to_vllm_mapper, orig_to_new_prefix={}) def __init__( self, @@ -437,10 +438,6 @@ def __init__( self.pooler = BertPooler(vllm_config.model_config) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - @default_pooling_type(seq_pooling_type="CLS") class BertEmbeddingModel(nn.Module, SupportsQuant): @@ -456,6 +453,11 @@ class BertEmbeddingModel(nn.Module, SupportsQuant): is_pooling_model = True + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_regex={re.compile(r"^(?!model\.)"): "model."}, + orig_to_new_prefix={"model.lm_head.": None}, + ) + def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): super().__init__() @@ -484,16 +486,6 @@ def forward( intermediate_tensors=intermediate_tensors, ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - weights_list = list(weights) - - has_model_prefix = any(name.startswith("model.") for name, _ in weights_list) - if not has_model_prefix: - mapper = WeightsMapper(orig_to_new_prefix={"": "model."}) - - loader = AutoWeightsLoader(self, skip_prefixes=["lm_head."]) - return loader.load_weights(weights_list, mapper=mapper) - def _build_model(self, vllm_config: VllmConfig, prefix: str = "") -> BertModel: return BertModel( vllm_config=vllm_config, prefix=prefix, embedding_class=BertEmbedding @@ -737,7 +729,7 @@ def _strip(name: str) -> str: model_side.append((name, w)) loaded: set[str] = set() - loaded_model = self.model.load_weights(model_side) + loaded_model = autoload_weights(self.model, model_side) loaded.update({"model." + n for n in loaded_model}) if mlm_side: @@ -803,11 +795,6 @@ def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor: return self.bert.embed_input_ids(input_ids) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader(self) - loaded_params = loader.load_weights(weights) - return loaded_params - def forward( self, input_ids: torch.Tensor | None, @@ -856,11 +843,6 @@ def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor: return self.bert.embed_input_ids(input_ids) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader(self) - loaded_params = loader.load_weights(weights) - return loaded_params - def forward( self, input_ids: torch.Tensor | None, diff --git a/vllm/model_executor/models/bert_with_rope.py b/vllm/model_executor/models/bert_with_rope.py index 020ef993474a..eee36336c9a3 100644 --- a/vllm/model_executor/models/bert_with_rope.py +++ b/vllm/model_executor/models/bert_with_rope.py @@ -31,11 +31,7 @@ from vllm.model_executor.layers.rotary_embedding import get_rope from vllm.model_executor.layers.vocab_parallel_embedding import VocabParallelEmbedding from vllm.model_executor.model_loader.weight_utils import default_weight_loader -from vllm.model_executor.models.utils import ( - AutoWeightsLoader, - WeightsMapper, - maybe_prefix, -) +from vllm.model_executor.models.utils import WeightsMapper, maybe_prefix from vllm.model_executor.utils import set_weight_attrs from vllm.platforms import current_platform from vllm.sequence import IntermediateTensors @@ -706,11 +702,6 @@ def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): classifier=self.classifier, ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader(self) - loaded_params = loader.load_weights(weights) - return loaded_params - def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor: return self.new.embed_input_ids(input_ids) diff --git a/vllm/model_executor/models/blip.py b/vllm/model_executor/models/blip.py index aecb99716137..d01d5d04fa0f 100644 --- a/vllm/model_executor/models/blip.py +++ b/vllm/model_executor/models/blip.py @@ -324,11 +324,6 @@ def forward(self, pixel_values: torch.Tensor) -> torch.Tensor: return self.post_layernorm(hidden_states) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - skip_prefixes: list[str] = [] - if self.post_layernorm is None: - skip_prefixes.append("post_layernorm.") - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - # omit layers when num_hidden_layers_override is set def _filter(ws): for name, weight in ws: @@ -338,4 +333,8 @@ def _filter(ws): continue yield name, weight - return loader.load_weights(_filter(weights), mapper=self.hf_to_vllm_mapper) + mapper = self.hf_to_vllm_mapper + if self.post_layernorm is None: + mapper |= WeightsMapper(orig_to_new_prefix={"post_layernorm.": None}) + loader = AutoWeightsLoader(self) + return loader.load_weights(_filter(weights), mapper=mapper) diff --git a/vllm/model_executor/models/blip2.py b/vllm/model_executor/models/blip2.py index 49d2a5a89f5f..6f78e58bc076 100644 --- a/vllm/model_executor/models/blip2.py +++ b/vllm/model_executor/models/blip2.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Literal, TypeAlias import torch @@ -44,7 +44,7 @@ SupportsQuant, ) from .module_mapping import MultiModelKeys -from .utils import AutoWeightsLoader, init_vllm_registered_model, maybe_prefix +from .utils import init_vllm_registered_model, maybe_prefix class Blip2ImagePixelInputs(TensorSchema): @@ -693,10 +693,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - def get_mm_mapping(self) -> MultiModelKeys: return MultiModelKeys.from_string_field( language_model="language_model", diff --git a/vllm/model_executor/models/bloom.py b/vllm/model_executor/models/bloom.py index cdcf82f385f7..f927640d5371 100644 --- a/vllm/model_executor/models/bloom.py +++ b/vllm/model_executor/models/bloom.py @@ -20,9 +20,9 @@ """Inference-only BLOOM model compatible with HuggingFace weights.""" import math -from collections.abc import Iterable from itertools import islice +import regex as re import torch from torch import nn from transformers import BloomConfig @@ -51,7 +51,7 @@ from .interfaces import SupportsPP, SupportsQuant from .utils import ( - AutoWeightsLoader, + WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, maybe_prefix, @@ -107,6 +107,7 @@ def __init__( bias=True, quant_config=quant_config, prefix=f"{prefix}.query_key_value", + fused_qkv_interleaved=True, ) self.dense = RowParallelLinear( self.hidden_size, @@ -295,26 +296,13 @@ def forward( hidden_states = self.ln_f(hidden_states) return hidden_states - def _repack_qkv( - self, weights: Iterable[tuple[str, torch.Tensor]] - ) -> Iterable[tuple[str, torch.Tensor]]: - # BLOOM's fused QKV is laid out as (num_heads * 3 * head_size) on its - # output dim (0), while vLLM expects (3 * num_heads * head_size). - num_heads = self.config.num_attention_heads - for name, loaded_weight in weights: - if "query_key_value" in name: - shape = loaded_weight.shape - loaded_weight = loaded_weight.view((num_heads, 3, -1) + shape[1:]) - loaded_weight = loaded_weight.transpose(0, 1) - loaded_weight = loaded_weight.reshape(shape) - yield name, loaded_weight - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(self._repack_qkv(weights)) - class BloomForCausalLM(nn.Module, SupportsPP, SupportsQuant): + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_regex={re.compile(r"^(?!transformer\.)"): "transformer."}, + orig_to_new_prefix={"lm_head.weight": None}, + ) + def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): super().__init__() config = vllm_config.model_config.hf_config @@ -359,17 +347,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["lm_head.weight"]) - weights = _add_transformer_prefix(weights) - return loader.load_weights(weights) - - -def _add_transformer_prefix( - weights: Iterable[tuple[str, torch.Tensor]], -) -> Iterable[tuple[str, torch.Tensor]]: - for name, tensor in weights: - if not name.startswith("transformer."): - name = "transformer." + name - yield name, tensor diff --git a/vllm/model_executor/models/chameleon.py b/vllm/model_executor/models/chameleon.py index fec2fa640976..aeed481f9c4b 100644 --- a/vllm/model_executor/models/chameleon.py +++ b/vllm/model_executor/models/chameleon.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from functools import cached_property from itertools import islice from typing import Annotated, Any, Literal @@ -63,7 +63,6 @@ SupportsQuant, ) from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -1029,8 +1028,3 @@ def compute_logits( logits[:, image_tokens] = torch.finfo(logits.dtype).min return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - skip_prefixes = ["lm_head."] if self.config.tie_word_embeddings else None - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/chatglm.py b/vllm/model_executor/models/chatglm.py index 4363188ff6e1..db767355b985 100644 --- a/vllm/model_executor/models/chatglm.py +++ b/vllm/model_executor/models/chatglm.py @@ -5,7 +5,6 @@ """Inference-only ChatGLM model compatible with THUDM weights.""" import json -from collections.abc import Iterable from itertools import islice import torch @@ -35,7 +34,6 @@ from .interfaces import SupportsLoRA, SupportsPP, SupportsQuant from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -380,10 +378,6 @@ def forward( return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class ChatGLMBaseModel(nn.Module): def __init__( @@ -424,10 +418,6 @@ def compute_logits( logits = self.logits_processor(self.lm_head, hidden_states) return logits - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - class ChatGLMForCausalLM(ChatGLMBaseModel, SupportsLoRA, SupportsPP, SupportsQuant): packed_modules_mapping = { diff --git a/vllm/model_executor/models/clip.py b/vllm/model_executor/models/clip.py index 8919d65de360..0d454a43059b 100644 --- a/vllm/model_executor/models/clip.py +++ b/vllm/model_executor/models/clip.py @@ -611,10 +611,6 @@ def forward( return last_hidden_state - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class CLIPVisionTransformer(nn.Module): hf_to_vllm_mapper = WeightsMapper( @@ -706,11 +702,6 @@ def forward( return encoder_outputs def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - skip_prefixes: list[str] = [] - if self.post_layernorm is None: - skip_prefixes.append("post_layernorm.") - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - # Drop layers beyond num_hidden_layers_override. def _filter(ws): for name, w in ws: @@ -720,7 +711,11 @@ def _filter(ws): continue yield name, w - return loader.load_weights(_filter(weights), mapper=self.hf_to_vllm_mapper) + mapper = self.hf_to_vllm_mapper + if self.post_layernorm is None: + mapper |= WeightsMapper(orig_to_new_prefix={"post_layernorm.": None}) + loader = AutoWeightsLoader(self) + return loader.load_weights(_filter(weights), mapper=mapper) class CLIPVisionModel(nn.Module): @@ -773,6 +768,7 @@ def device(self): ) class CLIPEmbeddingModel(nn.Module, SupportsMultiModal, SupportsQuant): is_pooling_model = True + hf_to_vllm_mapper = WeightsMapper(orig_to_new_substr={".position_ids": None}) packed_modules_mapping = {"qkv_proj": ["q_proj", "k_proj", "v_proj"]} @@ -978,8 +974,6 @@ def forward( def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): loader = AutoWeightsLoader( self, - skip_substrs=[".position_ids"], ignore_unexpected_prefixes=["logit_scale."], ) - - return loader.load_weights(weights) + return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/cohere2_moe.py b/vllm/model_executor/models/cohere2_moe.py index b993247ec6f3..ed93ae5452ad 100644 --- a/vllm/model_executor/models/cohere2_moe.py +++ b/vllm/model_executor/models/cohere2_moe.py @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable from itertools import islice import torch @@ -37,7 +36,6 @@ from .commandr import LayerNorm from .interfaces import SupportsPP, SupportsQuant from .utils import ( - AutoWeightsLoader, WeightsMapper, extract_layer_index, make_empty_intermediate_tensors_factory, @@ -526,7 +524,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.logits_processor(self.model.embed_tokens, hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["lm_head."]) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/cohere2_vision.py b/vllm/model_executor/models/cohere2_vision.py index 302619a8dbe7..a25d447f919c 100644 --- a/vllm/model_executor/models/cohere2_vision.py +++ b/vllm/model_executor/models/cohere2_vision.py @@ -3,7 +3,7 @@ # Adapted from vllm/model_executor/models/aya_vision.py """Command-A-Vision (Cohere2Vision) multimodal model implementation for vLLM.""" -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Literal import torch @@ -52,7 +52,6 @@ ) from .siglip import SiglipVisionModel from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -366,10 +365,6 @@ def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): def dtype(self): return next(self.parameters()).dtype - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def _process_image_input( self, image_input: Cohere2VisionImagePixelInputs, **kwargs ) -> list[torch.Tensor]: diff --git a/vllm/model_executor/models/cohere_asr.py b/vllm/model_executor/models/cohere_asr.py index da74404139aa..05c57eaf97d4 100644 --- a/vllm/model_executor/models/cohere_asr.py +++ b/vllm/model_executor/models/cohere_asr.py @@ -2004,7 +2004,15 @@ class CohereAsrForConditionalGeneration( } hf_to_vllm_mapper = WeightsMapper( - orig_to_new_substr={".fc1.": ".mlp.fc1.", ".fc2.": ".mlp.fc2."} + orig_to_new_prefix={ + "model.preprocessor.featurizer.fb": None, + "model.preprocessor.featurizer.window": None, + }, + orig_to_new_substr={ + ".fc1.": ".mlp.fc1.", + ".fc2.": ".mlp.fc2.", + "model.conv.batch_norm.num_batches_tracked": None, + }, ) supports_transcription_only = True @@ -2258,15 +2266,7 @@ def transform(inputs): return name, loaded_weight - loader = AutoWeightsLoader( - self, - skip_prefixes=[ - "model.preprocessor.featurizer.fb", - "model.preprocessor.featurizer.window", - ], - skip_substrs=["model.conv.batch_norm.num_batches_tracked"], - ) - + loader = AutoWeightsLoader(self) return loader.load_weights( map(transform, weights), mapper=self.hf_to_vllm_mapper ) diff --git a/vllm/model_executor/models/cohere_eagle.py b/vllm/model_executor/models/cohere_eagle.py index 64ec0d6dd544..82ce5f0e716c 100644 --- a/vllm/model_executor/models/cohere_eagle.py +++ b/vllm/model_executor/models/cohere_eagle.py @@ -22,6 +22,7 @@ from .utils import ( AutoWeightsLoader, + WeightsMapper, get_draft_quant_config, maybe_prefix, process_eagle_weight, @@ -179,17 +180,14 @@ def _track_and_forward(inputs): process_eagle_weight(self, name) return name, weight - loader = AutoWeightsLoader( - self, - skip_prefixes=( - ["lm_head.", "model.embed_tokens."] - if self.config.tie_word_embeddings - else None - ), + drop = WeightsMapper( + orig_to_new_prefix={"model.embed_tokens.": None} + if self.config.tie_word_embeddings + else {} ) - + loader = AutoWeightsLoader(self) loaded_weight_names = loader.load_weights( - map(_track_and_forward, weights), mapper=self.hf_to_vllm_mapper + map(_track_and_forward, weights), mapper=self.hf_to_vllm_mapper | drop ) # Embed tokens are tied with the target model and therefore not diff --git a/vllm/model_executor/models/colbert.py b/vllm/model_executor/models/colbert.py index cc5483fd7b3f..4699e1f01979 100644 --- a/vllm/model_executor/models/colbert.py +++ b/vllm/model_executor/models/colbert.py @@ -25,7 +25,11 @@ from vllm.config import PoolerConfig, VllmConfig from vllm.model_executor.layers.pooler import Pooler from vllm.model_executor.layers.pooler.tokwise import pooler_for_token_embed -from vllm.model_executor.models.utils import AutoWeightsLoader, WeightsMapper +from vllm.model_executor.model_loader.utils import autoload_weights +from vllm.model_executor.models.utils import ( + AutoWeightsLoader, + WeightsMapper, +) from .bert import BertEmbeddingModel, BertModel from .interfaces import HasInnerState, IsHybrid, SupportsLateInteraction @@ -284,7 +288,7 @@ def forward( def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): other_weights, colbert_loaded = self._load_colbert_weights(weights) - loaded_model = self.model.load_weights(other_weights) + loaded_model = autoload_weights(self.model, other_weights) loaded = {f"model.{name}" for name in loaded_model} | colbert_loaded # When the ST projector is loaded via `_build_colbert_pooler`, the weights @@ -358,10 +362,10 @@ def forward( def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): other_weights, colbert_loaded = self._load_colbert_weights(weights) - mapper = WeightsMapper(orig_to_new_prefix={"roberta.": "model."}) - - # Skip HF pooler weights (model.pooler.*) as they not used in ColBERT - loader = AutoWeightsLoader(self, skip_prefixes=["model.pooler."]) + mapper = WeightsMapper( + orig_to_new_prefix={"roberta.": "model.", "model.pooler.": None} + ) + loader = AutoWeightsLoader(self) loaded = loader.load_weights(other_weights, mapper=mapper) return loaded | colbert_loaded @@ -441,7 +445,7 @@ def forward( def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): other_weights, colbert_loaded = self._load_colbert_weights(weights) - loaded_model = self.model.load_weights(other_weights) + loaded_model = autoload_weights(self.model, other_weights) loaded = {f"model.{name}" for name in loaded_model} | colbert_loaded diff --git a/vllm/model_executor/models/colqwen3_5.py b/vllm/model_executor/models/colqwen3_5.py index 1b481ea2f40d..ce262a1c1ded 100644 --- a/vllm/model_executor/models/colqwen3_5.py +++ b/vllm/model_executor/models/colqwen3_5.py @@ -237,11 +237,11 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: else: model_weights.append((name, weight)) - loader = AutoWeightsLoader( - self, - skip_prefixes=["mtp."], + drop = WeightsMapper(orig_to_new_prefix={"mtp.": None}) + loader = AutoWeightsLoader(self) + loaded = loader.load_weights( + model_weights, mapper=self.hf_to_vllm_mapper | drop ) - loaded = loader.load_weights(model_weights, mapper=self.hf_to_vllm_mapper) for name, weight in proj_weights: param_name = name.split(".")[-1] diff --git a/vllm/model_executor/models/commandr.py b/vllm/model_executor/models/commandr.py index 813e0a2f5f2e..1e663fe12697 100644 --- a/vllm/model_executor/models/commandr.py +++ b/vllm/model_executor/models/commandr.py @@ -23,7 +23,6 @@ # This file is based on the LLama model definition file in transformers """PyTorch Cohere model.""" -from collections.abc import Iterable from itertools import islice import torch @@ -44,16 +43,13 @@ from vllm.model_executor.layers.quantization import QuantizationConfig from vllm.model_executor.layers.rotary_embedding import get_rope from vllm.model_executor.layers.vocab_parallel_embedding import VocabParallelEmbedding -from vllm.model_executor.model_loader.weight_utils import ( - row_parallel_weight_loader, -) +from vllm.model_executor.model_loader.weight_utils import row_parallel_weight_loader from vllm.model_executor.utils import set_weight_attrs from vllm.platforms import current_platform from vllm.sequence import IntermediateTensors from .interfaces import SupportsLoRA, SupportsPP, SupportsQuant from .utils import ( - AutoWeightsLoader, WeightsMapper, extract_layer_index, make_empty_intermediate_tensors_factory, @@ -411,9 +407,3 @@ def compute_logits( ) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, skip_prefixes=["lm_head", "rotary_emb.inv_freq"] - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/cosmos3_edge.py b/vllm/model_executor/models/cosmos3_edge.py index be61d564ccf2..52e4243d9cbd 100644 --- a/vllm/model_executor/models/cosmos3_edge.py +++ b/vllm/model_executor/models/cosmos3_edge.py @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable import torch import torch.nn as nn @@ -48,15 +47,8 @@ Qwen3VLMultiModalProcessor, Qwen3VLProcessingInfo, ) -from .utils import ( - AutoWeightsLoader, - WeightsMapper, - maybe_prefix, -) -from .vision import ( - is_vit_use_data_parallel, - run_dp_sharded_mrope_vision_model, -) +from .utils import WeightsMapper, maybe_prefix +from .vision import is_vit_use_data_parallel, run_dp_sharded_mrope_vision_model class Cosmos3EdgeVisionEncoder(Siglip2VisionTransformer): @@ -728,10 +720,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: return MultiModelKeys.from_string_field( language_model="language_model", diff --git a/vllm/model_executor/models/dbrx.py b/vllm/model_executor/models/dbrx.py index c28cf939241f..b3e2c9b6f88f 100644 --- a/vllm/model_executor/models/dbrx.py +++ b/vllm/model_executor/models/dbrx.py @@ -39,7 +39,6 @@ from .interfaces import SupportsPP from .utils import ( - AutoWeightsLoader, is_pp_missing_parameter, make_empty_intermediate_tensors_factory, make_layers, @@ -464,7 +463,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/deepencoder.py b/vllm/model_executor/models/deepencoder.py index fffd9382dd78..922c664fb7d0 100644 --- a/vllm/model_executor/models/deepencoder.py +++ b/vllm/model_executor/models/deepencoder.py @@ -10,7 +10,6 @@ # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. import math -from collections.abc import Iterable from functools import partial import torch @@ -24,7 +23,6 @@ from vllm.model_executor.layers.quantization import QuantizationConfig from .clip import CLIPEncoder, CLIPVisionEmbeddings -from .utils import AutoWeightsLoader class MLPBlock(nn.Module): @@ -669,7 +667,3 @@ def forward( return_all_hidden_states=select_layers is not None, ) return encoder_outputs - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/deepseek_eagle.py b/vllm/model_executor/models/deepseek_eagle.py index 76e90e327655..0045090213be 100644 --- a/vllm/model_executor/models/deepseek_eagle.py +++ b/vllm/model_executor/models/deepseek_eagle.py @@ -250,8 +250,5 @@ def transform(inputs): process_eagle_weight(self, name) return name, loaded_weight - loader = AutoWeightsLoader( - self, - skip_prefixes=None, - ) + loader = AutoWeightsLoader(self) loader.load_weights(map(transform, weights)) diff --git a/vllm/model_executor/models/deepseek_eagle3.py b/vllm/model_executor/models/deepseek_eagle3.py index 71ce971d530b..8676285e9981 100644 --- a/vllm/model_executor/models/deepseek_eagle3.py +++ b/vllm/model_executor/models/deepseek_eagle3.py @@ -275,10 +275,6 @@ def forward( }, ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Eagle3DeepseekV2ForCausalLM(LocalArgmaxMixin, DeepseekV2ForCausalLM): """Eagle3 speculative decoding model for DeepseekV2/V3.""" @@ -391,18 +387,15 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): model_weights[name] = loaded_weight process_eagle_weight(self, name) - skip_substrs = [] + orig_to_new_substr = {} if not includes_draft_id_mapping: - skip_substrs.append("draft_id_to_target_id") + orig_to_new_substr["draft_id_to_target_id"] = None if not includes_embed_tokens: - skip_substrs.append("embed_tokens") + orig_to_new_substr["embed_tokens"] = None - loader = AutoWeightsLoader( - self, - skip_prefixes=None, - skip_substrs=skip_substrs, - ) - loader.load_weights(model_weights.items()) + drop = WeightsMapper(orig_to_new_substr=orig_to_new_substr) + loader = AutoWeightsLoader(self) + loader.load_weights(model_weights.items(), mapper=drop) # Aliases for compatibility diff --git a/vllm/model_executor/models/deepseek_ocr.py b/vllm/model_executor/models/deepseek_ocr.py index b811afafb0e8..3b2ba1c2fa46 100644 --- a/vllm/model_executor/models/deepseek_ocr.py +++ b/vllm/model_executor/models/deepseek_ocr.py @@ -22,7 +22,6 @@ ) from vllm.model_executor.models.module_mapping import MultiModelKeys from vllm.model_executor.models.utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -616,11 +615,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - autoloaded_weights = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - return autoloaded_weights - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/deepseek_ocr2.py b/vllm/model_executor/models/deepseek_ocr2.py index 70f50ea7d445..ea8e209e3471 100644 --- a/vllm/model_executor/models/deepseek_ocr2.py +++ b/vllm/model_executor/models/deepseek_ocr2.py @@ -3,7 +3,7 @@ """Inference-only Deepseek-OCR model compatible with HuggingFace weights.""" import math -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from functools import partial import torch @@ -21,7 +21,6 @@ ) from vllm.model_executor.models.module_mapping import MultiModelKeys from vllm.model_executor.models.utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -438,11 +437,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - autoloaded_weights = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - return autoloaded_weights - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/deepseek_v2.py b/vllm/model_executor/models/deepseek_v2.py index daf4ea3de9f3..fb0857a006a5 100644 --- a/vllm/model_executor/models/deepseek_v2.py +++ b/vllm/model_executor/models/deepseek_v2.py @@ -85,7 +85,6 @@ maybe_remap_kv_scale_name, ) from vllm.model_executor.models.utils import ( - AutoWeightsLoader, extract_layer_index, sequence_parallel_chunk, ) @@ -1904,10 +1903,6 @@ def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: num_redundant_experts=0, ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - class DeepseekForCausalLM(DeepseekV2ForCausalLM): pass diff --git a/vllm/model_executor/models/deepseek_vl2.py b/vllm/model_executor/models/deepseek_vl2.py index b5ad00914bf3..51c0f8425f8d 100644 --- a/vllm/model_executor/models/deepseek_vl2.py +++ b/vllm/model_executor/models/deepseek_vl2.py @@ -5,7 +5,7 @@ """Inference-only Deepseek-VL2 model compatible with HuggingFace weights.""" import math -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Literal, TypeAlias import torch @@ -52,12 +52,7 @@ from vllm.utils.torch_utils import set_default_torch_dtype from .interfaces import MultiModalEmbeddings, SupportsMultiModal, SupportsPP -from .utils import ( - AutoWeightsLoader, - WeightsMapper, - init_vllm_registered_model, - maybe_prefix, -) +from .utils import WeightsMapper, init_vllm_registered_model, maybe_prefix # The image token id may be various _IMAGE_TOKEN = "" @@ -619,8 +614,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - autoloaded_weights = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - return autoloaded_weights diff --git a/vllm/model_executor/models/dots_ocr.py b/vllm/model_executor/models/dots_ocr.py index 65298a5fd323..5798bedc8368 100644 --- a/vllm/model_executor/models/dots_ocr.py +++ b/vllm/model_executor/models/dots_ocr.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable, Mapping +from collections.abc import Mapping from typing import Annotated, Literal, TypeAlias import torch @@ -47,7 +47,6 @@ Qwen2VLProcessingInfo, ) from vllm.model_executor.models.utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -751,10 +750,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/eagle2_5_vl.py b/vllm/model_executor/models/eagle2_5_vl.py index 30b8173f19cf..5411ae79f8bf 100644 --- a/vllm/model_executor/models/eagle2_5_vl.py +++ b/vllm/model_executor/models/eagle2_5_vl.py @@ -3,7 +3,6 @@ # Adapted from NVIDIA Eagle2.5-VL model # https://huggingface.co/nvidia/Eagle2.5-8B -from collections.abc import Iterable from typing import Annotated, Literal, TypeAlias import torch @@ -33,7 +32,7 @@ BaseInternVLMultiModalProcessor, BaseInternVLProcessingInfo, ) -from .utils import AutoWeightsLoader, init_vllm_registered_model, maybe_prefix +from .utils import init_vllm_registered_model, maybe_prefix class Eagle2_5_VLImagePixelInputs(TensorSchema): @@ -402,11 +401,6 @@ def compute_logits( """Compute logits from hidden states.""" return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - """Load model weights.""" - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - def get_mm_mapping(self) -> MultiModelKeys: """Get the module prefix mapping for multimodal models.""" return MultiModelKeys.from_string_field( diff --git a/vllm/model_executor/models/ernie45_moe.py b/vllm/model_executor/models/ernie45_moe.py index fea390ca21cc..a3980a66fcec 100644 --- a/vllm/model_executor/models/ernie45_moe.py +++ b/vllm/model_executor/models/ernie45_moe.py @@ -399,6 +399,7 @@ def forward( @support_torch_compile class Ernie4_5_MoeModel(nn.Module): hf_to_vllm_mapper = WeightsMapper( + orig_to_new_substr={"mtp": None}, orig_to_new_stacked={ ".q_proj": (".qkv_proj", "q"), ".k_proj": (".qkv_proj", "k"), @@ -408,7 +409,7 @@ class Ernie4_5_MoeModel(nn.Module): ".mlp.up_proj": (".mlp.gate_up_proj", 1), ".shared_experts.gate_proj": (".shared_experts.gate_up_proj", 0), ".shared_experts.up_proj": (".shared_experts.gate_up_proj", 1), - } + }, ) def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): @@ -504,7 +505,6 @@ def _preprocess( def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: loader = AutoWeightsLoader( self, - skip_substrs=["mtp"], ignore_unexpected_suffixes=[".bias", "_bias"], ) return loader.load_weights( @@ -632,10 +632,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/ernie45_vl.py b/vllm/model_executor/models/ernie45_vl.py index e7e71037cee9..b7fd00aabe13 100644 --- a/vllm/model_executor/models/ernie45_vl.py +++ b/vllm/model_executor/models/ernie45_vl.py @@ -82,7 +82,7 @@ SupportsMultiModal, SupportsPP, ) -from .utils import AutoWeightsLoader, WeightsMapper, maybe_prefix +from .utils import WeightsMapper, maybe_prefix from .vision import get_vit_attn_backend logger = init_logger(__name__) @@ -1626,7 +1626,3 @@ def forward( ) return hidden_states - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/ernie_mtp.py b/vllm/model_executor/models/ernie_mtp.py index b57da3698a55..29aa7e46b61f 100644 --- a/vllm/model_executor/models/ernie_mtp.py +++ b/vllm/model_executor/models/ernie_mtp.py @@ -214,6 +214,5 @@ def _filter( if any(k in name for k in ("mtp", "embed_tokens", "lm_head")): yield name, weight - skip_prefixes = ["lm_head"] if self.config.tie_word_embeddings else [] - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) + loader = AutoWeightsLoader(self) return loader.load_weights(_filter(weights), mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/exaone.py b/vllm/model_executor/models/exaone.py index 79314a7b9315..b15b27f3de76 100644 --- a/vllm/model_executor/models/exaone.py +++ b/vllm/model_executor/models/exaone.py @@ -25,7 +25,6 @@ # limitations under the License. """Inference-only Exaone model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -54,7 +53,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, make_empty_intermediate_tensors_factory, @@ -444,13 +442,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - # With tie_word_embeddings, we can skip lm_head.weight - # The weight might appear unnecessarily in the files if the model is - # processed with quantization, LoRA, fine-tuning, etc. - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/exaone4.py b/vllm/model_executor/models/exaone4.py index dc88c15fc019..eae5902cc858 100644 --- a/vllm/model_executor/models/exaone4.py +++ b/vllm/model_executor/models/exaone4.py @@ -21,7 +21,6 @@ # limitations under the License. """Inference-only Exaone model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -51,7 +50,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, extract_layer_index, @@ -441,13 +439,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - # With tie_word_embeddings, we can skip lm_head.weight - # The weight might appear unnecessarily in the files if the model is - # processed with quantization, LoRA, fine-tuning, etc. - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/exaone4_5.py b/vllm/model_executor/models/exaone4_5.py index 58ad3d4c61a3..415c4e988937 100644 --- a/vllm/model_executor/models/exaone4_5.py +++ b/vllm/model_executor/models/exaone4_5.py @@ -15,7 +15,7 @@ # limitations under the License. """Inference-only EXAONE-4.5 model compatible with HuggingFace weights.""" -from collections.abc import Callable, Iterable +from collections.abc import Callable from functools import partial import einops @@ -52,7 +52,11 @@ from .qwen2_vl import Qwen2VLDummyInputsBuilder as Exaone4_5_DummyInputsBuilder from .qwen2_vl import Qwen2VLMultiModalProcessor as Exaone4_5_MultiModalProcessor -from .utils import AutoWeightsLoader, init_vllm_registered_model, maybe_prefix +from .utils import ( + WeightsMapper, + init_vllm_registered_model, + maybe_prefix, +) logger = init_logger(__name__) @@ -317,6 +321,11 @@ def get_hf_processor(self, **kwargs: object) -> Exaone4_5_Processor: dummy_inputs=Exaone4_5_DummyInputsBuilder, ) class Exaone4_5_ForConditionalGeneration(Qwen2_5_VLForConditionalGeneration): + hf_to_vllm_mapper = ( + Qwen2_5_VLForConditionalGeneration.hf_to_vllm_mapper + | WeightsMapper(orig_to_new_prefix={"mtp.": None}) + ) + def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): nn.Module.__init__(self) @@ -352,13 +361,6 @@ def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): self.language_model.make_empty_intermediate_tensors ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["mtp."]), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - @classmethod def get_placeholder_str(cls, modality: str, i: int) -> str | None: if modality.startswith("image"): diff --git a/vllm/model_executor/models/exaone_moe.py b/vllm/model_executor/models/exaone_moe.py index 086040e2eaf7..f7e73603e8ae 100644 --- a/vllm/model_executor/models/exaone_moe.py +++ b/vllm/model_executor/models/exaone_moe.py @@ -421,12 +421,6 @@ def compute_logits( def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: loader = AutoWeightsLoader( self, - # With tie_word_embeddings, we can skip lm_head.weight - # The weight might appear unnecessarily in the files if the model is - # processed with quantization, LoRA, fine-tuning, etc. - skip_prefixes=( - ["lm_head.", "mtp."] if self.config.tie_word_embeddings else ["mtp."] - ), # Skip loading extra parameters for GPTQ/modelopt models. ignore_unexpected_suffixes=[ ".bias", @@ -441,4 +435,5 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: "_input_scale", ], ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) + mtp_drop = WeightsMapper(orig_to_new_prefix={"mtp.": None}) + return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper | mtp_drop) diff --git a/vllm/model_executor/models/fairseq2_llama.py b/vllm/model_executor/models/fairseq2_llama.py index e898034fbfa5..a1132e011c7b 100644 --- a/vllm/model_executor/models/fairseq2_llama.py +++ b/vllm/model_executor/models/fairseq2_llama.py @@ -34,6 +34,23 @@ class Fairseq2LlamaForCausalLM(LlamaForCausalLM): + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_prefix={ + "decoder_frontend.embed.": "model.embed_tokens.", + "decoder.": "model.", + "final_proj.": "lm_head.", + }, + orig_to_new_substr={ + ".self_attn_layer_norm.": ".input_layernorm.", + ".ffn_layer_norm.": ".post_attention_layernorm.", + ".self_attn.output_proj.": ".self_attn.o_proj.", + ".ffn.gate_proj.": ".mlp.gate_proj.", + ".ffn.inner_proj.": ".mlp.up_proj.", + ".ffn.output_proj.": ".mlp.down_proj.", + ".layer_norm.": ".norm.", + }, + ) + def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): super().__init__(vllm_config=vllm_config, prefix=prefix) self.tp_rank = get_tensor_model_parallel_rank() @@ -53,31 +70,9 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: weights_wrapped = dict(weights) weights = weights_wrapped[weights_wrapped["model_key"]].items() # type: ignore - # remap keys - fs2_to_vllm_mapper = WeightsMapper( - orig_to_new_prefix={ - "decoder_frontend.embed.": "model.embed_tokens.", - "decoder.": "model.", - "final_proj.": "lm_head.", - }, - orig_to_new_substr={ - ".self_attn_layer_norm.": ".input_layernorm.", - ".ffn_layer_norm.": ".post_attention_layernorm.", - ".self_attn.output_proj.": ".self_attn.o_proj.", - ".ffn.gate_proj.": ".mlp.gate_proj.", - ".ffn.inner_proj.": ".mlp.up_proj.", - ".ffn.output_proj.": ".mlp.down_proj.", - ".layer_norm.": ".norm.", - }, - ) - weights = fs2_to_vllm_mapper.apply(weights) - params = dict(self.named_parameters()) - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) + loader = AutoWeightsLoader(self) return loader.load_weights( self.reshape_fairseq2_weights(name, loaded_weight, params) for name, loaded_weight in weights diff --git a/vllm/model_executor/models/falcon.py b/vllm/model_executor/models/falcon.py index efd24b51442a..978ace332aec 100644 --- a/vllm/model_executor/models/falcon.py +++ b/vllm/model_executor/models/falcon.py @@ -21,7 +21,6 @@ """PyTorch Falcon model.""" import math -from collections.abc import Iterable from itertools import islice from typing import TypeAlias @@ -52,14 +51,11 @@ ParallelLMHead, VocabParallelEmbedding, ) -from vllm.model_executor.model_loader.weight_utils import default_weight_loader from vllm.sequence import IntermediateTensors from vllm.transformers_utils.configs.falcon import RWConfig from .interfaces import SupportsPP from .utils import ( - AutoWeightsLoader, - is_pp_missing_parameter, make_empty_intermediate_tensors_factory, make_layers, maybe_prefix, @@ -138,6 +134,7 @@ def __init__( skip_bias_add=True, quant_config=quant_config, prefix=f"{prefix}.query_key_value", + fused_qkv_interleaved=True, ) self.q_size = self.num_heads * self.head_dim self.kv_size = self.num_kv_heads * self.head_dim @@ -421,61 +418,6 @@ def forward( hidden_states = self.ln_f(hidden_states) return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - total_num_heads = self.config.num_attention_heads - if self.config.new_decoder_architecture: - total_num_kv_heads = self.config.num_kv_heads - elif self.config.multi_query: - total_num_kv_heads = 1 - else: - total_num_kv_heads = total_num_heads - num_query_heads_per_kv_head = total_num_heads // total_num_kv_heads - params_dict = dict(self.named_parameters(remove_duplicate=False)) - loaded_params: set[str] = set() - for name, loaded_weight in weights: - # Skip loading extra bias for GPTQ models. - if name.endswith(".bias") and name not in params_dict: - continue - if is_pp_missing_parameter(name, self): - continue - param = params_dict[name] - if "query_key_value" in name: - output_dim = getattr(param, "output_dim", None) - loaded_weight_shape = loaded_weight.shape - if output_dim is not None: - loaded_weight = loaded_weight.view( - loaded_weight_shape[:output_dim] - + (total_num_kv_heads, num_query_heads_per_kv_head + 2, -1) - + loaded_weight_shape[output_dim + 1 :] - ) - wq = loaded_weight.narrow( - output_dim + 1, 0, num_query_heads_per_kv_head - ).reshape( - *loaded_weight_shape[:output_dim], - -1, - *loaded_weight_shape[output_dim + 1 :], - ) - wk = loaded_weight.narrow( - output_dim + 1, num_query_heads_per_kv_head, 1 - ).reshape( - *loaded_weight_shape[:output_dim], - -1, - *loaded_weight_shape[output_dim + 1 :], - ) - wv = loaded_weight.narrow( - output_dim + 1, num_query_heads_per_kv_head + 1, 1 - ).reshape( - *loaded_weight_shape[:output_dim], - -1, - *loaded_weight_shape[output_dim + 1 :], - ) - loaded_weight = torch.cat([wq, wk, wv], dim=output_dim) - - weight_loader = getattr(param, "weight_loader", default_weight_loader) - weight_loader(param, loaded_weight) - loaded_params.add(name) - return loaded_params - class FalconForCausalLM(nn.Module, SupportsPP): packed_modules_mapping = { @@ -534,10 +476,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/falcon_h1.py b/vllm/model_executor/models/falcon_h1.py index 3c96d00c2897..573b44dda66d 100644 --- a/vllm/model_executor/models/falcon_h1.py +++ b/vllm/model_executor/models/falcon_h1.py @@ -2,7 +2,6 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project """Inference-only FalconH1 model.""" -from collections.abc import Iterable from itertools import islice import torch @@ -46,7 +45,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, make_empty_intermediate_tensors_factory, @@ -641,10 +639,3 @@ def compute_logits( logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/fireredasr2.py b/vllm/model_executor/models/fireredasr2.py index eea0c7d8897e..f3b4eb879cee 100644 --- a/vllm/model_executor/models/fireredasr2.py +++ b/vllm/model_executor/models/fireredasr2.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project import math -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, cast import torch @@ -52,12 +52,7 @@ _require_is_multimodal, ) from .qwen2 import Qwen2ForCausalLM -from .utils import ( - AutoWeightsLoader, - WeightsMapper, - _merge_multimodal_embeddings, - maybe_prefix, -) +from .utils import WeightsMapper, _merge_multimodal_embeddings, maybe_prefix logger = init_logger(__name__) @@ -332,7 +327,8 @@ class FireRedASR2ForConditionalGeneration( "net.0": "pre_layer_norm", "net.1": "linear_expand", "net.4": "linear_project", - } + }, + orig_to_new_prefix={"model.encoder.audio_encoder.positional_encoding.pe": None}, ) supports_transcription_only = True @@ -475,10 +471,3 @@ def _parse_and_validate_audio_input( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.model.decoder.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, skip_prefixes=["model.encoder.audio_encoder.positional_encoding.pe"] - ) - - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/fireredlid.py b/vllm/model_executor/models/fireredlid.py index 804ed2bc9fd9..ff03d3113976 100644 --- a/vllm/model_executor/models/fireredlid.py +++ b/vllm/model_executor/models/fireredlid.py @@ -15,7 +15,7 @@ from __future__ import annotations -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Literal import numpy as np @@ -59,11 +59,7 @@ SupportsMultiModal, SupportsTranscription, ) -from .utils import ( - AutoWeightsLoader, - WeightsMapper, - maybe_prefix, -) +from .utils import WeightsMapper, maybe_prefix from .whisper_utils import ISO639_1_SUPPORTED_LANGS logger = init_logger(__name__) @@ -589,7 +585,15 @@ class FireRedLIDForConditionalGeneration( "net.0": "pre_layer_norm", "net.1": "linear_expand", "net.4": "linear_project", - } + }, + orig_to_new_prefix={ + # Position encoding buffers are rebuilt at init + "model.encoder.positional_encoding.pe": None, + "model.decoder.positional_encoding.pe": None, + # Tied output projection (shared with embedding) + "model.decoder.tgt_word_prj.weight": None, + "proj_out.": None, + }, ) def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): @@ -776,17 +780,3 @@ def get_speech_to_text_config( def post_process_output(cls, text: str) -> str: # Strip any leading/trailing whitespace from the raw LID output. return text.strip() - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=[ - # Position encoding buffers are rebuilt at init - "model.encoder.positional_encoding.pe", - "model.decoder.positional_encoding.pe", - # Tied output projection (shared with embedding) - "model.decoder.tgt_word_prj.weight", - "proj_out.", - ], - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/funasr.py b/vllm/model_executor/models/funasr.py index e128b22e8e04..3d80bc058fb5 100644 --- a/vllm/model_executor/models/funasr.py +++ b/vllm/model_executor/models/funasr.py @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project import math -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, cast import torch @@ -59,7 +59,6 @@ ) from .qwen3 import Qwen3Model from .utils import ( - AutoWeightsLoader, WeightsMapper, _merge_multimodal_embeddings, maybe_prefix, @@ -643,10 +642,6 @@ def __init__( prefix=maybe_prefix(prefix, "audio_encoder"), ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class FunASRModel(nn.Module): def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): @@ -988,10 +983,3 @@ def _parse_and_validate_audio_input(self, **kwargs: object) -> FunASRAudioInputs def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - ) - - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/funaudiochat.py b/vllm/model_executor/models/funaudiochat.py index 72b12e26b5cf..2d4ae16cc39d 100644 --- a/vllm/model_executor/models/funaudiochat.py +++ b/vllm/model_executor/models/funaudiochat.py @@ -13,7 +13,7 @@ from __future__ import annotations -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from functools import cached_property from typing import Any @@ -53,7 +53,6 @@ from .interfaces import MultiModalEmbeddings, SupportsMultiModal, SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -141,10 +140,6 @@ def __init__(self, config: Any): # shard starts as zeros, while allowing q/v shards to load. self.qkv_proj.bias.zero_() - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def forward( self, hidden_states: torch.Tensor, @@ -772,6 +767,8 @@ def get_replacement_funaudiochat(item_idx: int): dummy_inputs=FunAudioChatDummyInputsBuilder, ) class FunAudioChatForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP): + hf_to_vllm_mapper = WeightsMapper(orig_to_new_prefix={"audio_invert_tower.": None}) + @classmethod def get_placeholder_str(cls, modality: str, i: int) -> str | None: if modality.startswith("audio"): @@ -979,7 +976,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["audio_invert_tower."]) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/gemma.py b/vllm/model_executor/models/gemma.py index 949799fa654d..2f26d3caf1f0 100644 --- a/vllm/model_executor/models/gemma.py +++ b/vllm/model_executor/models/gemma.py @@ -17,7 +17,6 @@ # limitations under the License. """Inference-only Gemma model compatible with HuggingFace weights.""" -from collections.abc import Iterable from functools import cache from itertools import islice from typing import Any @@ -46,7 +45,6 @@ from .interfaces import SupportsLoRA, SupportsPP, SupportsQuant from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -379,10 +377,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.model.embed_tokens, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/gemma2.py b/vllm/model_executor/models/gemma2.py index da5161ffa019..adb776f5757b 100644 --- a/vllm/model_executor/models/gemma2.py +++ b/vllm/model_executor/models/gemma2.py @@ -16,7 +16,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from collections.abc import Iterable from itertools import islice import torch @@ -43,7 +42,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, extract_layer_index, make_empty_intermediate_tensors_factory, @@ -369,10 +367,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.model.embed_tokens, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/gemma3.py b/vllm/model_executor/models/gemma3.py index 532a34d40fc0..c94c40e75123 100644 --- a/vllm/model_executor/models/gemma3.py +++ b/vllm/model_executor/models/gemma3.py @@ -15,7 +15,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from collections.abc import Iterable from itertools import islice import torch @@ -49,7 +48,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, extract_layer_index, make_empty_intermediate_tensors_factory, @@ -372,10 +370,6 @@ def forward( hidden_states, _ = self.norm(hidden_states, residual) return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Gemma3ForCausalLM(nn.Module, SupportsLoRA, SupportsPP): hf_to_vllm_mapper = Gemma3Model.hf_to_vllm_mapper @@ -440,10 +434,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/gemma3_mm.py b/vllm/model_executor/models/gemma3_mm.py index 0d9f8f14188f..191b078a0bc8 100644 --- a/vllm/model_executor/models/gemma3_mm.py +++ b/vllm/model_executor/models/gemma3_mm.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project import math -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Any, Literal import torch @@ -46,7 +46,6 @@ ) from .siglip import SiglipVisionModel from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -636,10 +635,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/gemma3n.py b/vllm/model_executor/models/gemma3n.py index 4b06fd418f3e..c4229ff93dd8 100644 --- a/vllm/model_executor/models/gemma3n.py +++ b/vllm/model_executor/models/gemma3n.py @@ -15,7 +15,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from collections.abc import Iterable import torch from torch import nn @@ -49,7 +48,6 @@ from .interfaces import SupportsQuant from .utils import ( - AutoWeightsLoader, WeightsMapper, extract_layer_index, make_layers, @@ -1050,12 +1048,13 @@ def forward( hidden_states = self.altup_unembed(hidden_states) return self.norm(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Gemma3nForCausalLM(nn.Module): + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_substr=dict.fromkeys( + ["embed_audio.", "embed_vision.", "audio_tower.", "vision_tower."], None + ) + ) packed_modules_mapping = { "qkv_proj": [ "q_proj", @@ -1110,12 +1109,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.model.embed_tokens, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_substrs=( - ["embed_audio.", "embed_vision.", "audio_tower.", "vision_tower."] - ), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/gemma3n_mm.py b/vllm/model_executor/models/gemma3n_mm.py index 1dd44313c1e5..558a2c3b05ec 100644 --- a/vllm/model_executor/models/gemma3n_mm.py +++ b/vllm/model_executor/models/gemma3n_mm.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Any, Literal import torch @@ -57,7 +57,6 @@ from .interfaces import MultiModalEmbeddings, SupportsMultiModal, SupportsTranscription from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -741,10 +740,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/gemma4.py b/vllm/model_executor/models/gemma4.py index 63d97fbd1b50..7ebfcfa8bc05 100644 --- a/vllm/model_executor/models/gemma4.py +++ b/vllm/model_executor/models/gemma4.py @@ -1522,6 +1522,11 @@ class Gemma4ForCausalLM( # under `...moe.*`. ".moe.experts.gate_up_proj": ".moe.gate_up_proj", ".moe.experts.down_proj": ".moe.down_proj", + # Skip multimodal weights — handled by the multimodal wrapper. + "audio_tower.": None, + "vision_tower.": None, + "embed_audio.": None, + "embed_vision.": None, }, ) # Note: qkv_proj packing applies to non-k_eq_v layers (sliding @@ -1707,16 +1712,5 @@ def _weight_iterator(): yield name, weight - # Skip multimodal weights — handled by the multimodal wrapper. - # Also skip lm_head when weights are tied. - skip = [ - "audio_tower.", - "vision_tower.", - "embed_audio.", - "embed_vision.", - ] - if self.config.tie_word_embeddings: - skip.append("lm_head.") - - loader = AutoWeightsLoader(self, skip_substrs=skip) - return loader.load_weights(_weight_iterator()) + loader = AutoWeightsLoader(self) + return loader.load_weights(_weight_iterator(), mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/glm4.py b/vllm/model_executor/models/glm4.py index a1fb94fb26fa..972ae7067c53 100644 --- a/vllm/model_executor/models/glm4.py +++ b/vllm/model_executor/models/glm4.py @@ -48,6 +48,7 @@ from .utils import ( AutoWeightsLoader, PPMissingLayer, + WeightsMapper, maybe_prefix, ) @@ -293,13 +294,14 @@ def compute_logits( return logits def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - skip_prefixes = ["lm_head."] if self.config.tie_word_embeddings else [] # Skip the speculative (MTP) layers, which are loaded by the # draft model instead. num_nextn_layers = getattr(self.config, "num_nextn_predict_layers", 0) - skip_prefixes += [ - f"model.layers.{self.config.num_hidden_layers + i}." - for i in range(num_nextn_layers) - ] - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - return loader.load_weights(weights) + drop = WeightsMapper( + orig_to_new_prefix={ + f"model.layers.{self.config.num_hidden_layers + i}.": None + for i in range(num_nextn_layers) + } + ) + loader = AutoWeightsLoader(self) + return loader.load_weights(weights, mapper=drop) diff --git a/vllm/model_executor/models/glm4_1v.py b/vllm/model_executor/models/glm4_1v.py index 810d9de87b47..7bdc9f1def31 100644 --- a/vllm/model_executor/models/glm4_1v.py +++ b/vllm/model_executor/models/glm4_1v.py @@ -28,7 +28,7 @@ compatible with HuggingFace weights.""" import math -from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence +from collections.abc import Callable, Iterator, Mapping, Sequence from functools import partial from typing import Annotated, Any, Literal, TypeAlias @@ -113,7 +113,6 @@ ) from .qwen2_vl import _create_qwen2vl_field_factory from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -970,10 +969,6 @@ def forward( return x - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Glm4vProcessingInfo(BaseProcessingInfo): def get_supported_mm_limits(self) -> Mapping[str, int | None]: @@ -2349,10 +2344,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/glm4_moe.py b/vllm/model_executor/models/glm4_moe.py index abb9970c403e..8d85ad028c2d 100644 --- a/vllm/model_executor/models/glm4_moe.py +++ b/vllm/model_executor/models/glm4_moe.py @@ -604,7 +604,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/glm4_moe_lite.py b/vllm/model_executor/models/glm4_moe_lite.py index 7f63130d883d..751bcd0735b0 100644 --- a/vllm/model_executor/models/glm4_moe_lite.py +++ b/vllm/model_executor/models/glm4_moe_lite.py @@ -23,8 +23,7 @@ # limitations under the License. """Inference-only GLM-4.7-Flash model compatible with HuggingFace weights.""" -import typing -from collections.abc import Callable, Iterable +from collections.abc import Iterable from itertools import islice from typing import TYPE_CHECKING @@ -34,26 +33,18 @@ if TYPE_CHECKING: from transformers.models.glm4_moe_lite import Glm4MoeLiteConfig -from vllm._aiter_ops import rocm_aiter_ops from vllm.compilation.decorators import support_torch_compile from vllm.config import VllmConfig from vllm.distributed import ( get_pp_group, ) from vllm.logger import init_logger -from vllm.model_executor.layers.fused_moe import ( - fused_moe_make_expert_params_mapping, -) from vllm.model_executor.layers.layernorm import RMSNorm from vllm.model_executor.layers.logits_processor import LogitsProcessor from vllm.model_executor.layers.vocab_parallel_embedding import ( ParallelLMHead, VocabParallelEmbedding, ) -from vllm.model_executor.model_loader.weight_utils import ( - default_weight_loader, - maybe_remap_kv_scale_name, -) from vllm.model_executor.models.deepseek_v2 import ( DeepseekV2Attention, DeepseekV2MLAAttention, @@ -70,11 +61,12 @@ from .utils import ( AutoWeightsLoader, PPMissingLayer, - get_spec_layer_idx_from_weight_name, - is_pp_missing_parameter, + WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, + maybe_fuse_shared_experts, maybe_prefix, + skip_spec_layers, ) logger = init_logger(__name__) @@ -308,211 +300,33 @@ def make_empty_intermediate_tensors( } ) - def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: - # Params for weights, fp8 weight scales, fp8 activation scales - # (param_name, weight_name, expert_id, shard_id) - return fused_moe_make_expert_params_mapping( - self, - ckpt_gate_proj_name="gate_proj", - ckpt_down_proj_name="down_proj", - ckpt_up_proj_name="up_proj", - num_experts=self.config.n_routed_experts, - ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - rocm_aiter_moe_shared_expert_enabled = ( - rocm_aiter_ops.is_fusion_moe_shared_experts_enabled() - ) - stacked_params_mapping = [ - # (param_name, shard_name, shard_id) - ("gate_up_proj", "gate_proj", 0), - ("gate_up_proj", "up_proj", 1), - ] - mla_params_mapping = [ - ("fused_qkv_a_proj", "q_a_proj", 0), - ("fused_qkv_a_proj", "kv_a_proj_with_mqa", 1), - ] - - stacked_params_mapping.extend(mla_params_mapping) - - # Params for weights, fp8 weight scales, fp8 activation scales - # (param_name, weight_name, expert_id, shard_id) - expert_params_mapping = fused_moe_make_expert_params_mapping( - self, - ckpt_gate_proj_name="gate_proj", - ckpt_down_proj_name="down_proj", - ckpt_up_proj_name="up_proj", - num_experts=self.config.n_routed_experts - + ( - self.config.n_shared_experts - if rocm_aiter_moe_shared_expert_enabled - else 0 - ), + # .experts.* is handled by FusedMoE.load_weights (self-serve). + stacked: dict[str, tuple[str, int | str]] = { + ".mlp.gate_proj": (".mlp.gate_up_proj", 0), + ".mlp.up_proj": (".mlp.gate_up_proj", 1), + ".shared_experts.gate_proj": (".shared_experts.gate_up_proj", 0), + ".shared_experts.up_proj": (".shared_experts.gate_up_proj", 1), + } + # The attention layout is config-dependent (`use_mla`): MLA with a fused + # low-rank projection, MLA without it, or standard qkv. Only add the + # stacked entries whose fused target actually exists as a parameter. + param_names = list(dict(self.named_parameters())) + if any(".fused_qkv_a_proj." in n for n in param_names): + stacked[".q_a_proj"] = (".fused_qkv_a_proj", 0) + stacked[".kv_a_proj_with_mqa"] = (".fused_qkv_a_proj", 1) + if any(".qkv_proj." in n for n in param_names): + stacked[".q_proj"] = (".qkv_proj", "q") + stacked[".k_proj"] = (".qkv_proj", "k") + stacked[".v_proj"] = (".qkv_proj", "v") + mapper = WeightsMapper(orig_to_new_stacked=stacked) + weights = maybe_fuse_shared_experts( + skip_spec_layers(weights, self.config), + n_routed_experts=self.config.n_routed_experts, + n_shared_experts=self.config.n_shared_experts or 1, ) - - params_dict = dict(self.named_parameters()) - loaded_params: set[str] = set() - for name, loaded_weight in weights: - if "rotary_emb.inv_freq" in name: - continue - - spec_layer = get_spec_layer_idx_from_weight_name(self.config, name) - if spec_layer is not None: - continue # skip spec decode layers for main model - - is_fusion_moe_shared_experts_layer = ( - rocm_aiter_moe_shared_expert_enabled and ("mlp.shared_experts" in name) - ) - - for param_name, weight_name, shard_id in stacked_params_mapping: - # Skip non-stacked layers and experts (experts handled below). - if weight_name not in name: - continue - # We have mlp.experts[0].gate_proj in the checkpoint. - # Since we handle the experts below in expert_params_mapping, - # we need to skip here BEFORE we update the name, otherwise - # name will be updated to mlp.experts[0].gate_up_proj, which - # will then be updated below in expert_params_mapping - # for mlp.experts[0].gate_gate_up_proj, which breaks load. - if ("mlp.experts." in name) and name not in params_dict: - continue - if is_fusion_moe_shared_experts_layer: - continue - name_mapped = name.replace(weight_name, param_name) - - # QKV fusion is optional, fall back to normal - # weight loading if it's not enabled - # if go with fusion option, then update name - if ( - param_name == "fused_qkv_a_proj" - ) and name_mapped not in params_dict: - continue - else: - name = name_mapped - # Skip loading extra bias for GPTQ models. - if name.endswith(".bias") and name not in params_dict: - continue - - if is_pp_missing_parameter(name, self): - continue - - param = params_dict[name] - weight_loader = param.weight_loader - weight_loader(param, loaded_weight, shard_id) - break - else: - is_expert_weight = False - - # Special handling: when AITER fusion_shared_experts is enabled, - # checkpoints may provide a single widened shared_experts tensor - # without explicit expert indices - # (e.g. ...mlp.shared_experts.gate_proj.weight). - # For models with multiple shared experts, split that tensor - # evenly into per-shared-expert slices and load them into - # appended expert slots mlp.experts.{n_routed_experts + j}.* - # accordingly. - num_chunks = 1 - if is_fusion_moe_shared_experts_layer: - num_chunks = getattr(self.config, "n_shared_experts", 1) or 1 - # Determine split axis based on op type - # gate/up: ColumnParallel → split along dim 0 - # down: RowParallel → split along dim 1 - split_dim = 1 if "down_proj.weight" in name else 0 - total = loaded_weight.shape[split_dim] - assert total % num_chunks == 0, ( - f"Shared expert weight dim {total} " - f"not divisible by num_chunks {num_chunks}" - ) - chunk_size = total // num_chunks - - for j in range(num_chunks): - chunk_name = name - weight_to_load = loaded_weight - - if is_fusion_moe_shared_experts_layer: - if split_dim == 0: - weight_to_load = loaded_weight[ - j * chunk_size : (j + 1) * chunk_size, : - ] - else: - weight_to_load = loaded_weight[ - :, j * chunk_size : (j + 1) * chunk_size - ] - # Synthesize an expert-style name so expert mapping - # can route it - chunk_name = name.replace( - "mlp.shared_experts", - f"mlp.experts.{self.config.n_routed_experts + j}", - ) - - # Use expert_params_mapping to locate the destination - # param and delegate to its expert-aware weight_loader - # with expert_id. - for mapping in expert_params_mapping: - param_name, weight_name, expert_id, shard_id = mapping - if weight_name not in chunk_name: - continue - - # Anyway, this is an expert weight and should not be - # attempted to load as other weights later - is_expert_weight = True - - # Do not modify `name` since the loop may continue here - # Instead, create a new variable - name_mapped = chunk_name.replace(weight_name, param_name) - - if is_pp_missing_parameter(name_mapped, self): - continue - - param = params_dict[name_mapped] - # We should ask the weight loader to return success or - # not here since otherwise we may skip experts with - # other available replicas. - weight_loader = typing.cast( - Callable[..., bool], param.weight_loader - ) - success = weight_loader( - param, - weight_to_load, - name_mapped, - shard_id=shard_id, - expert_id=expert_id, - return_success=True, - ) - if success: - if not is_fusion_moe_shared_experts_layer: - name = name_mapped - else: - loaded_params.add(name_mapped) - break - else: - if is_expert_weight: - # We've checked that this is an expert weight - # However it's not mapped locally to this rank - # So we simply skip it - continue - - # Skip loading extra bias for GPTQ models. - if name.endswith(".bias") and name not in params_dict: - continue - - # Remapping the name of FP8 kv-scale. - name = maybe_remap_kv_scale_name(name, params_dict) - if name is None: - continue - - if is_pp_missing_parameter(name, self): - continue - - param = params_dict[name] - weight_loader = getattr( - param, "weight_loader", default_weight_loader - ) - weight_loader(param, loaded_weight) - if not is_fusion_moe_shared_experts_layer: - loaded_params.add(name) - - return loaded_params + loader = AutoWeightsLoader(self) + return loader.load_weights(weights, mapper=mapper) class Glm4MoeLiteForCausalLM( @@ -613,19 +427,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: - # Params for weights, fp8 weight scales, fp8 activation scales - # (param_name, weight_name, expert_id, shard_id) - return fused_moe_make_expert_params_mapping( - self, - ckpt_gate_proj_name="gate_proj", - ckpt_down_proj_name="down_proj", - ckpt_up_proj_name="up_proj", - num_experts=self.config.n_routed_experts, - num_redundant_experts=0, - ) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/glmasr.py b/vllm/model_executor/models/glmasr.py index 1ff7224d7e4e..8136ba5ff6ca 100644 --- a/vllm/model_executor/models/glmasr.py +++ b/vllm/model_executor/models/glmasr.py @@ -915,6 +915,9 @@ class GlmAsrForConditionalGeneration( nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA, SupportsTranscription ): supported_languages = ISO639_1_SUPPORTED_LANGS + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_prefix={"audio_tower.embed_positions": None} + ) packed_modules_mapping = { "qkv_proj": ["q_proj", "k_proj", "v_proj"], @@ -1082,11 +1085,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - skip_prefixes = ["audio_tower.embed_positions"] - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - return loader.load_weights(weights) - @classmethod def _get_audio_token(cls, model_config: ModelConfig) -> str: """Get the audio token from processor. diff --git a/vllm/model_executor/models/gpt2.py b/vllm/model_executor/models/gpt2.py index 01dc119f8507..8b333dcda808 100644 --- a/vllm/model_executor/models/gpt2.py +++ b/vllm/model_executor/models/gpt2.py @@ -52,6 +52,7 @@ from .interfaces import SupportsCrossEncoding, SupportsPP from .utils import ( AutoWeightsLoader, + WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, maybe_prefix, @@ -182,6 +183,11 @@ def forward( @support_torch_compile class GPT2Model(nn.Module): + # Skip attention mask buffers; NOTE: "c_attn.bias" must not be skipped. + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_substr={".attn.bias": None, ".attn.masked_bias": None} + ) + def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): super().__init__() @@ -253,11 +259,10 @@ def _transpose_conv1d( yield name, loaded_weight def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - # Skip attention mask buffers; NOTE: "c_attn.bias" must not be skipped. - loader = AutoWeightsLoader( - self, skip_substrs=[".attn.bias", ".attn.masked_bias"] + loader = AutoWeightsLoader(self) + return loader.load_weights( + self._transpose_conv1d(weights), mapper=self.hf_to_vllm_mapper ) - return loader.load_weights(self._transpose_conv1d(weights)) class GPT2LMHeadModel(nn.Module, SupportsPP): diff --git a/vllm/model_executor/models/gpt_j.py b/vllm/model_executor/models/gpt_j.py index 44dec8734574..4c76937eeb43 100644 --- a/vllm/model_executor/models/gpt_j.py +++ b/vllm/model_executor/models/gpt_j.py @@ -19,7 +19,6 @@ # limitations under the License. """Inference-only GPT-J model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -47,7 +46,6 @@ from .interfaces import SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -238,12 +236,13 @@ def forward( class GPTJForCausalLM(nn.Module, SupportsPP): hf_to_vllm_mapper = WeightsMapper( + orig_to_new_substr={"attn.bias": None, "attn.masked_bias": None}, orig_to_new_stacked={ # weight_name: (param_name, shard_id) ".q_proj": (".qkv_proj", "q"), ".k_proj": (".qkv_proj", "k"), ".v_proj": (".qkv_proj", "v"), - } + }, ) def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): @@ -289,7 +288,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states, self.lm_head.bias) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_substrs=["attn.bias", "attn.masked_bias"]) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/gpt_neox.py b/vllm/model_executor/models/gpt_neox.py index 907ab7776015..80baef308a07 100644 --- a/vllm/model_executor/models/gpt_neox.py +++ b/vllm/model_executor/models/gpt_neox.py @@ -19,7 +19,6 @@ # limitations under the License. """Inference-only GPT-NeoX model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -47,7 +46,7 @@ from .interfaces import SupportsPP from .utils import ( - AutoWeightsLoader, + WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, maybe_prefix, @@ -79,6 +78,7 @@ def __init__( bias=self.bias, quant_config=quant_config, prefix=f"{prefix}.query_key_value", + fused_qkv_interleaved=True, ) self.dense = RowParallelLinear( config.hidden_size, @@ -196,6 +196,10 @@ def forward( @support_torch_compile class GPTNeoXModel(nn.Module): + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_substr={"attention.bias": None, "attention.masked_bias": None} + ) + def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): super().__init__() @@ -247,26 +251,6 @@ def forward( hidden_states = self.final_layer_norm(hidden_states) return hidden_states - def _repack_qkv( - self, weights: Iterable[tuple[str, torch.Tensor]] - ) -> Iterable[tuple[str, torch.Tensor]]: - # GPT-NeoX's fused QKV is laid out as (num_heads * 3 * head_size) on - # its output dim (0), while vLLM expects (3 * num_heads * head_size). - num_heads = self.config.num_attention_heads - for name, loaded_weight in weights: - if "query_key_value" in name: - shape = loaded_weight.shape - loaded_weight = loaded_weight.view((num_heads, 3, -1) + shape[1:]) - loaded_weight = loaded_weight.transpose(0, 1) - loaded_weight = loaded_weight.reshape(shape) - yield name, loaded_weight - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, skip_substrs=["attention.bias", "attention.masked_bias"] - ) - return loader.load_weights(self._repack_qkv(weights)) - class GPTNeoXForCausalLM(nn.Module, SupportsPP): def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): @@ -312,7 +296,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.embed_out, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/gpt_oss.py b/vllm/model_executor/models/gpt_oss.py index 5fc7e62640f5..ccffa28f84c6 100644 --- a/vllm/model_executor/models/gpt_oss.py +++ b/vllm/model_executor/models/gpt_oss.py @@ -59,7 +59,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, WeightsMapper, extract_layer_index, is_pp_missing_parameter, @@ -1240,10 +1239,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/granite.py b/vllm/model_executor/models/granite.py index c46fefbf8894..86e0532cf8c2 100644 --- a/vllm/model_executor/models/granite.py +++ b/vllm/model_executor/models/granite.py @@ -24,7 +24,6 @@ # limitations under the License. """Inference-only IBM Granite model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -53,7 +52,6 @@ from .interfaces import SupportsLoRA, SupportsPP, SupportsQuant from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, make_layers, @@ -328,10 +326,6 @@ def forward( hidden_states = self.norm(hidden_states) return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class GraniteForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsQuant): hf_to_vllm_mapper = GraniteModel.hf_to_vllm_mapper @@ -406,15 +400,3 @@ def make_empty_intermediate_tensors( ), } ) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - # With tie_word_embeddings, we can skip lm_head.weight - # The weight might appear unnecessarily in the files if the model is - # processed with quantization, LoRA, fine-tuning, etc. - skip_prefixes = ["lm_head."] if self.config.tie_word_embeddings else None - - loader = AutoWeightsLoader( - self, - skip_prefixes=skip_prefixes, - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/granite4_vision.py b/vllm/model_executor/models/granite4_vision.py index c6e4df2992cb..562d740c35b3 100644 --- a/vllm/model_executor/models/granite4_vision.py +++ b/vllm/model_executor/models/granite4_vision.py @@ -9,7 +9,7 @@ """ import math -from collections.abc import Iterable, Mapping +from collections.abc import Mapping from fractions import Fraction from itertools import islice @@ -48,7 +48,6 @@ from vllm.model_executor.models.module_mapping import MultiModelKeys from vllm.model_executor.models.siglip import SiglipVisionModel from vllm.model_executor.models.utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, maybe_prefix, @@ -925,7 +924,3 @@ def compute_logits( # GraniteForCausalLM.compute_logits uses # LogitsProcessor(scale=1/logits_scaling) return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/granite_speech.py b/vllm/model_executor/models/granite_speech.py index 5f97f8b9a519..5550fd0a806a 100644 --- a/vllm/model_executor/models/granite_speech.py +++ b/vllm/model_executor/models/granite_speech.py @@ -25,7 +25,7 @@ """Inference-only IBM Granite speech model.""" import math -from collections.abc import Iterable, Mapping +from collections.abc import Mapping from typing import Annotated import torch @@ -70,7 +70,7 @@ SupportsPP, SupportsTranscription, ) -from .utils import AutoWeightsLoader, init_vllm_registered_model, maybe_prefix +from .utils import init_vllm_registered_model, maybe_prefix # NOTE lang support is based on what is written here: # https://huggingface.co/ibm-granite/granite-speech-3.3-2b @@ -842,13 +842,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights( - self, - weights: Iterable[tuple[str, torch.Tensor]], - ) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - def get_mm_mapping(self) -> MultiModelKeys: """Get the module prefix in multimodal models.""" return MultiModelKeys.from_string_field( diff --git a/vllm/model_executor/models/granitemoe.py b/vllm/model_executor/models/granitemoe.py index 5909604bd543..f678b102e0f7 100644 --- a/vllm/model_executor/models/granitemoe.py +++ b/vllm/model_executor/models/granitemoe.py @@ -64,7 +64,7 @@ from vllm.sequence import IntermediateTensors from .interfaces import SupportsLoRA, SupportsPP -from .utils import AutoWeightsLoader, is_pp_missing_parameter, make_layers, maybe_prefix +from .utils import is_pp_missing_parameter, make_layers, maybe_prefix class GraniteMoeMoE(nn.Module): @@ -541,10 +541,3 @@ def make_empty_intermediate_tensors( ), } ) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/granitemoehybrid.py b/vllm/model_executor/models/granitemoehybrid.py index a50a95a302e8..01a7c4bdbc14 100644 --- a/vllm/model_executor/models/granitemoehybrid.py +++ b/vllm/model_executor/models/granitemoehybrid.py @@ -44,7 +44,6 @@ SupportsQuant, ) from .utils import ( - AutoWeightsLoader, is_pp_missing_parameter, make_empty_intermediate_tensors_factory, make_layers, @@ -697,7 +696,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/granitemoeshared.py b/vllm/model_executor/models/granitemoeshared.py index 7abc682c58e5..e4ae60f8ad23 100644 --- a/vllm/model_executor/models/granitemoeshared.py +++ b/vllm/model_executor/models/granitemoeshared.py @@ -32,7 +32,7 @@ from .granitemoe import GraniteMoeAttention, GraniteMoeModel, GraniteMoeMoE from .interfaces import SupportsLoRA, SupportsPP -from .utils import AutoWeightsLoader, make_layers, maybe_prefix +from .utils import make_layers, maybe_prefix class GraniteMoeSharedMLP(nn.Module): @@ -318,10 +318,3 @@ def make_empty_intermediate_tensors( ), } ) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/hrm_text.py b/vllm/model_executor/models/hrm_text.py index a7546b0cc444..4fbce93a3fac 100644 --- a/vllm/model_executor/models/hrm_text.py +++ b/vllm/model_executor/models/hrm_text.py @@ -21,7 +21,6 @@ ``output_sizes`` (the same path used by Phi-3's fused gate_up_proj). """ -from collections.abc import Iterable from typing import Literal import torch @@ -47,7 +46,7 @@ ) from vllm.sequence import IntermediateTensors -from .utils import AutoWeightsLoader, WeightsMapper, maybe_prefix +from .utils import WeightsMapper, maybe_prefix class HrmTextMLP(nn.Module): @@ -520,8 +519,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.logits_processor(self.lm_head, hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - skip_prefixes = ["lm_head."] if self.config.tie_word_embeddings else None - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/hunyuan_v1.py b/vllm/model_executor/models/hunyuan_v1.py index 4f70a9662896..9b0e47212d9f 100644 --- a/vllm/model_executor/models/hunyuan_v1.py +++ b/vllm/model_executor/models/hunyuan_v1.py @@ -77,7 +77,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, PPMissingLayer, is_pp_missing_parameter, make_layers, @@ -975,13 +974,6 @@ def make_empty_intermediate_tensors( } ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) - def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor: return self.model.embed_input_ids(input_ids) diff --git a/vllm/model_executor/models/hunyuan_vision.py b/vllm/model_executor/models/hunyuan_vision.py index b980e8ae46a7..55dd6d1dd9ee 100644 --- a/vllm/model_executor/models/hunyuan_vision.py +++ b/vllm/model_executor/models/hunyuan_vision.py @@ -24,7 +24,7 @@ # limitations under the License. """Inference-only HunYuan-VL model compatible with HuggingFace weights.""" -from collections.abc import Callable, Iterable, Mapping, Sequence +from collections.abc import Callable, Mapping, Sequence from functools import partial from typing import Annotated, Any, Literal, TypeAlias @@ -93,7 +93,6 @@ SupportsXDRoPE, ) from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -535,10 +534,6 @@ def forward( return image_embeds_list - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def _hunyuan_vl_field_config(hf_inputs: Mapping[str, torch.Tensor]): image_grid_thw = hf_inputs.get("image_grid_thw", torch.empty((0, 3))) @@ -1018,13 +1013,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/hy_v3.py b/vllm/model_executor/models/hy_v3.py index 68c6f2382798..dda54d48a2b1 100644 --- a/vllm/model_executor/models/hy_v3.py +++ b/vllm/model_executor/models/hy_v3.py @@ -24,8 +24,6 @@ # limitations under the License. """Inference-only HY model compatible with HuggingFace weights.""" -import typing -from collections.abc import Callable, Iterable from itertools import islice from typing import Any @@ -43,11 +41,7 @@ from vllm.logger import init_logger from vllm.model_executor.layers.activation import SiluAndMul from vllm.model_executor.layers.attention import Attention -from vllm.model_executor.layers.fused_moe import ( - FusedMoE, - GateLinear, - fused_moe_make_expert_params_mapping, -) +from vllm.model_executor.layers.fused_moe import FusedMoE, GateLinear from vllm.model_executor.layers.hpc import HpcRopeNorm, QkNormPolicy from vllm.model_executor.layers.layernorm import RMSNorm from vllm.model_executor.layers.linear import ( @@ -62,19 +56,13 @@ ParallelLMHead, VocabParallelEmbedding, ) -from vllm.model_executor.model_loader.weight_utils import ( - default_weight_loader, - maybe_remap_kv_scale_name, -) from vllm.sequence import IntermediateTensors from vllm.transformers_utils.configs.hy_v3 import HYV3Config from .interfaces import MixtureOfExperts, SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, - get_spec_layer_idx_from_weight_name, - is_pp_missing_parameter, + WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, maybe_prefix, @@ -434,6 +422,20 @@ def forward( @support_torch_compile class HYV3Model(nn.Module, MixtureOfExperts): + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_substr={"router.gate.": "gate."}, + orig_to_new_stacked={ + ".q_proj": (".qkv_proj", "q"), + ".k_proj": (".qkv_proj", "k"), + ".v_proj": (".qkv_proj", "v"), + # .experts.* is handled by FusedMoE.load_weights (self-serve). + ".mlp.gate_proj": (".mlp.gate_up_proj", 0), + ".mlp.up_proj": (".mlp.gate_up_proj", 1), + ".shared_mlp.gate_proj": (".shared_mlp.gate_up_proj", 0), + ".shared_mlp.up_proj": (".shared_mlp.gate_up_proj", 1), + }, + ) + def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): super().__init__() @@ -515,17 +517,6 @@ def update_physical_experts_metadata( moe.n_redundant_experts = self.num_redundant_experts moe.experts.update_expert_map() - def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: - # Params for weights, fp8 weight scales, fp8 activation scales - # (param_name, weight_name, expert_id, shard_id) - return fused_moe_make_expert_params_mapping( - self, - ckpt_gate_proj_name="gate_proj", - ckpt_down_proj_name="down_proj", - ckpt_up_proj_name="up_proj", - num_experts=self.config.num_experts, - ) - def forward( self, input_ids: torch.Tensor, @@ -560,96 +551,6 @@ def forward( return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - stacked_params_mapping = [ - # (param_name, shard_name, shard_id) - (".qkv_proj", ".q_proj", "q"), - (".qkv_proj", ".k_proj", "k"), - (".qkv_proj", ".v_proj", "v"), - (".gate_up_proj", ".gate_proj", 0), - (".gate_up_proj", ".up_proj", 1), - ] - params_dict = dict(self.named_parameters()) - expert_params_mapping = self.get_expert_mapping() - loaded_params: set[str] = set() - for name, loaded_weight in weights: - if self.config.tie_word_embeddings and "lm_head.weight" in name: - continue - if "scale" in name: - # Remapping the name of FP8 kv-scale. - name = maybe_remap_kv_scale_name(name, params_dict) - if name is None: - continue - is_found = False - for param_name, weight_name, shard_id in stacked_params_mapping: - if weight_name not in name: - continue - if "mlp.experts" in name: - continue - name = name.replace(weight_name, param_name) - # Skip loading extra bias for GPTQ models. - if name.endswith(".bias") and name not in params_dict: - continue - - # Skip layers on other devices. - if is_pp_missing_parameter(name, self): - continue - - param = params_dict[name] - weight_loader = param.weight_loader - weight_loader(param, loaded_weight, shard_id) - loaded_params.add(name) - is_found = True - break - if is_found: - continue - - if name.endswith(".bias") and name not in params_dict: - continue - is_expert_weight = False - for mapping in expert_params_mapping: - param_name, weight_name, expert_id, shard_id = mapping - if weight_name not in name: - continue - is_expert_weight = True - name_mapped = name.replace(weight_name, param_name) - # Skip layers on other devices. - if is_pp_missing_parameter(name_mapped, self): - continue - - param = params_dict[name_mapped] - weight_loader = typing.cast(Callable[..., bool], param.weight_loader) - success = weight_loader( - param, - loaded_weight, - name_mapped, - shard_id=shard_id, - expert_id=expert_id, - return_success=True, - ) - if success: - name = name_mapped - break - else: - if is_expert_weight: - # We've checked that this is an expert weight - # However it's not mapped locally to this rank - # So we simply skip it - continue - if name is None: - continue - if is_pp_missing_parameter(name, self): - continue - if "router.gate." in name: - name = name.replace("router.", "") - - param = params_dict[name] - weight_loader = getattr(param, "weight_loader", default_weight_loader) - weight_loader(param, loaded_weight) - loaded_params.add(name) - - return loaded_params - class HYV3ForCausalLM(nn.Module, SupportsPP, SupportsLoRA): packed_modules_mapping = { @@ -706,20 +607,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - def _filter_weights(weights): - for name, weight in weights: - spec_layer = get_spec_layer_idx_from_weight_name(self.config, name) - if spec_layer is not None: - continue - yield name, weight - - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(_filter_weights(weights)) - - def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: - return self.model.get_expert_mapping() diff --git a/vllm/model_executor/models/hyperclovax.py b/vllm/model_executor/models/hyperclovax.py index b6d66698c92d..f89891f7b43f 100644 --- a/vllm/model_executor/models/hyperclovax.py +++ b/vllm/model_executor/models/hyperclovax.py @@ -26,7 +26,6 @@ # limitations under the License. """Inference-only HyperCLOVAX model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -55,7 +54,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, make_empty_intermediate_tensors_factory, @@ -473,13 +471,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights( - self, - weights: Iterable[tuple[str, torch.Tensor]], - ) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=["lm_head."] if self.config.tie_word_embeddings else None, - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/hyperclovax_vision.py b/vllm/model_executor/models/hyperclovax_vision.py index 53923d88438a..a12822085c73 100644 --- a/vllm/model_executor/models/hyperclovax_vision.py +++ b/vllm/model_executor/models/hyperclovax_vision.py @@ -3,7 +3,7 @@ # copied from : https://github.com/huggingface/transformers import ast from collections import defaultdict -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from functools import partial from itertools import accumulate from typing import Annotated, Literal @@ -40,7 +40,6 @@ from .interfaces import MultiModalEmbeddings, SupportsMultiModal, SupportsPP from .siglip import SiglipVisionModel from .utils import ( - AutoWeightsLoader, flatten_bn, init_vllm_registered_model, maybe_prefix, @@ -928,13 +927,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights( - self, - weights: Iterable[tuple[str, torch.Tensor]], - ) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - def _init_possible_resolutions( self, config, diff --git a/vllm/model_executor/models/hyperclovax_vision_v2.py b/vllm/model_executor/models/hyperclovax_vision_v2.py index 6cfeac67a527..9175c23c7eb9 100644 --- a/vllm/model_executor/models/hyperclovax_vision_v2.py +++ b/vllm/model_executor/models/hyperclovax_vision_v2.py @@ -10,7 +10,7 @@ - HyperCLOVAX-SEED-Think-32B: Vision + Text """ -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from functools import partial from typing import Annotated, Literal @@ -42,7 +42,6 @@ from .interfaces import MultiModalEmbeddings, SupportsMultiModal, SupportsPP from .qwen2_5_vl import Qwen2_5_VisionTransformer from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -672,10 +671,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights( - self, - weights: Iterable[tuple[str, torch.Tensor]], - ) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/idefics2_vision_model.py b/vllm/model_executor/models/idefics2_vision_model.py index 81e7e51eb97a..b18de26c60d8 100644 --- a/vllm/model_executor/models/idefics2_vision_model.py +++ b/vllm/model_executor/models/idefics2_vision_model.py @@ -357,7 +357,8 @@ class Idefics2VisionTransformer(nn.Module): ".q_proj": (".qkv_proj", "q"), ".k_proj": (".qkv_proj", "k"), ".v_proj": (".qkv_proj", "v"), - } + }, + orig_to_new_prefix={"head.": None}, ) def __init__( @@ -461,12 +462,6 @@ def forward( return last_hidden_state def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - # head is a pooling header absent from this model. - skip_prefixes = ["head."] - if not self.require_post_norm: - skip_prefixes.append("post_layernorm.") - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - layer_count = len(self.encoder.layers) def _filter(ws: Iterable[tuple[str, torch.Tensor]]): @@ -479,4 +474,8 @@ def _filter(ws: Iterable[tuple[str, torch.Tensor]]): continue yield name, w - return loader.load_weights(_filter(weights), mapper=self.hf_to_vllm_mapper) + mapper = self.hf_to_vllm_mapper + if not self.require_post_norm: + mapper |= WeightsMapper(orig_to_new_prefix={"post_layernorm.": None}) + loader = AutoWeightsLoader(self) + return loader.load_weights(_filter(weights), mapper=mapper) diff --git a/vllm/model_executor/models/idefics3.py b/vllm/model_executor/models/idefics3.py index ad94719241c5..5e1adbb699b7 100644 --- a/vllm/model_executor/models/idefics3.py +++ b/vllm/model_executor/models/idefics3.py @@ -16,7 +16,7 @@ # limitations under the License. """Inference-only Idefics3 model compatible with HuggingFace weights.""" -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Literal, TypeAlias import torch @@ -62,7 +62,7 @@ SupportsMultiModal, ) from .llama import LlamaModel -from .utils import AutoWeightsLoader, maybe_prefix +from .utils import maybe_prefix class Idefics3ImagePixelInputs(TensorSchema): @@ -679,10 +679,6 @@ def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.lm_head, hidden_states) return logits - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/intern_vit.py b/vllm/model_executor/models/intern_vit.py index 44ed3ec0fed8..c2035bf4f51a 100644 --- a/vllm/model_executor/models/intern_vit.py +++ b/vllm/model_executor/models/intern_vit.py @@ -7,7 +7,6 @@ # Copyright (c) 2023 OpenGVLab # Licensed under The MIT License [see LICENSE for details] # -------------------------------------------------------- -from collections.abc import Iterable from functools import partial import torch @@ -37,7 +36,6 @@ ) from vllm.model_executor.layers.quantization import QuantizationConfig -from .utils import AutoWeightsLoader from .vision import is_vit_use_data_parallel, run_dp_sharded_vision_model NORM2FN = { @@ -443,7 +441,3 @@ def forward( encoder_outputs = self.encoder(inputs_embeds=hidden_states) return encoder_outputs - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/internlm2.py b/vllm/model_executor/models/internlm2.py index 81487f9cad5b..f5027ac7301f 100644 --- a/vllm/model_executor/models/internlm2.py +++ b/vllm/model_executor/models/internlm2.py @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable from functools import partial from itertools import islice from typing import Any @@ -40,7 +39,6 @@ from .interfaces import SupportsLoRA, SupportsPP, SupportsQuant from .interfaces_base import default_pooling_type from .utils import ( - AutoWeightsLoader, StageMissingLayer, WeightsMapper, make_empty_intermediate_tensors_factory, @@ -316,13 +314,11 @@ def forward( hidden_states, _ = self.norm(hidden_states, residual) return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class InternLM2ForCausalLM(nn.Module, SupportsPP, SupportsLoRA, SupportsQuant): - hf_to_vllm_mapper = InternLM2Model.hf_to_vllm_mapper + hf_to_vllm_mapper = InternLM2Model.hf_to_vllm_mapper | WeightsMapper( + orig_to_new_prefix={"output.": "lm_head."} + ) packed_modules_mapping = { "wqkv": ["wqkv"], "gate_up_proj": ["w1", "w3"], @@ -345,14 +341,14 @@ def __init__( self.model = model_type( vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model") ) - self.output = ParallelLMHead( + self.lm_head = ParallelLMHead( config.vocab_size, config.hidden_size, quant_config=quant_config, - prefix=maybe_prefix(prefix, "output"), + prefix=maybe_prefix(prefix, "lm_head"), ) if self.config.tie_word_embeddings: - self.output.weight = self.model.tok_embeddings.weight + self.lm_head.weight = self.model.tok_embeddings.weight self.logits_processor = LogitsProcessor(config.vocab_size) self.make_empty_intermediate_tensors = ( self.model.make_empty_intermediate_tensors @@ -377,16 +373,9 @@ def compute_logits( self, hidden_states: torch.Tensor, ) -> torch.Tensor | None: - logits = self.logits_processor(self.output, hidden_states) + logits = self.logits_processor(self.lm_head, hidden_states) return logits - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["output."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) - @default_pooling_type(tok_pooling_type="ALL") class InternLM2ForRewardModel(InternLM2ForCausalLM): @@ -401,7 +390,7 @@ def __init__( ): with no_init_weights( self, - lambda mod: StageMissingLayer("output", mod), + lambda mod: StageMissingLayer("lm_head", mod), targets=(LogitsProcessor, ParallelLMHead), ): super().__init__( diff --git a/vllm/model_executor/models/interns1.py b/vllm/model_executor/models/interns1.py index 8b3828a91209..9ed424008101 100644 --- a/vllm/model_executor/models/interns1.py +++ b/vllm/model_executor/models/interns1.py @@ -6,7 +6,7 @@ # Copyright (c) 2025 Shanghai AI Lab # Licensed under The MIT License [see LICENSE for details] # -------------------------------------------------------- -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Literal, TypeAlias import regex as re @@ -57,7 +57,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -805,10 +804,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/interns1_pro.py b/vllm/model_executor/models/interns1_pro.py index c04b47294541..63373d088324 100644 --- a/vllm/model_executor/models/interns1_pro.py +++ b/vllm/model_executor/models/interns1_pro.py @@ -625,9 +625,9 @@ def get_frope_params_map(self) -> str: def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): """load weights""" - skip_prefixes = ["model.time_series."] + orig_to_new_prefix = {"model.time_series.": None} if self.visual is None: - skip_prefixes.append("visual.") + orig_to_new_prefix["visual."] = None # FIXME(Isotr0py): See if we can avoid tighing FoPE to PP layers weights_mapper = WeightsMapper( orig_to_new_prefix={ @@ -637,5 +637,6 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): }, orig_to_new_suffix=self.get_frope_params_map(), ) - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) + weights_mapper |= WeightsMapper(orig_to_new_prefix=orig_to_new_prefix) + loader = AutoWeightsLoader(self) return loader.load_weights(weights, mapper=weights_mapper) diff --git a/vllm/model_executor/models/interns1_vit.py b/vllm/model_executor/models/interns1_vit.py index a5bc781561ff..59268e64b05b 100644 --- a/vllm/model_executor/models/interns1_vit.py +++ b/vllm/model_executor/models/interns1_vit.py @@ -21,8 +21,6 @@ from vllm.model_executor.layers.linear import ColumnParallelLinear, RowParallelLinear from vllm.model_executor.layers.quantization import QuantizationConfig -from .utils import AutoWeightsLoader - NORM2FN = { "rms_norm": RMSNorm, "layer_norm": nn.LayerNorm, @@ -432,7 +430,3 @@ def forward( encoder_outputs = self.layernorm(encoder_outputs) return encoder_outputs - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/interns2_preview.py b/vllm/model_executor/models/interns2_preview.py index 6efc98aabc1f..944d8fc71543 100644 --- a/vllm/model_executor/models/interns2_preview.py +++ b/vllm/model_executor/models/interns2_preview.py @@ -1,8 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable - -import torch from transformers import AutoProcessor from vllm.multimodal import MULTIMODAL_REGISTRY @@ -13,7 +10,7 @@ Qwen3VLMultiModalProcessor, Qwen3VLProcessingInfo, ) -from .utils import AutoWeightsLoader +from .utils import WeightsMapper class InternS2PreviewProcessingInfo(Qwen3VLProcessingInfo): @@ -30,9 +27,13 @@ def get_hf_processor(self, **kwargs: object) -> AutoProcessor: dummy_inputs=Qwen3VLDummyInputsBuilder, ) class InternS2PreviewForConditionalGeneration(Qwen3_5MoeForConditionalGeneration): - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=["mtp.", "model.time_series.", "time_series."], + hf_to_vllm_mapper = ( + Qwen3_5MoeForConditionalGeneration.hf_to_vllm_mapper + | WeightsMapper( + orig_to_new_prefix={ + "mtp.": None, + "model.time_series.": None, + "time_series.": None, + } ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) + ) diff --git a/vllm/model_executor/models/internvl.py b/vllm/model_executor/models/internvl.py index eae9e66fb794..c2bd179284cf 100644 --- a/vllm/model_executor/models/internvl.py +++ b/vllm/model_executor/models/internvl.py @@ -8,7 +8,7 @@ # Licensed under The MIT License [see LICENSE for details] # -------------------------------------------------------- from abc import abstractmethod -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from functools import cached_property from typing import Annotated, Any, Literal, TypeAlias, TypeVar @@ -59,7 +59,7 @@ SupportsMultiModal, SupportsPP, ) -from .utils import AutoWeightsLoader, init_vllm_registered_model, maybe_prefix +from .utils import WeightsMapper, init_vllm_registered_model, maybe_prefix class InternVLImagePixelInputs(TensorSchema): @@ -552,6 +552,24 @@ class InternVLChatModel( ): supports_encoder_tp_data = True + # unused modules appear in OpenGVLab/InternVideo2_5_Chat_8B + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_prefix={ + "action_embed": None, + "temporal_embed": None, + "track_embed": None, + "track_embed_decoder": None, + "box_token": None, + "cg_criterion": None, + "cg_model": None, + "loc_encoder": None, + "loc_decoder": None, + "sam": None, + "temporal_token": None, + "track_token": None, + } + ) + @classmethod def get_placeholder_str(cls, modality: str, i: int) -> str | None: if modality.startswith("image"): @@ -862,25 +880,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - # unused modules appear in OpenGVLab/InternVideo2_5_Chat_8B - skip_prefixes = [ - "action_embed", - "temporal_embed", - "track_embed", - "track_embed_decoder", - "box_token", - "cg_criterion", - "cg_model", - "loc_encoder", - "loc_decoder", - "sam", - "temporal_token", - "track_token", - ] - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - return loader.load_weights(weights) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/iquest_loopcoder.py b/vllm/model_executor/models/iquest_loopcoder.py index 3755cba5d1ae..ba2feab10c64 100644 --- a/vllm/model_executor/models/iquest_loopcoder.py +++ b/vllm/model_executor/models/iquest_loopcoder.py @@ -50,7 +50,6 @@ from vllm.v1.attention.backend import AttentionType from .utils import ( - AutoWeightsLoader, extract_layer_index, make_layers, maybe_prefix, @@ -574,10 +573,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/isaac.py b/vllm/model_executor/models/isaac.py index 87932b50328e..32d0dbadc69b 100644 --- a/vllm/model_executor/models/isaac.py +++ b/vllm/model_executor/models/isaac.py @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project from __future__ import annotations -from collections.abc import Iterable, Iterator, Mapping, Sequence +from collections.abc import Iterator, Mapping, Sequence from typing import Annotated, Any import numpy as np @@ -35,7 +35,6 @@ from vllm.model_executor.models.module_mapping import MultiModelKeys from vllm.model_executor.models.siglip import SiglipMLP from vllm.model_executor.models.utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -719,10 +718,6 @@ def forward( # return last_hidden_state return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def _resolve_vision_token_id(model_config: ModelConfig, vision_token: str) -> int: tokenizer = cached_tokenizer_from_config(model_config) @@ -993,10 +988,6 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/jais2.py b/vllm/model_executor/models/jais2.py index 95b8c3ee44fe..529ee192ca9b 100644 --- a/vllm/model_executor/models/jais2.py +++ b/vllm/model_executor/models/jais2.py @@ -25,8 +25,6 @@ """Inference-only Jais2 model compatible with HuggingFace weights.""" -from collections.abc import Iterable - import torch from torch import nn from transformers import Jais2Config @@ -55,7 +53,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, extract_layer_index, @@ -435,10 +432,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/jamba.py b/vllm/model_executor/models/jamba.py index 33a8c6364176..9e44a60f8d8e 100644 --- a/vllm/model_executor/models/jamba.py +++ b/vllm/model_executor/models/jamba.py @@ -2,7 +2,6 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project """Inference-only Jamba model.""" -from collections.abc import Iterable from itertools import islice import torch @@ -46,7 +45,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -495,10 +493,6 @@ def compute_logits( logits = self.logits_processor(self.lm_head, hidden_states) return logits - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class JambaForSequenceClassification(JambaForCausalLM): is_pooling_model = True diff --git a/vllm/model_executor/models/jina.py b/vllm/model_executor/models/jina.py index 06f5ce282c6c..27f92114b5bb 100644 --- a/vllm/model_executor/models/jina.py +++ b/vllm/model_executor/models/jina.py @@ -32,6 +32,7 @@ class JinaForRanking(nn.Module, SupportsLateInteraction): is_pooling_model = True + hf_to_vllm_mapper = WeightsMapper(orig_to_new_prefix={"lm_head.": None}) def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): super().__init__() @@ -76,10 +77,6 @@ def forward( ) return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=(["lm_head."])) - return loader.load_weights(weights) - class JinaForRankingPool(StepPool): def __init__(self, projector: nn.Sequential): diff --git a/vllm/model_executor/models/kanana_v.py b/vllm/model_executor/models/kanana_v.py index 125d7e71c7b5..2e140c87ac01 100644 --- a/vllm/model_executor/models/kanana_v.py +++ b/vllm/model_executor/models/kanana_v.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from functools import partial from typing import Annotated, Literal, TypeAlias @@ -40,7 +40,7 @@ from .interfaces import MultiModalEmbeddings, SupportsMultiModal, SupportsPP from .qwen2_vl import Qwen2VisionTransformer -from .utils import AutoWeightsLoader, init_vllm_registered_model, maybe_prefix +from .utils import init_vllm_registered_model, maybe_prefix logger = init_logger(__name__) @@ -752,7 +752,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/keye.py b/vllm/model_executor/models/keye.py index dd1fb892ad19..05cd92793107 100644 --- a/vllm/model_executor/models/keye.py +++ b/vllm/model_executor/models/keye.py @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project import math from abc import abstractmethod -from collections.abc import Iterable, Iterator, Mapping, Sequence +from collections.abc import Iterator, Mapping, Sequence from functools import partial from typing import Annotated, Any, Literal, TypeAlias, TypeVar @@ -69,7 +69,6 @@ ) from .siglip import SiglipMLP from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -714,11 +713,12 @@ class KeyeSiglipVisionModel(nn.Module): main_input_name = "pixel_values" hf_to_vllm_mapper = WeightsMapper( + orig_to_new_prefix={"vision_model.head.": None}, orig_to_new_stacked={ ".q_proj": (".qkv_proj", "q"), ".k_proj": (".qkv_proj", "k"), ".v_proj": (".qkv_proj", "v"), - } + }, ) def __init__( @@ -778,10 +778,6 @@ def forward( window_size=window_size, ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["vision_model.head."]) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Projector(nn.Module): def __init__( @@ -1449,10 +1445,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """Get the module prefix in multimodal models.""" return MultiModelKeys.from_string_field( diff --git a/vllm/model_executor/models/kimi_audio.py b/vllm/model_executor/models/kimi_audio.py index cb3c83e70891..187c8b2bd803 100644 --- a/vllm/model_executor/models/kimi_audio.py +++ b/vllm/model_executor/models/kimi_audio.py @@ -108,10 +108,6 @@ def __init__( init_in_fp32=init_in_fp32, ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - # ----------------------------------------------------------------------------- # Processing Info, Dummy Inputs, and MultiModal Processor @@ -575,18 +571,19 @@ def compute_logits( def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: """Load weights, skipping MIMO layers (TTS-only) for ASR.""" # Filter out MIMO/TTS weights since we only do ASR (speech-to-text) - skipped_patterns = [ - # Audio tower - "model.", - # MIMO/TTS - "mimo_layers.", - "mimo_output.", - "mimo_norm.", - ] - # Load main model weights (LLM + projector) with mapper - loader = AutoWeightsLoader(self, skip_prefixes=skipped_patterns) - loaded = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) + drop = WeightsMapper( + orig_to_new_prefix={ + # Audio tower + "model.": None, + # MIMO/TTS + "mimo_layers.": None, + "mimo_output.": None, + "mimo_norm.": None, + } + ) + loader = AutoWeightsLoader(self) + loaded = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper | drop) return loaded @classmethod diff --git a/vllm/model_executor/models/kimi_k25.py b/vllm/model_executor/models/kimi_k25.py index 79b6e272bbb1..bbd29a9d2fb0 100644 --- a/vllm/model_executor/models/kimi_k25.py +++ b/vllm/model_executor/models/kimi_k25.py @@ -6,7 +6,7 @@ Kimi-K2.5 extends Kimi-K2 with vision support. """ -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from dataclasses import dataclass from typing import Annotated, Any, Literal @@ -64,7 +64,6 @@ from vllm.utils.tensor_schema import TensorSchema, TensorShape from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -469,7 +468,3 @@ def set_aux_hidden_state_layers(self, layers: tuple[int, ...]) -> None: def get_eagle3_aux_hidden_state_layers(self) -> tuple[int, ...]: return self.language_model.get_eagle3_aux_hidden_state_layers() - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/kimi_linear.py b/vllm/model_executor/models/kimi_linear.py index 057d4d01cb05..1ad75d964ca4 100644 --- a/vllm/model_executor/models/kimi_linear.py +++ b/vllm/model_executor/models/kimi_linear.py @@ -50,7 +50,6 @@ from .interfaces import HasInnerState, IsHybrid, MixtureOfExperts, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, get_spec_layer_idx_from_weight_name, is_pp_missing_parameter, @@ -637,10 +636,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.logits_processor(self.lm_head, hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/kimi_vl.py b/vllm/model_executor/models/kimi_vl.py index 2b08fc6c1fd2..110f7edac89b 100644 --- a/vllm/model_executor/models/kimi_vl.py +++ b/vllm/model_executor/models/kimi_vl.py @@ -43,7 +43,7 @@ # SOFTWARE. import math -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from dataclasses import dataclass from typing import Annotated, Any, Literal @@ -85,7 +85,7 @@ from vllm.utils.tensor_schema import TensorSchema, TensorShape from vllm.v1.worker.encoder_cudagraph_defs import EncoderCudaGraphReplayBuffers -from .utils import AutoWeightsLoader, init_vllm_registered_model, maybe_prefix +from .utils import init_vllm_registered_model, maybe_prefix from .vision import is_vit_use_data_parallel, run_dp_sharded_mrope_vision_model @@ -603,7 +603,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor, **kwargs) -> torch.Tensor: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/laguna.py b/vllm/model_executor/models/laguna.py index e71054f4da39..a0242862afc5 100644 --- a/vllm/model_executor/models/laguna.py +++ b/vllm/model_executor/models/laguna.py @@ -765,10 +765,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/lfm2.py b/vllm/model_executor/models/lfm2.py index 601bd22b2fac..f95c0b86b5d0 100644 --- a/vllm/model_executor/models/lfm2.py +++ b/vllm/model_executor/models/lfm2.py @@ -1,8 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable from itertools import islice +import regex as re import torch import torch.nn as nn from transformers import Lfm2Config @@ -36,7 +36,6 @@ from .interfaces import HasInnerState, IsHybrid, SupportsLoRA, SupportsPP, SupportsQuant from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, extract_layer_index, @@ -298,8 +297,10 @@ class Lfm2Model(nn.Module): # HF uses .conv. but vLLM uses .short_conv. to avoid LoRA regex collision # with the inner .conv.conv child (ShortConv has a child self.conv, so # naming the container .conv too makes _match_target_modules match both). + # Anchored on the layer index so it is idempotent (the mapper is applied + # both at the root and on recursion into this module). hf_to_vllm_mapper = WeightsMapper( - orig_to_new_substr={".conv.": ".short_conv."}, + orig_to_new_regex={re.compile(r"(\d+)\.conv\."): r"\1.short_conv."}, orig_to_new_stacked={ ".q_proj": (".qkv_proj", "q"), ".k_proj": (".qkv_proj", "k"), @@ -386,10 +387,6 @@ def forward( hidden_states, _ = self.embedding_norm(hidden_states, residual) return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Lfm2ForCausalLM( nn.Module, HasInnerState, SupportsLoRA, SupportsPP, IsHybrid, SupportsQuant @@ -505,10 +502,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/lfm2_moe.py b/vllm/model_executor/models/lfm2_moe.py index 698f1fb72ef2..a14abd86c710 100644 --- a/vllm/model_executor/models/lfm2_moe.py +++ b/vllm/model_executor/models/lfm2_moe.py @@ -672,10 +672,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/lfm2_siglip2.py b/vllm/model_executor/models/lfm2_siglip2.py index f1679af813c4..a03a481f8374 100644 --- a/vllm/model_executor/models/lfm2_siglip2.py +++ b/vllm/model_executor/models/lfm2_siglip2.py @@ -508,11 +508,6 @@ def forward( ) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - skip_prefixes = [] - if self.vision_model.post_layernorm is None: - skip_prefixes.append("vision_model.post_layernorm.") - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - # Drop layers omitted by num_hidden_layers_override. layer_count = len(self.vision_model.encoder.layers) @@ -525,4 +520,10 @@ def _filter(ws): continue yield n, w - return loader.load_weights(_filter(weights), mapper=self.hf_to_vllm_mapper) + mapper = self.hf_to_vllm_mapper + if self.vision_model.post_layernorm is None: + mapper |= WeightsMapper( + orig_to_new_prefix={"vision_model.post_layernorm.": None} + ) + loader = AutoWeightsLoader(self) + return loader.load_weights(_filter(weights), mapper=mapper) diff --git a/vllm/model_executor/models/lfm2_vl.py b/vllm/model_executor/models/lfm2_vl.py index ce60f2d236d9..5d7859d21da8 100644 --- a/vllm/model_executor/models/lfm2_vl.py +++ b/vllm/model_executor/models/lfm2_vl.py @@ -3,7 +3,7 @@ import itertools import math -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Any, Literal import torch @@ -56,7 +56,6 @@ ) from .lfm2_siglip2 import Siglip2Model from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -1246,10 +1245,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/lightonocr.py b/vllm/model_executor/models/lightonocr.py index c1ee640f63a5..fc3d18289db1 100644 --- a/vllm/model_executor/models/lightonocr.py +++ b/vllm/model_executor/models/lightonocr.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import TypeVar import torch @@ -20,7 +20,6 @@ ) from vllm.model_executor.models.pixtral import PixtralHFEncoderInfo from vllm.model_executor.models.utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -178,7 +177,3 @@ def __init__(self, *, vllm_config: VllmConfig, prefix: str = "") -> None: self.make_empty_intermediate_tensors = ( self.language_model.make_empty_intermediate_tensors ) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/llama.py b/vllm/model_executor/models/llama.py index bb223a311460..c3239bb0f5b6 100644 --- a/vllm/model_executor/models/llama.py +++ b/vllm/model_executor/models/llama.py @@ -24,7 +24,6 @@ # limitations under the License. """Inference-only LLaMA model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -66,7 +65,6 @@ SupportsQuant, ) from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, extract_layer_index, @@ -438,10 +436,6 @@ def forward( return hidden_states, aux_hidden_states return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class LlamaForCausalLM( LocalArgmaxMixin, @@ -532,13 +526,6 @@ def compute_logits( logits = self.logits_processor(self.lm_head, hidden_states) return logits - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) - class LlamaBidirectionalForSequenceClassification(as_seq_cls_model(LlamaForCausalLM)): # This class sets the correct attention type and pooling type diff --git a/vllm/model_executor/models/llama4.py b/vllm/model_executor/models/llama4.py index 71df54a42417..c94d415e33c0 100644 --- a/vllm/model_executor/models/llama4.py +++ b/vllm/model_executor/models/llama4.py @@ -792,10 +792,7 @@ def _init_model( ) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) + loader = AutoWeightsLoader(self) # Use a generator (not a list comprehension) so the weights iterator is # consumed lazily by AutoWeightsLoader. Materializing it here would hold # the entire language-model checkpoint in host memory at once, which can diff --git a/vllm/model_executor/models/llama4_eagle.py b/vllm/model_executor/models/llama4_eagle.py index d94dbb049668..03858d119206 100644 --- a/vllm/model_executor/models/llama4_eagle.py +++ b/vllm/model_executor/models/llama4_eagle.py @@ -122,10 +122,6 @@ def forward( hidden_states, _ = self.norm(hidden_states, residual) return hidden_states, hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def validate_and_update_config( self, start_layer_id: int, quant_config: QuantizationConfig | None = None ) -> None: @@ -206,9 +202,5 @@ def transform(inputs): process_eagle_weight(self, name) return name, weight - loader = AutoWeightsLoader( - self, - # lm_head is tied with target model (Llama4ForCausalLM) - skip_prefixes=([]), - ) + loader = AutoWeightsLoader(self) loader.load_weights(map(transform, weights)) diff --git a/vllm/model_executor/models/llama_eagle.py b/vllm/model_executor/models/llama_eagle.py index 5d13b29c0cbf..ae255f8b1ebf 100644 --- a/vllm/model_executor/models/llama_eagle.py +++ b/vllm/model_executor/models/llama_eagle.py @@ -123,10 +123,6 @@ def forward( hidden_states = hidden_states + residual return hidden_states, hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class EagleLlamaForCausalLM(LlamaForCausalLM): def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): @@ -175,8 +171,5 @@ def transform(inputs): process_eagle_weight(self, name) return name, loaded_weight - loader = AutoWeightsLoader( - self, - skip_prefixes=None, - ) + loader = AutoWeightsLoader(self) loader.load_weights(map(transform, weights)) diff --git a/vllm/model_executor/models/llama_eagle3.py b/vllm/model_executor/models/llama_eagle3.py index 549e8b7bf63a..62b412767cde 100644 --- a/vllm/model_executor/models/llama_eagle3.py +++ b/vllm/model_executor/models/llama_eagle3.py @@ -264,10 +264,6 @@ def forward( }, ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Eagle3LlamaForCausalLM(LlamaForCausalLM): def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): @@ -415,18 +411,15 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): "Please provide mask_hidden in the weights." ) - skip_substrs = ["mask_hidden"] + orig_to_new_substr = {"mask_hidden": None} if not includes_draft_id_mapping: - skip_substrs.append("draft_id_to_target_id") + orig_to_new_substr["draft_id_to_target_id"] = None if not includes_embed_tokens: - skip_substrs.append("embed_tokens") + orig_to_new_substr["embed_tokens"] = None if not self.model.use_aux_hidden_state: - skip_substrs.append("fc.") + orig_to_new_substr["fc."] = None if not self.model.norm_before_fc: - skip_substrs.append("input_norm.") - loader = AutoWeightsLoader( - self, - skip_prefixes=None, - skip_substrs=skip_substrs, - ) - loader.load_weights(model_weights.items()) + orig_to_new_substr["input_norm."] = None + drop = WeightsMapper(orig_to_new_substr=orig_to_new_substr) + loader = AutoWeightsLoader(self) + loader.load_weights(model_weights.items(), mapper=drop) diff --git a/vllm/model_executor/models/llava.py b/vllm/model_executor/models/llava.py index 1e850a7efc6e..444cacc505a1 100644 --- a/vllm/model_executor/models/llava.py +++ b/vllm/model_executor/models/llava.py @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project from abc import abstractmethod -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Final, Literal, Protocol, TypeAlias, TypeVar import torch @@ -61,7 +61,6 @@ from .pixtral import PixtralHFEncoderInfo, PixtralHFVisionModel from .siglip import SiglipVisionModel from .utils import ( - AutoWeightsLoader, WeightsMapper, get_layer_index, init_vllm_registered_model, @@ -723,10 +722,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/llava_next.py b/vllm/model_executor/models/llava_next.py index fdd1d41af5a3..5463cdd8bb41 100644 --- a/vllm/model_executor/models/llava_next.py +++ b/vllm/model_executor/models/llava_next.py @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project from abc import abstractmethod -from collections.abc import Iterable, Mapping +from collections.abc import Mapping from typing import Annotated, Final, Literal, Protocol, TypeAlias, TypeVar import torch @@ -32,7 +32,6 @@ ) from .siglip import SiglipVisionModel from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -580,7 +579,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/llava_onevision.py b/vllm/model_executor/models/llava_onevision.py index 1beec4207d53..034acc0ecf35 100644 --- a/vllm/model_executor/models/llava_onevision.py +++ b/vllm/model_executor/models/llava_onevision.py @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project import math -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Final, Literal, Protocol, TypeAlias import torch @@ -42,7 +42,6 @@ ) from .siglip import SiglipVisionModel from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -912,7 +911,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/llava_onevision2.py b/vllm/model_executor/models/llava_onevision2.py index 552e2a9e8f8d..7fc19b0669e8 100644 --- a/vllm/model_executor/models/llava_onevision2.py +++ b/vllm/model_executor/models/llava_onevision2.py @@ -26,7 +26,7 @@ import importlib import json import os -from collections.abc import Callable, Iterable, Mapping, Sequence +from collections.abc import Callable, Mapping, Sequence from functools import lru_cache from typing import ( Annotated, @@ -70,7 +70,6 @@ ) from vllm.model_executor.models.module_mapping import MultiModelKeys from vllm.model_executor.models.utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -2254,10 +2253,6 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor): return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: return MultiModelKeys.from_string_field( language_model="language_model", diff --git a/vllm/model_executor/models/longcat_flash.py b/vllm/model_executor/models/longcat_flash.py index 18628a64cef7..31bea70ad56a 100644 --- a/vllm/model_executor/models/longcat_flash.py +++ b/vllm/model_executor/models/longcat_flash.py @@ -69,7 +69,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, is_pp_missing_parameter, make_empty_intermediate_tensors_factory, @@ -779,7 +778,3 @@ def compute_logits( def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: return self.model.get_expert_mapping() - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/longcat_flash_ngram.py b/vllm/model_executor/models/longcat_flash_ngram.py index 5aaa1aad9bb8..fbb06e700851 100644 --- a/vllm/model_executor/models/longcat_flash_ngram.py +++ b/vllm/model_executor/models/longcat_flash_ngram.py @@ -31,7 +31,7 @@ from .interfaces import SupportsLoRA, SupportsPP from .longcat_flash import FlashConfig, FlashModel -from .utils import AutoWeightsLoader, PPMissingLayer, maybe_prefix +from .utils import PPMissingLayer, WeightsMapper, maybe_prefix def uses_ngram_embedding(config: FlashConfig) -> bool: @@ -208,6 +208,7 @@ class LongcatFlashNgramForCausalLM(nn.Module, SupportsLoRA, SupportsPP): "qkv_proj": ["q_proj", "k_proj", "v_proj"], "gate_up_proj": ["gate_proj", "up_proj"], } + hf_to_vllm_mapper = WeightsMapper(orig_to_new_prefix={"model.mtp.": None}) def __init__(self, *, vllm_config: VllmConfig, prefix: str = "") -> None: super().__init__() @@ -264,13 +265,6 @@ def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None: def get_expert_mapping(self): return self.model.get_expert_mapping() - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - # AutoWeightsLoader routes ``model.*`` to FlashNgramModel.load_weights - # (which handles the ngram split) and ``lm_head.*`` to the head. MTP - # weights are not part of this model. - loader = AutoWeightsLoader(self, skip_prefixes=["model.mtp."]) - return loader.load_weights(weights) - class LongcatNgramModelState(DefaultModelState): """Per-request n-gram token history for LongCat-Flash-Lite. diff --git a/vllm/model_executor/models/mamba.py b/vllm/model_executor/models/mamba.py index 6a77a58abf4d..77bcc5828d5a 100644 --- a/vllm/model_executor/models/mamba.py +++ b/vllm/model_executor/models/mamba.py @@ -2,7 +2,6 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project """PyTorch MAMBA model.""" -from collections.abc import Iterable from itertools import islice import torch @@ -35,7 +34,6 @@ from vllm.sequence import IntermediateTensors from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -259,7 +257,3 @@ def get_seqlen_agnostic_capture_inputs(self, batch_size: int): def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/mamba2.py b/vllm/model_executor/models/mamba2.py index 343111ee0151..cd22cb7e0647 100644 --- a/vllm/model_executor/models/mamba2.py +++ b/vllm/model_executor/models/mamba2.py @@ -2,8 +2,6 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project """PyTorch MAMBA2 model.""" -from collections.abc import Iterable - import torch from torch import nn from transformers import MambaConfig @@ -33,7 +31,6 @@ from vllm.sequence import IntermediateTensors from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -271,7 +268,3 @@ def get_seqlen_agnostic_capture_inputs(self, batch_size: int): def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/midashenglm.py b/vllm/model_executor/models/midashenglm.py index 5ecc92e4d04b..604506b369a2 100644 --- a/vllm/model_executor/models/midashenglm.py +++ b/vllm/model_executor/models/midashenglm.py @@ -25,7 +25,7 @@ import collections import collections.abc -from collections.abc import Callable, Iterable, Mapping, Sequence +from collections.abc import Callable, Mapping, Sequence from typing import Annotated, Any, TypeAlias, cast import numpy as np @@ -66,7 +66,7 @@ from vllm.utils.tensor_schema import TensorSchema, TensorShape from .interfaces import MultiModalEmbeddings, SupportsMultiModal, SupportsPP -from .utils import AutoWeightsLoader, init_vllm_registered_model, maybe_prefix +from .utils import init_vllm_registered_model, maybe_prefix _Tuple2: TypeAlias = int | tuple[int, int] | Sequence[int] @@ -821,7 +821,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.decoder.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/mimo.py b/vllm/model_executor/models/mimo.py index e4247fa8d8df..cb208ce0cd21 100644 --- a/vllm/model_executor/models/mimo.py +++ b/vllm/model_executor/models/mimo.py @@ -26,7 +26,6 @@ # limitations under the License. """Inference-only MiMo model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -41,7 +40,7 @@ from vllm.model_executor.models.qwen2 import Qwen2ForCausalLM, Qwen2Model from vllm.sequence import IntermediateTensors -from .utils import AutoWeightsLoader, PPMissingLayer, maybe_prefix +from .utils import PPMissingLayer, WeightsMapper, maybe_prefix logger = init_logger(__name__) @@ -87,6 +86,8 @@ def forward( class MiMoForCausalLM(Qwen2ForCausalLM, nn.Module): + hf_to_vllm_mapper = WeightsMapper(orig_to_new_prefix={"model.mtp_layers.": None}) + def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): nn.Module.__init__(self) config = vllm_config.model_config.hf_config @@ -119,13 +120,6 @@ def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): self.model.make_empty_intermediate_tensors ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - skip_prefixes = ["lm_head."] if self.config.tie_word_embeddings else [] - # MTP layers are loaded by the draft model, not the main model. - skip_prefixes.append("model.mtp_layers.") - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - return loader.load_weights(weights) - def compute_logits( self, hidden_states: torch.Tensor, diff --git a/vllm/model_executor/models/mimo_v2.py b/vllm/model_executor/models/mimo_v2.py index 4c2ebd958b58..f71f14dcc887 100644 --- a/vllm/model_executor/models/mimo_v2.py +++ b/vllm/model_executor/models/mimo_v2.py @@ -60,7 +60,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, PPMissingLayer, extract_layer_index, is_pp_missing_parameter, @@ -894,10 +893,6 @@ def compute_logits( def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: return self.model.get_expert_mapping() - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - class MiMoV2ForCausalLM(MiMoV2FlashForCausalLM): packed_modules_mapping = { diff --git a/vllm/model_executor/models/mimo_v2_omni.py b/vllm/model_executor/models/mimo_v2_omni.py index d0d9589ae1da..d5970a1defc4 100644 --- a/vllm/model_executor/models/mimo_v2_omni.py +++ b/vllm/model_executor/models/mimo_v2_omni.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project import math -from collections.abc import Callable, Iterable, Mapping, Sequence +from collections.abc import Callable, Mapping, Sequence from functools import partial from typing import Any @@ -67,7 +67,7 @@ Qwen2_5_VLVideoPixelInputs, ) from .qwen2_vl import _create_qwen2vl_field_factory -from .utils import AutoWeightsLoader, IntermediateTensors, WeightsMapper, maybe_prefix +from .utils import IntermediateTensors, WeightsMapper, maybe_prefix class MiMoVisionMLP(Qwen2_5_VisionMLP): @@ -632,10 +632,6 @@ def forward(self, x: torch.Tensor, grid_thw: torch.Tensor) -> torch.Tensor: x = self.merger(x) return x - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class MiMoV2OmniProcessingInfo(BaseProcessingInfo): def get_supported_mm_limits(self) -> Mapping[str, int | None]: @@ -1160,6 +1156,7 @@ class MiMoV2OmniForCausalLM(nn.Module, SupportsMultiModal, SupportsPP, SupportsQ # To ensure correct weight loading and mapping. hf_to_vllm_mapper = WeightsMapper( orig_to_new_prefix={ + "audio_tokenizer.": None, # audio encoder "speech_embeddings.": "audio_encoder.speech_embeddings.", # mapping for new names in checkpoint saved after transformers v4.52 @@ -1465,10 +1462,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - audio_loaded: set[str] = set() - - loader = AutoWeightsLoader(self, skip_prefixes=["audio_tokenizer."]) - auto_loaded = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - return audio_loaded | auto_loaded diff --git a/vllm/model_executor/models/minicpm.py b/vllm/model_executor/models/minicpm.py index ee9b31f140bd..32b114c18fcb 100644 --- a/vllm/model_executor/models/minicpm.py +++ b/vllm/model_executor/models/minicpm.py @@ -71,7 +71,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, is_pp_missing_parameter, make_empty_intermediate_tensors_factory, make_layers, @@ -646,10 +645,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/minicpm_eagle.py b/vllm/model_executor/models/minicpm_eagle.py index 890d52961c4e..89ce01d6117c 100644 --- a/vllm/model_executor/models/minicpm_eagle.py +++ b/vllm/model_executor/models/minicpm_eagle.py @@ -387,8 +387,5 @@ def transform(inputs): process_eagle_weight(self, name) return name, loaded_weight - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) + loader = AutoWeightsLoader(self) return loader.load_weights(map(transform, weights)) diff --git a/vllm/model_executor/models/minicpmo.py b/vllm/model_executor/models/minicpmo.py index bd8547420c6d..ae246da6b564 100644 --- a/vllm/model_executor/models/minicpmo.py +++ b/vllm/model_executor/models/minicpmo.py @@ -71,7 +71,7 @@ MiniCPMVProcessingInfo, _minicpmv_field_config, ) -from .utils import AutoWeightsLoader, cast_overflow_tensors, maybe_prefix +from .utils import AutoWeightsLoader, WeightsMapper, cast_overflow_tensors, maybe_prefix CPU_DEVICE = torch.device("cpu") @@ -672,6 +672,8 @@ def forward( class MiniCPMOBaseModel: """Base mixin class for MiniCPM-O models with audio support.""" + hf_to_vllm_mapper: WeightsMapper = WeightsMapper(orig_to_new_prefix={"tts": None}) + packed_modules_mapping = { "qkv_proj": [ "q_proj", @@ -718,8 +720,8 @@ def init_audio_module(self, *, vllm_config: VllmConfig, prefix: str = ""): return model def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["tts"]) - loaded = loader.load_weights(weights) + loader = AutoWeightsLoader(self) + loaded = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) self._ensure_resampler_device() return loaded diff --git a/vllm/model_executor/models/minicpmv.py b/vllm/model_executor/models/minicpmv.py index 60b111298214..2370dcd92f52 100644 --- a/vllm/model_executor/models/minicpmv.py +++ b/vllm/model_executor/models/minicpmv.py @@ -93,7 +93,7 @@ SupportsMultiModal, SupportsPP, ) -from .utils import AutoWeightsLoader, flatten_bn, maybe_prefix +from .utils import AutoWeightsLoader, WeightsMapper, flatten_bn, maybe_prefix # For profile run _MAX_FRAMES_PER_VIDEO = 16 @@ -1513,8 +1513,11 @@ def get_vision_hidden_states(self, data: MiniCPMVImagePixelInputs) -> torch.Tens return self.resampler(vision_embedding, tgt_sizes) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["apm.", "audio", "tts"]) - loaded = loader.load_weights(weights) + loader = AutoWeightsLoader(self) + drop = WeightsMapper( + orig_to_new_prefix={"apm.": None, "audio": None, "tts": None} + ) + loaded = loader.load_weights(weights, mapper=drop) self._ensure_resampler_device() return loaded @@ -1610,8 +1613,11 @@ def get_vision_hidden_states(self, data: MiniCPMVImagePixelInputs) -> torch.Tens return self.resampler(vision_embedding, tgt_sizes) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["apm.", "audio", "tts"]) - loaded = loader.load_weights(weights) + loader = AutoWeightsLoader(self) + drop = WeightsMapper( + orig_to_new_prefix={"apm.": None, "audio": None, "tts": None} + ) + loaded = loader.load_weights(weights, mapper=drop) self._ensure_resampler_device() return loaded @@ -1712,8 +1718,11 @@ def get_vision_hidden_states(self, data: MiniCPMVImagePixelInputs) -> torch.Tens return self.resampler(vision_embedding, tgt_sizes, all_temporal_ids) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["apm.", "audio", "tts"]) - loaded = loader.load_weights(weights) + loader = AutoWeightsLoader(self) + drop = WeightsMapper( + orig_to_new_prefix={"apm.": None, "audio": None, "tts": None} + ) + loaded = loader.load_weights(weights, mapper=drop) self._ensure_resampler_device() return loaded diff --git a/vllm/model_executor/models/minicpmv4_6.py b/vllm/model_executor/models/minicpmv4_6.py index dc75928eb6c1..73ad2b9ee8a8 100644 --- a/vllm/model_executor/models/minicpmv4_6.py +++ b/vllm/model_executor/models/minicpmv4_6.py @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project """Inference-only MiniCPM-V 4.6 model (MiniCPMV4_6ForConditionalGeneration).""" -from collections.abc import Iterable, Mapping +from collections.abc import Mapping from typing import Any import numpy as np @@ -63,7 +63,6 @@ from .module_mapping import MultiModelKeys from .qwen3_5 import Qwen3_5ForCausalLM from .utils import ( - AutoWeightsLoader, WeightsMapper, _merge_multimodal_embeddings, flatten_bn, @@ -704,10 +703,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: out, _ = self.out_proj(attn_out) return out - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class MiniCPMV4_6ViTWindowAttentionMerger(nn.Module): def __init__( @@ -956,6 +951,7 @@ class MiniCPMV4_6ForConditionalGeneration( "model.merger.": "merger.", "model.language_model.": "language_model.model.", "lm_head.": "language_model.lm_head.", + "mtp.": None, } ) @@ -1275,13 +1271,6 @@ def compute_logits( # ----- Weight loading ----- - def load_weights( - self, - weights: Iterable[tuple[str, torch.Tensor]], - ) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["mtp."]) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: return MultiModelKeys.from_string_field( language_model="language_model", diff --git a/vllm/model_executor/models/minimax_m2.py b/vllm/model_executor/models/minimax_m2.py index 79bd8f439e3f..6c506e8f6b9c 100644 --- a/vllm/model_executor/models/minimax_m2.py +++ b/vllm/model_executor/models/minimax_m2.py @@ -417,16 +417,14 @@ def forward( def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: # Skip spec-decode (MTP) layers; they are appended after the main # decoder layers and have no destination in the main model. - skip_prefixes = None + orig_to_new_prefix = {} num_mtp = getattr(self.config, "num_mtp_modules", 0) if num_mtp: base = self.config.num_hidden_layers - skip_prefixes = [f"layers.{base + i}." for i in range(num_mtp)] - loader = AutoWeightsLoader( - self, - skip_prefixes=skip_prefixes, - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) + orig_to_new_prefix = {f"layers.{base + i}.": None for i in range(num_mtp)} + drop = WeightsMapper(orig_to_new_prefix=orig_to_new_prefix) + loader = AutoWeightsLoader(self) + return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper | drop) class MiniMaxM2ForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsEagle3): @@ -486,7 +484,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/mistral.py b/vllm/model_executor/models/mistral.py index ce1332d0c9d1..86c4b171e5f1 100644 --- a/vllm/model_executor/models/mistral.py +++ b/vllm/model_executor/models/mistral.py @@ -277,10 +277,7 @@ def _init_model( ) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) + loader = AutoWeightsLoader(self) return loader.load_weights( self.maybe_remap_mistral(name, loaded_weight) for name, loaded_weight in weights diff --git a/vllm/model_executor/models/mistral3.py b/vllm/model_executor/models/mistral3.py index 025ce564083c..bbca6bd74673 100644 --- a/vllm/model_executor/models/mistral3.py +++ b/vllm/model_executor/models/mistral3.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Literal import torch @@ -44,7 +44,6 @@ ) from .pixtral import PixtralHFEncoderInfo, PixtralHFVisionModel from .utils import ( - AutoWeightsLoader, WeightsMapper, get_layer_index, init_vllm_registered_model, @@ -559,10 +558,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/mistral_large_3.py b/vllm/model_executor/models/mistral_large_3.py index 603ce5c0f010..776be18dc3ff 100644 --- a/vllm/model_executor/models/mistral_large_3.py +++ b/vllm/model_executor/models/mistral_large_3.py @@ -1,12 +1,10 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable import regex -import torch from vllm.model_executor.models.deepseek_v2 import DeepseekV3ForCausalLM -from vllm.model_executor.models.utils import AutoWeightsLoader, WeightsMapper +from vllm.model_executor.models.utils import WeightsMapper class MistralLarge3ForCausalLM(DeepseekV3ForCausalLM): @@ -82,11 +80,3 @@ class MistralLarge3ForCausalLM(DeepseekV3ForCausalLM): ".qscale_weight": ".weight_scale", }, ) - - # Bypass super().load_weights() and construct AutoWeightsLoader(self) - # directly (same pattern as Qwen2ForCausalLM). Any logic in the parent - # class's load_weights is a thin wrapper around AutoWeightsLoader, and - # we must apply hf_to_vllm_mapper before the loader walks the tree. - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/mistral_large_3_eagle.py b/vllm/model_executor/models/mistral_large_3_eagle.py index 8ace01205d03..d405f264faca 100644 --- a/vllm/model_executor/models/mistral_large_3_eagle.py +++ b/vllm/model_executor/models/mistral_large_3_eagle.py @@ -23,7 +23,12 @@ from vllm.model_executor.models.mistral_large_3 import MistralLarge3ForCausalLM from .interfaces import SupportsMultiModal -from .utils import WeightsMapper, make_empty_intermediate_tensors_factory, maybe_prefix +from .utils import ( + AutoWeightsLoader, + WeightsMapper, + make_empty_intermediate_tensors_factory, + maybe_prefix, +) logger = init_logger(__name__) @@ -149,7 +154,9 @@ def forward( def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: # Pretend we've loaded the embedding and lm_head weights # (later copied from target model) - return super().load_weights(weights) | { + loader = AutoWeightsLoader(self) + loaded = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) + return loaded | { "model.embed_tokens.weight", "lm_head.weight", } diff --git a/vllm/model_executor/models/mixtral.py b/vllm/model_executor/models/mixtral.py index 8305ecc330f9..a24eefcf7143 100644 --- a/vllm/model_executor/models/mixtral.py +++ b/vllm/model_executor/models/mixtral.py @@ -24,7 +24,6 @@ # limitations under the License. """Inference-only Mixtral model.""" -from collections.abc import Iterable from itertools import islice import torch @@ -59,7 +58,6 @@ from .interfaces import MixtureOfExperts, SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, make_empty_intermediate_tensors_factory, @@ -368,10 +366,6 @@ def forward( hidden_states, _ = self.norm(hidden_states, residual) return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class MixtralForCausalLM(nn.Module, SupportsLoRA, SupportsPP, MixtureOfExperts): fall_back_to_pt_during_load = False @@ -483,7 +477,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/mllama4.py b/vllm/model_executor/models/mllama4.py index 178dae506c6b..317bbf5ec496 100644 --- a/vllm/model_executor/models/mllama4.py +++ b/vllm/model_executor/models/mllama4.py @@ -266,14 +266,16 @@ def __init__( prefix=f"{prefix}.attn", ) + self.qkv_proj = QKVParallelLinear( + self.embed_dim, + self.head_dim, + self.num_heads, + bias=True, + quant_config=quant_config, + prefix=f"{prefix}.qkv_proj", + disable_tp=use_data_parallel, + ) if use_data_parallel: - self.qkv_proj = ReplicatedLinear( - self.embed_dim, - self.q_size + 2 * self.kv_size, - bias=True, - quant_config=quant_config, - prefix=f"{prefix}.qkv_proj", - ) self.o_proj = ReplicatedLinear( self.num_heads * self.head_dim, self.embed_dim, @@ -282,14 +284,6 @@ def __init__( prefix=f"{prefix}.o_proj", ) else: - self.qkv_proj = QKVParallelLinear( - self.embed_dim, - self.head_dim, - self.num_heads, - bias=True, - quant_config=quant_config, - prefix=f"{prefix}.qkv_proj", - ) self.o_proj = RowParallelLinear( self.num_heads * self.head_dim, self.embed_dim, @@ -1056,30 +1050,6 @@ def get_other_weights() -> Iterable[tuple[str, torch.Tensor]]: return get_prefix_weights(), get_other_weights() - def _consolidate_qkv_weights( - self, weights: Iterable[tuple[str, torch.Tensor]] - ) -> Iterable[tuple[str, torch.Tensor]]: - qkv_idx_mappings = { - ".self_attn.q_proj": 0, - ".self_attn.k_proj": 1, - ".self_attn.v_proj": 2, - } - qkv_weights = {} - for name, loaded_weight in weights: - for weight_name, idx in qkv_idx_mappings.items(): - if weight_name not in name: - continue - new_name = name.replace(weight_name, ".self_attn.qkv_proj") - if new_name not in qkv_weights: - qkv_weights[new_name] = [None] * 3 - qkv_weights[new_name][idx] = loaded_weight - break - else: - yield name, loaded_weight - for key, weight in qkv_weights.items(): - qkv_weight = torch.cat(weight, dim=0) - yield key, qkv_weight - def _rename_weight_for_modelopt_checkpoint(self, name: str) -> str: """Rename weights from ModelOpt llama4 fp8 checkpoints to vLLM format.""" @@ -1133,13 +1103,10 @@ def _load_other_weights( """Load non-language-model weights with stacking support.""" updated_params = set() - if self.use_data_parallel: - other_weights = self._consolidate_qkv_weights(other_weights) - for name, loaded_weight in other_weights: # Try stacked parameter mapping first for param_name, weight_name, shard_id in stacked_params_mapping: - if weight_name not in name or self.use_data_parallel: + if weight_name not in name: continue name = name.replace(weight_name, param_name) param = params_dict[name] diff --git a/vllm/model_executor/models/modernbert.py b/vllm/model_executor/models/modernbert.py index d182fa071594..cf344fcd8040 100644 --- a/vllm/model_executor/models/modernbert.py +++ b/vllm/model_executor/models/modernbert.py @@ -24,12 +24,13 @@ from vllm.model_executor.layers.pooler.tokwise import pooler_for_token_classify from vllm.model_executor.layers.rotary_embedding import get_rope from vllm.model_executor.layers.vocab_parallel_embedding import VocabParallelEmbedding +from vllm.model_executor.model_loader.utils import autoload_weights from vllm.model_executor.model_loader.weight_utils import default_weight_loader from vllm.sequence import IntermediateTensors from .interfaces import SupportsCrossEncoding from .interfaces_base import attn_type, default_pooling_type -from .utils import AutoWeightsLoader, WeightsMapper, maybe_prefix +from .utils import WeightsMapper, maybe_prefix class ModernBertEmbeddings(nn.Module): @@ -383,7 +384,7 @@ def weight_filter(): else: self_weights.append((name, weight)) - self.model.load_weights(weight_filter()) + autoload_weights(self.model, weight_filter()) params_dict = dict(self.named_parameters()) @@ -433,6 +434,7 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: @default_pooling_type(tok_pooling_type="ALL") class ModernBertForTokenClassification(nn.Module): is_pooling_model = True + hf_to_vllm_mapper = WeightsMapper(orig_to_new_prefix={"drop": None}) def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): super().__init__() @@ -455,11 +457,6 @@ def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor: return self.model.embed_input_ids(input_ids) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader(self, skip_prefixes=["drop"]) - loaded_params = loader.load_weights(weights) - return loaded_params - def forward( self, input_ids: torch.Tensor | None, diff --git a/vllm/model_executor/models/molmo.py b/vllm/model_executor/models/molmo.py index cf4550a10765..fd747225192c 100644 --- a/vllm/model_executor/models/molmo.py +++ b/vllm/model_executor/models/molmo.py @@ -805,10 +805,6 @@ def forward( # image_features: (batch_size, num_image, num_patch, d_model) return image_features - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - @support_torch_compile class MolmoModel(nn.Module, SupportsQuant): @@ -885,9 +881,6 @@ def forward( hidden_states = self.norm(hidden_states) return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - return AutoWeightsLoader(self).load_weights(weights) - def _lowest_multiple(x: int, k: int) -> int: return (x // k) * k diff --git a/vllm/model_executor/models/molmo2.py b/vllm/model_executor/models/molmo2.py index d8de4f5ed17c..4837f314676c 100644 --- a/vllm/model_executor/models/molmo2.py +++ b/vllm/model_executor/models/molmo2.py @@ -850,10 +850,6 @@ def forward( valid_token.flatten() ] - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Molmo2Attention(nn.Module): """Molmo2's LLM Attention.""" @@ -1218,9 +1214,6 @@ def forward( hidden_states = self.norm(hidden_states) return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - return AutoWeightsLoader(self).load_weights(weights) - def get_patches_grid_size( *, diff --git a/vllm/model_executor/models/moss_audio.py b/vllm/model_executor/models/moss_audio.py index bef8057d2fb5..d995018e0301 100644 --- a/vllm/model_executor/models/moss_audio.py +++ b/vllm/model_executor/models/moss_audio.py @@ -67,7 +67,6 @@ from .module_mapping import MultiModelKeys from .qwen3 import Qwen3ForCausalLM, Qwen3Model from .utils import ( - AutoWeightsLoader, WeightsMapper, _merge_multimodal_embeddings, maybe_prefix, @@ -1450,6 +1449,8 @@ class MossAudioModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA): "language_model.embed_tokens.": "language_model.model.embed_tokens.", "language_model.layers.": "language_model.model.layers.", "language_model.norm.": "language_model.model.norm.", + # Rebuilt at init, not loaded from the checkpoint. + "audio_encoder.embed_positions": None, }, orig_to_new_stacked={ ".gate_proj": (".gate_up_proj", 0), @@ -1859,10 +1860,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=["audio_encoder.embed_positions"], - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/moss_transcribe_diarize.py b/vllm/model_executor/models/moss_transcribe_diarize.py index 5236f5c61be9..ea264cce0bf8 100644 --- a/vllm/model_executor/models/moss_transcribe_diarize.py +++ b/vllm/model_executor/models/moss_transcribe_diarize.py @@ -792,10 +792,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights( - weights, - mapper=self.hf_to_vllm_mapper, - ) diff --git a/vllm/model_executor/models/mpt.py b/vllm/model_executor/models/mpt.py index 8e509fbcb4c6..ac040078727c 100644 --- a/vllm/model_executor/models/mpt.py +++ b/vllm/model_executor/models/mpt.py @@ -3,7 +3,6 @@ # Adapted from https://huggingface.co/mosaicml/mpt-7b/tree/main import math -from collections.abc import Iterable from itertools import islice import torch @@ -31,7 +30,6 @@ from .interfaces import SupportsPP from .utils import ( - AutoWeightsLoader, make_empty_intermediate_tensors_factory, make_layers, maybe_prefix, @@ -312,7 +310,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/nano_nemotron_vl.py b/vllm/model_executor/models/nano_nemotron_vl.py index 64667503d578..1221abb434e3 100644 --- a/vllm/model_executor/models/nano_nemotron_vl.py +++ b/vllm/model_executor/models/nano_nemotron_vl.py @@ -24,6 +24,7 @@ from vllm.logger import init_logger from vllm.model_executor.layers.activation import ReLUSquaredActivation from vllm.model_executor.layers.layernorm import RMSNorm +from vllm.model_executor.model_loader.utils import autoload_weights from vllm.model_executor.model_loader.weight_utils import default_weight_loader from vllm.model_executor.models.interfaces import ( HasInnerState, @@ -1553,7 +1554,7 @@ def llm_weights_gen(): # Fully drain the generator so every mm tensor is buffered, even if # the LLM loader stops iterating early. llm_weights_iter = llm_weights_gen() - self.language_model.load_weights(llm_weights_iter) + autoload_weights(self.language_model, llm_weights_iter) for _ in llm_weights_iter: pass @@ -1563,9 +1564,9 @@ def llm_weights_gen(): param = adapter_dict[trimmed_name] with torch.no_grad(): default_weight_loader(param, w) - self.vision_model.load_weights(vision_weights) + autoload_weights(self.vision_model, vision_weights) if self.sound_encoder is not None and len(sound_weights) > 0: - self.sound_encoder.load_weights(sound_weights) + autoload_weights(self.sound_encoder, sound_weights) def get_vit_model_from_radio_config(self, hf_config): hf_config_vision = hf_config.vision_config diff --git a/vllm/model_executor/models/nemotron.py b/vllm/model_executor/models/nemotron.py index 6f0b61205b3c..320c07993d5d 100644 --- a/vllm/model_executor/models/nemotron.py +++ b/vllm/model_executor/models/nemotron.py @@ -24,7 +24,6 @@ # limitations under the License. """Inference-only Nemotron model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -52,7 +51,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, make_empty_intermediate_tensors_factory, @@ -438,7 +436,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/nemotron_h.py b/vllm/model_executor/models/nemotron_h.py index 84f24094a3d8..17b7f388cff7 100644 --- a/vllm/model_executor/models/nemotron_h.py +++ b/vllm/model_executor/models/nemotron_h.py @@ -18,7 +18,7 @@ # limitations under the License. """Inference-only NemotronH model.""" -from collections.abc import Iterable, Mapping +from collections.abc import Mapping from itertools import islice import torch @@ -71,7 +71,6 @@ SupportsQuant, ) from vllm.model_executor.models.utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -712,7 +711,7 @@ class NemotronHForCausalLM( is_non_gated_moe: bool = True hf_to_vllm_mapper = WeightsMapper( - orig_to_new_prefix={"backbone": "model"}, + orig_to_new_prefix={"backbone": "model", "mtp": None}, orig_to_new_substr={"A_log": "A", "embeddings": "embed_tokens"}, orig_to_new_stacked={ ".q_proj": (".qkv_proj", "q"), @@ -873,7 +872,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["mtp"]) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/nemotron_nas.py b/vllm/model_executor/models/nemotron_nas.py index 5a5f0e77739f..11811cd07ad7 100644 --- a/vllm/model_executor/models/nemotron_nas.py +++ b/vllm/model_executor/models/nemotron_nas.py @@ -24,7 +24,6 @@ # limitations under the License. """Inference-only deci model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -48,7 +47,6 @@ from .interfaces import HasNoOps, SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, make_empty_intermediate_tensors_factory, @@ -410,10 +408,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/nemotron_parse.py b/vllm/model_executor/models/nemotron_parse.py index 6e52e7cfe7f4..0ab616bebf94 100644 --- a/vllm/model_executor/models/nemotron_parse.py +++ b/vllm/model_executor/models/nemotron_parse.py @@ -33,6 +33,7 @@ ParallelLMHead, VocabParallelEmbedding, ) +from vllm.model_executor.model_loader.utils import autoload_weights from vllm.model_executor.model_loader.weight_utils import default_weight_loader from vllm.model_executor.models.interfaces import ( MultiModalEmbeddings, @@ -570,7 +571,7 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): with torch.no_grad(): default_weight_loader(param, w) - self.model_encoder.load_weights(model_encoder_weights) + autoload_weights(self.model_encoder, model_encoder_weights) @MULTIMODAL_REGISTRY.register_processor( @@ -720,6 +721,6 @@ def is_lm_head(name: str): logger.info("Found unexpected weight: %s", name) # Load encoder weights - self.encoder.load_weights(encoder_weights) + autoload_weights(self.encoder, encoder_weights) # Load decoder weights - self.decoder.load_weights(decoder_weights) + autoload_weights(self.decoder, decoder_weights) diff --git a/vllm/model_executor/models/nemotron_vl.py b/vllm/model_executor/models/nemotron_vl.py index 734968819b9a..22e13364175d 100644 --- a/vllm/model_executor/models/nemotron_vl.py +++ b/vllm/model_executor/models/nemotron_vl.py @@ -89,6 +89,10 @@ def get_hf_processor(self, **kwargs: object) -> LlamaNemotronNanoVLProcessor: dummy_inputs=BaseInternVLDummyInputsBuilder[NemotronVLProcessingInfo], ) class LlamaNemotronVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA): + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_substr={"norm_mean": None, "norm_std": None} + ) + @classmethod def get_placeholder_str(cls, modality: str, i: int) -> str | None: if modality.startswith("image"): @@ -376,13 +380,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - ## Ignore registered_buffers - ## see https://huggingface.co/nvidia/C-RADIOv2-H/blob/main/input_conditioner.py#L28 # noqa: E501 - skip_substrs = ["norm_mean", "norm_std"] - loader = AutoWeightsLoader(self, skip_substrs=skip_substrs) - return loader.load_weights(weights) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models @@ -530,11 +527,6 @@ def _call_vision_model(self, pixel_values: torch.Tensor) -> torch.Tensor: """Override to handle SigLIP interface.""" return self.vision_model(pixel_values) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - """Override to use different weight mapping for SigLIP.""" - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class LlamaNemotronVLForSequenceClassification( LlamaNemotronVLForEmbedding, SupportsCrossEncoding @@ -569,7 +561,8 @@ def __init__(self, *, vllm_config: VllmConfig, prefix: str = "") -> None: self.pooler = DispatchPooler.for_seq_cls(pooler_config, classifier=self.score) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loaded_weights = super().load_weights(weights) + loader = AutoWeightsLoader(self) + loaded_weights = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) # reranker checkpoint omits the inner LM seq-cls head # (`language_model.score.*`). It is unused by this outer model, but diff --git a/vllm/model_executor/models/olmo3.py b/vllm/model_executor/models/olmo3.py index 922834a8ee68..989a2758d9dc 100644 --- a/vllm/model_executor/models/olmo3.py +++ b/vllm/model_executor/models/olmo3.py @@ -24,7 +24,6 @@ # limitations under the License. """Inference-only OLMo3 model compatible with HuggingFace weights.""" -from collections.abc import Iterable from functools import partial from itertools import islice @@ -54,7 +53,6 @@ ) from vllm.model_executor.models.interfaces import SupportsLoRA, SupportsPP from vllm.model_executor.models.utils import ( - AutoWeightsLoader, WeightsMapper, extract_layer_index, make_empty_intermediate_tensors_factory, @@ -407,12 +405,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader( - self, - skip_prefixes=( - ["lm_head.weight"] if self.config.tie_word_embeddings else None - ), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/olmo_hybrid.py b/vllm/model_executor/models/olmo_hybrid.py index 51bc410363ce..156885cecd6a 100644 --- a/vllm/model_executor/models/olmo_hybrid.py +++ b/vllm/model_executor/models/olmo_hybrid.py @@ -21,7 +21,6 @@ # limitations under the License. """Inference-only OLMo Hybrid model compatible with HuggingFace weights.""" -from collections.abc import Iterable from functools import partial from itertools import islice @@ -67,7 +66,6 @@ from .interfaces import HasInnerState, IsHybrid, SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, extract_layer_index, make_empty_intermediate_tensors_factory, @@ -372,10 +370,6 @@ def forward( hidden_states = self.norm(hidden_states) return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class OlmoHybridForCausalLM( nn.Module, HasInnerState, SupportsPP, SupportsLoRA, IsHybrid @@ -473,12 +467,3 @@ def get_mamba_state_shape_from_config( @classmethod def get_mamba_state_copy_func(cls) -> tuple[MambaStateCopyFunc, MambaStateCopyFunc]: return MambaStateCopyFuncCalculator.gated_delta_net_state_copy_func() - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader( - self, - skip_prefixes=( - ["lm_head.weight"] if self.config.tie_word_embeddings else None - ), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/olmoe.py b/vllm/model_executor/models/olmoe.py index a57ef9cf4307..2b8031510af9 100644 --- a/vllm/model_executor/models/olmoe.py +++ b/vllm/model_executor/models/olmoe.py @@ -14,7 +14,6 @@ # limitations under the License. """Inference-only OLMoE model compatible with HuggingFace weights.""" -from collections.abc import Iterable from functools import partial from itertools import islice @@ -52,7 +51,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -401,7 +399,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/openpangu.py b/vllm/model_executor/models/openpangu.py index fd40033e7154..916c15e9e961 100644 --- a/vllm/model_executor/models/openpangu.py +++ b/vllm/model_executor/models/openpangu.py @@ -1162,13 +1162,6 @@ def compute_logits( logits = self.logits_processor(self.lm_head, hidden_states) return logits - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) - class OpenPanguMoEModel(OpenPanguModelBase, MixtureOfExperts): def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): diff --git a/vllm/model_executor/models/openpangu_vl.py b/vllm/model_executor/models/openpangu_vl.py index 04a6dba41f42..08d3ceb459a4 100644 --- a/vllm/model_executor/models/openpangu_vl.py +++ b/vllm/model_executor/models/openpangu_vl.py @@ -20,7 +20,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence +from collections.abc import Callable, Iterator, Mapping, Sequence from functools import lru_cache, partial from typing import Annotated, Literal, Optional @@ -61,7 +61,6 @@ Qwen2_5_VLProcessingInfo, ) from vllm.model_executor.models.utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -1127,10 +1126,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/opt.py b/vllm/model_executor/models/opt.py index 32bb532f5c5b..16b7f490a6c3 100644 --- a/vllm/model_executor/models/opt.py +++ b/vllm/model_executor/models/opt.py @@ -20,7 +20,6 @@ # limitations under the License. """Inference-only OPT model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -48,7 +47,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -383,12 +381,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=( - ["lm_head.weight"] if self.config.tie_word_embeddings else None - ), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/orion.py b/vllm/model_executor/models/orion.py index 0871c347ac5c..b1a3e0b45f6a 100644 --- a/vllm/model_executor/models/orion.py +++ b/vllm/model_executor/models/orion.py @@ -7,7 +7,6 @@ # LICENSE: https://huggingface.co/OrionStarAI/Orion-14B-Base/blob/main/LICENSE """Inference-only Orion-14B model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice from typing import Any @@ -36,7 +35,6 @@ from .interfaces import SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -332,7 +330,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/ouro.py b/vllm/model_executor/models/ouro.py index 527eeaa13bc6..b720918feef5 100644 --- a/vllm/model_executor/models/ouro.py +++ b/vllm/model_executor/models/ouro.py @@ -26,7 +26,6 @@ # limitations under the License. """Inference-only Ouro model compatible with HuggingFace weights.""" -from collections.abc import Iterable from typing import Any import torch @@ -56,7 +55,6 @@ from .interfaces import SupportsLoRA from .utils import ( - AutoWeightsLoader, WeightsMapper, extract_layer_index, make_empty_intermediate_tensors_factory, @@ -439,10 +437,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/ovis.py b/vllm/model_executor/models/ovis.py index f25585fd7643..24168b1694c5 100644 --- a/vllm/model_executor/models/ovis.py +++ b/vllm/model_executor/models/ovis.py @@ -19,7 +19,7 @@ """PyTorch Ovis model.""" import math -from collections.abc import Iterable, Mapping +from collections.abc import Mapping from typing import Annotated, Literal import torch @@ -36,7 +36,6 @@ from vllm.model_executor.models.aimv2 import AIMv2Model from vllm.model_executor.models.siglip import SiglipVisionModel from vllm.model_executor.models.utils import ( - AutoWeightsLoader, flatten_bn, init_vllm_registered_model, maybe_prefix, @@ -553,7 +552,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.llm.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/ovis2_5.py b/vllm/model_executor/models/ovis2_5.py index 6dbed78a6fc6..1b615d633285 100644 --- a/vllm/model_executor/models/ovis2_5.py +++ b/vllm/model_executor/models/ovis2_5.py @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project """PyTorch Ovis model.""" -from collections.abc import Iterable, Mapping +from collections.abc import Mapping from functools import partial from typing import Annotated, Literal @@ -18,7 +18,6 @@ from vllm.model_executor.models.ovis import VisualEmbedding from vllm.model_executor.models.siglip2navit import Siglip2NavitModel from vllm.model_executor.models.utils import ( - AutoWeightsLoader, flatten_bn, init_vllm_registered_model, maybe_prefix, @@ -646,7 +645,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.llm.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/paddleocr_vl.py b/vllm/model_executor/models/paddleocr_vl.py index 0dae22115d43..d9e13873bc05 100644 --- a/vllm/model_executor/models/paddleocr_vl.py +++ b/vllm/model_executor/models/paddleocr_vl.py @@ -15,7 +15,7 @@ # limitations under the License. import math -from collections.abc import Iterable, Iterator, Mapping, Sequence +from collections.abc import Iterator, Mapping, Sequence from functools import partial from typing import Annotated, Literal @@ -73,12 +73,7 @@ from .ernie45 import Ernie4_5ForCausalLM from .interfaces import MultiModalEmbeddings, SupportsMRoPE, SupportsMultiModal from .siglip import SiglipMLP -from .utils import ( - AutoWeightsLoader, - PPMissingLayer, - WeightsMapper, - maybe_prefix, -) +from .utils import PPMissingLayer, WeightsMapper, maybe_prefix from .vision import get_vit_attn_backend @@ -880,11 +875,20 @@ def forward( class SiglipVisionModel(nn.Module): hf_to_vllm_mapper = WeightsMapper( + # Skip the SigLIP attention pooling head and packing pos embedding + # present in the checkpoint but absent from this vision tower. + orig_to_new_substr={ + "head.attention": None, + "head.layernorm": None, + "head.mlp": None, + "head.probe": None, + "packing_position_embedding": None, + }, orig_to_new_stacked={ ".q_proj": (".qkv_proj", "q"), ".k_proj": (".qkv_proj", "k"), ".v_proj": (".qkv_proj", "v"), - } + }, ) def __init__( @@ -930,21 +934,6 @@ def forward( cu_seqlens=cu_seqlens, ) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - # Skip the SigLIP attention pooling head and packing pos embedding - # present in the checkpoint but absent from this vision tower. - loader = AutoWeightsLoader( - self, - skip_substrs=[ - "head.attention", - "head.layernorm", - "head.mlp", - "head.probe", - "packing_position_embedding", - ], - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - @MULTIMODAL_REGISTRY.register_processor( PaddleOCRVLMultiModalProcessor, @@ -1167,8 +1156,3 @@ def embed_multimodal(self, **kwargs) -> MultiModalEmbeddings: multimodal_embeddings += tuple(image_embeds) return multimodal_embeddings - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - autoloaded_weights = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - return autoloaded_weights diff --git a/vllm/model_executor/models/paligemma.py b/vllm/model_executor/models/paligemma.py index d7b8e77c63b6..feebee322f34 100644 --- a/vllm/model_executor/models/paligemma.py +++ b/vllm/model_executor/models/paligemma.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Literal, TypeAlias import torch @@ -45,7 +45,6 @@ from .module_mapping import MultiModelKeys from .siglip import SiglipVisionModel from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -405,10 +404,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: return MultiModelKeys.from_string_field( language_model="language_model", diff --git a/vllm/model_executor/models/param2moe.py b/vllm/model_executor/models/param2moe.py index 48c0c714ed8d..19cfcfaa52be 100644 --- a/vllm/model_executor/models/param2moe.py +++ b/vllm/model_executor/models/param2moe.py @@ -706,10 +706,3 @@ def compute_logits( if not get_pp_group().is_last_rank: return None return self.logits_processor(self.lm_head, hidden_states) - - def load_weights( - self, - weights: Iterable[tuple[str, torch.Tensor]], - ) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/phi.py b/vllm/model_executor/models/phi.py index 61c243aadf25..c4e58a9ddcbc 100644 --- a/vllm/model_executor/models/phi.py +++ b/vllm/model_executor/models/phi.py @@ -38,7 +38,6 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Inference-only Phi-1.5 model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -66,7 +65,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -319,7 +317,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states, self.lm_head.bias) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/phi4mm.py b/vllm/model_executor/models/phi4mm.py index dc055978668a..2fac0c3442f4 100644 --- a/vllm/model_executor/models/phi4mm.py +++ b/vllm/model_executor/models/phi4mm.py @@ -21,9 +21,7 @@ from vllm.inputs import MultiModalDataDict from vllm.model_executor.layers.logits_processor import LogitsProcessor from vllm.model_executor.layers.quantization import QuantizationConfig -from vllm.model_executor.layers.vocab_parallel_embedding import ( - ParallelLMHead, -) +from vllm.model_executor.layers.vocab_parallel_embedding import ParallelLMHead from vllm.model_executor.models.llama import LlamaModel from vllm.model_executor.models.module_mapping import MultiModelKeys from vllm.multimodal import MULTIMODAL_REGISTRY @@ -1029,9 +1027,7 @@ class Phi4MMForCausalLM(nn.Module, SupportsLoRA, SupportsMultiModal): } hf_to_vllm_mapper = WeightsMapper( - orig_to_new_substr={ - "base_layer.": "", - }, + orig_to_new_substr={"base_layer.": ""}, orig_to_new_prefix={ "model.embed_tokens_extend.audio_embed.audio_projection.vision.": "embed_tokens_extend.audio_projection_for_vision.", # noqa: E501 "model.embed_tokens_extend.audio_embed.audio_projection.speech.": "embed_tokens_extend.audio_projection.", # noqa: E501 @@ -1273,8 +1269,13 @@ def compute_logits( return logits def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> None: - loader = AutoWeightsLoader(self, skip_substrs=["lora"]) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) + # Drop the frozen base-model LoRA weights at load time only. + # This must not live in `hf_to_vllm_mapper`: the LoRA loader + # also consults that mapper to translate adapter weight names. + loader = AutoWeightsLoader(self) + drop = WeightsMapper(orig_to_new_substr={"lora": None}) + mapper = self.hf_to_vllm_mapper | drop + return loader.load_weights(weights, mapper=mapper) def get_mm_mapping(self) -> MultiModelKeys: """ diff --git a/vllm/model_executor/models/phi4siglip.py b/vllm/model_executor/models/phi4siglip.py index d71a572f6ad8..961fb7035d15 100644 --- a/vllm/model_executor/models/phi4siglip.py +++ b/vllm/model_executor/models/phi4siglip.py @@ -6,7 +6,7 @@ """ import math -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Any, Literal import torch @@ -42,7 +42,6 @@ from .lfm2_siglip2 import Siglip2Model from .llava import LlavaMultiModalProjector from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -423,7 +422,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/phimoe.py b/vllm/model_executor/models/phimoe.py index dc2af1e8d6fa..6f0078a8b775 100644 --- a/vllm/model_executor/models/phimoe.py +++ b/vllm/model_executor/models/phimoe.py @@ -24,7 +24,6 @@ # limitations under the License. """Inference-only PhiMoE model.""" -from collections.abc import Iterable from itertools import islice import torch @@ -54,7 +53,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -581,7 +579,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/pixtral.py b/vllm/model_executor/models/pixtral.py index 447d6edd9864..5edb47b85062 100644 --- a/vllm/model_executor/models/pixtral.py +++ b/vllm/model_executor/models/pixtral.py @@ -35,6 +35,7 @@ RowParallelLinear, ) from vllm.model_executor.layers.quantization import QuantizationConfig +from vllm.model_executor.model_loader.utils import autoload_weights from vllm.model_executor.model_loader.weight_utils import default_weight_loader from vllm.model_executor.models.utils import WeightsMapper from vllm.multimodal import MULTIMODAL_REGISTRY, MultiModalKwargsItems @@ -573,7 +574,7 @@ def llm_weights_generator(): name = name.removeprefix("language_model.") yield (name, w) - self.language_model.load_weights(llm_weights_generator()) + autoload_weights(self.language_model, llm_weights_generator()) def get_mm_mapping(self) -> MultiModelKeys: return MultiModelKeys.from_string_field( diff --git a/vllm/model_executor/models/plamo2.py b/vllm/model_executor/models/plamo2.py index 5fd925cf0bee..a7136c8d0628 100644 --- a/vllm/model_executor/models/plamo2.py +++ b/vllm/model_executor/models/plamo2.py @@ -60,7 +60,6 @@ SupportsPP, ) from vllm.model_executor.models.utils import ( - AutoWeightsLoader, is_pp_missing_parameter, make_empty_intermediate_tensors_factory, make_layers, @@ -983,10 +982,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/plamo3.py b/vllm/model_executor/models/plamo3.py index 2ba38a7b1f8f..0ed35357de83 100644 --- a/vllm/model_executor/models/plamo3.py +++ b/vllm/model_executor/models/plamo3.py @@ -2,7 +2,6 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project """Inference-only PLaMo3 model.""" -from collections.abc import Iterable from itertools import islice from typing import TYPE_CHECKING, Any @@ -37,7 +36,6 @@ ) from vllm.model_executor.models.interfaces import SupportsLoRA, SupportsPP from vllm.model_executor.models.utils import ( - AutoWeightsLoader, extract_layer_index, make_empty_intermediate_tensors_factory, make_layers, @@ -428,10 +426,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/qwen2.py b/vllm/model_executor/models/qwen2.py index 182b9758308d..e6713dda0730 100644 --- a/vllm/model_executor/models/qwen2.py +++ b/vllm/model_executor/models/qwen2.py @@ -25,7 +25,6 @@ # limitations under the License. """Inference-only Qwen2 model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice from typing import Any @@ -67,7 +66,6 @@ SupportsQuant, ) from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, extract_layer_index, @@ -433,10 +431,6 @@ def forward( return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Qwen2ForCausalLM( nn.Module, SupportsLoRA, SupportsPP, SupportsEagle, SupportsEagle3, SupportsQuant @@ -499,10 +493,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/qwen2_5_omni_thinker.py b/vllm/model_executor/models/qwen2_5_omni_thinker.py index a0e9b84f3441..7e970e6e116a 100644 --- a/vllm/model_executor/models/qwen2_5_omni_thinker.py +++ b/vllm/model_executor/models/qwen2_5_omni_thinker.py @@ -22,7 +22,7 @@ # limitations under the License. """Inference-only Qwen2.5-Omni model (thinker part).""" -from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence +from collections.abc import Callable, Iterator, Mapping, Sequence from functools import partial from typing import Annotated, Any, Literal @@ -99,7 +99,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -1078,6 +1077,8 @@ class Qwen2_5OmniThinkerForConditionalGeneration( ): hf_to_vllm_mapper = WeightsMapper( orig_to_new_prefix={ + "talker.": None, + "token2wav.": None, "thinker.lm_head.": "language_model.lm_head.", "thinker.model.": "language_model.model.", "thinker.": "", @@ -1558,10 +1559,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["talker.", "token2wav."]) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/qwen2_5_vl.py b/vllm/model_executor/models/qwen2_5_vl.py index c987e07b43de..54dd9130c7ee 100644 --- a/vllm/model_executor/models/qwen2_5_vl.py +++ b/vllm/model_executor/models/qwen2_5_vl.py @@ -26,7 +26,7 @@ # limitations under the License. """Inference-only Qwen2.5-VL model compatible with HuggingFace weights.""" -from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence +from collections.abc import Callable, Iterator, Mapping, Sequence from functools import lru_cache, partial from typing import Annotated, Any, Literal, TypeAlias @@ -105,7 +105,6 @@ Qwen2VLProcessingInfo, ) from .utils import ( - AutoWeightsLoader, WeightsMapper, cast_overflow_tensors, init_vllm_registered_model, @@ -1124,10 +1123,6 @@ def forward( hidden_states = hidden_states[reverse_indices, :] return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Qwen2_5_VLProcessingInfo(Qwen2VLProcessingInfo): def get_hf_config(self): @@ -2024,10 +2019,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/qwen2_audio.py b/vllm/model_executor/models/qwen2_audio.py index 9692d9615b51..d097b25aa2bb 100644 --- a/vllm/model_executor/models/qwen2_audio.py +++ b/vllm/model_executor/models/qwen2_audio.py @@ -23,7 +23,7 @@ # limitations under the License. """Inference-only Qwen2-Audio model compatible with HuggingFace weights.""" -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Any, Literal, TypeAlias import torch @@ -63,7 +63,7 @@ from vllm.utils.tensor_schema import TensorSchema, TensorShape from .interfaces import MultiModalEmbeddings, SupportsMultiModal, SupportsPP -from .utils import AutoWeightsLoader, init_vllm_registered_model, maybe_prefix +from .utils import init_vllm_registered_model, maybe_prefix # # === Audio Inputs === # @@ -479,7 +479,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/qwen2_vl.py b/vllm/model_executor/models/qwen2_vl.py index 539f141cbaa7..0be89a72e5c3 100644 --- a/vllm/model_executor/models/qwen2_vl.py +++ b/vllm/model_executor/models/qwen2_vl.py @@ -26,7 +26,7 @@ """Inference-only Qwen2-VL model compatible with HuggingFace weights.""" import math -from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence +from collections.abc import Callable, Iterator, Mapping, Sequence from functools import partial from typing import Annotated, Any, Literal, TypeAlias @@ -97,7 +97,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -749,10 +748,6 @@ def forward( return x - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def _create_qwen2vl_field_factory( spatial_merge_size: int, @@ -1706,10 +1701,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/qwen3.py b/vllm/model_executor/models/qwen3.py index cf136db5be48..6d464028466d 100644 --- a/vllm/model_executor/models/qwen3.py +++ b/vllm/model_executor/models/qwen3.py @@ -23,7 +23,6 @@ # limitations under the License. """Inference-only Qwen3 model compatible with HuggingFace weights.""" -from collections.abc import Iterable from typing import Any import torch @@ -57,7 +56,7 @@ ) from .qwen2 import Qwen2MLP as Qwen3MLP from .qwen2 import Qwen2Model -from .utils import AutoWeightsLoader, PPMissingLayer, extract_layer_index, maybe_prefix +from .utils import PPMissingLayer, extract_layer_index, maybe_prefix logger = init_logger(__name__) @@ -334,10 +333,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/qwen3_5.py b/vllm/model_executor/models/qwen3_5.py index bcd2576b74f1..d05b44006644 100644 --- a/vllm/model_executor/models/qwen3_5.py +++ b/vllm/model_executor/models/qwen3_5.py @@ -296,6 +296,7 @@ class Qwen3_5ForCausalLMBase( "in_proj_qkvz": ["in_proj_qkv", "in_proj_z"], "in_proj_ba": ["in_proj_b", "in_proj_a"], } + hf_to_vllm_mapper = WeightsMapper(orig_to_new_prefix={"mtp.": None}) def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): config = vllm_config.model_config.hf_text_config @@ -366,13 +367,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.logits_processor(self.lm_head, hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=["mtp."], - ) - return loader.load_weights(weights) - class Qwen3_5ForCausalLM(Qwen3_5ForCausalLMBase): pass @@ -404,6 +398,10 @@ class Qwen3_5ForConditionalGeneration(Qwen3VLForConditionalGeneration, IsHybrid) "in_proj_qkvz": ["in_proj_qkv", "in_proj_z"], "in_proj_ba": ["in_proj_b", "in_proj_a"], } + hf_to_vllm_mapper = ( + Qwen3VLForConditionalGeneration.hf_to_vllm_mapper + | WeightsMapper(orig_to_new_prefix={"mtp.": None}) + ) def __init__(self, *, vllm_config: VllmConfig, prefix: str = "model"): # protocols have not __init__ method, so we need to use nn.Module.__init__ @@ -512,13 +510,6 @@ def forward( return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=["mtp."], - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - @classmethod def get_mamba_state_dtype_from_config( cls, diff --git a/vllm/model_executor/models/qwen3_asr.py b/vllm/model_executor/models/qwen3_asr.py index b9224adc6c8e..711a3cf8a4b3 100644 --- a/vllm/model_executor/models/qwen3_asr.py +++ b/vllm/model_executor/models/qwen3_asr.py @@ -22,7 +22,7 @@ # limitations under the License. """Inference-only Qwen3-ASR model.""" -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from typing import Any import regex as re @@ -56,7 +56,6 @@ Qwen3OmniMoeThinkerMultiModalProcessor, ) from vllm.model_executor.models.utils import ( - AutoWeightsLoader, WeightsMapper, _merge_multimodal_embeddings, maybe_prefix, @@ -89,9 +88,7 @@ Qwen3ASRThinkerConfig, ) from vllm.transformers_utils.processor import cached_processor_from_config -from vllm.transformers_utils.processors.qwen3_asr import ( - Qwen3ASRProcessor, -) +from vllm.transformers_utils.processors.qwen3_asr import Qwen3ASRProcessor logger = init_logger(__name__) _ASR_TEXT_TAG = "" @@ -363,6 +360,8 @@ class Qwen3ASRForConditionalGeneration( hf_to_vllm_mapper = WeightsMapper( orig_to_new_prefix={ + "talker.": None, + "code2wav.": None, "thinker.lm_head.": "language_model.lm_head.", "thinker.model.": "language_model.model.", "thinker.": "", @@ -537,15 +536,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=["talker.", "code2wav."], - ) - loaded_weights = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - - return loaded_weights - def get_mrope_input_positions( self, input_tokens: list[int], diff --git a/vllm/model_executor/models/qwen3_asr_forced_aligner.py b/vllm/model_executor/models/qwen3_asr_forced_aligner.py index 56c57f477da1..6292d788a7e7 100644 --- a/vllm/model_executor/models/qwen3_asr_forced_aligner.py +++ b/vllm/model_executor/models/qwen3_asr_forced_aligner.py @@ -2,8 +2,6 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project """Inference-only Qwen3-ASR ForcedAligner model (token classification).""" -from collections.abc import Iterable - import torch import torch.nn as nn @@ -16,7 +14,7 @@ Qwen3ASRMultiModalProcessor, Qwen3ASRProcessingInfo, ) -from vllm.model_executor.models.utils import AutoWeightsLoader, WeightsMapper +from vllm.model_executor.models.utils import WeightsMapper from vllm.multimodal import MULTIMODAL_REGISTRY from vllm.sequence import IntermediateTensors @@ -56,6 +54,8 @@ class Qwen3ASRForcedAlignerForTokenClassification( # Map thinker.lm_head -> classifier (not language_model.lm_head) hf_to_vllm_mapper = WeightsMapper( orig_to_new_prefix={ + "talker.": None, + "code2wav.": None, "thinker.lm_head.": "classifier.", "thinker.model.": "language_model.model.", "thinker.": "", @@ -111,10 +111,3 @@ def forward( # Apply classification head -> [num_tokens, classify_num] return self.classifier(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=["talker.", "code2wav."], - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/qwen3_dflash.py b/vllm/model_executor/models/qwen3_dflash.py index bf5ea501cc49..8e02c8e85441 100644 --- a/vllm/model_executor/models/qwen3_dflash.py +++ b/vllm/model_executor/models/qwen3_dflash.py @@ -791,21 +791,18 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): model_weights["model.mask_embedding"] = mask_embedding self.model.has_separate_mask_embedding = True - skip_substrs = [] + orig_to_new_substr = {} if not includes_draft_id_mapping: - skip_substrs.append("draft_id_to_target_id") + orig_to_new_substr["draft_id_to_target_id"] = None if not includes_embed_tokens: - skip_substrs.append("embed_tokens") + orig_to_new_substr["embed_tokens"] = None if not self.model.use_aux_hidden_state: - skip_substrs.append("fc.") + orig_to_new_substr["fc."] = None if not self.model.has_separate_mask_embedding: - skip_substrs.append("mask_embedding") - loader = AutoWeightsLoader( - self, - skip_prefixes=None, - skip_substrs=skip_substrs, - ) - loader.load_weights(model_weights.items()) + orig_to_new_substr["mask_embedding"] = None + drop = WeightsMapper(orig_to_new_substr=orig_to_new_substr) + loader = AutoWeightsLoader(self) + loader.load_weights(model_weights.items(), mapper=drop) self.model._build_fused_kv_buffers() def _read_mask_embedding(self) -> torch.Tensor | None: diff --git a/vllm/model_executor/models/qwen3_dspark.py b/vllm/model_executor/models/qwen3_dspark.py index 219819759ac0..1fdfba3a1ccc 100644 --- a/vllm/model_executor/models/qwen3_dspark.py +++ b/vllm/model_executor/models/qwen3_dspark.py @@ -28,7 +28,12 @@ ) from .qwen3_dflash import DFlashQwen3ForCausalLM, DFlashQwen3Model -from .utils import AutoWeightsLoader, maybe_prefix, process_eagle_weight +from .utils import ( + AutoWeightsLoader, + WeightsMapper, + maybe_prefix, + process_eagle_weight, +) logger = init_logger(__name__) @@ -173,13 +178,14 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): # confidence_head is not wired into inference yet; skip its weights. # embed_tokens / lm_head are optional; when omitted they are shared from # the target by load_dspark_model, so skip the unloaded params here. - skip_substrs = ["mask_embedding", "confidence_head"] + orig_to_new_substr = {"mask_embedding": None, "confidence_head": None} if not includes_embed_tokens: - skip_substrs.append("embed_tokens") + orig_to_new_substr["embed_tokens"] = None if not includes_lm_head: - skip_substrs.append("lm_head") + orig_to_new_substr["lm_head"] = None if not includes_draft_id_mapping: - skip_substrs.append("draft_id_to_target_id") - loader = AutoWeightsLoader(self, skip_substrs=skip_substrs) - loader.load_weights(model_weights.items()) + orig_to_new_substr["draft_id_to_target_id"] = None + drop = WeightsMapper(orig_to_new_substr=orig_to_new_substr) + loader = AutoWeightsLoader(self) + loader.load_weights(model_weights.items(), mapper=drop) self.model._build_fused_kv_buffers() diff --git a/vllm/model_executor/models/qwen3_eagle3.py b/vllm/model_executor/models/qwen3_eagle3.py index 3255c65e2736..55e0d6f7cb1e 100644 --- a/vllm/model_executor/models/qwen3_eagle3.py +++ b/vllm/model_executor/models/qwen3_eagle3.py @@ -274,10 +274,6 @@ def forward( return hidden_states, aux_output - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Eagle3Qwen3ForCausalLM(Qwen3ForCausalLM): def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): @@ -425,18 +421,15 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): "Please provide mask_hidden in the weights." ) - skip_substrs = ["mask_hidden"] + orig_to_new_substr = {"mask_hidden": None} if not includes_draft_id_mapping: - skip_substrs.append("draft_id_to_target_id") + orig_to_new_substr["draft_id_to_target_id"] = None if not includes_embed_tokens: - skip_substrs.append("embed_tokens") + orig_to_new_substr["embed_tokens"] = None if not self.model.use_aux_hidden_state: - skip_substrs.append("fc.") + orig_to_new_substr["fc."] = None if not self.model.norm_before_fc: - skip_substrs.append("input_norm.") - loader = AutoWeightsLoader( - self, - skip_prefixes=None, - skip_substrs=skip_substrs, - ) - loader.load_weights(model_weights.items()) + orig_to_new_substr["input_norm."] = None + drop = WeightsMapper(orig_to_new_substr=orig_to_new_substr) + loader = AutoWeightsLoader(self) + loader.load_weights(model_weights.items(), mapper=drop) diff --git a/vllm/model_executor/models/qwen3_next.py b/vllm/model_executor/models/qwen3_next.py index 50bc4cce187c..6010d3f2b258 100644 --- a/vllm/model_executor/models/qwen3_next.py +++ b/vllm/model_executor/models/qwen3_next.py @@ -785,6 +785,7 @@ class Qwen3NextForCausalLM( "in_proj_qkvz": ["in_proj_qkvz"], "in_proj_ba": ["in_proj_ba"], } + hf_to_vllm_mapper = WeightsMapper(orig_to_new_prefix={"mtp.": None}) def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): config = vllm_config.model_config.hf_text_config @@ -879,7 +880,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.logits_processor(self.lm_head, hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["mtp."]) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/qwen3_omni_moe_thinker.py b/vllm/model_executor/models/qwen3_omni_moe_thinker.py index 32a622567ceb..e3b042044af2 100755 --- a/vllm/model_executor/models/qwen3_omni_moe_thinker.py +++ b/vllm/model_executor/models/qwen3_omni_moe_thinker.py @@ -22,7 +22,7 @@ # limitations under the License. """Inference-only Qwen3-Omni-Moe model (thinker part).""" -from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence +from collections.abc import Callable, Iterator, Mapping, Sequence from functools import partial from typing import Any, cast @@ -100,12 +100,7 @@ Qwen2_5_VLProcessingInfo, ) from .qwen3_moe import Qwen3MoeForCausalLM, Qwen3MoeModel -from .utils import ( - AutoWeightsLoader, - WeightsMapper, - _merge_multimodal_embeddings, - maybe_prefix, -) +from .utils import WeightsMapper, _merge_multimodal_embeddings, maybe_prefix from .vision import get_vit_attn_backend logger = init_logger(__name__) @@ -537,10 +532,6 @@ def _get_cnn_output_lengths(self, input_lengths: torch.Tensor) -> torch.Tensor: lengths = (lengths - 1) // 2 + 1 return lengths - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Qwen3_VisionPatchEmbed(nn.Module): def __init__( @@ -1031,10 +1022,6 @@ def forward( return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - @support_torch_compile( dynamic_arg_dims={ @@ -1610,6 +1597,8 @@ class Qwen3OmniMoeThinkerForConditionalGeneration( ): hf_to_vllm_mapper = WeightsMapper( orig_to_new_prefix={ + "talker.": None, + "code2wav.": None, "thinker.lm_head.": "language_model.lm_head.", "thinker.model.": "language_model.model.", "thinker.": "", @@ -1969,15 +1958,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=["talker.", "code2wav."], - ) - loaded_weights = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - - return loaded_weights - def _compute_audio_token_count(self, audio_feature_length: int) -> int: """Compute audio tokens from feature length using Qwen3-Omni formula.""" return _get_feat_extract_output_lengths( diff --git a/vllm/model_executor/models/qwen3_vl.py b/vllm/model_executor/models/qwen3_vl.py index f86560e5f4e7..cc75d47a254d 100644 --- a/vllm/model_executor/models/qwen3_vl.py +++ b/vllm/model_executor/models/qwen3_vl.py @@ -24,7 +24,7 @@ # limitations under the License. """Inference-only Qwen3VL model compatible with HuggingFace weights.""" -from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence +from collections.abc import Callable, Iterator, Mapping, Sequence from functools import lru_cache, partial from itertools import islice from typing import Any @@ -129,7 +129,6 @@ ) from .qwen3 import Qwen3ForCausalLM, Qwen3Model from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, _merge_multimodal_embeddings, @@ -840,10 +839,6 @@ def forward( ) # [seq_len, hidden_size * (1 + depth_of_deepstack)] return hidden_states - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class Qwen3VLProcessingInfo(Qwen2VLProcessingInfo): def get_hf_config(self): @@ -2931,10 +2926,6 @@ def compute_logits( ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - def get_mm_mapping(self) -> MultiModelKeys: """ Get the module prefix in multimodal models diff --git a/vllm/model_executor/models/rnj1.py b/vllm/model_executor/models/rnj1.py index 2bcd27919813..2c8b9bc59027 100644 --- a/vllm/model_executor/models/rnj1.py +++ b/vllm/model_executor/models/rnj1.py @@ -4,7 +4,6 @@ # RNJ-1 model: Gemma3-based architecture with chunked (block-local) attention. # Chunked attention restricts local layers to attend within aligned blocks, # with lookback to one previous block. -from collections.abc import Iterable from itertools import islice import torch @@ -35,7 +34,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, extract_layer_index, make_empty_intermediate_tensors_factory, @@ -393,10 +391,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/roberta.py b/vllm/model_executor/models/roberta.py index 948a939b9d58..21f6bb75df3a 100644 --- a/vllm/model_executor/models/roberta.py +++ b/vllm/model_executor/models/roberta.py @@ -4,6 +4,7 @@ import itertools from collections.abc import Iterable +import regex as re import torch from torch import nn from transformers import RobertaConfig @@ -117,6 +118,11 @@ def forward(self, x: torch.Tensor) -> torch.Tensor: class RobertaEmbeddingModel(BertEmbeddingModel): """A model that uses Roberta to provide embedding functionalities.""" + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_regex={re.compile(r"^(?!model\.)(?:roberta\.)?"): "model."}, + orig_to_new_prefix={"model.lm_head.": None}, + ) + def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): super().__init__(vllm_config=vllm_config, prefix=prefix) self.padding_idx: int = vllm_config.model_config.hf_config.pad_token_id @@ -145,23 +151,6 @@ def _build_model( else: return JinaRobertaModel(**kwargs) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - weights_list = list(weights) - has_roberta_prefix = any( - name.startswith("roberta.") for name, _ in weights_list - ) - if has_roberta_prefix: - # For models with the `roberta.` prefix e.g. - # `FacebookAI/roberta-base` - mapper = WeightsMapper(orig_to_new_prefix={"roberta.": "model."}) - else: - # For models without the `roberta.` prefix e.g. - # `sentence-transformers/stsb-roberta-base-v2` - mapper = WeightsMapper(orig_to_new_prefix={"": "model."}) - - loader = AutoWeightsLoader(self, skip_prefixes=["lm_head."]) - return loader.load_weights(weights_list, mapper=mapper) - def filter_secondary_weights( all_weights: Iterable[tuple[str, torch.Tensor]], @@ -370,10 +359,6 @@ def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor: return self.roberta.embed_input_ids(input_ids) - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - def forward( self, input_ids: torch.Tensor | None, diff --git a/vllm/model_executor/models/sarvam.py b/vllm/model_executor/models/sarvam.py index b9f9532ae1b1..6b57efc596cb 100644 --- a/vllm/model_executor/models/sarvam.py +++ b/vllm/model_executor/models/sarvam.py @@ -676,16 +676,6 @@ def compute_logits( logits = self.logits_processor(self.lm_head, hidden_states) return logits - def load_weights( - self, - weights: Iterable[tuple[str, torch.Tensor]], - ) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.tie_word_embeddings else None), - ) - return loader.load_weights(weights) - class SarvamMoEForCausalLM(BailingMoeForCausalLM): """Same as BailingMoeForCausalLM, but normalizes gate expert_bias pre-load.""" diff --git a/vllm/model_executor/models/seed_oss.py b/vllm/model_executor/models/seed_oss.py index d2c767846d70..b6d57c7ce129 100644 --- a/vllm/model_executor/models/seed_oss.py +++ b/vllm/model_executor/models/seed_oss.py @@ -23,7 +23,6 @@ # limitations under the License. """Inference-only SeedOss model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -55,7 +54,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, make_empty_intermediate_tensors_factory, @@ -427,10 +425,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/siglip.py b/vllm/model_executor/models/siglip.py index 5808c9539bfc..efe37e83e885 100644 --- a/vllm/model_executor/models/siglip.py +++ b/vllm/model_executor/models/siglip.py @@ -618,10 +618,6 @@ def forward( return last_hidden_state - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) - class SiglipMultiheadAttentionPoolingHead(nn.Module): """Multihead Attention Pooling.""" @@ -796,13 +792,6 @@ def maybe_layer_norm_and_apply_head( return encoder_outputs def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - skip_prefixes = [] - if self.post_layernorm is None: - skip_prefixes.append("post_layernorm.") - if self.head is None: - skip_prefixes.append("head.") - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - layer_count = len(self.encoder.layers) def _filter(ws): @@ -814,7 +803,13 @@ def _filter(ws): continue yield name, w - return loader.load_weights(_filter(weights), mapper=self.hf_to_vllm_mapper) + mapper = self.hf_to_vllm_mapper + if self.post_layernorm is None: + mapper |= WeightsMapper(orig_to_new_prefix={"post_layernorm.": None}) + if self.head is None: + mapper |= WeightsMapper(orig_to_new_prefix={"head.": None}) + loader = AutoWeightsLoader(self) + return loader.load_weights(_filter(weights), mapper=mapper) class SiglipVisionModel(nn.Module): @@ -910,6 +905,7 @@ def forward( ) class SiglipEmbeddingModel(nn.Module, SupportsMultiModal, SupportsQuant): is_pooling_model = True + hf_to_vllm_mapper = WeightsMapper(orig_to_new_substr={".position_ids": None}) packed_modules_mapping = {"qkv_proj": ["q_proj", "k_proj", "v_proj"]} @@ -1149,8 +1145,6 @@ def forward( def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): loader = AutoWeightsLoader( self, - skip_substrs=[".position_ids"], ignore_unexpected_prefixes=["logit_scale.", "logit_bias."], ) - - return loader.load_weights(weights) + return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/siglip2navit.py b/vllm/model_executor/models/siglip2navit.py index 5ee1c2c91059..db7a34d51eda 100644 --- a/vllm/model_executor/models/siglip2navit.py +++ b/vllm/model_executor/models/siglip2navit.py @@ -3,8 +3,6 @@ """Implementation of SiglipVisionModel intended to be only used within a vision language model.""" -from collections.abc import Iterable - import torch from torch import nn from torch.nn import functional as F @@ -28,7 +26,7 @@ ) from vllm.platforms import current_platform -from .utils import AutoWeightsLoader, WeightsMapper, maybe_prefix +from .utils import WeightsMapper, maybe_prefix from .vision import is_vit_use_data_parallel @@ -618,7 +616,3 @@ def forward( pixel_values=pixel_values, grid_thws=grid_thws, ) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/skyworkr1v.py b/vllm/model_executor/models/skyworkr1v.py index d57da08598a1..7055d4207cd1 100644 --- a/vllm/model_executor/models/skyworkr1v.py +++ b/vllm/model_executor/models/skyworkr1v.py @@ -7,7 +7,7 @@ # Copyright (c) 2025 Skywork # Licensed under The MIT License [see LICENSE for details] # -------------------------------------------------------- -from collections.abc import Iterable, Mapping +from collections.abc import Mapping from typing import Annotated, Literal, TypeAlias import torch @@ -38,7 +38,7 @@ BaseInternVLMultiModalProcessor, BaseInternVLProcessingInfo, ) -from .utils import AutoWeightsLoader, init_vllm_registered_model, maybe_prefix +from .utils import WeightsMapper, init_vllm_registered_model, maybe_prefix class SkyworkR1VImagePixelInputs(TensorSchema): @@ -150,6 +150,23 @@ def get_dummy_mm_data( dummy_inputs=BaseInternVLDummyInputsBuilder, ) class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP): + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_prefix={ + "action_embed": None, + "temporal_embed": None, + "track_embed": None, + "track_embed_decoder": None, + "box_token": None, + "cg_criterion": None, + "cg_model": None, + "loc_encoder": None, + "loc_decoder": None, + "sam": None, + "temporal_token": None, + "track_token": None, + } + ) + @classmethod def get_placeholder_str(cls, modality: str, i: int) -> str | None: if modality.startswith("image"): @@ -409,21 +426,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - skip_prefixes = [ - "action_embed", - "temporal_embed", - "track_embed", - "track_embed_decoder", - "box_token", - "cg_criterion", - "cg_model", - "loc_encoder", - "loc_decoder", - "sam", - "temporal_token", - "track_token", - ] - loader = AutoWeightsLoader(self, skip_prefixes=skip_prefixes) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/solar.py b/vllm/model_executor/models/solar.py index 478a61da6754..70250a97d253 100644 --- a/vllm/model_executor/models/solar.py +++ b/vllm/model_executor/models/solar.py @@ -24,8 +24,6 @@ # limitations under the License. """Inference-only Solar model compatible with HuggingFace weights.""" -from collections.abc import Iterable - import torch from torch import nn from transformers import PretrainedConfig @@ -52,7 +50,6 @@ from .interfaces import SupportsLoRA, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, make_empty_intermediate_tensors_factory, @@ -417,7 +414,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/stablelm.py b/vllm/model_executor/models/stablelm.py index 58758b11cdda..e84d61512bfa 100644 --- a/vllm/model_executor/models/stablelm.py +++ b/vllm/model_executor/models/stablelm.py @@ -22,7 +22,6 @@ """Inference-only StableLM (https://github.com/Stability-AI/StableLM) model compatible with HuggingFace weights.""" -from collections.abc import Iterable from itertools import islice import torch @@ -49,7 +48,6 @@ from .interfaces import SupportsPP from .utils import ( - AutoWeightsLoader, WeightsMapper, make_empty_intermediate_tensors_factory, make_layers, @@ -321,7 +319,3 @@ def compute_logits( ) -> torch.Tensor | None: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/step1.py b/vllm/model_executor/models/step1.py index c18bf8a3c353..561eba42e97b 100644 --- a/vllm/model_executor/models/step1.py +++ b/vllm/model_executor/models/step1.py @@ -5,7 +5,6 @@ from __future__ import annotations import math -from collections.abc import Iterable import torch from torch import nn @@ -37,7 +36,6 @@ SupportsPP, ) from vllm.model_executor.models.utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, make_empty_intermediate_tensors_factory, @@ -381,7 +379,3 @@ def compute_logits( if not get_pp_group().is_last_rank: return None return self.logits_processor(self.lm_head, hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/step3_text.py b/vllm/model_executor/models/step3_text.py index 7fb5a9170599..c7a1813e0a3f 100644 --- a/vllm/model_executor/models/step3_text.py +++ b/vllm/model_executor/models/step3_text.py @@ -41,7 +41,6 @@ from .interfaces import SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, is_pp_missing_parameter, make_empty_intermediate_tensors_factory, @@ -566,7 +565,3 @@ def forward( def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/step3_vl.py b/vllm/model_executor/models/step3_vl.py index 7b3bb93ad116..314710ec0a0c 100644 --- a/vllm/model_executor/models/step3_vl.py +++ b/vllm/model_executor/models/step3_vl.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project import math -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Mapping, Sequence from math import sqrt from typing import Annotated, Any, Literal, TypeAlias @@ -53,7 +53,6 @@ SupportsPP, ) from .utils import ( - AutoWeightsLoader, WeightsMapper, init_vllm_registered_model, maybe_prefix, @@ -962,7 +961,3 @@ def compute_logits( hidden_states: torch.Tensor, ) -> torch.Tensor | None: return self.language_model.compute_logits(hidden_states) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]): - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/step3p5.py b/vllm/model_executor/models/step3p5.py index 07a25d23c8c4..94e708f81d2e 100644 --- a/vllm/model_executor/models/step3p5.py +++ b/vllm/model_executor/models/step3p5.py @@ -49,7 +49,6 @@ from .interfaces import MixtureOfExperts, SupportsPP from .utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, extract_layer_index, @@ -975,7 +974,3 @@ def update_physical_experts_metadata( layer.n_physical_experts = num_physical_experts layer.n_redundant_experts = self.num_redundant_experts layer.experts.update_expert_map() - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/telechat2.py b/vllm/model_executor/models/telechat2.py index 42fa6d6871a6..70719524057e 100644 --- a/vllm/model_executor/models/telechat2.py +++ b/vllm/model_executor/models/telechat2.py @@ -120,10 +120,3 @@ def _init_model( layer_type: type[nn.Module] = LlamaDecoderLayer, ): return TeleChat2Model(vllm_config=vllm_config, prefix=prefix) - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader( - self, - skip_prefixes=(["lm_head."] if self.config.tie_word_embeddings else None), - ) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/model_executor/models/transformers/base.py b/vllm/model_executor/models/transformers/base.py index 24cad1da20d2..24c95f4b5bf0 100644 --- a/vllm/model_executor/models/transformers/base.py +++ b/vllm/model_executor/models/transformers/base.py @@ -117,10 +117,6 @@ def __init__(self, *, vllm_config: "VllmConfig", prefix: str = ""): self.tp_group = get_tp_group() # Attrs for weight loading (see self.load_weights) - self.skip_prefixes: list[str] = [] - """Skip loading weights whose qualname starts with these prefixes.""" - self.skip_substrs: list[str] = [] - """Skip loading weights whose qualname contains these substrings.""" self.ignore_unexpected_prefixes: list[str] = [] """Ignore unexpected weights whose qualname starts with these prefixes.""" self.ignore_unexpected_suffixes: list[str] = [] @@ -662,8 +658,6 @@ def forward( def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: loader = AutoWeightsLoader( self, - skip_prefixes=self.skip_prefixes, - skip_substrs=self.skip_substrs, ignore_unexpected_prefixes=self.ignore_unexpected_prefixes, ignore_unexpected_suffixes=self.ignore_unexpected_suffixes, ) diff --git a/vllm/model_executor/models/transformers/causal.py b/vllm/model_executor/models/transformers/causal.py index 01a7e4198341..a173a3cf200b 100644 --- a/vllm/model_executor/models/transformers/causal.py +++ b/vllm/model_executor/models/transformers/causal.py @@ -37,11 +37,10 @@ def __init__(self, *, vllm_config: "VllmConfig", prefix: str = ""): vllm_config=vllm_config, prefix=prefix ) - # Tell `Base.load_weights` to skip - # `lm_head` if the model has tied word embeddings + # Skip loading `lm_head` if the model has tied word embeddings tie_word_embeddings = self._get_tie_word_embeddings() if tie_word_embeddings: - self.skip_prefixes.append("lm_head.") + self.hf_to_vllm_mapper.orig_to_new_prefix["lm_head."] = None if self.pp_group.is_last_rank: self.lm_head = ParallelLMHead( diff --git a/vllm/model_executor/models/transformers/legacy.py b/vllm/model_executor/models/transformers/legacy.py index 49c5e9dcf68a..77715e0a445d 100644 --- a/vllm/model_executor/models/transformers/legacy.py +++ b/vllm/model_executor/models/transformers/legacy.py @@ -31,25 +31,25 @@ def __init__(self, *, vllm_config: "VllmConfig", prefix: str = ""): super().__init__(vllm_config=vllm_config, prefix=prefix) # Skip unsupported/unwanted output embeddings layers - self.skip_prefixes.extend( - [ - "model.lm_head.", - "model.predictions.", - "model.qa_outputs.", - "model.embeddings_project.", - "model.discriminator_predictions.", - ] + self.hf_to_vllm_mapper.orig_to_new_prefix.update( + { + "model.lm_head.": None, + "model.predictions.": None, + "model.qa_outputs.": None, + "model.embeddings_project.": None, + "model.discriminator_predictions.": None, + } ) # Some encoder models have the position_ids buffer in the checkpoint. # vLLM will always pass position_ids as an argument, so we skip loading # the buffer if it exists - self.skip_substrs.append("position_ids") + self.hf_to_vllm_mapper.orig_to_new_substr["position_ids"] = None # Some encoder models have the bias of the final classifier layer # in the checkpoint. vLLM does not use this bias, so we skip loading # it if it exists - self.skip_substrs.append("score.bias") + self.hf_to_vllm_mapper.orig_to_new_substr["score.bias"] = None # roberta-like models an extra padding in positions. # FIXME(Isotr0py): This is quite hacky for roberta edge case, diff --git a/vllm/model_executor/models/utils.py b/vllm/model_executor/models/utils.py index a6f39f6ebf8b..21fa1d280060 100644 --- a/vllm/model_executor/models/utils.py +++ b/vllm/model_executor/models/utils.py @@ -188,31 +188,33 @@ class AutoWeightsLoader: # Models trained using early version ColossalAI or quantized by # GPTQModel may include these tensors in checkpoint. Skip them. - ROTARY_EMBEDS_UNUSED_WEIGHTS = [ - "rotary_pos_emb.inv_freq", - "rotary_emb.inv_freq", - "rotary_emb.cos_cached", - "rotary_emb.sin_cached", - ] + REMOVE_UNUSED_ROTARY_EMBEDS_MAPPER = WeightsMapper( + orig_to_new_substr={ + "rotary_pos_emb.inv_freq": None, + "rotary_emb.inv_freq": None, + "rotary_emb.cos_cached": None, + "rotary_emb.sin_cached": None, + } + ) + REMOVE_TIED_LM_HEAD_MAPPER = WeightsMapper(orig_to_new_prefix={"lm_head.": None}) def __init__( self, module: nn.Module, *, - skip_prefixes: list[str] | None = None, - skip_substrs: list[str] | None = None, ignore_unexpected_prefixes: list[str] | None = None, ignore_unexpected_suffixes: list[str] | None = None, ) -> None: super().__init__() self.module = module - self.skip_prefixes = skip_prefixes or [] - self.skip_substrs = skip_substrs or [] self.ignore_unexpected_prefixes = ignore_unexpected_prefixes or [] self.ignore_unexpected_suffixes = ignore_unexpected_suffixes or [] - # update default skip_substrs - self.skip_substrs += self.ROTARY_EMBEDS_UNUSED_WEIGHTS + # If the module has a `mtp_start_layer_idx` attribute, + # it is an MTP head and should only load spec layers. + self.loads_spec_layers_only = any( + hasattr(m, "mtp_start_layer_idx") for m in module.modules() + ) def _groupby_prefix( self, @@ -242,11 +244,6 @@ def _get_qualname(self, prefix: str, rest: str) -> str: return ".".join((prefix, rest)) - def _can_skip(self, qualname: str) -> bool: - return any(qualname.startswith(p) for p in self.skip_prefixes) or any( - substr in qualname for substr in self.skip_substrs - ) - def _can_ignore_unexpected(self, qualname: str) -> bool: iup = (qualname.startswith(p) for p in self.ignore_unexpected_prefixes) ius = (qualname.endswith(s) for s in self.ignore_unexpected_suffixes) @@ -261,11 +258,6 @@ def _load_param( for weight_name, weight_data in weights: weight_qualname = self._get_qualname(base_prefix, weight_name) - if self._can_skip(weight_qualname): - logger.debug("Skipping weight %s", weight_qualname) - - continue - if weight_name != "": if self._can_ignore_unexpected(weight_qualname): logger.debug("Ignoring weight %s", weight_qualname) @@ -339,6 +331,12 @@ def _load_module( loaded_params, ) + # If the module has a `hf_to_vllm_mapper` attribute, apply it to the weights. + if not callable(getattr(module, "load_weights", None)): + module_mapper = getattr(module, "hf_to_vllm_mapper", None) + if module_mapper is not None: + weights = module_mapper.apply(weights) + child_modules = dict(module.named_children()) child_params = dict(module.named_parameters(recurse=False)) @@ -350,31 +348,14 @@ def _load_module( prefix = self._get_qualname(base_prefix, child_prefix) if child_prefix in child_modules: - if self._can_skip(prefix + "."): - logger.debug("Skipping module %s", prefix) - - continue - yield from self._load_module( prefix, child_modules[child_prefix], child_weights ) elif child_prefix in child_params: - if self._can_skip(prefix): - logger.debug("Skipping param %s", prefix) - - continue - yield from self._load_param( prefix, child_params[child_prefix], child_weights ) else: - can_skip_module = self._can_skip(prefix + ".") - can_skip_param = self._can_skip(prefix) - if can_skip_module or can_skip_param: - logger.debug("Skipping missing %s", prefix) - - continue - can_ignore_module = self._can_ignore_unexpected(prefix + ".") can_ignore_param = self._can_ignore_unexpected(prefix) if can_ignore_module or can_ignore_param: @@ -382,6 +363,22 @@ def _load_module( continue + # Skip spec layers on base models and skip base layers on spec models. + config = getattr(self.module, "config", None) + if config is not None: + is_spec_layer = ( + get_spec_layer_idx_from_weight_name(config, prefix + ".") + is not None + ) + if is_spec_layer != self.loads_spec_layers_only: + logger.debug( + "Skipping %s model layer %s", + "base" if self.loads_spec_layers_only else "speculative", + prefix, + ) + + continue + named_parameters = module.named_parameters(recurse=True) desc_param_keys = { maybe_prefix(base_prefix, k) for k, _ in named_parameters @@ -404,22 +401,25 @@ def load_weights( # Ignore unexpected biases (typically from GPTQ models) self.ignore_unexpected_suffixes.append(".bias") + # Ensure we have a mapper + mapper = mapper or WeightsMapper() # Many models store quant_config in the base model instead of the causal model. # We look at the causal model's direct children for this reason. modules = (self.module, *self.module.children()) iterator = (m.quant_config for m in modules if hasattr(m, "quant_config")) if quant_config := next(iterator, None): # Get mappings and ignore prefixes for KV cache quantization scales - mapper = mapper or WeightsMapper() mapper |= quant_config.get_cache_scale_mapper() ignore_unexpected_suffixes = quant_config._ignore_unexpected_suffixes self.ignore_unexpected_suffixes.extend(ignore_unexpected_suffixes) - if mapper is not None: - weights = mapper.apply(weights) - # filter out weights with first-prefix/substr to skip in name - weights = ( - (name, weight) for name, weight in weights if not self._can_skip(name) - ) + # Always drop the known-unused rotary buffers some checkpoints ship. + mapper |= self.REMOVE_UNUSED_ROTARY_EMBEDS_MAPPER + # Drop lm_head weights when the model ties them to the input embeddings. + config = getattr(self.module, "config", None) + if config is not None and getattr(config, "tie_word_embeddings", False): + mapper |= self.REMOVE_TIED_LM_HEAD_MAPPER + + weights = mapper.apply(weights) autoloaded_weights = set(self._load_module("", self.module, weights)) return autoloaded_weights diff --git a/vllm/model_executor/models/voxtral.py b/vllm/model_executor/models/voxtral.py index f15ec491af14..75c4690b2ec0 100644 --- a/vllm/model_executor/models/voxtral.py +++ b/vllm/model_executor/models/voxtral.py @@ -24,6 +24,7 @@ from vllm.inputs import MultiModalDataDict, PromptType, TokensPrompt from vllm.logger import init_logger from vllm.model_executor.layers.quantization import QuantizationConfig +from vllm.model_executor.model_loader.utils import autoload_weights from vllm.model_executor.model_loader.weight_utils import default_weight_loader from vllm.model_executor.models import SupportsPP from vllm.model_executor.models.module_mapping import MultiModelKeys @@ -556,7 +557,7 @@ def llm_weights_generator(): else: yield (name, w) - for name in self.language_model.load_weights(llm_weights_generator()): + for name in autoload_weights(self.language_model, llm_weights_generator()): loaded_weights.add(f"language_model.{name}") # potentially manually add position embeddings diff --git a/vllm/model_executor/models/voyage.py b/vllm/model_executor/models/voyage.py index 92d6d7633f02..56e2775852a7 100644 --- a/vllm/model_executor/models/voyage.py +++ b/vllm/model_executor/models/voyage.py @@ -2,14 +2,12 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project from __future__ import annotations -from collections.abc import Iterable - import torch import torch.nn as nn from vllm.config import VllmConfig from vllm.model_executor.models.qwen3 import Qwen3Model -from vllm.model_executor.models.utils import AutoWeightsLoader, maybe_prefix +from vllm.model_executor.models.utils import maybe_prefix from vllm.sequence import IntermediateTensors WeightItem = tuple[str, torch.Tensor] @@ -61,7 +59,3 @@ def forward( ) -> torch.Tensor: out = self.model(input_ids, positions, intermediate_tensors, inputs_embeds) return self.linear(out) - - def load_weights(self, weights: Iterable[WeightItem]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) diff --git a/vllm/model_executor/models/whisper.py b/vllm/model_executor/models/whisper.py index 8efab53db8a8..a7e36efb7c3e 100644 --- a/vllm/model_executor/models/whisper.py +++ b/vllm/model_executor/models/whisper.py @@ -771,6 +771,7 @@ class WhisperForConditionalGeneration( } hf_to_vllm_mapper = WeightsMapper( + orig_to_new_prefix={"proj_out.": None}, orig_to_new_substr={".fc1.": ".mlp.fc1.", ".fc2.": ".mlp.fc2."}, orig_to_new_stacked={ # weight_name: (param_name, shard_id) @@ -990,7 +991,7 @@ def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor: return logits def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_prefixes=["proj_out."]) + loader = AutoWeightsLoader(self) # add fake zeros bias for k_proj to state_dict weights = _create_fake_bias_for_k_proj(weights, ".k_proj.weight") diff --git a/vllm/model_executor/models/zamba2.py b/vllm/model_executor/models/zamba2.py index f80c8a3b0783..d0042d5d613c 100644 --- a/vllm/model_executor/models/zamba2.py +++ b/vllm/model_executor/models/zamba2.py @@ -8,7 +8,6 @@ model alternates between state space model layers and attention-based layers. """ -from collections.abc import Iterable from itertools import cycle from typing import Any @@ -46,7 +45,7 @@ from vllm.sequence import IntermediateTensors from .interfaces import HasInnerState, IsHybrid, SupportsMambaPrefixCaching -from .utils import AutoWeightsLoader, WeightsMapper, maybe_prefix +from .utils import WeightsMapper, maybe_prefix class Zamba2LoRA(nn.Module): @@ -962,7 +961,3 @@ def compute_logits( """ logits = self.logits_processor(self.lm_head, hidden_states) return logits - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/models/deepseek_v4/amd/model.py b/vllm/models/deepseek_v4/amd/model.py index 9093bd412899..fe6fade1c9c9 100644 --- a/vllm/models/deepseek_v4/amd/model.py +++ b/vllm/models/deepseek_v4/amd/model.py @@ -852,8 +852,10 @@ def get_mtp_target_hidden_states(self) -> torch.Tensor | None: return getattr(self.model, "_mtp_hidden_buffer", None) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_substrs=["mtp."]) - loaded_params = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) + drop = WeightsMapper(orig_to_new_substr={"mtp.": None}) + mapper = self.hf_to_vllm_mapper | drop + loader = AutoWeightsLoader(self) + loaded_params = loader.load_weights(weights, mapper=mapper) return loaded_params def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: diff --git a/vllm/models/deepseek_v4/nvidia/model.py b/vllm/models/deepseek_v4/nvidia/model.py index ddc2fe0f4bc2..626dc44a5fc3 100644 --- a/vllm/models/deepseek_v4/nvidia/model.py +++ b/vllm/models/deepseek_v4/nvidia/model.py @@ -1466,8 +1466,10 @@ def get_mtp_target_hidden_states(self) -> torch.Tensor | None: return getattr(self.model, "_mtp_hidden_buffer", None) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_substrs=["mtp."]) - loaded_params = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) + drop = WeightsMapper(orig_to_new_substr={"mtp.": None}) + mapper = self.hf_to_vllm_mapper | drop + loader = AutoWeightsLoader(self) + loaded_params = loader.load_weights(weights, mapper=mapper) self.model.finalize_mega_moe_weights() self.model.finalize_mhc_broadcast_weights() return loaded_params diff --git a/vllm/models/deepseek_v4/xpu/model.py b/vllm/models/deepseek_v4/xpu/model.py index e8449b9c058b..0439281dd026 100644 --- a/vllm/models/deepseek_v4/xpu/model.py +++ b/vllm/models/deepseek_v4/xpu/model.py @@ -1374,8 +1374,10 @@ def get_mtp_target_hidden_states(self) -> torch.Tensor | None: return getattr(self.model, "_mtp_hidden_buffer", None) def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self, skip_substrs=["mtp."]) - loaded_params = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) + drop = WeightsMapper(orig_to_new_substr={"mtp.": None}) + mapper = self.hf_to_vllm_mapper | drop + loader = AutoWeightsLoader(self) + loaded_params = loader.load_weights(weights, mapper=mapper) self.model.finalize_mega_moe_weights() return loaded_params diff --git a/vllm/models/inkling/nvidia/model.py b/vllm/models/inkling/nvidia/model.py index a8506d92327b..e0cf69d331a4 100644 --- a/vllm/models/inkling/nvidia/model.py +++ b/vllm/models/inkling/nvidia/model.py @@ -671,8 +671,9 @@ def _iter_loadable_weights() -> Iterable[tuple[str, torch.Tensor]]: # The release checkpoint also carries auxiliary prediction-head weights; # they are not part of the causal LM served by this implementation. - loader = AutoWeightsLoader(module, skip_prefixes=["model.mtp."]) - loaded |= loader.load_weights(_iter_loadable_weights()) + loader = AutoWeightsLoader(module) + drop = WeightsMapper(orig_to_new_prefix={"model.mtp.": None}) + loaded |= loader.load_weights(_iter_loadable_weights(), mapper=drop) # Post-load MoE fixups (default input scales, zeroed EP-padding experts). for moe_name, moe in moe_modules.items(): diff --git a/vllm/models/minimax_m3/amd/model.py b/vllm/models/minimax_m3/amd/model.py index 324104e055f8..479f7e49688e 100644 --- a/vllm/models/minimax_m3/amd/model.py +++ b/vllm/models/minimax_m3/amd/model.py @@ -70,7 +70,6 @@ SupportsPP, ) from vllm.model_executor.models.utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, init_vllm_registered_model, @@ -1327,10 +1326,6 @@ def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None: def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: return self.model.get_expert_mapping() - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - # TODO(refactor): this VL wrapper is platform-agnostic and byte-identical to the # NVIDIA copy — it only orchestrates the shared vision tower + the per-platform @@ -1533,7 +1528,3 @@ def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None: def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: return self.language_model.get_expert_mapping() - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/models/minimax_m3/common/vision_tower.py b/vllm/models/minimax_m3/common/vision_tower.py index 23b8b3ed3197..b94eed81a134 100644 --- a/vllm/models/minimax_m3/common/vision_tower.py +++ b/vllm/models/minimax_m3/common/vision_tower.py @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project -from collections.abc import Iterable import numpy as np import torch @@ -21,8 +20,7 @@ ) from vllm.model_executor.layers.quantization import QuantizationConfig from vllm.model_executor.layers.rotary_embedding.common import ApplyRotaryEmb -from vllm.model_executor.model_loader.weight_utils import default_weight_loader -from vllm.model_executor.models.utils import maybe_prefix +from vllm.model_executor.models.utils import WeightsMapper, maybe_prefix from vllm.model_executor.models.vision import ( get_vit_attn_backend, is_vit_use_data_parallel, @@ -676,6 +674,14 @@ def forward(self, x: torch.Tensor) -> torch.Tensor: class MiniMaxVLVisionModel(nn.Module): """Full vision model: ViT → projector → patch merger.""" + hf_to_vllm_mapper = WeightsMapper( + orig_to_new_stacked={ + "q_proj.": ("qkv_proj.", "q"), + "k_proj.": ("qkv_proj.", "k"), + "v_proj.": ("qkv_proj.", "v"), + } + ) + def __init__( self, config: PretrainedConfig, @@ -736,30 +742,3 @@ def forward( hidden = self.multi_modal_projector(hidden) hidden = self.patch_merge_mlp(hidden) return hidden - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - stacked_params_mapping = [ - # (param_name, shard_name, shard_id) - ("qkv_proj.", "q_proj.", "q"), - ("qkv_proj.", "k_proj.", "k"), - ("qkv_proj.", "v_proj.", "v"), - ] - params_dict = dict(self.named_parameters(remove_duplicate=False)) - loaded_params: set[str] = set() - - for name, loaded_weight in weights: - for param_name, weight_name, shard_id in stacked_params_mapping: - if weight_name not in name: - continue - name = name.replace(weight_name, param_name) - - param = params_dict[name] - weight_loader = param.weight_loader - weight_loader(param, loaded_weight, shard_id) - break - else: - param = params_dict[name] - weight_loader = getattr(param, "weight_loader", default_weight_loader) - weight_loader(param, loaded_weight) - loaded_params.add(name) - return loaded_params diff --git a/vllm/models/minimax_m3/nvidia/model.py b/vllm/models/minimax_m3/nvidia/model.py index e29514ab9a32..17b85166d92f 100644 --- a/vllm/models/minimax_m3/nvidia/model.py +++ b/vllm/models/minimax_m3/nvidia/model.py @@ -60,7 +60,6 @@ SupportsPP, ) from vllm.model_executor.models.utils import ( - AutoWeightsLoader, PPMissingLayer, WeightsMapper, init_vllm_registered_model, @@ -1039,10 +1038,6 @@ def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None: def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: return self.model.get_expert_mapping() - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights) - @MULTIMODAL_REGISTRY.register_processor( MiniMaxM3VLMultiModalProcessor, @@ -1251,7 +1246,3 @@ def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None: def get_expert_mapping(self) -> list[tuple[str, str, int, str]]: return self.language_model.get_expert_mapping() - - def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: - loader = AutoWeightsLoader(self) - return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper) diff --git a/vllm/v1/worker/gpu_model_runner.py b/vllm/v1/worker/gpu_model_runner.py index f3f0afb1301f..73d9104997ed 100644 --- a/vllm/v1/worker/gpu_model_runner.py +++ b/vllm/v1/worker/gpu_model_runner.py @@ -74,6 +74,7 @@ finalize_layerwise_reload, initialize_layerwise_reload, ) +from vllm.model_executor.model_loader.utils import autoload_weights from vllm.model_executor.models.interfaces import ( MixtureOfExperts, MultiModalEmbeddings, @@ -5526,7 +5527,7 @@ def reload_weights( if is_checkpoint_format: # load weights from checkpoint/ original model format initialize_layerwise_reload(model) - loaded_weights = model.load_weights(weights_iterator) + loaded_weights = autoload_weights(model, weights_iterator) finalize_layerwise_reload(model, self.model_config) else: