@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 193069d129
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 9, 23:00 UTC

[5/N] Initialize MM components in context managers (Q-Z) (#32695)

Signed-off-by: DarkLight1337 <tlleungac@connect.ust.hk>

Cyrus Leung committed Jan 21, 2026 at 03:10 UTC 193069d129414f8f70218f8fb88fb92c75f17ce5
9 files changed +177 -167
vllm/model_executor/models/qwen2_audio.py
+13 -15
@@ -334,20 +334,21 @@ class Qwen2AudioForConditionalGeneration(nn.Module, SupportsMultiModal, Supports
334 multimodal_config = vllm_config.model_config.multimodal_config
335 self.config = config
336 self.multimodal_config = multimodal_config
337 -
338 - self.audio_tower = Qwen2AudioEncoder(config.audio_config)
339 - self.multi_modal_projector = Qwen2AudioMultiModalProjector(
340 - config.audio_config.d_model, config.text_config.hidden_size
341 - )
342 -
337 self.quant_config = quant_config
338
345 - self.language_model = init_vllm_registered_model(
346 - vllm_config=vllm_config,
347 - hf_config=config.text_config,
348 - prefix=maybe_prefix(prefix, "language_model"),
349 - architectures=["Qwen2ForCausalLM"],
350 - )
339 + with self._mark_tower_model(vllm_config, "audio"):
340 + self.audio_tower = Qwen2AudioEncoder(config.audio_config)
341 + self.multi_modal_projector = Qwen2AudioMultiModalProjector(
342 + config.audio_config.d_model, config.text_config.hidden_size
343 + )
344 +
345 + with self._mark_language_model(vllm_config):
346 + self.language_model = init_vllm_registered_model(
347 + vllm_config=vllm_config,
348 + hf_config=config.text_config,
349 + prefix=maybe_prefix(prefix, "language_model"),
350 + architectures=["Qwen2ForCausalLM"],
351 + )
352
353 self.make_empty_intermediate_tensors = (
354 self.language_model.make_empty_intermediate_tensors
@@ -441,9 +442,6 @@ class Qwen2AudioForConditionalGeneration(nn.Module, SupportsMultiModal, Supports
442 masked_audio_features, audio_output_lengths.flatten().tolist()
443 )
444
444 - def get_language_model(self) -> torch.nn.Module:
445 - return self.language_model
446 -
445 def embed_multimodal(self, **kwargs: object) -> MultiModalEmbeddings:
446 audio_input = self._parse_and_validate_audio_input(**kwargs)
447 if audio_input is None:
vllm/model_executor/models/qwen3_omni_moe_thinker.py
+52 -45
@@ -1612,32 +1612,14 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1612 multimodal_config = vllm_config.model_config.multimodal_config
1613 self.config = thinker_config
1614 self.multimodal_config = multimodal_config
1615 -
1616 - self.audio_tower = Qwen3OmniMoeAudioEncoder(
1617 - thinker_config.audio_config,
1618 - multimodal_config=multimodal_config,
1619 - prefix=maybe_prefix(prefix, "audio_tower"),
1620 - )
1621 -
1622 - self.visual = Qwen3Omni_VisionTransformer(
1623 - vision_config=thinker_config.vision_config,
1624 - norm_eps=getattr(thinker_config.text_config, "rms_norm_eps", 1e-6),
1625 - quant_config=quant_config,
1626 - prefix=maybe_prefix(prefix, "visual"),
1627 - multimodal_config=multimodal_config,
1628 - )
1615 self.quant_config = quant_config
1616
1631 - self.language_model = Qwen3MoeLLMForCausalLM(
1632 - vllm_config=vllm_config.with_hf_config(
1633 - thinker_config.text_config, architectures=["Qwen3MoeForCausalLM"]
1634 - ),
1635 - prefix=maybe_prefix(prefix, "language_model"),
1636 - )
1637 -
1638 - self.make_empty_intermediate_tensors = (
1639 - self.language_model.make_empty_intermediate_tensors
1640 - )
1617 + with self._mark_tower_model(vllm_config, "audio"):
1618 + self.audio_tower = Qwen3OmniMoeAudioEncoder(
1619 + thinker_config.audio_config,
1620 + multimodal_config=multimodal_config,
1621 + prefix=maybe_prefix(prefix, "audio_tower"),
1622 + )
1623
1624 self.use_deepstack = hasattr(
1625 thinker_config.vision_config, "deepstack_visual_indexes"
@@ -1647,22 +1629,48 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1629 if self.use_deepstack
1630 else 0
1631 )
1650 - # register buffer for deepstack
1651 - self.deepstack_input_embeds = (
1652 - [
1653 - torch.zeros(
1654 - vllm_config.scheduler_config.max_num_batched_tokens,
1655 - thinker_config.text_config.hidden_size,
1656 - )
1657 - for _ in range(self.deepstack_num_level)
1658 - ]
1659 - if self.use_deepstack
1660 - else None
1661 - )
1632 self.visual_dim = thinker_config.vision_config.out_hidden_size
1633 self.multiscale_dim = self.visual_dim * self.deepstack_num_level
1634
1665 - def _get_deepstack_input_embeds(self, num_tokens: int) -> IntermediateTensors:
1635 + with self._mark_tower_model(vllm_config, {"image", "video"}):
1636 + self.visual = Qwen3Omni_VisionTransformer(
1637 + vision_config=thinker_config.vision_config,
1638 + norm_eps=getattr(thinker_config.text_config, "rms_norm_eps", 1e-6),
1639 + quant_config=quant_config,
1640 + prefix=maybe_prefix(prefix, "visual"),
1641 + multimodal_config=multimodal_config,
1642 + )
1643 +
1644 + # register buffer for deepstack
1645 + if self.use_deepstack:
1646 + self.deepstack_input_embeds = [
1647 + torch.zeros(
1648 + vllm_config.scheduler_config.max_num_batched_tokens,
1649 + thinker_config.text_config.hidden_size,
1650 + )
1651 + for _ in range(self.deepstack_num_level)
1652 + ]
1653 +
1654 + with self._mark_language_model(vllm_config):
1655 + self.language_model = Qwen3MoeLLMForCausalLM(
1656 + vllm_config=vllm_config.with_hf_config(
1657 + thinker_config.text_config,
1658 + architectures=["Qwen3MoeForCausalLM"],
1659 + ),
1660 + prefix=maybe_prefix(prefix, "language_model"),
1661 + )
1662 +
1663 + self.make_empty_intermediate_tensors = (
1664 + self.language_model.make_empty_intermediate_tensors
1665 + )
1666 +
1667 + def _get_deepstack_input_embeds(
1668 + self,
1669 + num_tokens: int,
1670 + ) -> IntermediateTensors | None:
1671 + if not getattr(self, "deepstack_input_embeds", None):
1672 + return None # If vision tower is skipped
1673 +
1674 # get deepstack_input_embeds from buffer, and clear the buffer
1675 return IntermediateTensors(
1676 {
@@ -1674,6 +1682,9 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1682 )
1683
1684 def _set_deepstack_input_embeds(self, deepstack_input_embeds: torch.Tensor) -> None:
1685 + if not getattr(self, "deepstack_input_embeds", None):
1686 + return
1687 +
1688 # set deepstack_input_embeds to buffer
1689 num_tokens = deepstack_input_embeds.size(1)
1690 if num_tokens > self.deepstack_input_embeds[0].size(0):
@@ -1692,6 +1703,9 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1703 )
1704
1705 def _clear_deepstack_input_embeds(self, num_tokens: int) -> None:
1706 + if not getattr(self, "deepstack_input_embeds", None):
1707 + return
1708 +
1709 # clear deepstack_input_embeds in buffer
1710 if num_tokens > 0:
1711 for idx in range(self.deepstack_num_level):
@@ -1726,9 +1740,6 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1740 )
1741 return mm_input_by_modality
1742
1729 - def get_language_model(self) -> torch.nn.Module:
1730 - return self.language_model
1731 -
1743 def embed_multimodal(self, **kwargs: object) -> MultiModalEmbeddings | None:
1744 mm_input_by_modality = self._parse_and_validate_multimodal_inputs(**kwargs)
1745 if not mm_input_by_modality:
@@ -1844,11 +1855,7 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1855 if intermediate_tensors is not None:
1856 inputs_embeds = None
1857
1847 - if (
1848 - self.use_deepstack
1849 - and inputs_embeds is not None
1850 - and get_pp_group().is_first_rank
1851 - ):
1858 + if inputs_embeds is not None and get_pp_group().is_first_rank:
1859 deepstack_input_embeds = self._get_deepstack_input_embeds(
1860 inputs_embeds.size(0)
1861 )
vllm/model_executor/models/qwen3_vl.py
+14 -6
@@ -1321,7 +1321,13 @@ class Qwen3VLForConditionalGeneration(
1321 num_layers = len(self.language_model.model.layers)
1322 return (2, num_layers // 2, num_layers - 3)
1323
1324 - def _get_deepstack_input_embeds(self, num_tokens: int) -> IntermediateTensors:
1324 + def _get_deepstack_input_embeds(
1325 + self,
1326 + num_tokens: int,
1327 + ) -> IntermediateTensors | None:
1328 + if not getattr(self, "deepstack_input_embeds", None):
1329 + return None # If vision tower is skipped
1330 +
1331 # get deepstack_input_embeds from buffer, and clear the buffer
1332 return IntermediateTensors(
1333 {
@@ -1333,6 +1339,9 @@ class Qwen3VLForConditionalGeneration(
1339 )
1340
1341 def _set_deepstack_input_embeds(self, deepstack_input_embeds: torch.Tensor) -> None:
1342 + if not getattr(self, "deepstack_input_embeds", None):
1343 + return
1344 +
1345 # set deepstack_input_embeds to buffer
1346 num_tokens = deepstack_input_embeds.size(1)
1347 if num_tokens > self.deepstack_input_embeds[0].size(0):
@@ -1351,6 +1360,9 @@ class Qwen3VLForConditionalGeneration(
1360 )
1361
1362 def _clear_deepstack_input_embeds(self, num_tokens: int) -> None:
1363 + if not getattr(self, "deepstack_input_embeds", None):
1364 + return
1365 +
1366 # clear deepstack_input_embeds in buffer
1367 if num_tokens > 0:
1368 for idx in range(self.deepstack_num_level):
@@ -2037,11 +2049,7 @@ class Qwen3VLForConditionalGeneration(
2049 if intermediate_tensors is not None:
2050 inputs_embeds = None
2051
2040 - if (
2041 - self.use_deepstack
2042 - and inputs_embeds is not None
2043 - and get_pp_group().is_first_rank
2044 - ):
2052 + if inputs_embeds is not None and get_pp_group().is_first_rank:
2053 deepstack_input_embeds = self._get_deepstack_input_embeds(
2054 inputs_embeds.size(0)
2055 )
vllm/model_executor/models/radio.py
-1
@@ -620,7 +620,6 @@ class RadioInternVisionModel(nn.Module):
620 x: torch.Tensor,
621 imgs_sizes: torch.Tensor | None = None,
622 ) -> torch.FloatTensor:
623 - assert self.patch_generator is not None
623 hidden_states = self.patch_generator(x, imgs_sizes=imgs_sizes)
624 attn_mask = None
625 if imgs_sizes is not None and len(imgs_sizes) > 1:
vllm/model_executor/models/siglip.py
+14 -15
@@ -1033,20 +1033,22 @@ class SiglipEmbeddingModel(nn.Module, SupportsMultiModal, SupportsQuant):
1033
1034 self.text_embed_dim = text_config.hidden_size
1035 self.vision_embed_dim = vision_config.hidden_size
1036 + self.text_projection_size = text_config.projection_size
1037
1037 - self.text_model = SiglipTextTransformer(
1038 - text_config,
1039 - quant_config=quant_config,
1040 - prefix=maybe_prefix(prefix, "text_model"),
1041 - )
1042 - self.vision_model = SiglipVisionTransformer(
1043 - vision_config,
1044 - quant_config=quant_config,
1045 - multimodal_config=multimodal_config,
1046 - prefix=maybe_prefix(prefix, "vision_model"),
1047 - )
1038 + with self._mark_language_model(vllm_config):
1039 + self.text_model = SiglipTextTransformer(
1040 + text_config,
1041 + quant_config=quant_config,
1042 + prefix=maybe_prefix(prefix, "text_model"),
1043 + )
1044
1049 - self.text_projection_size = text_config.projection_size
1045 + with self._mark_tower_model(vllm_config, "image"):
1046 + self.vision_model = SiglipVisionTransformer(
1047 + vision_config,
1048 + quant_config=quant_config,
1049 + multimodal_config=multimodal_config,
1050 + prefix=maybe_prefix(prefix, "vision_model"),
1051 + )
1052
1053 pooler_config = vllm_config.model_config.pooler_config
1054 assert pooler_config is not None
@@ -1155,9 +1157,6 @@ class SiglipEmbeddingModel(nn.Module, SupportsMultiModal, SupportsQuant):
1157
1158 return self.get_image_features(pixel_values)
1159
1158 - def get_language_model(self) -> torch.nn.Module:
1159 - return self.text_model
1160 -
1160 def _embed_text_input_ids(
1161 self,
1162 input_ids: torch.Tensor,
vllm/model_executor/models/skyworkr1v.py
+18 -21
@@ -674,24 +674,26 @@ class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP):
674 self.downsample_ratio = config.downsample_ratio
675 self.ps_version = config.ps_version
676
677 - self.llm_arch_name = config.text_config.architectures[0]
678 - self.is_mono = self.llm_arch_name == "SkyworkLM2VEForCausalLM"
679 - self.vision_model = self._init_vision_model(
680 - config,
681 - quant_config=quant_config,
682 - is_mono=self.is_mono,
683 - prefix=maybe_prefix(prefix, "vision_model"),
684 - )
677 + llm_arch_name = config.text_config.architectures[0]
678 + self.is_mono = llm_arch_name == "SkyworkLM2VEForCausalLM"
679
686 - self.language_model = init_vllm_registered_model(
687 - vllm_config=vllm_config,
688 - hf_config=config.text_config,
689 - prefix=maybe_prefix(prefix, "language_model"),
690 - )
680 + with self._mark_tower_model(vllm_config, "image"):
681 + self.vision_model = self._init_vision_model(
682 + config,
683 + quant_config=quant_config,
684 + is_mono=self.is_mono,
685 + prefix=maybe_prefix(prefix, "vision_model"),
686 + )
687 + self.mlp1 = self._init_mlp1(
688 + config, quant_config, prefix=maybe_prefix(prefix, "mlp1")
689 + )
690
692 - self.mlp1 = self._init_mlp1(
693 - config, quant_config, prefix=maybe_prefix(prefix, "mlp1")
694 - )
691 + with self._mark_language_model(vllm_config):
692 + self.language_model = init_vllm_registered_model(
693 + vllm_config=vllm_config,
694 + hf_config=config.text_config,
695 + prefix=maybe_prefix(prefix, "language_model"),
696 + )
697
698 self.img_context_token_id = None
699 self.visual_token_mask = None
@@ -838,8 +840,6 @@ class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP):
840 if image_input["type"] == "image_embeds":
841 return image_input["data"]
842
841 - assert self.vision_model is not None
842 -
843 image_embeds = self.extract_feature(image_input["pixel_values_flat"])
844
845 num_patches = image_input["num_patches"]
@@ -867,9 +867,6 @@ class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP):
867 else:
868 self.visual_token_mask = None
869
870 - def get_language_model(self) -> torch.nn.Module:
871 - return self.language_model
872 -
870 def embed_multimodal(self, **kwargs: object) -> MultiModalEmbeddings:
871 image_input = self._parse_and_validate_image_input(**kwargs)
872 if image_input is None:
vllm/model_executor/models/tarsier.py
+37 -36
@@ -423,38 +423,43 @@ class TarsierForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
423 multimodal_config = vllm_config.model_config.multimodal_config
424
425 self.config = config # Storing the Tarsier-specific HF config
426 - self.vision_tower = init_vision_tower_for_tarsier(
427 - config,
428 - quant_config=quant_config,
429 - multimodal_config=multimodal_config,
430 - require_post_norm=False,
431 - prefix=maybe_prefix(prefix, "vision_tower"),
432 - )
433 - projector_bias = getattr(config, "multimodal_projector_bias", True)
426
435 - self.multi_modal_projector = TarsierMultiModalProjector(
436 - vision_hidden_size=config.vision_config.hidden_size,
437 - text_hidden_size=config.text_config.hidden_size,
438 - projector_hidden_act=config.projector_hidden_act,
439 - multimodal_projector_bias=projector_bias,
440 - quant_config=quant_config,
441 - prefix=maybe_prefix(prefix, "multi_modal_projector"),
442 - )
443 - self.language_model = init_vllm_registered_model(
444 - vllm_config=vllm_config,
445 - hf_config=config.text_config, # Use text_config from Tarsier's main config
446 - prefix=maybe_prefix(prefix, "language_model"),
447 - )
448 - self.register_buffer(
449 - "image_newline_idx_tensor",
450 - torch.tensor([config.image_newline_idx], dtype=torch.long),
451 - persistent=False,
452 - )
453 - self.register_buffer(
454 - "image_new_idx_tensor",
455 - torch.tensor([config.image_new_idx], dtype=torch.long),
456 - persistent=False,
457 - )
427 + with self._mark_tower_model(vllm_config, "image"):
428 + self.vision_tower = init_vision_tower_for_tarsier(
429 + config,
430 + quant_config=quant_config,
431 + multimodal_config=multimodal_config,
432 + require_post_norm=False,
433 + prefix=maybe_prefix(prefix, "vision_tower"),
434 + )
435 + projector_bias = getattr(config, "multimodal_projector_bias", True)
436 +
437 + self.multi_modal_projector = TarsierMultiModalProjector(
438 + vision_hidden_size=config.vision_config.hidden_size,
439 + text_hidden_size=config.text_config.hidden_size,
440 + projector_hidden_act=config.projector_hidden_act,
441 + multimodal_projector_bias=projector_bias,
442 + quant_config=quant_config,
443 + prefix=maybe_prefix(prefix, "multi_modal_projector"),
444 + )
445 + self.register_buffer(
446 + "image_newline_idx_tensor",
447 + torch.tensor([config.image_newline_idx], dtype=torch.long),
448 + persistent=False,
449 + )
450 + self.register_buffer(
451 + "image_new_idx_tensor",
452 + torch.tensor([config.image_new_idx], dtype=torch.long),
453 + persistent=False,
454 + )
455 +
456 + with self._mark_language_model(vllm_config):
457 + self.language_model = init_vllm_registered_model(
458 + vllm_config=vllm_config,
459 + # Use text_config from Tarsier's main config
460 + hf_config=config.text_config,
461 + prefix=maybe_prefix(prefix, "language_model"),
462 + )
463
464 self.make_empty_intermediate_tensors = (
465 self.language_model.make_empty_intermediate_tensors
@@ -547,7 +552,6 @@ class TarsierForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
552 self,
553 inputs: TarsierImagePixelInputs,
554 ) -> torch.Tensor | tuple[torch.Tensor, ...]:
550 - assert self.vision_tower is not None
555 pixel_values = inputs["pixel_values"]
556 image_features_selected = self._image_pixels_to_features(
557 self.vision_tower, pixel_values
@@ -575,11 +579,8 @@ class TarsierForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
579 "Incorrect type of image_embeds. "
580 f"Got type: {type(projected_features)}. "
581 )
578 - assert self.vision_tower is not None
579 - return self._process_image_pixels(image_input)
582
581 - def get_language_model(self) -> torch.nn.Module:
582 - return self.language_model
583 + return self._process_image_pixels(image_input)
584
585 def embed_multimodal(self, **kwargs: object) -> MultiModalEmbeddings:
586 image_input = self._parse_and_validate_image_input(**kwargs)
vllm/model_executor/models/ultravox.py
+14 -13
@@ -543,7 +543,6 @@ class UltravoxModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA):
543 assert self.multi_modal_config
544
545 self.secondary_weights = []
546 - self.audio_tower = ModifiedWhisperEncoder(config.audio_config)
546 if config.audio_model_id is not None:
547 # this prefix is not for initialization, but for loading weights
548 # note the trailing dot
@@ -554,15 +553,6 @@ class UltravoxModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA):
553 prefix="audio_tower.",
554 )
555 )
557 - if config.num_projector_layers > 0:
558 - self.multi_modal_projector = UltravoxTransformerProjector(config)
559 - else:
560 - self.multi_modal_projector = UltravoxFeedForwardProjector(config)
561 - self.language_model = init_vllm_registered_model(
562 - vllm_config=vllm_config,
563 - hf_config=config.wrapped_model_config,
564 - prefix=maybe_prefix(prefix, "language_model"),
565 - )
556 if config.text_model_id is not None:
557 # this prefix is not for initialization, but for loading weights
558 # note the trailing dot
@@ -574,6 +564,20 @@ class UltravoxModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA):
564 )
565 )
566
567 + with self._mark_tower_model(vllm_config, "audio"):
568 + self.audio_tower = ModifiedWhisperEncoder(config.audio_config)
569 + if config.num_projector_layers > 0:
570 + self.multi_modal_projector = UltravoxTransformerProjector(config)
571 + else:
572 + self.multi_modal_projector = UltravoxFeedForwardProjector(config)
573 +
574 + with self._mark_language_model(vllm_config):
575 + self.language_model = init_vllm_registered_model(
576 + vllm_config=vllm_config,
577 + hf_config=config.wrapped_model_config,
578 + prefix=maybe_prefix(prefix, "language_model"),
579 + )
580 +
581 self.make_empty_intermediate_tensors = (
582 self.language_model.make_empty_intermediate_tensors
583 )
@@ -681,9 +685,6 @@ class UltravoxModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA):
685 ]
686 return flattened_embeddings.split(embed_lens)
687
684 - def get_language_model(self) -> torch.nn.Module:
685 - return self.language_model
686 -
688 def embed_multimodal(self, **kwargs: object) -> MultiModalEmbeddings:
689 audio_input = self._parse_and_validate_audio_input(**kwargs)
690 if audio_input is None:
vllm/model_executor/models/voxtral.py
+15 -15
@@ -366,22 +366,22 @@ class VoxtralForConditionalGeneration(
366 self.config = config
367 self.downsample_factor = self.config.audio_config.downsample_factor
368
369 - self.language_model = init_vllm_registered_model(
370 - vllm_config=vllm_config,
371 - hf_config=config.text_config,
372 - prefix=maybe_prefix(prefix, "language_model"),
373 - )
374 - self.whisper_encoder = VoxtralEncoderModel(
375 - vllm_config.with_hf_config(config.audio_config),
376 - prefix=maybe_prefix(prefix, "whisper_encoder"),
377 - )
378 - self.audio_language_adapter = AudioLanguageAdapter(
379 - hidden_size=config.audio_config.d_model * self.downsample_factor,
380 - dim=config.text_config.hidden_size,
381 - )
369 + with self._mark_language_model(vllm_config):
370 + self.language_model = init_vllm_registered_model(
371 + vllm_config=vllm_config,
372 + hf_config=config.text_config,
373 + prefix=maybe_prefix(prefix, "language_model"),
374 + )
375
383 - def get_language_model(self) -> torch.nn.Module:
384 - return self.language_model
376 + with self._mark_tower_model(vllm_config, "audio"):
377 + self.whisper_encoder = VoxtralEncoderModel(
378 + vllm_config.with_hf_config(config.audio_config),
379 + prefix=maybe_prefix(prefix, "whisper_encoder"),
380 + )
381 + self.audio_language_adapter = AudioLanguageAdapter(
382 + hidden_size=config.audio_config.d_model * self.downsample_factor,
383 + dim=config.text_config.hidden_size,
384 + )
385
386 def get_mm_mapping(self) -> MultiModelKeys:
387 """Get module prefix for multimodal models to filter LoRA modules."""