diff --git a/vllm/model_executor/models/qwen3_omni_moe_thinker.py b/vllm/model_executor/models/qwen3_omni_moe_thinker.py index 2b46d4ae55..a5b759e7f7 100755 --- a/vllm/model_executor/models/qwen3_omni_moe_thinker.py +++ b/vllm/model_executor/models/qwen3_omni_moe_thinker.py @@ -102,6 +102,7 @@ from .qwen2_5_vl import ( from .qwen3_moe import Qwen3MoeForCausalLM, Qwen3MoeModel from .utils import ( AutoWeightsLoader, + StageMissingLayer, WeightsMapper, _merge_multimodal_embeddings, maybe_prefix, @@ -1620,17 +1621,6 @@ class Qwen3OmniMoeThinkerForConditionalGeneration( prefix=maybe_prefix(prefix, "audio_tower"), ) - self.use_deepstack = hasattr( - thinker_config.vision_config, "deepstack_visual_indexes" - ) - self.deepstack_num_level = ( - len(thinker_config.vision_config.deepstack_visual_indexes) - if self.use_deepstack - else 0 - ) - self.visual_dim = thinker_config.vision_config.out_hidden_size - self.multiscale_dim = self.visual_dim * self.deepstack_num_level - with self._mark_tower_model(vllm_config, {"image", "video"}): self.visual = Qwen3Omni_VisionTransformer( vision_config=thinker_config.vision_config, @@ -1639,18 +1629,28 @@ class Qwen3OmniMoeThinkerForConditionalGeneration( prefix=maybe_prefix(prefix, "visual"), ) - # register buffer for deepstack - if self.use_deepstack: - self.deepstack_input_embeds = [ - torch.zeros( - vllm_config.scheduler_config.max_num_batched_tokens, - thinker_config.text_config.hidden_size, - ) - for _ in range(self.deepstack_num_level) - ] - # Tracks the valid token span currently stored in the buffer. - # Zero means there is no active deepstack payload to consume. - self.deepstack_input_embeds_num_tokens = 0 + self.use_deepstack = hasattr( + thinker_config.vision_config, "deepstack_visual_indexes" + ) and not isinstance(self.visual, StageMissingLayer) + self.deepstack_num_level = ( + len(thinker_config.vision_config.deepstack_visual_indexes) + if self.use_deepstack + else 0 + ) + self.visual_dim = thinker_config.vision_config.out_hidden_size + self.multiscale_dim = self.visual_dim * self.deepstack_num_level + + if self.use_deepstack: + self.deepstack_input_embeds = [ + torch.zeros( + vllm_config.scheduler_config.max_num_batched_tokens, + thinker_config.text_config.hidden_size, + ) + for _ in range(self.deepstack_num_level) + ] + # Tracks the valid token span currently stored in the buffer. + # Zero means there is no active deepstack payload to consume. + self.deepstack_input_embeds_num_tokens = 0 with self._mark_language_model(vllm_config): self.language_model = Qwen3MoeLLMForCausalLM( diff --git a/vllm/model_executor/models/qwen3_vl.py b/vllm/model_executor/models/qwen3_vl.py index baf75fa2dd..7af3ba76bc 100644 --- a/vllm/model_executor/models/qwen3_vl.py +++ b/vllm/model_executor/models/qwen3_vl.py @@ -142,6 +142,7 @@ from .qwen3 import Qwen3ForCausalLM, Qwen3Model from .utils import ( AutoWeightsLoader, PPMissingLayer, + StageMissingLayer, WeightsMapper, _merge_multimodal_embeddings, maybe_prefix, @@ -1769,15 +1770,6 @@ class Qwen3VLForConditionalGeneration( self.use_data_parallel = multimodal_config.mm_encoder_tp_mode == "data" self._init_video_pruning(multimodal_config) - self.use_deepstack = hasattr(config.vision_config, "deepstack_visual_indexes") - self.deepstack_num_level = ( - len(config.vision_config.deepstack_visual_indexes) - if self.use_deepstack - else 0 - ) - self.visual_dim = config.vision_config.out_hidden_size - self.multiscale_dim = self.visual_dim * self.deepstack_num_level - with self._mark_tower_model(vllm_config, {"image", "video"}): self.visual = Qwen3_VisionTransformer( config.vision_config, @@ -1786,18 +1778,28 @@ class Qwen3VLForConditionalGeneration( prefix=maybe_prefix(prefix, "visual"), ) - # register buffer for deepstack - if self.use_deepstack: - self.deepstack_input_embeds = [ - torch.zeros( - vllm_config.scheduler_config.max_num_batched_tokens, - config.text_config.hidden_size, - ) - for _ in range(self.deepstack_num_level) - ] - # Tracks the valid token span currently stored in the buffer. - # Zero means there is no active deepstack payload to consume. - self.deepstack_input_embeds_num_tokens = 0 + self.use_deepstack = hasattr( + config.vision_config, "deepstack_visual_indexes" + ) and not isinstance(self.visual, StageMissingLayer) + self.deepstack_num_level = ( + len(config.vision_config.deepstack_visual_indexes) + if self.use_deepstack + else 0 + ) + self.visual_dim = config.vision_config.out_hidden_size + self.multiscale_dim = self.visual_dim * self.deepstack_num_level + + if self.use_deepstack: + self.deepstack_input_embeds = [ + torch.zeros( + vllm_config.scheduler_config.max_num_batched_tokens, + config.text_config.hidden_size, + ) + for _ in range(self.deepstack_num_level) + ] + # Tracks the valid token span currently stored in the buffer. + # Zero means there is no active deepstack payload to consume. + self.deepstack_input_embeds_num_tokens = 0 with self._mark_language_model(vllm_config): self.language_model = Qwen3LLMForCausalLM( diff --git a/vllm/model_executor/models/qwen3_vl_moe.py b/vllm/model_executor/models/qwen3_vl_moe.py index f1409d2339..f4a36f2897 100644 --- a/vllm/model_executor/models/qwen3_vl_moe.py +++ b/vllm/model_executor/models/qwen3_vl_moe.py @@ -54,7 +54,7 @@ from .qwen3_vl import ( Qwen3VLMultiModalProcessor, Qwen3VLProcessingInfo, ) -from .utils import maybe_prefix +from .utils import StageMissingLayer, maybe_prefix logger = init_logger(__name__) @@ -222,15 +222,6 @@ class Qwen3VLMoeForConditionalGeneration( self.use_data_parallel = multimodal_config.mm_encoder_tp_mode == "data" self._init_video_pruning(multimodal_config) - self.use_deepstack = hasattr(config.vision_config, "deepstack_visual_indexes") - self.deepstack_num_level = ( - len(config.vision_config.deepstack_visual_indexes) - if self.use_deepstack - else 0 - ) - self.visual_dim = config.vision_config.out_hidden_size - self.multiscale_dim = self.visual_dim * self.deepstack_num_level - with self._mark_tower_model(vllm_config, {"image", "video"}): self.visual = Qwen3_VisionTransformer( config.vision_config, @@ -239,15 +230,25 @@ class Qwen3VLMoeForConditionalGeneration( prefix=maybe_prefix(prefix, "visual"), ) - # register buffer for deepstack - if self.use_deepstack: - self.deepstack_input_embeds = [ - torch.zeros( - vllm_config.scheduler_config.max_num_batched_tokens, - config.text_config.hidden_size, - ) - for _ in range(self.deepstack_num_level) - ] + self.use_deepstack = hasattr( + config.vision_config, "deepstack_visual_indexes" + ) and not isinstance(self.visual, StageMissingLayer) + self.deepstack_num_level = ( + len(config.vision_config.deepstack_visual_indexes) + if self.use_deepstack + else 0 + ) + self.visual_dim = config.vision_config.out_hidden_size + self.multiscale_dim = self.visual_dim * self.deepstack_num_level + + if self.use_deepstack: + self.deepstack_input_embeds = [ + torch.zeros( + vllm_config.scheduler_config.max_num_batched_tokens, + config.text_config.hidden_size, + ) + for _ in range(self.deepstack_num_level) + ] with self._mark_language_model(vllm_config): self.language_model = Qwen3MoeLLMForCausalLM(