from types import SimpleNamespace import torch from sglang.multimodal_gen.runtime.models.encoders.qwen3 import Qwen3ForCausalLM class _CaptureLayer(torch.nn.Module): def __init__(self): super().__init__() self.position_ids = None self.attention_lengths = None def forward(self, position_ids, hidden_states, residual, attention_lengths): self.position_ids = position_ids self.attention_lengths = attention_lengths if residual is None: residual = torch.zeros_like(hidden_states) return hidden_states, residual class _IdentityNorm(torch.nn.Module): def forward(self, hidden_states, residual): if residual is not None: hidden_states = hidden_states + residual return hidden_states, None def test_default_position_ids_batch_shape(): model = Qwen3ForCausalLM.__new__(Qwen3ForCausalLM) torch.nn.Module.__init__(model) layer = _CaptureLayer() model.config = SimpleNamespace(output_hidden_states=False) model.layers = torch.nn.ModuleList([layer]) model.norm = _IdentityNorm() def get_input_embeddings(input_ids): return torch.zeros(input_ids.shape[0], input_ids.shape[1], 8) model.get_input_embeddings = get_input_embeddings input_ids = torch.zeros(2, 4, dtype=torch.long) attention_mask = torch.ones(2, 4, dtype=torch.long) model(input_ids=input_ids, attention_mask=attention_mask) assert layer.position_ids.shape == input_ids.shape assert torch.equal(layer.position_ids[0], torch.arange(4)) assert torch.equal(layer.position_ids[1], torch.arange(4)) assert layer.attention_lengths == (4, 4)