import math import torch import torch.nn.functional as F from diffusers.configuration_utils import ConfigMixin, register_to_config from diffusers.models.attention_processor import Attention from diffusers.models.embeddings import TimestepEmbedding, Timesteps from diffusers.models.modeling_utils import ModelMixin from einops import rearrange, repeat from torch import nn from transformers.models.qwen2.modeling_qwen2 import Qwen2RMSNorm from .rope_real import RotaryPosEmbedReal try: from transformers.modeling_flash_attention_utils import ( # type: ignore flash_attn_varlen_func, # pyright: ignore[reportAttributeAccessIssue] is_flash_attn_available, ) except Exception: # pragma: no cover - best-effort compatibility flash_attn_varlen_func = None # type: ignore[assignment] def is_flash_attn_available() -> bool: # type: ignore[override] return False from .rope_real import apply_real_rotary_emb _HAS_FLASH_ATTN_VARLEN = bool(is_flash_attn_available()) and flash_attn_varlen_func is not None class LuminaRMSNormZero(nn.Module): """ Norm layer adaptive RMS normalization zero. Parameters: embedding_dim (`int`): The size of each embedding vector. """ def __init__( self, embedding_dim: int, norm_eps: float, norm_elementwise_affine: bool, ): super().__init__() self.silu = nn.SiLU() self.linear = nn.Linear( min(embedding_dim, 1024), 4 * embedding_dim, bias=True, ) self.norm = Qwen2RMSNorm(embedding_dim, eps=norm_eps) def forward( self, x: torch.Tensor, emb: torch.Tensor | None = None, ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]: emb = self.linear(self.silu(emb)) scale_msa, gate_msa, scale_mlp, gate_mlp = emb.chunk(4, dim=1) x = self.norm(x) * (1 + scale_msa[:, None]) return x, gate_msa, scale_mlp, gate_mlp class LuminaFeedForward(nn.Module): def __init__( self, dim: int, inner_dim: int, multiple_of: int | None = 256, ffn_dim_multiplier: float | None = None, ): super().__init__() # custom hidden_size factor multiplier if ffn_dim_multiplier is not None: inner_dim = int(ffn_dim_multiplier * inner_dim) inner_dim = multiple_of * ((inner_dim + multiple_of - 1) // multiple_of) self.linear_1 = nn.Linear( dim, inner_dim, bias=False, ) self.linear_2 = nn.Linear( inner_dim, dim, bias=False, ) self.linear_3 = nn.Linear( dim, inner_dim, bias=False, ) def swiglu(self, x, y): return F.silu(x.float(), inplace=False).to(x.dtype) * y def forward(self, x): h1, h2 = self.linear_1(x), self.linear_3(x) return self.linear_2(self.swiglu(h1, h2)) class LuminaLayerNormContinuous(nn.Module): def __init__( self, embedding_dim: int, conditioning_embedding_dim: int, # NOTE: It is a bit weird that the norm layer can be configured to have scale and shift parameters # because the output is immediately scaled and shifted by the projected conditioning embeddings. # Note that AdaLayerNorm does not let the norm layer have scale and shift parameters. # However, this is how it was implemented in the original code, and it's rather likely you should # set `elementwise_affine` to False. elementwise_affine=True, eps=1e-5, bias=True, norm_type="layer_norm", out_dim: int | None = None, ): super().__init__() self.silu = nn.SiLU() self.linear_1 = nn.Linear(conditioning_embedding_dim, embedding_dim, bias=bias) if norm_type == "layer_norm": self.norm = nn.LayerNorm(embedding_dim, eps, elementwise_affine, bias) elif norm_type == "rms_norm": self.norm = Qwen2RMSNorm(embedding_dim, eps=eps) else: raise ValueError(f"unknown norm_type {norm_type}") self.linear_2 = None if out_dim is not None: self.linear_2 = nn.Linear(embedding_dim, out_dim, bias=bias) def forward( self, x: torch.Tensor, conditioning_embedding: torch.Tensor, ) -> torch.Tensor: scale = self.linear_1(self.silu(conditioning_embedding).to(x.dtype)) x = self.norm(x) * (1 + scale)[:, None, :] if self.linear_2 is not None: x = self.linear_2(x) return x class Lumina2CombinedTimestepCaptionEmbedding(nn.Module): def __init__( self, hidden_size: int = 2520, text_feat_dim: int = 3584, frequency_embedding_size: int = 256, norm_eps: float = 1e-5, timestep_scale: float = 1.0, ) -> None: super().__init__() self.time_proj = Timesteps( num_channels=frequency_embedding_size, flip_sin_to_cos=True, downscale_freq_shift=0.0, scale=timestep_scale ) self.timestep_embedder = TimestepEmbedding( in_channels=frequency_embedding_size, time_embed_dim=min(hidden_size, 1024) ) self.caption_embedder = nn.Sequential( Qwen2RMSNorm(text_feat_dim, eps=norm_eps), nn.Linear(text_feat_dim, hidden_size, bias=True), ) def forward( self, timestep: torch.Tensor, text_hidden_states: torch.Tensor, dtype: torch.dtype, ) -> tuple[torch.Tensor, torch.Tensor]: timestep_proj = self.time_proj(timestep).to(dtype=dtype) time_embed = self.timestep_embedder(timestep_proj) caption_embed = self.caption_embedder(text_hidden_states) return time_embed, caption_embed class SimpleQFormerImageRefiner(nn.Module): def __init__( self, hidden_size: int, output_hidden_size: int | None = None, num_queries: int = 128, num_layers: int = 2, num_heads: int | None = None, dropout: float = 0.0, norm_eps: float = 1e-5, ) -> None: super().__init__() input_hidden_size = hidden_size hidden_size = output_hidden_size or hidden_size self.hidden_size = hidden_size self.num_queries = num_queries # ensure num_heads divides hidden_size if num_heads is None: num_heads = max(1, hidden_size // 128) self.num_heads = self._choose_valid_num_heads(hidden_size, num_heads) self.input_proj = nn.Sequential( Qwen2RMSNorm(input_hidden_size, eps=norm_eps), nn.Linear(input_hidden_size, hidden_size, bias=True), ) # Learnable query embeddings scale = hidden_size**-0.5 self.query = nn.Parameter(scale * torch.randn(1, num_queries, hidden_size)) # Decoder layers self.layers = nn.ModuleList() for _ in range(num_layers): self.layers.append( nn.ModuleDict( dict( ln_q1=Qwen2RMSNorm(hidden_size, eps=norm_eps), self_attn=nn.MultiheadAttention( embed_dim=hidden_size, num_heads=self.num_heads, dropout=dropout, batch_first=True ), ln_q2=Qwen2RMSNorm(hidden_size, eps=norm_eps), cross_attn=nn.MultiheadAttention( embed_dim=hidden_size, num_heads=self.num_heads, dropout=dropout, batch_first=True ), ln_ffn=Qwen2RMSNorm(hidden_size, eps=norm_eps), ffn=LuminaFeedForward(dim=hidden_size, inner_dim=4 * hidden_size), ) ) ) @staticmethod def _choose_valid_num_heads(hidden_size: int, proposed_heads: int, preferred_head_dim: int = 128) -> int: """Pick a number of heads that divides hidden_size, close to proposed or preferred.""" # If proposed is valid, use it if proposed_heads > 0 and hidden_size % proposed_heads == 0: return proposed_heads # target based on preferred head dim target = max(1, round(hidden_size / preferred_head_dim)) # collect divisors up to 128 heads (more than enough) max_heads_cap = min(128, hidden_size) divisors = [d for d in range(1, max_heads_cap + 1) if hidden_size % d == 0] # choose closest to target best = min(divisors, key=lambda d: (abs(d - target), -d)) return best def forward(self, x: torch.Tensor, attention_mask: torch.Tensor) -> torch.Tensor: """ Args: x: Tensor of shape (batch, seq_len, input_dim) Returns: Tensor of shape (batch, num_queries, hidden_size) """ batch, _, _ = x.shape kv = self.input_proj(x) q = self.query.repeat(batch, 1, 1).to(kv.dtype) for layer in self.layers: # Self-attention on queries q_norm = layer["ln_q1"](q) attn_out, _ = layer["self_attn"](q_norm, q_norm, q_norm, need_weights=False) q = q + attn_out # Cross-attention: queries attend to inputs q_norm = layer["ln_q2"](q) cross_out, _ = layer["cross_attn"](q_norm, kv, kv, need_weights=False, key_padding_mask=attention_mask) q = q + cross_out # Feed-forward q = q + layer["ffn"](layer["ln_ffn"](q)) return q class AttnProcessor: def __init__(self) -> None: if not hasattr(F, "scaled_dot_product_attention"): raise ImportError("AttnProcessor requires PyTorch 2.0+ (F.scaled_dot_product_attention).") def __call__( self, attn: Attention, hidden_states: torch.Tensor, encoder_hidden_states: torch.Tensor, attention_mask: torch.Tensor | None = None, image_rotary_emb: torch.Tensor | None = None, base_sequence_length: int | None = None, ) -> torch.Tensor: batch_size, sequence_length, _ = hidden_states.shape # Get Query-Key-Value Pair query = attn.to_q(hidden_states) key = attn.to_k(encoder_hidden_states) value = attn.to_v(encoder_hidden_states) query_dim = query.shape[-1] inner_dim = key.shape[-1] head_dim = query_dim // attn.heads dtype = query.dtype # Get key-value heads kv_heads = inner_dim // head_dim # Reshape tensors for attention computation query = query.view(batch_size, -1, attn.heads, head_dim) key = key.view(batch_size, -1, kv_heads, head_dim) value = value.view(batch_size, -1, kv_heads, head_dim) # Apply Query-Key normalization if attn.norm_q is not None: query = attn.norm_q(query) if attn.norm_k is not None: key = attn.norm_k(key) # Apply Rotary Position Embeddings if image_rotary_emb is not None: query = apply_real_rotary_emb(query, image_rotary_emb[0], image_rotary_emb[1]) key = apply_real_rotary_emb(key, image_rotary_emb[0], image_rotary_emb[1]) query, key = query.to(dtype), key.to(dtype) # Calculate attention scale if base_sequence_length is not None: softmax_scale = math.sqrt(math.log(sequence_length, base_sequence_length)) * attn.scale else: softmax_scale = attn.scale if _HAS_FLASH_ATTN_VARLEN and attention_mask is not None and hidden_states.is_cuda: # Flash-Attn varlen expects packed tokens + cu_seqlens. Here we only need # the self-attention case (q/k/v share the same padding mask). attention_mask = attention_mask.to(torch.bool) seqlens = attention_mask.sum(dim=-1, dtype=torch.int32) indices = torch.nonzero(attention_mask.flatten(), as_tuple=False).flatten() max_seqlen = int(seqlens.max().item()) cu_seqlens = F.pad(torch.cumsum(seqlens, dim=0, dtype=torch.int32), (1, 0)) query_states = query.reshape(batch_size * sequence_length, attn.heads, head_dim)[indices] key_states = key.reshape(batch_size * sequence_length, kv_heads, head_dim)[indices] value_states = value.reshape(batch_size * sequence_length, kv_heads, head_dim)[indices] if kv_heads < attn.heads: key_states = repeat(key_states, "l h c -> l (h k) c", k=attn.heads // kv_heads) value_states = repeat(value_states, "l h c -> l (h k) c", k=attn.heads // kv_heads) attn_output_unpad = flash_attn_varlen_func( query_states, key_states, value_states, cu_seqlens_q=cu_seqlens, cu_seqlens_k=cu_seqlens, max_seqlen_q=max_seqlen, max_seqlen_k=max_seqlen, dropout_p=0.0, causal=False, softmax_scale=softmax_scale, ) out = torch.zeros( (batch_size * sequence_length, attn.heads, head_dim), device=attn_output_unpad.device, dtype=attn_output_unpad.dtype, ) out[indices] = attn_output_unpad hidden_states = out.view(batch_size, sequence_length, attn.heads, head_dim).flatten(-2) hidden_states = hidden_states.type_as(query) else: # PyTorch SDPA path. attn_mask = None if attention_mask is not None: attention_mask = attention_mask.to(torch.bool) attn_mask = attention_mask.view(batch_size, 1, 1, -1) query = query.transpose(1, 2) # [B, H, S, D] key = key.transpose(1, 2) # [B, H_kv, S, D] value = value.transpose(1, 2) if kv_heads < attn.heads: key = key.repeat_interleave(attn.heads // kv_heads, dim=1) value = value.repeat_interleave(attn.heads // kv_heads, dim=1) hidden_states = F.scaled_dot_product_attention( query, key, value, attn_mask=attn_mask, dropout_p=0.0, is_causal=False, scale=softmax_scale, ) if attention_mask is not None: # Keep padding tokens consistent with the flash-varlen path (zero output). hidden_states = hidden_states * attention_mask[:, None, :, None] hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim) hidden_states = hidden_states.type_as(query) # Apply output projection hidden_states = attn.to_out[0](hidden_states) hidden_states = attn.to_out[1](hidden_states) return hidden_states class TransformerBlock(nn.Module): def __init__( self, dim: int, num_attention_heads: int, num_kv_heads: int, multiple_of: int, ffn_dim_multiplier: float, norm_eps: float, modulation: bool = True, ) -> None: """Initialize the transformer block.""" super().__init__() self.head_dim = dim // num_attention_heads self.modulation = modulation processor = AttnProcessor() # Initialize attention layer self.attn = Attention( query_dim=dim, cross_attention_dim=None, dim_head=dim // num_attention_heads, qk_norm=None, heads=num_attention_heads, kv_heads=num_kv_heads, eps=1e-5, bias=False, out_bias=False, processor=processor, ) # 显式使用 transformers 的 Qwen2RMSNorm,避免依赖 diffusers 内部创建的 `RMSNorm` 再做递归替换。 self.attn.norm_q = Qwen2RMSNorm(self.head_dim, eps=1e-5) self.attn.norm_k = Qwen2RMSNorm(self.head_dim, eps=1e-5) # Initialize feed-forward network self.feed_forward = LuminaFeedForward( dim=dim, inner_dim=4 * dim, multiple_of=multiple_of, ffn_dim_multiplier=ffn_dim_multiplier ) # Initialize normalization layers if modulation: self.norm1 = LuminaRMSNormZero(embedding_dim=dim, norm_eps=norm_eps, norm_elementwise_affine=True) else: self.norm1 = Qwen2RMSNorm(dim, eps=norm_eps) self.ffn_norm1 = Qwen2RMSNorm(dim, eps=norm_eps) self.norm2 = Qwen2RMSNorm(dim, eps=norm_eps) self.ffn_norm2 = Qwen2RMSNorm(dim, eps=norm_eps) def forward( self, hidden_states: torch.Tensor, attention_mask: torch.Tensor, image_rotary_emb: torch.Tensor, temb: torch.Tensor | None = None, ) -> torch.Tensor: if self.modulation: if temb is None: raise ValueError("temb must be provided when modulation is enabled") norm_hidden_states, gate_msa, scale_mlp, gate_mlp = self.norm1(hidden_states, temb) attn_output = self.attn( hidden_states=norm_hidden_states, encoder_hidden_states=norm_hidden_states, attention_mask=attention_mask, image_rotary_emb=image_rotary_emb, ) hidden_states = hidden_states + gate_msa.unsqueeze(1).tanh() * self.norm2(attn_output) mlp_output = self.feed_forward(self.ffn_norm1(hidden_states) * (1 + scale_mlp.unsqueeze(1))) hidden_states = hidden_states + gate_mlp.unsqueeze(1).tanh() * self.ffn_norm2(mlp_output) else: norm_hidden_states = self.norm1(hidden_states) attn_output = self.attn( hidden_states=norm_hidden_states, encoder_hidden_states=norm_hidden_states, attention_mask=attention_mask, image_rotary_emb=image_rotary_emb, ) hidden_states = hidden_states + self.norm2(attn_output) mlp_output = self.feed_forward(self.ffn_norm1(hidden_states)) hidden_states = hidden_states + self.ffn_norm2(mlp_output) return hidden_states class Transformer2DModel(ModelMixin, ConfigMixin): """MammothModa2 DiT transformer""" @register_to_config def __init__( self, patch_size: int = 2, in_channels: int = 16, out_channels: int | None = None, hidden_size: int = 2304, num_layers: int = 26, num_refiner_layers: int = 2, num_attention_heads: int = 24, num_kv_heads: int = 8, multiple_of: int = 256, ffn_dim_multiplier: float | None = None, norm_eps: float = 1e-5, axes_dim_rope: tuple[int, int, int] = (32, 32, 32), axes_lens: tuple[int, int, int] = (300, 512, 512), text_feat_dim: int = 1024, timestep_scale: float = 1.0, ) -> None: """Initialize the transformer model.""" super().__init__() self.hidden_size = hidden_size # Validate configuration if (hidden_size // num_attention_heads) != sum(axes_dim_rope): raise ValueError( f"hidden_size // num_attention_heads ({hidden_size // num_attention_heads}) " f"must equal sum(axes_dim_rope) ({sum(axes_dim_rope)})" ) self.out_channels = out_channels or in_channels # Initialize embeddings self.rope_embedder = RotaryPosEmbedReal( theta=10000, axes_dim=axes_dim_rope, axes_lens=axes_lens, patch_size=patch_size, ) self.x_embedder = nn.Linear( in_features=patch_size * patch_size * in_channels, out_features=hidden_size, ) self.ref_image_patch_embedder = nn.Linear( in_features=patch_size * patch_size * in_channels, out_features=hidden_size, ) self.time_caption_embed = Lumina2CombinedTimestepCaptionEmbedding( hidden_size=hidden_size, text_feat_dim=text_feat_dim, norm_eps=norm_eps, timestep_scale=timestep_scale, ) # Initialize transformer blocks self.noise_refiner = nn.ModuleList( [ TransformerBlock( hidden_size, num_attention_heads, num_kv_heads, multiple_of, ffn_dim_multiplier, norm_eps, modulation=True, ) for _ in range(num_refiner_layers) ] ) self.ref_image_refiner = nn.ModuleList( [ TransformerBlock( hidden_size, num_attention_heads, num_kv_heads, multiple_of, ffn_dim_multiplier, norm_eps, modulation=True, ) for _ in range(num_refiner_layers) ] ) self.context_refiner = nn.ModuleList( [ TransformerBlock( hidden_size, num_attention_heads, num_kv_heads, multiple_of, ffn_dim_multiplier, norm_eps, modulation=False, ) for _ in range(num_refiner_layers) ] ) # 3. Transformer blocks self.layers = nn.ModuleList( [ TransformerBlock( hidden_size, num_attention_heads, num_kv_heads, multiple_of, ffn_dim_multiplier, norm_eps, modulation=True, ) for _ in range(num_layers) ] ) # 4. Output norm & projection self.norm_out = LuminaLayerNormContinuous( embedding_dim=hidden_size, conditioning_embedding_dim=min(hidden_size, 1024), elementwise_affine=False, eps=1e-6, bias=True, out_dim=patch_size * patch_size * self.out_channels, ) # Add learnable embeddings to distinguish different images self.image_index_embedding = nn.Parameter(torch.randn(5, hidden_size)) # support max 5 ref images def _validate_inputs( self, hidden_states: torch.Tensor, text_hidden_states: torch.Tensor, text_attention_mask: torch.Tensor, ref_image_hidden_states: list[list[torch.Tensor]] | None, return_dict: bool, ) -> tuple[int, int, int]: if return_dict: raise ValueError("return_dict=True is not supported in vLLM inference.") if ref_image_hidden_states is not None: raise ValueError("ref_image_hidden_states is not supported in vLLM inference.") if hidden_states.ndim != 4: raise ValueError(f"Expected hidden_states to be 4D [B,C,H,W], got shape={tuple(hidden_states.shape)}") batch_size, _channels, height, width = hidden_states.shape if batch_size != text_hidden_states.shape[0] or batch_size != text_attention_mask.shape[0]: raise ValueError( "Batch size mismatch: " f"hidden_states={batch_size}, text_hidden_states={text_hidden_states.shape[0]}, " f"text_attention_mask={text_attention_mask.shape[0]}" ) p = self.config.patch_size if height % p != 0 or width % p != 0: raise ValueError(f"Input latent H/W must be divisible by patch_size={p}, got {height}x{width}") return batch_size, height, width def _prepare_embeddings( self, hidden_states: torch.Tensor, timestep: torch.Tensor, text_hidden_states: torch.Tensor, text_attention_mask: torch.Tensor, freqs_cis: torch.Tensor, batch_size: int, height: int, width: int, ar_image_hidden_states: torch.Tensor | None = None, ar_image_attention_mask: torch.Tensor | None = None, ): device = hidden_states.device p = self.config.patch_size temb, text_hidden_states = self.time_caption_embed(timestep, text_hidden_states, hidden_states.dtype) image_embedder = getattr(self.time_caption_embed, "image_embedder", None) if image_embedder is not None and ar_image_hidden_states is not None: if ar_image_attention_mask is None: ar_image_attention_mask = torch.ones( ar_image_hidden_states.shape[:2], dtype=torch.bool, device=ar_image_hidden_states.device, ) image_hidden_states = image_embedder( ar_image_hidden_states, ~ar_image_attention_mask.bool(), ) image_attention_mask = torch.ones( image_hidden_states.shape[:2], dtype=torch.bool, device=image_hidden_states.device, ) text_hidden_states = torch.cat([text_hidden_states, image_hidden_states], dim=1) text_attention_mask = torch.cat([text_attention_mask, image_attention_mask], dim=1) img_tokens = rearrange(hidden_states, "b c (h p1) (w p2) -> b (h w) (p1 p2 c)", p1=p, p2=p) img_tokens = self.x_embedder(img_tokens) img_len = (height // p) * (width // p) img_mask = torch.ones((batch_size, img_len), dtype=torch.bool, device=device) l_effective_img_len = [img_len for _ in range(batch_size)] img_sizes = [(height, width) for _ in range(batch_size)] l_effective_ref_img_len = [[] for _ in range(batch_size)] ref_img_sizes = [None for _ in range(batch_size)] ( context_rotary_emb, _ref_img_rotary_emb, noise_rotary_emb, rotary_emb, encoder_seq_lengths, seq_lengths, ) = self.rope_embedder( freqs_cis, text_attention_mask, l_effective_ref_img_len, l_effective_img_len, ref_img_sizes, img_sizes, device, ) return ( temb, text_hidden_states, text_attention_mask, img_tokens, img_mask, img_len, context_rotary_emb, noise_rotary_emb, rotary_emb, encoder_seq_lengths, seq_lengths, ) def _apply_refiners( self, text_hidden_states: torch.Tensor, text_attention_mask: torch.Tensor, context_rotary_emb: torch.Tensor, img_tokens: torch.Tensor, img_mask: torch.Tensor, noise_rotary_emb: torch.Tensor, temb: torch.Tensor, ): for layer in self.context_refiner: text_hidden_states = layer(text_hidden_states, text_attention_mask, context_rotary_emb) for layer in self.noise_refiner: img_tokens = layer(img_tokens, img_mask, noise_rotary_emb, temb) return text_hidden_states, img_tokens def _apply_transformer_layers(self, hidden_states, attention_mask, rotary_emb, temb): for layer in self.layers: hidden_states = layer(hidden_states, attention_mask, rotary_emb, temb) return hidden_states def forward( self, hidden_states: torch.Tensor, timestep: torch.Tensor, text_hidden_states: torch.Tensor, freqs_cis: torch.Tensor, text_attention_mask: torch.Tensor, ref_image_hidden_states: list[list[torch.Tensor]] | None = None, ar_image_hidden_states: torch.Tensor | None = None, ar_image_attention_mask: torch.Tensor | None = None, return_dict: bool = False, ) -> torch.Tensor: batch_size, height, width = self._validate_inputs( hidden_states, text_hidden_states, text_attention_mask, ref_image_hidden_states, return_dict ) ( temb, text_hidden_states, text_attention_mask, img_tokens, img_mask, img_len, context_rotary_emb, noise_rotary_emb, rotary_emb, encoder_seq_lengths, seq_lengths, ) = self._prepare_embeddings( hidden_states, timestep, text_hidden_states, text_attention_mask, freqs_cis, batch_size, height, width, ar_image_hidden_states, ar_image_attention_mask, ) text_hidden_states, img_tokens = self._apply_refiners( text_hidden_states, text_attention_mask, context_rotary_emb, img_tokens, img_mask, noise_rotary_emb, temb, ) max_seq_len = max(seq_lengths) attention_mask = hidden_states.new_zeros(batch_size, max_seq_len, dtype=torch.bool) joint_hidden_states = hidden_states.new_zeros(batch_size, max_seq_len, self.config.hidden_size) for i, (encoder_seq_len, seq_len) in enumerate(zip(encoder_seq_lengths, seq_lengths)): attention_mask[i, :seq_len] = True joint_hidden_states[i, :encoder_seq_len] = text_hidden_states[i, :encoder_seq_len] joint_hidden_states[i, encoder_seq_len : encoder_seq_len + img_len] = img_tokens[i, :img_len] hidden_states = self._apply_transformer_layers(joint_hidden_states, attention_mask, rotary_emb, temb) hidden_states = self.norm_out(hidden_states, temb) p = self.config.patch_size img_hidden_states = torch.stack( [ hidden_states[i, encoder_seq_len : encoder_seq_len + img_len] for i, encoder_seq_len in enumerate(encoder_seq_lengths) ], dim=0, ) output = rearrange( img_hidden_states, "b (h w) (p1 p2 c) -> b c (h p1) (w p2)", h=height // p, w=width // p, p1=p, p2=p, ) return output