main
py 787 lines 29.2 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 # Copyright 2025 The Baidu team.
5 # Copyright 2023 The vLLM team.
6 # Copyright 2022 EleutherAI and the HuggingFace Inc. team. All rights reserved.
7 #
8 # This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
9 # and OPT implementations in this library. It has been modified from its
10 # original forms to accommodate minor architectural differences compared
11 # to GPT-NeoX and OPT used by the Meta AI team that trained the model.
12 #
13 # Licensed under the Apache License, Version 2.0 (the "License");
14 # you may not use this file except in compliance with the License.
15 # You may obtain a copy of the License at
16 #
17 # http://www.apache.org/licenses/LICENSE-2.0
18 #
19 # Unless required by applicable law or agreed to in writing, software
20 # distributed under the License is distributed on an "AS IS" BASIS,
21 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 # See the License for the specific language governing permissions and
23 # limitations under the License.
24 """Inference-only Erine VL model compatible with HuggingFace weights."""
25
26 from collections.abc import Iterable
27 from itertools import islice
28 from typing import Any
29
30 import torch
31 from torch import nn
32 from transformers import PreTrainedConfig
33
34 # from vllm.compilation.decorators import support_torch_compile
35 from vllm.config import CacheConfig, VllmConfig
36 from vllm.distributed import get_pp_group, get_tensor_model_parallel_world_size
37 from vllm.logger import init_logger
38 from vllm.model_executor.layers.attention import Attention
39 from vllm.model_executor.layers.fused_moe import (
40 FusedMoEFactory,
41 fused_moe_make_expert_params_mapping,
42 )
43 from vllm.model_executor.layers.layernorm import RMSNorm
44 from vllm.model_executor.layers.linear import (
45 QKVParallelLinear,
46 ReplicatedLinear,
47 RowParallelLinear,
48 )
49 from vllm.model_executor.layers.logits_processor import LogitsProcessor
50 from vllm.model_executor.layers.quantization import QuantizationConfig
51 from vllm.model_executor.layers.rotary_embedding.ernie45_vl_rope import (
52 Ernie4_5_VLRotaryEmbedding,
53 )
54 from vllm.model_executor.layers.vocab_parallel_embedding import (
55 ParallelLMHead,
56 VocabParallelEmbedding,
57 )
58 from vllm.model_executor.model_loader.weight_utils import (
59 default_weight_loader,
60 maybe_remap_kv_scale_name,
61 )
62 from vllm.sequence import IntermediateTensors
63 from vllm.transformers_utils.config import set_default_rope_theta
64
65 from .ernie45_moe import Ernie4_5_MoeMLP
66 from .interfaces import SupportsPP
67 from .utils import (
68 PPMissingLayer,
69 extract_layer_index,
70 is_pp_missing_parameter,
71 make_empty_intermediate_tensors_factory,
72 make_layers,
73 maybe_prefix,
74 )
75
76 logger = init_logger(__name__)
77
78
79 class Ernie4_5_VLMoeMLP(Ernie4_5_MoeMLP):
80 def __init__(self, shared_experts: torch.nn.Module | None = None, **kwargs):
81 super().__init__(**kwargs)
82 self.shared_experts = shared_experts
83
84 def forward(self, x):
85 if self.shared_experts is not None:
86 return self.shared_experts(x) + super().forward(x)
87 else:
88 return super().forward(x)
89
90
91 class Ernie4_5_VLMoeAttention(nn.Module):
92 def __init__(
93 self,
94 hidden_size: int,
95 num_heads: int,
96 num_kv_heads: int,
97 rope_parameters: dict[str, Any],
98 head_dim: int | None = None,
99 freq_allocation: int = 20,
100 max_position_embeddings: int = 131072,
101 rms_norm_eps: float = 1e-05,
102 qkv_bias: bool = False,
103 cache_config: CacheConfig | None = None,
104 quant_config: QuantizationConfig | None = None,
105 prefix: str = "",
106 ) -> None:
107 super().__init__()
108 layer_idx = extract_layer_index(prefix) if len(prefix) > 0 else 0
109 self.layer_idx = layer_idx
110 self.hidden_size = hidden_size
111 tp_size = get_tensor_model_parallel_world_size()
112 self.total_num_heads = num_heads
113 assert self.total_num_heads % tp_size == 0
114 self.num_heads = self.total_num_heads // tp_size
115
116 self.total_num_kv_heads = num_kv_heads
117 if self.total_num_kv_heads >= tp_size:
118 # Number of KV heads is greater than TP size, so we partition
119 # the KV heads across multiple tensor parallel GPUs.
120 assert self.total_num_kv_heads % tp_size == 0
121 else:
122 # Number of KV heads is less than TP size, so we replicate
123 # the KV heads across multiple tensor parallel GPUs.
124 assert tp_size % self.total_num_kv_heads == 0
125 self.num_kv_heads = max(1, self.total_num_kv_heads // tp_size)
126 self.head_dim = head_dim or (hidden_size // self.total_num_heads)
127
128 self.q_size = self.num_heads * self.head_dim
129 self.kv_size = self.num_kv_heads * self.head_dim
130 self.scaling = self.head_dim**-0.5
131 self.max_position_embeddings = max_position_embeddings
132
133 self.qkv_proj = QKVParallelLinear(
134 hidden_size,
135 self.head_dim,
136 self.total_num_heads,
137 self.total_num_kv_heads,
138 bias=qkv_bias,
139 quant_config=quant_config,
140 prefix=f"{prefix}.qkv_proj",
141 )
142
143 self.o_proj = RowParallelLinear(
144 self.total_num_heads * self.head_dim,
145 hidden_size,
146 bias=False,
147 quant_config=quant_config,
148 prefix=f"{prefix}.o_proj",
149 )
150
151 t_rope = freq_allocation
152 h_rope = (self.head_dim // 2 - freq_allocation) // 2
153 w_rope = (self.head_dim // 2 - freq_allocation) // 2
154
155 self.rotary_emb = Ernie4_5_VLRotaryEmbedding(
156 head_size=self.head_dim,
157 rotary_dim=self.head_dim,
158 max_position_embeddings=max_position_embeddings,
159 base=rope_parameters["rope_theta"],
160 is_neox_style=False,
161 dtype=torch.get_default_dtype(),
162 mrope_section=[h_rope, w_rope, t_rope],
163 )
164
165 self.attn = Attention(
166 self.num_heads,
167 self.head_dim,
168 self.scaling,
169 num_kv_heads=self.num_kv_heads,
170 cache_config=cache_config,
171 quant_config=quant_config,
172 prefix=f"{prefix}.attn",
173 )
174
175 def forward(
176 self,
177 positions: torch.Tensor,
178 hidden_states: torch.Tensor,
179 ) -> torch.Tensor:
180 qkv, _ = self.qkv_proj(hidden_states)
181
182 q, k, v = qkv.split([self.q_size, self.kv_size, self.kv_size], dim=-1)
183 q, k = self.rotary_emb(positions, q, k)
184
185 # Attention
186 attn_output = self.attn(q, k, v)
187 # Output projection
188 output, _ = self.o_proj(attn_output)
189 return output
190
191
192 class Ernie4_5_VLMoeMoE(nn.Module):
193 def __init__(
194 self,
195 config: PreTrainedConfig,
196 quant_config: QuantizationConfig | None = None,
197 prefix: str = "",
198 ):
199 super().__init__()
200
201 layer_idx = extract_layer_index(prefix)
202 self.layer_idx = layer_idx
203 self.tp_size = get_tensor_model_parallel_world_size()
204 self.has_shared_experts = getattr(config, "moe_num_shared_experts", 0) > 0
205 self.hidden_size = config.hidden_size
206
207 moe_num_experts = config.moe_num_experts
208 max_moe_num_experts = max(moe_num_experts)
209
210 if self.tp_size > max_moe_num_experts:
211 raise ValueError(
212 f"Tensor parallel size {self.tp_size} is greater than "
213 f"the number of experts {moe_num_experts}."
214 )
215
216 moe_layer_start_index = config.moe_layer_start_index
217 text_moe_layer_start_index = moe_layer_start_index[0]
218 vision_moe_layer_start_index = moe_layer_start_index[1]
219 moe_layer_end_index = config.moe_layer_end_index
220 moe_layer_end_index = getattr(
221 config,
222 "moe_layer_end_index",
223 [config.num_hidden_layers - 1, config.num_hidden_layers - 1],
224 )
225 text_moe_layer_end_index = moe_layer_end_index[0]
226 vision_moe_layer_end_index = moe_layer_end_index[1]
227
228 assert config.moe_num_experts[0] == config.moe_num_experts[1]
229 self.e_score_correction_bias = nn.Parameter(
230 torch.empty(2, config.moe_num_experts[0], dtype=torch.float32)
231 )
232
233 assert text_moe_layer_start_index <= text_moe_layer_end_index
234
235 self.shared_experts: Ernie4_5_VLMoeMLP | None
236 if self.has_shared_experts:
237 intermediate_size = (
238 config.moe_intermediate_size[0] * config.moe_num_shared_experts
239 )
240 self.shared_experts = Ernie4_5_VLMoeMLP(
241 hidden_size=config.hidden_size,
242 intermediate_size=intermediate_size,
243 hidden_act=config.hidden_act,
244 quant_config=quant_config,
245 prefix=f"{prefix}.shared_experts",
246 reduce_results=False,
247 )
248 else:
249 self.shared_experts = None
250
251 if (
252 layer_idx >= text_moe_layer_start_index
253 and layer_idx <= text_moe_layer_end_index
254 ):
255 self.text_experts_gate = ReplicatedLinear(
256 config.hidden_size,
257 config.moe_num_experts[0],
258 bias=False,
259 params_dtype=torch.float32,
260 quant_config=quant_config,
261 prefix=f"{prefix}.text_experts_gate",
262 )
263
264 self.text_experts = FusedMoEFactory(
265 shared_experts=self.shared_experts,
266 num_experts=config.moe_num_experts[0],
267 top_k=config.moe_k,
268 hidden_size=config.hidden_size,
269 intermediate_size=config.moe_intermediate_size[0],
270 renormalize=True,
271 quant_config=quant_config,
272 e_score_correction_bias=self.e_score_correction_bias[0],
273 prefix=f"{prefix}.text_experts",
274 router_logits_dtype=torch.float32,
275 )
276 else:
277 self.text_experts = Ernie4_5_VLMoeMLP(
278 shared_experts=self.shared_experts,
279 hidden_size=config.hidden_size,
280 intermediate_size=config.intermediate_size,
281 hidden_act=config.hidden_act,
282 use_bias=getattr(config, "use_bias", False),
283 quant_config=quant_config,
284 prefix=f"{prefix}.mlp",
285 )
286
287 assert vision_moe_layer_start_index <= vision_moe_layer_end_index
288 if (
289 layer_idx >= vision_moe_layer_start_index
290 and layer_idx <= vision_moe_layer_end_index
291 ):
292 self.vision_experts_gate = ReplicatedLinear(
293 config.hidden_size,
294 config.moe_num_experts[1],
295 bias=False,
296 params_dtype=torch.float32,
297 quant_config=quant_config,
298 prefix=f"{prefix}.vision_experts_gate",
299 )
300
301 self.vision_experts = FusedMoEFactory(
302 shared_experts=self.shared_experts,
303 num_experts=config.moe_num_experts[1],
304 top_k=config.moe_k,
305 hidden_size=config.hidden_size,
306 intermediate_size=config.moe_intermediate_size[1],
307 renormalize=True,
308 quant_config=quant_config,
309 e_score_correction_bias=self.e_score_correction_bias[1],
310 prefix=f"{prefix}.vision_experts",
311 router_logits_dtype=torch.float32,
312 )
313 else:
314 self.vision_experts = Ernie4_5_VLMoeMLP(
315 shared_experts=self.shared_experts,
316 hidden_size=config.hidden_size,
317 intermediate_size=config.intermediate_size,
318 hidden_act=config.hidden_act,
319 use_bias=getattr(config, "use_bias", False),
320 quant_config=quant_config,
321 prefix=f"{prefix}.mlp",
322 )
323
324 def forward(
325 self,
326 hidden_states: torch.Tensor,
327 visual_token_mask: torch.Tensor,
328 **kwargs: object,
329 ) -> torch.Tensor:
330 orig_shape = hidden_states.shape
331 hidden_dim = hidden_states.shape[-1]
332 hidden_states = hidden_states.view(-1, hidden_dim)
333
334 if visual_token_mask is not None and visual_token_mask.all():
335 # only vision modal input
336 router_logits, _ = self.vision_experts_gate(
337 hidden_states.to(dtype=torch.float32)
338 )
339 final_hidden_states = self.vision_experts(
340 hidden_states=hidden_states, router_logits=router_logits
341 )
342 elif visual_token_mask is not None and visual_token_mask.any():
343 # text and vision modals input
344 visual_token_mask = visual_token_mask.repeat(1, self.hidden_size).bool()
345 text_token_mask = ~visual_token_mask
346 final_experts_hidden_states = torch.zeros_like(hidden_states)
347
348 text_hidden_states = hidden_states[text_token_mask].reshape(
349 -1, self.hidden_size
350 )
351 vision_hidden_states = hidden_states[visual_token_mask].reshape(
352 -1, self.hidden_size
353 )
354
355 text_router_logits, _ = self.text_experts_gate(
356 text_hidden_states.to(dtype=torch.float32)
357 )
358 text_output = self.text_experts(
359 hidden_states=text_hidden_states, router_logits=text_router_logits
360 )
361 final_experts_hidden_states[text_token_mask] = text_output.flatten()
362
363 vision_router_logits, _ = self.vision_experts_gate(
364 vision_hidden_states.to(dtype=torch.float32)
365 )
366 vision_output = self.vision_experts(
367 hidden_states=vision_hidden_states, router_logits=vision_router_logits
368 )
369 final_experts_hidden_states[visual_token_mask] = vision_output.flatten()
370
371 final_hidden_states = final_experts_hidden_states
372 else:
373 # only text modal input
374 text_router_logits, _ = self.text_experts_gate(
375 hidden_states.to(dtype=torch.float32)
376 )
377
378 final_hidden_states = self.text_experts(
379 hidden_states=hidden_states, router_logits=text_router_logits
380 )
381
382 return final_hidden_states.view(orig_shape)
383
384
385 class Ernie4_5_VLMoeDecoderLayer(nn.Module):
386 def __init__(
387 self,
388 config: PreTrainedConfig,
389 cache_config: CacheConfig | None = None,
390 quant_config: QuantizationConfig | None = None,
391 prefix: str = "",
392 ) -> None:
393 super().__init__()
394 self.hidden_size = config.hidden_size
395 set_default_rope_theta(config, default_theta=500000)
396 freq_allocation = getattr(config, "freq_allocation", 20)
397 max_position_embeddings = getattr(config, "max_position_embeddings", 131072)
398
399 self.self_attn = Ernie4_5_VLMoeAttention(
400 hidden_size=self.hidden_size,
401 num_heads=config.num_attention_heads,
402 num_kv_heads=config.num_key_value_heads,
403 head_dim=getattr(config, "head_dim", None),
404 rope_parameters=config.rope_parameters,
405 freq_allocation=freq_allocation,
406 max_position_embeddings=max_position_embeddings,
407 rms_norm_eps=config.rms_norm_eps,
408 qkv_bias=getattr(config, "use_bias", False),
409 cache_config=cache_config,
410 quant_config=quant_config,
411 prefix=f"{prefix}.self_attn",
412 )
413
414 layer_idx = extract_layer_index(prefix)
415 self.layer_idx = layer_idx
416
417 # MoE
418 moe_layer_start_index = config.moe_layer_start_index
419 min_moe_layer_start_index = min(moe_layer_start_index)
420 moe_layer_end_index = getattr(
421 config,
422 "moe_layer_end_index",
423 [config.num_hidden_layers - 1, config.num_hidden_layers - 1],
424 )
425 max_moe_layer_end_index = max(moe_layer_end_index)
426 assert min_moe_layer_start_index <= max_moe_layer_end_index
427 moe_num_experts = config.moe_num_experts
428 max_moe_num_experts = max(moe_num_experts)
429 moe_layer_interval = getattr(config, "moe_layer_interval", 1)
430 use_moe = getattr(config, "use_moe", max_moe_num_experts > 0)
431
432 if (
433 use_moe
434 and ((layer_idx + 1) % moe_layer_interval == 0)
435 and layer_idx >= min_moe_layer_start_index
436 and layer_idx <= max_moe_layer_end_index
437 ):
438 self.mlp = Ernie4_5_VLMoeMoE(
439 config=config, quant_config=quant_config, prefix=f"{prefix}.mlp"
440 )
441 else:
442 self.mlp = Ernie4_5_VLMoeMLP(
443 hidden_size=config.hidden_size,
444 intermediate_size=config.intermediate_size,
445 hidden_act=config.hidden_act,
446 use_bias=getattr(config, "use_bias", False),
447 quant_config=quant_config,
448 prefix=f"{prefix}.mlp",
449 )
450
451 self.input_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
452 self.post_attention_layernorm = RMSNorm(
453 config.hidden_size, eps=config.rms_norm_eps
454 )
455
456 def forward(
457 self,
458 positions: torch.Tensor,
459 hidden_states: torch.Tensor,
460 residual: torch.Tensor | None,
461 visual_token_mask: torch.Tensor | None,
462 **kwargs: object,
463 ) -> torch.Tensor:
464 # Self Attention
465 if residual is None:
466 residual = hidden_states
467 hidden_states = self.input_layernorm(hidden_states)
468 else:
469 hidden_states, residual = self.input_layernorm(hidden_states, residual)
470
471 hidden_states = self.self_attn(
472 positions=positions,
473 hidden_states=hidden_states,
474 )
475
476 # Fully Connected
477 hidden_states, residual = self.post_attention_layernorm(hidden_states, residual)
478
479 if isinstance(self.mlp, Ernie4_5_VLMoeMoE):
480 hidden_states = self.mlp(hidden_states, visual_token_mask, **kwargs)
481 else:
482 hidden_states = self.mlp(hidden_states)
483
484 return hidden_states, residual
485
486
487 # Since Ernie VL distinguishes between text experts and vision experts,
488 # enabling torch.compile will cause errors.
489 # @support_torch_compile(
490 # dynamic_arg_dims={
491 # "input_ids": 0,
492 # "positions": -1,
493 # "intermediate_tensors": 0,
494 # "inputs_embeds": 0,
495 # "visual_token_mask": 0,
496 # })
497 class Ernie4_5_VLMoeModel(nn.Module):
498 def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""):
499 super().__init__()
500
501 config = vllm_config.model_config.hf_config
502 cache_config = vllm_config.cache_config
503 quant_config = vllm_config.quant_config
504
505 self.vocab_size = config.vocab_size
506 self.config = config
507
508 self.im_patch_id = config.im_patch_id
509
510 if get_pp_group().is_first_rank:
511 self.embed_tokens = VocabParallelEmbedding(
512 config.vocab_size,
513 config.hidden_size,
514 quant_config=quant_config,
515 prefix=f"{prefix}.embed_tokens",
516 )
517 else:
518 self.embed_tokens = PPMissingLayer()
519
520 self.start_layer, self.end_layer, self.layers = make_layers(
521 config.num_hidden_layers,
522 lambda prefix: Ernie4_5_VLMoeDecoderLayer(
523 config=config,
524 cache_config=cache_config,
525 quant_config=quant_config,
526 prefix=prefix,
527 ),
528 prefix=f"{prefix}.layers",
529 )
530
531 if get_pp_group().is_last_rank:
532 self.norm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
533 else:
534 self.norm = PPMissingLayer()
535
536 self.make_empty_intermediate_tensors = make_empty_intermediate_tensors_factory(
537 ["hidden_states", "residual"], config.hidden_size
538 )
539
540 def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
541 return self.embed_tokens(input_ids)
542
543 def forward(
544 self,
545 input_ids: torch.Tensor | None,
546 positions: torch.Tensor,
547 intermediate_tensors: IntermediateTensors | None = None,
548 inputs_embeds: torch.Tensor | None = None,
549 visual_token_mask: torch.Tensor | None = None,
550 **kwargs: object,
551 ) -> torch.Tensor | IntermediateTensors:
552 if get_pp_group().is_first_rank:
553 if inputs_embeds is not None:
554 hidden_states = inputs_embeds
555 else:
556 hidden_states = self.embed_input_ids(input_ids)
557 residual = None
558 else:
559 assert intermediate_tensors is not None
560 hidden_states = intermediate_tensors["hidden_states"]
561 residual = intermediate_tensors["residual"]
562
563 for layer in islice(self.layers, self.start_layer, self.end_layer):
564 hidden_states, residual = layer(
565 positions, hidden_states, residual, visual_token_mask, **kwargs
566 )
567
568 if not get_pp_group().is_last_rank:
569 return IntermediateTensors(
570 {"hidden_states": hidden_states, "residual": residual}
571 )
572
573 hidden_states, _ = self.norm(hidden_states, residual)
574
575 return hidden_states
576
577
578 # only used as text backbone for ernie4.5-vl
579 class Ernie4_5_VLMoeForCausalLM(nn.Module, SupportsPP):
580 packed_modules_mapping = {
581 "qkv_proj": [
582 "q_proj",
583 "k_proj",
584 "v_proj",
585 ],
586 "gate_up_proj": [
587 "gate_proj",
588 "up_proj",
589 ],
590 }
591
592 fall_back_to_pt_during_load = False
593
594 def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""):
595 super().__init__()
596 config = vllm_config.model_config.hf_config
597 quant_config = vllm_config.quant_config
598 self.config = config
599 self.quant_config = quant_config
600 self.model = Ernie4_5_VLMoeModel(
601 vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model")
602 )
603
604 if get_pp_group().is_last_rank:
605 self.lm_head = ParallelLMHead(
606 config.vocab_size,
607 config.hidden_size,
608 quant_config=quant_config,
609 prefix=maybe_prefix(prefix, "lm_head"),
610 )
611 else:
612 self.lm_head = PPMissingLayer()
613
614 if self.config.tie_word_embeddings:
615 self.lm_head = self.lm_head.tie_weights(self.model.embed_tokens)
616 self.logits_processor = LogitsProcessor(config.vocab_size)
617 self.make_empty_intermediate_tensors = (
618 self.model.make_empty_intermediate_tensors
619 )
620
621 def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
622 return self.model.embed_input_ids(input_ids)
623
624 def forward(
625 self,
626 input_ids: torch.Tensor | None,
627 positions: torch.Tensor,
628 intermediate_tensors: IntermediateTensors | None = None,
629 inputs_embeds: torch.Tensor | None = None,
630 **kwargs: object,
631 ) -> torch.Tensor | IntermediateTensors:
632 hidden_states = self.model(
633 input_ids, positions, intermediate_tensors, inputs_embeds, **kwargs
634 )
635 return hidden_states
636
637 def compute_logits(
638 self,
639 hidden_states: torch.Tensor,
640 ) -> torch.Tensor | None:
641 logits = self.logits_processor(self.lm_head, hidden_states)
642 return logits
643
644 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
645 stacked_params_mapping = [
646 # (param_name, shard_name, shard_id)
647 ("qkv_proj", "q_proj", "q"),
648 ("qkv_proj", "k_proj", "k"),
649 ("qkv_proj", "v_proj", "v"),
650 ("gate_up_proj", "gate_proj", 0),
651 ("gate_up_proj", "up_proj", 1),
652 ]
653
654 # Params for weights, fp8 weight scales, fp8 activation scales
655 # (param_name, weight_name, expert_id, shard_id)
656 expert_params_mapping = fused_moe_make_expert_params_mapping(
657 self,
658 ckpt_gate_proj_name="gate_proj",
659 ckpt_down_proj_name="down_proj",
660 ckpt_up_proj_name="up_proj",
661 num_experts=max(self.config.moe_num_experts),
662 )
663
664 params_dict = dict(self.named_parameters())
665 loaded_params: set[str] = set()
666 for name, loaded_weight in weights:
667 if self.config.tie_word_embeddings and name.endswith("lm_head.weight"):
668 loaded_params.add("lm_head.weight")
669 continue
670 # MTP will be supported soon.
671 if "mtp" in name or "vision_model" in name or "resampler_model" in name:
672 continue
673
674 for param_name, weight_name, shard_id in stacked_params_mapping:
675 # Skip non-stacked layers and experts (experts handled below).
676 if weight_name not in name:
677 continue
678
679 if ("mlp.experts." in name) and name not in params_dict:
680 continue
681 name = name.replace(weight_name, param_name)
682 # Skip loading extra bias for GPTQ models.
683 if (
684 name.endswith(".bias") or name.endswith("_bias")
685 ) and name not in params_dict:
686 continue
687 # Skip layers on other devices.
688 if is_pp_missing_parameter(name, self):
689 continue
690
691 param = params_dict[name]
692 weight_loader = param.weight_loader
693 weight_loader(param, loaded_weight, shard_id)
694 break
695 else:
696 # Distinguish between vision experts and text experts
697 if "mlp.experts" in name:
698 moe_offset = int(name.split(".")[-3])
699 vision_expert_start_idx = self.config.moe_num_experts[0]
700 is_text_expert = moe_offset <= vision_expert_start_idx - 1
701 routed_experts = (
702 ".routed_experts" if ("w13_" in name or "w2_" in name) else ""
703 )
704 if is_text_expert:
705 name = name.replace(
706 ".experts", f".text_experts{routed_experts}"
707 )
708 else:
709 delta = moe_offset - vision_expert_start_idx
710 name = name.replace(
711 f".experts.{moe_offset}",
712 f".vision_experts{routed_experts}.{delta}",
713 )
714
715 for mapping in expert_params_mapping:
716 param_name, weight_name, expert_id, shard_id = mapping
717
718 if weight_name not in name:
719 continue
720
721 # Distinguish between vision experts and text experts
722 moe_offset = int(name.split(".")[-3])
723 is_text_expert = moe_offset <= self.config.moe_num_experts[0] - 1
724
725 name = name.replace(weight_name, param_name)
726 if is_text_expert:
727 name = name.replace(".experts.", ".text_experts.")
728 else:
729 name = name.replace(".experts.", ".vision_experts.")
730
731 # Skip layers on other devices.
732 if is_pp_missing_parameter(name, self):
733 continue
734
735 # Skip loading extra bias for GPTQ models.
736 if (
737 name.endswith(".bias") or name.endswith("_bias")
738 ) and name not in params_dict:
739 continue
740 param = params_dict[name]
741
742 weight_loader = param.weight_loader
743 weight_loader(
744 param,
745 loaded_weight,
746 name,
747 shard_id=shard_id,
748 expert_id=expert_id,
749 )
750 break
751 else:
752 # Distinguish between vision expert gate
753 # and text expert gate
754 if name.endswith("mlp.gate.weight"):
755 name = name.replace("gate.weight", "text_experts_gate.weight")
756 loaded_weight = loaded_weight.T
757 elif name.endswith("mlp.gate.weight_1"):
758 name = name.replace(
759 "gate.weight_1", "vision_experts_gate.weight"
760 )
761 loaded_weight = loaded_weight.T
762
763 if "e_score_correction_bias" in name:
764 name = name.replace(".moe_statics.", ".")
765
766 # Skip loading extra bias for GPTQ models.
767 if (
768 name.endswith(".bias") or name.endswith("_bias")
769 ) and name not in params_dict:
770 continue
771 # Skip layers on other devices.
772 if is_pp_missing_parameter(name, self):
773 continue
774 # Remapping the name of FP8 kv-scale.
775 remapped_name = maybe_remap_kv_scale_name(name, params_dict)
776 if remapped_name is None:
777 continue
778 name = remapped_name
779
780 param = params_dict[name]
781
782 weight_loader = getattr(
783 param, "weight_loader", default_weight_loader
784 )
785 weight_loader(param, loaded_weight)
786 loaded_params.add(name)
787 return loaded_params