phizero / diffsynth /models /ideogram4_text_encoder.py
multimodalart's picture
multimodalart HF Staff
Upload folder using huggingface_hub
16e2001 verified
Raw History Blame Contribute Delete
4.9 kB
import torch
import torch.nn as nn
from .ideogram4_dit import Ideogram4Fp8QuantBackend # noqa: F401
LLM_TOKEN_INDICATOR = 3
QWEN3_VL_ACTIVATION_LAYERS = (0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 35)
_DEFAULT_TEXT_ENCODER_CONFIG = {
"architectures": ["Qwen3VLModel"],
"dtype": "bfloat16",
"image_token_id": 151655,
"model_type": "qwen3_vl",
"text_config": {
"attention_bias": False,
"attention_dropout": 0.0,
"bos_token_id": 151643,
"dtype": "bfloat16",
"eos_token_id": 151645,
"head_dim": 128,
"hidden_act": "silu",
"hidden_size": 4096,
"initializer_range": 0.02,
"intermediate_size": 12288,
"max_position_embeddings": 262144,
"model_type": "qwen3_vl_text",
"num_attention_heads": 32,
"num_hidden_layers": 36,
"num_key_value_heads": 8,
"pad_token_id": None,
"rms_norm_eps": 1e-06,
"rope_parameters": {
"mrope_interleaved": True,
"mrope_section": [24, 20, 20],
"rope_theta": 5000000,
"rope_type": "default",
},
"use_cache": True,
"vocab_size": 151936,
},
"tie_word_embeddings": False,
"transformers_version": "5.8.0",
"video_token_id": 151656,
"vision_config": {
"deepstack_visual_indexes": [8, 16, 24],
"depth": 27,
"dtype": "bfloat16",
"hidden_act": "gelu_pytorch_tanh",
"hidden_size": 1152,
"in_channels": 3,
"initializer_range": 0.02,
"intermediate_size": 4304,
"model_type": "qwen3_vl_vision",
"num_heads": 16,
"num_position_embeddings": 2304,
"out_hidden_size": 4096,
"patch_size": 16,
"spatial_merge_size": 2,
"temporal_patch_size": 2,
},
"vision_end_token_id": 151653,
"vision_start_token_id": 151652,
"ideogram_fp8_weight_only": True,
}
class Ideogram4TextEncoder(nn.Module):
"""Qwen3-VL-8B-Instruct wrapper that extracts hidden states from specific layers."""
def __init__(self, config_path: str = None, **kwargs) -> None:
super().__init__()
from transformers import AutoConfig, AutoModel
if config_path is None:
config_kwargs = {k: v for k, v in _DEFAULT_TEXT_ENCODER_CONFIG.items() if k != "model_type"}
config = AutoConfig.for_model("qwen3_vl", **config_kwargs)
else:
config = AutoConfig.from_pretrained(config_path, trust_remote_code=True)
self.model = AutoModel.from_config(config, trust_remote_code=True)
self.config = config
def forward(
self,
token_ids: torch.Tensor,
attention_mask: torch.Tensor,
text_position_ids: torch.Tensor,
) -> torch.Tensor:
"""Extract hidden states from specific layers of Qwen3-VL.
Args:
token_ids: (B, L) token ids
attention_mask: (B, L) attention mask
text_position_ids: (B, L) position ids for text tokens
Returns:
(B, L, hidden_size * num_activation_layers) concatenated hidden states
"""
from transformers.masking_utils import create_causal_mask
language_model = self.model.language_model
inputs_embeds = language_model.embed_tokens(token_ids)
position_ids_4d = text_position_ids[None, ...].expand(4, text_position_ids.shape[0], -1)
text_position_ids_4d = position_ids_4d[0]
mrope_position_ids = position_ids_4d[1:]
causal_mask = create_causal_mask(
config=language_model.config,
inputs_embeds=inputs_embeds,
attention_mask=attention_mask,
past_key_values=None,
position_ids=text_position_ids_4d,
)
position_embeddings = language_model.rotary_emb(inputs_embeds, mrope_position_ids)
tap_set = set(QWEN3_VL_ACTIVATION_LAYERS)
captured: dict[int, torch.Tensor] = {}
hidden_states = inputs_embeds
for layer_idx, decoder_layer in enumerate(language_model.layers):
hidden_states = decoder_layer(
hidden_states,
attention_mask=causal_mask,
position_ids=text_position_ids_4d,
past_key_values=None,
position_embeddings=position_embeddings,
)
if layer_idx in tap_set:
captured[layer_idx] = hidden_states
selected = [captured[i] for i in QWEN3_VL_ACTIVATION_LAYERS]
stacked = torch.stack(selected, dim=0)
stacked = torch.permute(stacked, (1, 2, 3, 0))
batch_size, seq_len, hidden_size = stacked.shape[:3]
stacked = stacked.reshape(batch_size, seq_len, -1)
text_mask = attention_mask.to(stacked.dtype).unsqueeze(-1)
stacked = stacked * text_mask
return stacked.to(torch.float32)