main
py 715 lines 25.7 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Inference-only GraniteMoeHybrid model."""
4
5 # Added by the IBM Team, 2025
6 from collections.abc import Iterable
7
8 import torch
9 from torch import nn
10 from transformers import GraniteMoeHybridConfig
11
12 from vllm.compilation.decorators import support_torch_compile
13 from vllm.config import CacheConfig, ModelConfig, VllmConfig
14 from vllm.distributed import get_tensor_model_parallel_world_size
15 from vllm.distributed.parallel_state import get_pp_group
16 from vllm.model_executor.layers.attention import Attention
17 from vllm.model_executor.layers.layernorm import RMSNorm
18 from vllm.model_executor.layers.linear import QKVParallelLinear, RowParallelLinear
19 from vllm.model_executor.layers.logits_processor import LogitsProcessor
20 from vllm.model_executor.layers.mamba.mamba_mixer2 import MambaMixer2
21 from vllm.model_executor.layers.mamba.mamba_utils import (
22 MambaStateCopyFunc,
23 MambaStateCopyFuncCalculator,
24 MambaStateDtypeCalculator,
25 MambaStateShapeCalculator,
26 )
27 from vllm.model_executor.layers.quantization import QuantizationConfig
28 from vllm.model_executor.layers.rotary_embedding import get_rope
29 from vllm.model_executor.layers.vocab_parallel_embedding import (
30 ParallelLMHead,
31 VocabParallelEmbedding,
32 )
33 from vllm.model_executor.model_loader.weight_utils import (
34 default_weight_loader,
35 maybe_remap_moe_expert_param_name,
36 )
37 from vllm.sequence import IntermediateTensors
38
39 from .granitemoe import GraniteMoeMoE
40 from .granitemoeshared import GraniteMoeSharedMLP
41 from .interfaces import (
42 HasInnerState,
43 IsHybrid,
44 SupportsLoRA,
45 SupportsMambaPrefixCaching,
46 SupportsPP,
47 SupportsQuant,
48 )
49 from .utils import (
50 AutoWeightsLoader,
51 is_pp_missing_parameter,
52 make_empty_intermediate_tensors_factory,
53 make_layers,
54 maybe_prefix,
55 )
56
57
58 class GraniteMoeHybridMambaDecoderLayer(nn.Module):
59 def __init__(
60 self,
61 config: GraniteMoeHybridConfig,
62 layer_idx: int,
63 model_config: ModelConfig | None = None,
64 cache_config: CacheConfig | None = None,
65 quant_config: QuantizationConfig | None = None,
66 prefix: str = "",
67 ) -> None:
68 super().__init__()
69 self.config = config
70 self.hidden_size = config.hidden_size
71 self.residual_multiplier = config.residual_multiplier
72
73 self.mamba = MambaMixer2(
74 hidden_size=config.hidden_size,
75 ssm_state_size=config.mamba_d_state,
76 conv_kernel_size=config.mamba_d_conv,
77 intermediate_size=config.mamba_expand * config.hidden_size,
78 use_conv_bias=config.mamba_conv_bias,
79 use_bias=config.mamba_proj_bias,
80 n_groups=config.mamba_n_groups,
81 num_heads=config.mamba_n_heads,
82 head_dim=config.mamba_d_head,
83 rms_norm_eps=config.rms_norm_eps,
84 activation=config.hidden_act,
85 model_config=model_config,
86 cache_config=cache_config,
87 quant_config=quant_config,
88 prefix=f"{prefix}.mixer",
89 )
90
91 self.block_sparse_moe = None
92 if getattr(config, "num_local_experts", 0) > 0:
93 self.block_sparse_moe = GraniteMoeMoE(
94 num_experts=config.num_local_experts,
95 top_k=config.num_experts_per_tok,
96 hidden_size=config.hidden_size,
97 intermediate_size=config.intermediate_size,
98 quant_config=quant_config,
99 prefix=f"{prefix}.block_sparse_moe",
100 )
101
102 self.shared_mlp = (
103 None
104 if getattr(config, "shared_intermediate_size", 0) == 0
105 else GraniteMoeSharedMLP(
106 config, quant_config=quant_config, prefix=f"{prefix}.shared_mlp"
107 )
108 )
109
110 self.input_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
111 self.post_attention_layernorm = RMSNorm(
112 config.hidden_size, eps=config.rms_norm_eps
113 )
114
115 def forward(
116 self,
117 hidden_states: torch.Tensor,
118 residual: torch.Tensor | None,
119 **kwargs,
120 ):
121 residual = hidden_states
122 hidden_states = self.input_layernorm(hidden_states)
123 output = self.mamba(hidden_states)
124 hidden_states = residual + output * self.residual_multiplier
125
126 residual = hidden_states
127 hidden_states = self.post_attention_layernorm(hidden_states)
128 if self.shared_mlp is None:
129 if self.block_sparse_moe is not None:
130 hidden_states = self.block_sparse_moe(hidden_states)
131 # else: skip
132 else:
133 # create a copy since block_sparse_moe modifies in-place
134 if self.block_sparse_moe is not None:
135 moe_hidden_states = hidden_states.clone()
136 moe_hidden_states = self.block_sparse_moe(moe_hidden_states)
137 hidden_states = moe_hidden_states + self.shared_mlp(hidden_states)
138 del moe_hidden_states
139 else:
140 hidden_states = self.shared_mlp(hidden_states)
141 hidden_states = residual + hidden_states * self.residual_multiplier
142
143 return hidden_states, residual
144
145
146 class GraniteMoeHybridAttentionDecoderLayer(nn.Module):
147 def __init__(
148 self,
149 config: GraniteMoeHybridConfig,
150 layer_idx: int,
151 model_config: ModelConfig | None = None,
152 cache_config: CacheConfig | None = None,
153 quant_config: QuantizationConfig | None = None,
154 prefix: str = "",
155 ) -> None:
156 super().__init__()
157 self.hidden_size = config.hidden_size
158 self.residual_multiplier = config.residual_multiplier
159
160 self.self_attn = GraniteMoeHybridAttention(
161 config,
162 cache_config=cache_config,
163 quant_config=quant_config,
164 prefix=f"{prefix}.self_attn",
165 )
166
167 self.block_sparse_moe = None
168 if getattr(config, "num_local_experts", 0) > 0:
169 self.block_sparse_moe = GraniteMoeMoE(
170 num_experts=config.num_local_experts,
171 top_k=config.num_experts_per_tok,
172 hidden_size=config.hidden_size,
173 intermediate_size=config.intermediate_size,
174 quant_config=quant_config,
175 prefix=f"{prefix}.block_sparse_moe",
176 )
177
178 self.shared_mlp = (
179 None
180 if getattr(config, "shared_intermediate_size", 0) == 0
181 else GraniteMoeSharedMLP(
182 config, quant_config=quant_config, prefix=f"{prefix}.shared_mlp"
183 )
184 )
185
186 self.input_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
187 self.post_attention_layernorm = RMSNorm(
188 config.hidden_size, eps=config.rms_norm_eps
189 )
190
191 def forward(
192 self,
193 positions: torch.Tensor,
194 hidden_states: torch.Tensor,
195 residual: torch.Tensor | None,
196 ) -> torch.Tensor:
197 residual = hidden_states
198 hidden_states = self.input_layernorm(hidden_states)
199
200 hidden_states = self.self_attn(
201 positions=positions,
202 hidden_states=hidden_states,
203 )
204 hidden_states = residual + hidden_states * self.residual_multiplier
205
206 residual = hidden_states
207 hidden_states = self.post_attention_layernorm(hidden_states)
208 if self.shared_mlp is None:
209 if self.block_sparse_moe is not None:
210 hidden_states = self.block_sparse_moe(hidden_states)
211 # else: skip
212 else:
213 # create a copy since block_sparse_moe modifies in-place
214 if self.block_sparse_moe is not None:
215 moe_hidden_states = hidden_states.clone()
216 moe_hidden_states = self.block_sparse_moe(moe_hidden_states)
217 hidden_states = moe_hidden_states + self.shared_mlp(hidden_states)
218 del moe_hidden_states
219 else:
220 hidden_states = self.shared_mlp(hidden_states)
221 hidden_states = residual + hidden_states * self.residual_multiplier
222
223 return hidden_states, residual
224
225
226 class GraniteMoeHybridAttention(nn.Module):
227 def __init__(
228 self,
229 config: GraniteMoeHybridConfig,
230 model_config: ModelConfig | None = None,
231 cache_config: CacheConfig | None = None,
232 quant_config: QuantizationConfig | None = None,
233 prefix: str = "",
234 ) -> None:
235 super().__init__()
236 self.causal = True
237 self.hidden_size = config.hidden_size
238 self.attention_bias = config.attention_bias
239 self.attention_multiplier = config.attention_multiplier
240 self.total_num_heads = config.num_attention_heads
241 self.head_dim = self.hidden_size // self.total_num_heads
242 self.total_num_kv_heads = config.num_key_value_heads
243
244 # TensorParallel logic
245 tp_size = get_tensor_model_parallel_world_size()
246 assert self.total_num_heads % tp_size == 0
247 self.num_heads = self.total_num_heads // tp_size
248 if self.total_num_kv_heads >= tp_size:
249 # Number of KV heads is greater than TP size, so we partition
250 # the KV heads across multiple tensor parallel GPUs.
251 assert self.total_num_kv_heads % tp_size == 0
252 else:
253 # Number of KV heads is less than TP size, so we replicate
254 # the KV heads across multiple tensor parallel GPUs.
255 assert tp_size % self.total_num_kv_heads == 0
256 self.num_key_value_heads = max(1, self.total_num_kv_heads // tp_size)
257
258 self.qkv_proj = QKVParallelLinear(
259 self.hidden_size,
260 self.head_dim,
261 self.total_num_heads,
262 self.total_num_kv_heads,
263 bias=self.attention_bias,
264 quant_config=quant_config,
265 prefix=f"{prefix}.qkv_proj",
266 )
267
268 self.o_proj = RowParallelLinear(
269 self.hidden_size,
270 self.hidden_size,
271 bias=self.attention_bias,
272 quant_config=quant_config,
273 prefix=f"{prefix}.o_proj",
274 )
275
276 self.rotary_emb: nn.Module | None
277 if config.position_embedding_type == "rope":
278 self.rotary_emb = get_rope(
279 self.head_dim,
280 max_position=config.max_position_embeddings,
281 rope_parameters=config.rope_parameters,
282 is_neox_style=True,
283 )
284 else:
285 self.rotary_emb = None
286
287 self.attn = Attention(
288 self.num_heads,
289 self.head_dim,
290 self.attention_multiplier,
291 num_kv_heads=self.num_key_value_heads,
292 cache_config=cache_config,
293 quant_config=quant_config,
294 prefix=f"{prefix}.attn",
295 )
296
297 def forward(
298 self,
299 positions: torch.Tensor,
300 hidden_states: torch.Tensor,
301 ) -> torch.Tensor:
302 qkv, _ = self.qkv_proj(hidden_states)
303 query, key, value = qkv.split(
304 [
305 self.num_heads * self.head_dim,
306 self.num_key_value_heads * self.head_dim,
307 self.num_key_value_heads * self.head_dim,
308 ],
309 dim=-1,
310 )
311
312 if self.rotary_emb is not None:
313 query, key = self.rotary_emb(positions, query, key)
314
315 hidden_states = self.attn(query, key, value)
316 del query, key, value
317
318 hidden_states = self.o_proj(hidden_states)[0]
319 return hidden_states
320
321
322 ALL_DECODER_LAYER_TYPES = {
323 # Transformers < 5.13.0
324 "attention": GraniteMoeHybridAttentionDecoderLayer,
325 "mamba": GraniteMoeHybridMambaDecoderLayer,
326 # Transformers >= 5.13.0
327 "full_attention": GraniteMoeHybridAttentionDecoderLayer,
328 "linear_attention": GraniteMoeHybridMambaDecoderLayer,
329 }
330
331
332 @support_torch_compile
333 class GraniteMoeHybridModel(nn.Module):
334 def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""):
335 super().__init__()
336
337 config = vllm_config.model_config.hf_config
338 model_config = vllm_config.model_config
339 cache_config = vllm_config.cache_config
340 quant_config = vllm_config.quant_config
341
342 self.config = config
343 self.quant_config = quant_config
344
345 self.vocab_size = config.vocab_size
346
347 self.embed_tokens = VocabParallelEmbedding(
348 self.vocab_size,
349 config.hidden_size,
350 )
351 self.embedding_multiplier = config.embedding_multiplier
352
353 def get_layer(prefix: str):
354 layer_idx = int(prefix.rsplit(".", 1)[1])
355 layer_class = ALL_DECODER_LAYER_TYPES[config.layer_types[layer_idx]]
356 return layer_class(
357 config,
358 layer_idx,
359 model_config,
360 cache_config,
361 quant_config=quant_config,
362 prefix=prefix,
363 )
364
365 self.start_layer, self.end_layer, self.layers = make_layers(
366 config.num_hidden_layers, get_layer, prefix=f"{prefix}.layers"
367 )
368 self.make_empty_intermediate_tensors = make_empty_intermediate_tensors_factory(
369 ["hidden_states", "residual"], config.hidden_size
370 )
371
372 self.norm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
373
374 def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
375 return self.embed_tokens(input_ids)
376
377 def forward(
378 self,
379 input_ids: torch.Tensor | None,
380 positions: torch.Tensor,
381 intermediate_tensors: IntermediateTensors | None = None,
382 inputs_embeds: torch.Tensor | None = None,
383 ) -> torch.Tensor:
384 if get_pp_group().is_first_rank:
385 if inputs_embeds is not None:
386 hidden_states = inputs_embeds
387 else:
388 hidden_states = self.embed_input_ids(input_ids)
389 hidden_states *= self.embedding_multiplier
390 residual = None
391 else:
392 if intermediate_tensors is None:
393 raise RuntimeError("Intermediate tensors may not be None!")
394 hidden_states = intermediate_tensors["hidden_states"]
395 residual = intermediate_tensors["residual"]
396
397 num_attn = 0
398 for i, layer in enumerate(self.layers):
399 if isinstance(layer, GraniteMoeHybridAttentionDecoderLayer):
400 num_attn += 1
401 hidden_states, residual = layer(
402 positions=positions, hidden_states=hidden_states, residual=residual
403 )
404
405 if not get_pp_group().is_last_rank:
406 return IntermediateTensors(
407 {"hidden_states": hidden_states, "residual": residual}
408 )
409
410 hidden_states = self.norm(hidden_states)
411 return hidden_states
412
413 def get_expert_mapping(self) -> list[tuple[str, str, int, str]]:
414 # Params for weights, fp8 weight scales, fp8 activation scales
415 # (param_name, weight_name, expert_id, shard_id)
416 # layers.0.block_sparse_moe.expert_0.input_linear.input_scale
417 ckpt_gate_proj_name = "gate_proj"
418 ckpt_down_proj_name = "down_proj"
419 ckpt_up_proj_name = "up_proj"
420 num_experts = self.config.num_local_experts
421
422 return [
423 # (param_name, weight_name, expert_id, shard_id)
424 (
425 "block_sparse_moe.experts.w13_"
426 if weight_name in [ckpt_gate_proj_name, ckpt_up_proj_name]
427 else "block_sparse_moe.experts.w2_",
428 f"block_sparse_moe.experts.{expert_id}.{weight_name}.",
429 expert_id,
430 shard_id,
431 )
432 for expert_id in range(num_experts)
433 for shard_id, weight_name in [
434 ("w1", ckpt_gate_proj_name),
435 ("w2", ckpt_down_proj_name),
436 ("w3", ckpt_up_proj_name),
437 ]
438 ]
439
440 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
441 stacked_params_mapping = [
442 # (param_name, shard_name, shard_id)
443 (".qkv_proj", ".q_proj", "q"),
444 (".qkv_proj", ".k_proj", "k"),
445 (".qkv_proj", ".v_proj", "v"),
446 ]
447 params_dict = dict(self.named_parameters())
448 loaded_params: set[str] = set()
449 expert_params_mapping = self.get_expert_mapping()
450
451 def _load(n, p):
452 param = params_dict[n]
453 weight_loader = getattr(param, "weight_loader", default_weight_loader)
454 weight_loader(param, p)
455 loaded_params.add(n)
456
457 def _load_shard(n, p, shard_id):
458 # Skip layers on other devices.
459 if not is_pp_missing_parameter(n, self):
460 param = params_dict[n]
461 weight_loader = getattr(param, "weight_loader", None)
462 if not callable(weight_loader):
463 raise TypeError(f"{n} requires a shard-aware weight loader")
464 weight_loader(param, p, shard_id)
465 loaded_params.add(n)
466
467 def _load_expert(n, p, name, shard_id, expert_id):
468 if n not in params_dict:
469 return
470 param = params_dict[n]
471 weight_loader = getattr(param, "weight_loader", None)
472 if not callable(weight_loader):
473 raise TypeError(f"{n} requires an expert-aware weight loader")
474 weight_loader(param, p, name, shard_id=shard_id, expert_id=expert_id)
475 loaded_params.add(n)
476
477 def _load_quant_expert(name, loaded_weight):
478 for mapping in expert_params_mapping:
479 param_name, weight_name, expert_id, shard_id = mapping
480
481 if weight_name not in name:
482 continue
483
484 name_mapped = name.replace(weight_name, param_name)
485 name_mapped = maybe_remap_moe_expert_param_name(
486 name_mapped, params_dict
487 )
488
489 # Skip layers on other devices.
490 if is_pp_missing_parameter(name_mapped, self):
491 continue
492
493 param = params_dict[name_mapped]
494 weight_loader = param.weight_loader
495 success = False
496
497 if weight_loader is not None:
498 success = weight_loader(
499 param,
500 loaded_weight,
501 name_mapped,
502 shard_id=shard_id,
503 expert_id=expert_id,
504 return_success=True,
505 )
506
507 if success:
508 return name_mapped
509 return None
510
511 for n, p in weights:
512 if "A_log" in n:
513 n = n.replace("A_log", "A")
514
515 if _load_quant_expert(n, p):
516 continue
517
518 # Logic analogous to: https://github.com/vllm-project/vllm/blob/f49e5aff11c986ed4d45202b1716c5d74786efa9/vllm/model_executor/models/granitemoeshared.py#L215
519 # Mapping different experts' layout:
520 # from HF (input_linear, output_linear, router)
521 # to vLLM (experts_w13({e}.w1, {e}.w2), experts_w3({e}.w3), gate)
522 # The renaming and parameter loading logic is the same for weight
523 # and weight_scale tensors so we can reuse them without issues.
524 if n.endswith(".block_sparse_moe.input_linear.weight") or n.endswith(
525 ".block_sparse_moe.input_linear.weight_scale"
526 ):
527 for e in range(p.size(0)):
528 w1_name = n.replace(
529 ".block_sparse_moe.input_linear.weight",
530 f".block_sparse_moe.experts.{e}.w1.weight",
531 )
532 w3_name = n.replace(
533 ".block_sparse_moe.input_linear.weight",
534 f".block_sparse_moe.experts.{e}.w3.weight",
535 )
536 w1_param, w3_param = p[e].chunk(2, dim=0)
537 _load_expert(
538 n.replace(".input_linear.", ".experts.routed_experts.w13_"),
539 w1_param,
540 w1_name,
541 shard_id="w1",
542 expert_id=e,
543 )
544 _load_expert(
545 n.replace(".input_linear.", ".experts.routed_experts.w13_"),
546 w3_param,
547 w3_name,
548 shard_id="w3",
549 expert_id=e,
550 )
551 elif n.endswith(".block_sparse_moe.output_linear.weight") or n.endswith(
552 ".block_sparse_moe.output_linear.weight_scale"
553 ):
554 for e in range(p.size(0)):
555 w2_name = n.replace(
556 ".block_sparse_moe.output_linear.weight",
557 f".block_sparse_moe.experts.{e}.w2.weight",
558 )
559 w2_param = p[e]
560 _load_expert(
561 n.replace(".output_linear.", ".experts.routed_experts.w2_"),
562 w2_param,
563 w2_name,
564 shard_id="w2",
565 expert_id=e,
566 )
567 elif n.endswith(".block_sparse_moe.router.layer.weight"):
568 gate_name = n.replace(
569 ".block_sparse_moe.router.layer.weight",
570 ".block_sparse_moe.gate.weight",
571 )
572 _load(gate_name, p)
573 else:
574 loaded = False
575 for param_name, weight_name, shard_id in stacked_params_mapping:
576 if weight_name in n:
577 _load_shard(
578 n.replace(weight_name, param_name), p, shard_id=shard_id
579 )
580 loaded = True
581 if not loaded:
582 _load(n, p)
583
584 return loaded_params
585
586
587 class GraniteMoeHybridForCausalLM(
588 nn.Module,
589 HasInnerState,
590 SupportsLoRA,
591 SupportsPP,
592 IsHybrid,
593 SupportsQuant,
594 SupportsMambaPrefixCaching,
595 ):
596 packed_modules_mapping: dict[str, list[str]] = {
597 "qkv_proj": [
598 "q_proj",
599 "k_proj",
600 "v_proj",
601 ],
602 "conv1d": ["conv1d"],
603 "in_proj": ["in_proj"],
604 "input_linear": ["input_linear"],
605 }
606 embedding_modules = {
607 "embed_tokens": "input_embeddings",
608 "lm_head": "output_embeddings",
609 }
610
611 @classmethod
612 def get_mamba_state_dtype_from_config(
613 cls,
614 vllm_config: "VllmConfig",
615 ) -> tuple[torch.dtype, torch.dtype]:
616 return MambaStateDtypeCalculator.mamba2_state_dtype(
617 vllm_config.model_config.dtype,
618 vllm_config.cache_config.mamba_cache_dtype,
619 vllm_config.cache_config.mamba_ssm_cache_dtype,
620 )
621
622 @classmethod
623 def get_mamba_state_shape_from_config(
624 cls,
625 vllm_config: "VllmConfig",
626 ) -> tuple[tuple[int, int], tuple[int, int, int]]:
627 """Calculate shapes for Mamba's convolutional and state caches.
628
629 Args:
630 vllm_config: vLLM config
631
632 Returns:
633 Tuple containing:
634 - conv_state_shape: Shape for convolutional state cache
635 - temporal_state_shape: Shape for state space model cache
636
637 """
638 parallel_config = vllm_config.parallel_config
639 hf_config = vllm_config.model_config.hf_config
640 intermediate_size = hf_config.mamba_expand * hf_config.hidden_size
641
642 return MambaStateShapeCalculator.mamba2_state_shape(
643 intermediate_size=intermediate_size,
644 tp_world_size=parallel_config.tensor_parallel_size,
645 n_groups=hf_config.mamba_n_groups,
646 num_heads=hf_config.mamba_n_heads,
647 head_dim=hf_config.mamba_d_head,
648 state_size=hf_config.mamba_d_state,
649 conv_kernel=hf_config.mamba_d_conv,
650 )
651
652 @classmethod
653 def get_mamba_state_copy_func(cls) -> tuple[MambaStateCopyFunc, MambaStateCopyFunc]:
654 return MambaStateCopyFuncCalculator.mamba2_state_copy_func()
655
656 def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""):
657 super().__init__()
658
659 config = vllm_config.model_config.hf_config
660 self.vllm_config = vllm_config
661 self.model_config = vllm_config.model_config
662
663 scheduler_config = vllm_config.scheduler_config
664 self.quant_config = vllm_config.quant_config
665 self.config = config
666 self.scheduler_config = scheduler_config
667 self.model = GraniteMoeHybridModel(
668 vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model")
669 )
670
671 self.lm_head = ParallelLMHead(
672 config.vocab_size,
673 config.hidden_size,
674 quant_config=self.quant_config,
675 prefix=maybe_prefix(prefix, "lm_head"),
676 )
677 if config.tie_word_embeddings:
678 self.lm_head = self.lm_head.tie_weights(self.model.embed_tokens)
679 self.logits_processor = LogitsProcessor(
680 config.vocab_size,
681 config.vocab_size,
682 scale=1 / self.config.logits_scaling,
683 )
684
685 self.make_empty_intermediate_tensors = (
686 self.model.make_empty_intermediate_tensors
687 )
688
689 def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
690 return self.model.embed_input_ids(input_ids)
691
692 def forward(
693 self,
694 input_ids: torch.Tensor | None,
695 positions: torch.Tensor,
696 intermediate_tensors: IntermediateTensors | None = None,
697 inputs_embeds: torch.Tensor | None = None,
698 **kwargs,
699 ):
700 hidden_states = self.model(
701 input_ids, positions, intermediate_tensors, inputs_embeds
702 )
703
704 return hidden_states
705
706 def compute_logits(
707 self,
708 hidden_states: torch.Tensor,
709 ) -> torch.Tensor | None:
710 logits = self.logits_processor(self.lm_head, hidden_states)
711 return logits
712
713 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
714 loader = AutoWeightsLoader(self)
715 return loader.load_weights(weights)