harrypart commited on
Commit
9e54510
·
verified ·
1 Parent(s): 6cdded2

remove vLLM plugin

Browse files
Files changed (1) hide show
  1. plugins/vllm_glm5v/glm5v.py +0 -241
plugins/vllm_glm5v/glm5v.py DELETED
@@ -1,241 +0,0 @@
1
- # SPDX-License-Identifier: Apache-2.0
2
- """
3
- glm5v: out-of-tree vLLM model = MoonViT (Kimi-K2.6) vision tower + trained MLP
4
- projector + GLM-5.2 (GlmMoeDsa) text decoder.
5
-
6
- This is a thin frankenstein over vLLM's in-tree `kimi_k25` VLM:
7
- * vision tower + projector classes are imported VERBATIM from kimi_k25_vit
8
- (the MoonViT3d encoder + KimiK25MultiModalProjector are bit-identical to the
9
- encoder/projector we trained against).
10
- * the text backbone is swapped from DeepseekV2ForCausalLM -> GlmMoeDsaForCausalLM
11
- (GLM-5.2; same `deepseek_v2.py` MLA+MoE+DSA stack in vLLM).
12
- * the image placeholder is GLM's `<|image|>` (154854), span
13
- `<|begin_of_image|><|image|><|end_of_image|>`, instead of Kimi's `<|media_pad|>`.
14
- * projector `linear_2` outputs GLM hidden (6144) via vision_config.mm_hidden_size.
15
-
16
- Register out-of-tree via `ModelRegistry.register_model` (see register.py) with the
17
- config.json `architectures = ["Glm5vForConditionalGeneration"]`.
18
- """
19
-
20
- from collections.abc import Iterable, Mapping
21
- from typing import Any
22
-
23
- import torch
24
- from torch import nn
25
-
26
- from vllm.config import VllmConfig
27
- from vllm.logger import init_logger
28
- from vllm.model_executor.layers.quantization import QuantizationConfig
29
- from vllm.model_executor.layers.quantization.compressed_tensors import (
30
- compressed_tensors,
31
- )
32
- from vllm.model_executor.models.interfaces import (
33
- SupportsMultiModal,
34
- SupportsPP,
35
- SupportsQuant,
36
- )
37
- from vllm.model_executor.models.kimi_k25 import (
38
- KimiK25DummyInputsBuilder,
39
- KimiK25MultiModalProcessor,
40
- KimiK25ProcessingInfo,
41
- )
42
- from vllm.model_executor.models.kimi_k25_vit import (
43
- KimiK25MultiModalProjector,
44
- MoonViT3dPretrainedModel,
45
- vision_tower_forward,
46
- )
47
- from vllm.multimodal import MULTIMODAL_REGISTRY
48
- from vllm.multimodal.inputs import NestedTensors
49
- from vllm.platforms import current_platform
50
- from vllm.sequence import IntermediateTensors
51
-
52
- from .glm5v_config import Glm5vConfig
53
- from vllm.model_executor.models.utils import (
54
- AutoWeightsLoader,
55
- WeightsMapper,
56
- init_vllm_registered_model,
57
- maybe_prefix,
58
- )
59
-
60
- logger = init_logger(__name__)
61
-
62
-
63
- class Glm5vProcessingInfo(KimiK25ProcessingInfo):
64
- """Processing info: GLM tokenizer + `<|image|>` placeholder + MoonViT image proc.
65
-
66
- Reuses Kimi-K2.6's image processor (identical MoonViT preprocessing) and its
67
- `KimiK25Processor` wiring; only the config type and placeholder token differ.
68
- """
69
-
70
- def get_hf_config(self):
71
- return self.ctx.get_hf_config(Glm5vConfig)
72
-
73
-
74
- class Glm5vDummyInputsBuilder(KimiK25DummyInputsBuilder):
75
- pass
76
-
77
-
78
- class Glm5vMultiModalProcessor(KimiK25MultiModalProcessor):
79
- pass
80
-
81
-
82
- @MULTIMODAL_REGISTRY.register_processor(
83
- Glm5vMultiModalProcessor,
84
- info=Glm5vProcessingInfo,
85
- dummy_inputs=Glm5vDummyInputsBuilder,
86
- )
87
- class Glm5vForConditionalGeneration(
88
- nn.Module,
89
- SupportsMultiModal,
90
- SupportsPP,
91
- SupportsQuant,
92
- ):
93
- """glm5v: MoonViT vision + trained projector + GLM-5.2 text."""
94
-
95
- supports_encoder_tp_data = True
96
-
97
- hf_to_vllm_mapper = WeightsMapper(
98
- orig_to_new_prefix={
99
- # GLM-5.2 text shards are stored with raw `model.*` / `lm_head.*` keys;
100
- # nest them under the `language_model` submodule. (vision_tower.* and
101
- # mm_projector.* keys are already correctly namespaced in our assembly.)
102
- "lm_head.": "language_model.lm_head.",
103
- "model.": "language_model.model.",
104
- }
105
- )
106
-
107
- @classmethod
108
- def get_placeholder_str(cls, modality: str, i: int) -> str | None:
109
- if modality == "image":
110
- # GLM image span; the inner <|image|> token is the one expanded.
111
- return "<|begin_of_image|><|image|><|end_of_image|>"
112
- raise ValueError(f"Unsupported modality: {modality}")
113
-
114
- def __init__(self, vllm_config: VllmConfig, prefix: str = "") -> None:
115
- super().__init__()
116
- model_config = vllm_config.model_config
117
- config: Glm5vConfig = model_config.hf_config
118
- self.config = config
119
- quant_config = vllm_config.quant_config
120
-
121
- self.use_data_parallel = (
122
- model_config.multimodal_config.mm_encoder_tp_mode == "data"
123
- )
124
- self.hidden_size = config.text_config.hidden_size
125
- self.device = current_platform.current_device()
126
-
127
- # Vision tower + projector (MoonViT, kept out of compressed-tensors quant).
128
- with self._mark_tower_model(vllm_config, "vision_chunk"):
129
- self.vision_tower = MoonViT3dPretrainedModel(
130
- config.vision_config,
131
- quant_config=self._maybe_ignore_quant_config(quant_config),
132
- prefix=maybe_prefix(prefix, "vision_tower"),
133
- )
134
- self.vision_tower = self.vision_tower.to(
135
- device=self.device, dtype=model_config.dtype
136
- )
137
- self.mm_projector = KimiK25MultiModalProjector(
138
- config=config.vision_config,
139
- use_data_parallel=self.use_data_parallel,
140
- quant_config=self._maybe_ignore_quant_config(quant_config),
141
- prefix=maybe_prefix(prefix, "mm_projector"),
142
- )
143
- self.mm_projector = self.mm_projector.to(
144
- device=self.device, dtype=model_config.dtype
145
- )
146
-
147
- self.quant_config = quant_config
148
- with self._mark_language_model(vllm_config):
149
- self.language_model = init_vllm_registered_model(
150
- vllm_config=vllm_config,
151
- hf_config=config.text_config,
152
- prefix=maybe_prefix(prefix, "language_model"),
153
- architectures=["GlmMoeDsaForCausalLM"],
154
- )
155
- self.make_empty_intermediate_tensors = (
156
- self.language_model.make_empty_intermediate_tensors
157
- )
158
- self.media_placeholder: int = self.config.media_placeholder_token_id
159
-
160
- def _maybe_ignore_quant_config(self, quant_config: QuantizationConfig):
161
- # Keep the MoonViT vision tower + trained projector in bf16; only the GLM
162
- # text backbone is quantized. The GLM-5.2-NVFP4 checkpoint uses ModelOpt
163
- # NVFP4 (modelopt_fp4) for the text Linears, but our vision/projector
164
- # weights are bf16 -- so skip quant for them regardless of method.
165
- from vllm.model_executor.layers.quantization.modelopt import (
166
- ModelOptNvFp4Config,
167
- ModelOptFp8Config,
168
- )
169
-
170
- if isinstance(
171
- quant_config,
172
- (
173
- compressed_tensors.CompressedTensorsConfig,
174
- ModelOptNvFp4Config,
175
- ModelOptFp8Config,
176
- ),
177
- ):
178
- return None
179
- return quant_config
180
-
181
- def _parse_and_validate_media_input(self, **kwargs: object):
182
- pixel_values = kwargs.pop("pixel_values", None)
183
- grid_thws = kwargs.pop("grid_thws", None)
184
- if pixel_values is None:
185
- return None
186
- if isinstance(pixel_values, list):
187
- pixel_values = torch.cat(pixel_values, dim=0)
188
- if len(pixel_values.shape) == 5 or len(pixel_values.shape) == 3:
189
- pixel_values = pixel_values.reshape(
190
- pixel_values.shape[0] * pixel_values.shape[1], *pixel_values.shape[2:]
191
- )
192
- target_dtype = next(self.vision_tower.parameters()).dtype
193
- pixel_values = pixel_values.to(target_dtype)
194
- assert isinstance(grid_thws, torch.Tensor)
195
- grid_thws = grid_thws.reshape(-1, grid_thws.shape[-1])
196
- assert grid_thws.ndim == 2 and grid_thws.size(1) == 3
197
- return {"pixel_values": pixel_values, "grid_thws": grid_thws}
198
-
199
- def _process_media_input(self, media_input) -> list[torch.Tensor]:
200
- return vision_tower_forward(
201
- self.vision_tower,
202
- media_input["pixel_values"],
203
- media_input["grid_thws"],
204
- mm_projector=self.mm_projector,
205
- use_data_parallel=self.use_data_parallel,
206
- )
207
-
208
- def embed_multimodal(self, **kwargs: object) -> NestedTensors | None:
209
- media_input = self._parse_and_validate_media_input(**kwargs)
210
- if media_input is None:
211
- return None
212
- return self._process_media_input(media_input)
213
-
214
- def forward(
215
- self,
216
- input_ids: torch.Tensor,
217
- positions: torch.Tensor,
218
- intermediate_tensors: IntermediateTensors | None = None,
219
- inputs_embeds: torch.Tensor | None = None,
220
- **kwargs: object,
221
- ) -> IntermediateTensors:
222
- if intermediate_tensors is not None:
223
- inputs_embeds = None
224
- return self.language_model(
225
- input_ids=input_ids,
226
- positions=positions,
227
- intermediate_tensors=intermediate_tensors,
228
- inputs_embeds=inputs_embeds,
229
- )
230
-
231
- def compute_logits(self, hidden_states: torch.Tensor, **kwargs) -> torch.Tensor:
232
- return self.language_model.compute_logits(hidden_states)
233
-
234
- def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]):
235
- loader = AutoWeightsLoader(self)
236
- loaded = loader.load_weights(weights, mapper=self.hf_to_vllm_mapper)
237
- # Sanity log: confirm the trained projector tensors were actually loaded
238
- # (not left at init). Helps catch key-name mismatches.
239
- proj = sorted(k for k in loaded if "mm_projector" in k)
240
- logger.info("[glm5v] mm_projector keys loaded (%d): %s", len(proj), proj)
241
- return loaded