| | """PyTorch LFM2-VL model.""" |
| |
|
| | from dataclasses import dataclass |
| |
|
| | import torch |
| | from torch import nn |
| | from transformers import AutoConfig, AutoModel |
| | from transformers.activations import ACT2FN |
| | from transformers.cache_utils import Cache |
| | from transformers.configuration_utils import PretrainedConfig |
| | from transformers.generation import GenerationMixin |
| | from transformers.modeling_flash_attention_utils import FlashAttentionKwargs |
| | from transformers.modeling_outputs import BaseModelOutputWithPast, ModelOutput |
| | from transformers.modeling_utils import PreTrainedModel |
| | from transformers.models.lfm2.configuration_lfm2 import Lfm2Config |
| | from transformers.models.siglip2.configuration_siglip2 import Siglip2VisionConfig |
| | from transformers.models.siglip2.modeling_siglip2 import Siglip2VisionModel |
| | from transformers.processing_utils import Unpack |
| | from transformers.utils import can_return_tuple, logging |
| |
|
| | logger = logging.get_logger(__name__) |
| |
|
| |
|
| | class Lfm2VlConfig(PretrainedConfig): |
| | r""" |
| | This is the configuration class to store the configuration of a [`Lfm2VlForConditionalGeneration`]. It is used to instantiate an |
| | Lfm2Vl model according to the specified arguments, defining the model architecture. Instantiating a configuration |
| | with the defaults will yield a similar configuration to that of the Lfm2-VL-1.6B. |
| | |
| | e.g. [LiquidAI/LFM2-VL-1.6B](https://huggingface.co/LiquidAI/LFM2-VL-1.6B) |
| | |
| | Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the |
| | documentation from [`PretrainedConfig`] for more information. |
| | |
| | Args: |
| | vision_config (`AutoConfig | dict`, *optional*, defaults to `Siglip2ImageConfig`): |
| | The config object or dictionary of the vision backbone. |
| | text_config (`AutoConfig | dict`, *optional*, defaults to `Lfm2Config`): |
| | The config object or dictionary of the text backbone. |
| | image_token_id (`int`, *optional*, defaults to 396): |
| | The image token index to encode the image prompt. |
| | projector_hidden_act (`str`, *optional*, defaults to `"gelu"`): |
| | The activation function used by the multimodal projector. |
| | projector_hidden_size (`int`, *optional*, defaults to 2056): |
| | The hidden size of the multimodal projector. |
| | projector_bias (`bool`, *optional*, defaults to `True`): |
| | Whether to use bias in the multimodal projector. |
| | downsample_factor (`int`, *optional*, defaults to 2): |
| | The downsample_factor factor of the vision backbone. |
| | vision_feature_layer (`int`, *optional*, defaults to -1): |
| | The layer of the vision tower to use as features. |
| | min_image_tokens (`int`, *optional*, defaults to 64): |
| | The minimum number of image tokens for smart resize. |
| | max_image_tokens (`int`, *optional*, defaults to 256): |
| | The maximum number of image tokens for smart resize. |
| | encoder_patch_size (`int`, *optional*, defaults to 16): |
| | The patch size of the encoder. |
| | max_num_patches (`int`, *optional*, defaults to 1024): |
| | The maximum number of image tokens passed to the encoder per image or tile. |
| | use_image_special_tokens (`bool`, *optional*, defaults to `True`): |
| | Whether to use image special tokens. |
| | do_image_splitting (`bool`, *optional*, defaults to `True`): |
| | Whether to split large images into tiles. |
| | min_tiles (`int`, *optional*, defaults to 2): |
| | The minimum number of tiles to split the image into. |
| | max_tiles (`int`, *optional*, defaults to 10): |
| | The maximum number of tiles to split the image into. |
| | tile_size (`int`, *optional*, defaults to 512): |
| | The size of the tile to split the image into. |
| | max_pixels_tolerance (`float`, *optional*, defaults to 2.0): |
| | The maximum tolerance for the number of pixels in the image before splitting. |
| | use_thumbnail (`bool`, *optional*, defaults to `True`): |
| | Whether to append the thumbnail of the image when splitting. |
| | """ |
| |
|
| | model_type = "lfm2-vl" |
| | attribute_map = { |
| | "image_token_id": "image_token_index", |
| | } |
| | sub_configs = {"text_config": AutoConfig, "vision_config": AutoConfig} |
| |
|
| | def __init__( |
| | self, |
| | vision_config=None, |
| | text_config=None, |
| | image_token_index=396, |
| | projector_hidden_act="gelu", |
| | projector_hidden_size=2560, |
| | projector_bias=True, |
| | downsample_factor=2, |
| | vision_feature_layer=-1, |
| | min_image_tokens=64, |
| | max_image_tokens=256, |
| | encoder_patch_size=16, |
| | max_num_patches=1024, |
| | use_image_special_tokens=True, |
| | do_image_splitting=True, |
| | min_tiles=2, |
| | max_tiles=10, |
| | tile_size=512, |
| | max_pixels_tolerance=2.0, |
| | use_thumbnail=True, |
| | torch_dtype=torch.bfloat16, |
| | **kwargs, |
| | ): |
| | self.vision_config = vision_config |
| | self.text_config = text_config |
| | self.image_token_index = image_token_index |
| | self.projector_hidden_act = projector_hidden_act |
| | self.projector_hidden_size = projector_hidden_size |
| | self.projector_bias = projector_bias |
| | self.downsample_factor = downsample_factor |
| | self.vision_feature_layer = vision_feature_layer |
| | self.min_image_tokens = min_image_tokens |
| | self.max_image_tokens = max_image_tokens |
| | self.encoder_patch_size = encoder_patch_size |
| | self.max_num_patches = max_num_patches |
| | self.use_image_special_tokens = use_image_special_tokens |
| | self.do_image_splitting = do_image_splitting |
| | self.min_tiles = min_tiles |
| | self.max_tiles = max_tiles |
| | self.tile_size = tile_size |
| | self.max_pixels_tolerance = max_pixels_tolerance |
| | self.use_thumbnail = use_thumbnail |
| | self.torch_dtype = torch_dtype |
| | |
| | if isinstance(vision_config, dict): |
| | vision_config = Siglip2VisionConfig(**vision_config) |
| | elif vision_config is None: |
| | vision_config = Siglip2VisionConfig() |
| | self.vision_config = vision_config |
| |
|
| | self.vision_config = vision_config |
| |
|
| | if isinstance(text_config, dict): |
| | text_config = Lfm2Config(**text_config) |
| | elif text_config is None: |
| | text_config = Lfm2Config() |
| |
|
| | self.text_config = text_config |
| |
|
| | super().__init__(**kwargs) |
| |
|
| |
|
| | @dataclass |
| | class Lfm2VlModelOutputWithPast(BaseModelOutputWithPast): |
| | r""" |
| | past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): |
| | Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape |
| | `(batch_size, num_heads, sequence_length, embed_size_per_head)`) |
| | |
| | Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see |
| | `past_key_values` input) to speed up sequential decoding. |
| | image_hidden_states (`torch.FloatTensor`, *optional*): |
| | A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`. |
| | image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state. |
| | """ |
| |
|
| | image_hidden_states: torch.FloatTensor | None = None |
| |
|
| |
|
| | @dataclass |
| | class Lfm2VlCausalLMOutputWithPast(ModelOutput): |
| | r""" |
| | loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided): |
| | Language modeling loss (for next-token prediction). |
| | logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): |
| | Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). |
| | past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): |
| | Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape |
| | `(batch_size, num_heads, sequence_length, embed_size_per_head)`) |
| | |
| | Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see |
| | `past_key_values` input) to speed up sequential decoding. |
| | image_hidden_states (`torch.FloatTensor`, *optional*): |
| | A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`. |
| | image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state. |
| | """ |
| |
|
| | loss: torch.FloatTensor | None = None |
| | logits: torch.FloatTensor | None = None |
| | past_key_values: list[torch.FloatTensor] | None = None |
| | hidden_states: tuple[torch.FloatTensor] | None = None |
| | attentions: tuple[torch.FloatTensor] | None = None |
| | image_hidden_states: torch.FloatTensor | None = None |
| |
|
| |
|
| | class Lfm2VlMultiModalProjector(nn.Module): |
| | def __init__(self, config: Lfm2VlConfig): |
| | super().__init__() |
| | in_channels = config.vision_config.hidden_size * (config.downsample_factor**2) |
| | self.layer_norm = nn.LayerNorm(in_channels) |
| | self.linear_1 = nn.Linear( |
| | in_channels, |
| | config.projector_hidden_size, |
| | bias=config.projector_bias, |
| | ) |
| | self.act = ACT2FN[config.projector_hidden_act] |
| | self.linear_2 = nn.Linear( |
| | config.projector_hidden_size, |
| | config.text_config.hidden_size, |
| | bias=config.projector_bias, |
| | ) |
| |
|
| | def forward(self, image_features): |
| | image_features = self.layer_norm(image_features) |
| | hidden_states = self.linear_1(image_features) |
| | hidden_states = self.act(hidden_states) |
| | hidden_states = self.linear_2(hidden_states) |
| | return hidden_states |
| |
|
| |
|
| | class PixelUnshuffleBlock(nn.Module): |
| | def __init__(self, factor: int): |
| | super().__init__() |
| | self.factor = factor |
| |
|
| | def forward(self, x: torch.Tensor) -> torch.Tensor: |
| | n, w, h, c = x.size() |
| | if w % self.factor != 0: |
| | x = torch.concat( |
| | [ |
| | x, |
| | torch.zeros( |
| | (n, self.factor - (w % self.factor), h, c), dtype=x.dtype |
| | ).to(x.device), |
| | ], |
| | dim=1, |
| | ).contiguous() |
| | n, w, h, c = x.size() |
| | x = x.contiguous() |
| | if h % self.factor != 0: |
| | x = torch.concat( |
| | [ |
| | x, |
| | torch.zeros( |
| | (n, w, self.factor - (h % self.factor), c), dtype=x.dtype |
| | ).to(x.device), |
| | ], |
| | dim=2, |
| | ).contiguous() |
| | n, w, h, c = x.size() |
| | x = x.view(n, w, int(h / self.factor), int(c * self.factor)) |
| | x = x.permute(0, 2, 1, 3).contiguous() |
| | x = x.view( |
| | n, int(h / self.factor), int(w / self.factor), int(c * self.factor**2) |
| | ) |
| | x = x.permute(0, 2, 1, 3).contiguous() |
| | return x |
| |
|
| |
|
| | class Lfm2VlPreTrainedModel(PreTrainedModel): |
| | config: Lfm2VlConfig |
| | base_model_prefix = "" |
| | supports_gradient_checkpointing = True |
| | _skip_keys_device_placement = ["past_key_values"] |
| |
|
| | _supports_flash_attn = True |
| | _supports_sdpa = True |
| |
|
| | _can_compile_fullgraph = False |
| | _supports_flex_attn = True |
| | _supports_attention_backend = True |
| |
|
| |
|
| | class Lfm2VlModel(Lfm2VlPreTrainedModel): |
| | _checkpoint_conversion_mapping = {"language_model.model": "language_model"} |
| |
|
| | def __init__(self, config: Lfm2VlConfig): |
| | super().__init__(config) |
| | self.vision_tower = Siglip2VisionModel(config.vision_config) |
| |
|
| | if config.vision_feature_layer != -1: |
| | self.vision_tower.vision_model.encoder.layers = ( |
| | self.vision_tower.vision_model.encoder.layers[ |
| | : config.vision_feature_layer + 1 |
| | ] |
| | ) |
| | if config.downsample_factor > 1: |
| | self.pixel_unshuffle = PixelUnshuffleBlock(config.downsample_factor) |
| | else: |
| | self.pixel_unshuffle = nn.Identity() |
| |
|
| | self.multi_modal_projector = Lfm2VlMultiModalProjector(config) |
| | self.language_model = AutoModel.from_config(config.text_config) |
| | self.post_init() |
| |
|
| | def get_input_embeddings(self): |
| | return self.language_model.get_input_embeddings() |
| |
|
| | def set_input_embeddings(self, value): |
| | self.language_model.set_input_embeddings(value) |
| |
|
| | def set_decoder(self, decoder): |
| | self.language_model = decoder |
| |
|
| | def get_decoder(self): |
| | return self.language_model |
| |
|
| | def get_image_features( |
| | self, |
| | pixel_values: torch.FloatTensor, |
| | spatial_shapes: torch.Tensor, |
| | pixel_attention_mask: torch.Tensor, |
| | **kwargs, |
| | ) -> list[torch.Tensor]: |
| | """ |
| | Obtains image last hidden states from the vision tower and apply multimodal projection. |
| | |
| | Args: |
| | pixel_values (`torch.FloatTensor]` of shape `(batch_size, channels, height, width)`): |
| | The tensors corresponding to the input images. |
| | spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`): |
| | The spatial shapes of the input images. |
| | pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`): |
| | The pixel attention mask of the input images. |
| | Returns: |
| | image_features (`list[torch.Tensor]`): Image feature tensor of shape `(num_images, image_length, embed_dim)`). |
| | """ |
| | image_outputs = self.vision_tower( |
| | pixel_values=pixel_values, |
| | spatial_shapes=spatial_shapes, |
| | pixel_attention_mask=pixel_attention_mask, |
| | ).last_hidden_state |
| |
|
| | img_feature_lengths = pixel_attention_mask.sum(dim=1) |
| | image_features = [] |
| |
|
| | for img_idx in range(image_outputs.size(0)): |
| | feature = image_outputs[img_idx] |
| | |
| | feature = feature[: img_feature_lengths[img_idx], :].unsqueeze(0) |
| |
|
| | feature_org_h, feature_org_w = spatial_shapes[img_idx] |
| | feature = feature.reshape(1, feature_org_h, feature_org_w, -1) |
| | feature = self.pixel_unshuffle(feature) |
| |
|
| | |
| | img_embedding = self.multi_modal_projector(feature) |
| |
|
| | |
| | img_embedding = img_embedding.reshape(-1, img_embedding.size(-1)) |
| | image_features.append(img_embedding) |
| |
|
| | return image_features |
| |
|
| | def get_placeholder_mask( |
| | self, |
| | input_ids: torch.LongTensor | None, |
| | inputs_embeds: torch.FloatTensor, |
| | image_features: torch.FloatTensor, |
| | ): |
| | """ |
| | Obtains multimodal placeholdr mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is |
| | equal to the length of multimodal features. If the lengths are different, an error is raised. |
| | """ |
| | if input_ids is None: |
| | special_image_mask = inputs_embeds == self.get_input_embeddings()( |
| | torch.tensor( |
| | self.config.image_token_id, |
| | dtype=torch.long, |
| | device=inputs_embeds.device, |
| | ) |
| | ) |
| | special_image_mask = special_image_mask.all(-1) |
| | else: |
| | special_image_mask = input_ids == self.config.image_token_id |
| | n_image_tokens = special_image_mask.sum() |
| | special_image_mask = ( |
| | special_image_mask.unsqueeze(-1) |
| | .expand_as(inputs_embeds) |
| | .to(inputs_embeds.device) |
| | ) |
| | n_image_features = image_features.shape[0] |
| | if inputs_embeds[special_image_mask].numel() != image_features.numel(): |
| | raise ValueError( |
| | f"Image features and image tokens do not match: tokens: {n_image_tokens}, features {n_image_features}" |
| | ) |
| | return special_image_mask |
| |
|
| | @can_return_tuple |
| | def forward( |
| | self, |
| | input_ids: torch.LongTensor = None, |
| | attention_mask: torch.Tensor | None = None, |
| | position_ids: torch.LongTensor | None = None, |
| | pixel_values: torch.FloatTensor = None, |
| | spatial_shapes: torch.Tensor = None, |
| | pixel_attention_mask: torch.Tensor = None, |
| | past_key_values: Cache | None = None, |
| | inputs_embeds: torch.FloatTensor | None = None, |
| | use_cache: bool | None = None, |
| | output_attentions: bool | None = None, |
| | output_hidden_states: bool | None = None, |
| | return_dict: bool | None = None, |
| | cache_position: torch.LongTensor | None = None, |
| | image_sizes: torch.Tensor = None, |
| | **kwargs: Unpack[FlashAttentionKwargs], |
| | ) -> tuple | Lfm2VlModelOutputWithPast: |
| | """ |
| | spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`, *optional*): |
| | The spatial shapes of the input images. |
| | pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`, *optional*): |
| | The pixel attention mask of the input images. |
| | """ |
| | output_attentions = ( |
| | output_attentions |
| | if output_attentions is not None |
| | else self.config.output_attentions |
| | ) |
| | output_hidden_states = ( |
| | output_hidden_states |
| | if output_hidden_states is not None |
| | else self.config.output_hidden_states |
| | ) |
| | return_dict = ( |
| | return_dict if return_dict is not None else self.config.use_return_dict |
| | ) |
| |
|
| | if (input_ids is None) ^ (inputs_embeds is not None): |
| | raise ValueError( |
| | "You must specify exactly one of input_ids or inputs_embeds" |
| | ) |
| |
|
| | if inputs_embeds is None: |
| | inputs_embeds = self.get_input_embeddings()(input_ids) |
| |
|
| | if pixel_values is not None: |
| | image_features = self.get_image_features( |
| | pixel_values=pixel_values, |
| | spatial_shapes=spatial_shapes, |
| | pixel_attention_mask=pixel_attention_mask, |
| | ) |
| | image_features = torch.cat(image_features, dim=0).to( |
| | inputs_embeds.device, inputs_embeds.dtype |
| | ) |
| | special_image_mask = self.get_placeholder_mask( |
| | input_ids=input_ids, |
| | inputs_embeds=inputs_embeds, |
| | image_features=image_features, |
| | ) |
| | inputs_embeds = inputs_embeds.masked_scatter( |
| | special_image_mask, image_features |
| | ) |
| |
|
| | outputs = self.language_model( |
| | attention_mask=attention_mask, |
| | position_ids=position_ids, |
| | past_key_values=past_key_values, |
| | inputs_embeds=inputs_embeds, |
| | use_cache=use_cache, |
| | output_attentions=output_attentions, |
| | output_hidden_states=output_hidden_states, |
| | return_dict=True, |
| | cache_position=cache_position, |
| | **kwargs, |
| | ) |
| |
|
| | return Lfm2VlModelOutputWithPast( |
| | last_hidden_state=outputs.last_hidden_state, |
| | past_key_values=outputs.past_key_values, |
| | hidden_states=outputs.hidden_states, |
| | attentions=outputs.attentions, |
| | image_hidden_states=image_features if pixel_values is not None else None, |
| | ) |
| |
|
| |
|
| | class Lfm2VlForConditionalGeneration(Lfm2VlPreTrainedModel, GenerationMixin): |
| | _tied_weights_keys = ["lm_head.weight"] |
| |
|
| | def __init__(self, config: Lfm2VlConfig): |
| | super().__init__(config) |
| | self.model = Lfm2VlModel(config) |
| | self.lm_head = nn.Linear( |
| | config.text_config.hidden_size, config.text_config.vocab_size, bias=False |
| | ) |
| | self.post_init() |
| |
|
| | def _supports_default_dynamic_cache(self): |
| | return False |
| |
|
| | def get_input_embeddings(self): |
| | return self.model.get_input_embeddings() |
| |
|
| | def set_input_embeddings(self, value): |
| | self.model.set_input_embeddings(value) |
| |
|
| | def get_output_embeddings(self) -> nn.Module: |
| | return self.lm_head |
| |
|
| | def set_decoder(self, decoder): |
| | self.model.set_decoder(decoder) |
| |
|
| | def get_decoder(self): |
| | return self.model.get_decoder() |
| |
|
| | def get_image_features( |
| | self, |
| | pixel_values: torch.FloatTensor, |
| | spatial_shapes: torch.Tensor, |
| | pixel_attention_mask: torch.Tensor, |
| | **kwargs, |
| | ): |
| | return self.model.get_image_features( |
| | pixel_values=pixel_values, |
| | spatial_shapes=spatial_shapes, |
| | pixel_attention_mask=pixel_attention_mask, |
| | **kwargs, |
| | ) |
| |
|
| | @property |
| | def language_model(self): |
| | return self.model.language_model |
| |
|
| | @property |
| | def vision_tower(self): |
| | return self.model.vision_tower |
| |
|
| | @property |
| | def multi_modal_projector(self): |
| | return self.model.multi_modal_projector |
| |
|
| | @can_return_tuple |
| | def forward( |
| | self, |
| | input_ids: torch.LongTensor = None, |
| | pixel_values: torch.FloatTensor = None, |
| | spatial_shapes: torch.Tensor = None, |
| | pixel_attention_mask: torch.Tensor = None, |
| | attention_mask: torch.Tensor | None = None, |
| | position_ids: torch.LongTensor | None = None, |
| | past_key_values: Cache | None = None, |
| | inputs_embeds: torch.FloatTensor | None = None, |
| | labels: torch.LongTensor | None = None, |
| | use_cache: bool | None = None, |
| | output_attentions: bool | None = None, |
| | output_hidden_states: bool | None = None, |
| | return_dict: bool | None = None, |
| | cache_position: torch.LongTensor | None = None, |
| | logits_to_keep: int | torch.Tensor = 0, |
| | image_sizes: torch.Tensor | None = None, |
| | **kwargs, |
| | ) -> tuple | Lfm2VlCausalLMOutputWithPast: |
| | r""" |
| | pixel_values (`torch.FloatTensor` of shape `(batch_size, channels, height, width)`, *optional*): |
| | The input image tensors. |
| | spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`, *optional*): |
| | The spatial shapes of the input images. |
| | pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`, *optional*): |
| | The pixel attention mask of the input images. |
| | labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): |
| | Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., |
| | config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored |
| | (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. |
| | |
| | Example: |
| | |
| | ```python |
| | >>> from PIL import Image |
| | >>> import requests |
| | >>> from transformers import AutoProcessor, AutoModelForImageTextToText |
| | >>> from transformers.image_utils import load_image |
| | |
| | >>> model = AutoModelForImageTextToText.from_pretrained( |
| | ... "LiquidAI/LFM2-VL-1.6B", |
| | ... trust_remote_code=True |
| | ... ) |
| | >>> processor = AutoProcessor.from_pretrained( |
| | ... "LiquidAI/LFM2-VL-1.6B", |
| | ... trust_remote_code=True |
| | ... ) |
| | |
| | >>> url = "https://www.ilankelman.org/stopsigns/australia.jpg" |
| | >>> image = load_image(url) |
| | |
| | >>> conversation = [ |
| | ... { |
| | ... "role": "user", |
| | ... "content": [ |
| | ... {"type": "image", "image": image}, |
| | ... {"type": "text", "text": "What is in this image?"}, |
| | ... ], |
| | ... }, |
| | ... ] |
| | |
| | >>> inputs = processor.apply_chat_template( |
| | ... conversation, |
| | ... add_generation_prompt=True, |
| | ... tokenize=True, |
| | ... return_dict=True, |
| | ... return_tensors="pt" |
| | ... ) |
| | |
| | >>> # Generate |
| | >>> outputs = model.generate(**inputs, max_new_tokens=45) |
| | >>> processor.batch_decode(outputs, skip_special_tokens=True)[0] |
| | 'This image depicts a vibrant street scene in what appears to be a Chinatown or similar cultural area. The focal point is a large red stop sign with white lettering, mounted on a pole.' |
| | ```""" |
| | output_attentions = ( |
| | output_attentions |
| | if output_attentions is not None |
| | else self.config.output_attentions |
| | ) |
| | output_hidden_states = ( |
| | output_hidden_states |
| | if output_hidden_states is not None |
| | else self.config.output_hidden_states |
| | ) |
| | return_dict = ( |
| | return_dict if return_dict is not None else self.config.use_return_dict |
| | ) |
| |
|
| | outputs = self.model( |
| | input_ids=input_ids, |
| | pixel_values=pixel_values, |
| | spatial_shapes=spatial_shapes, |
| | pixel_attention_mask=pixel_attention_mask, |
| | attention_mask=attention_mask, |
| | position_ids=position_ids, |
| | past_key_values=past_key_values, |
| | inputs_embeds=inputs_embeds, |
| | use_cache=use_cache, |
| | output_attentions=output_attentions, |
| | output_hidden_states=output_hidden_states, |
| | return_dict=True, |
| | cache_position=cache_position, |
| | image_sizes=image_sizes, |
| | **kwargs, |
| | ) |
| |
|
| | hidden_states = outputs[0] |
| | |
| | slice_indices = ( |
| | slice(-logits_to_keep, None) |
| | if isinstance(logits_to_keep, int) |
| | else logits_to_keep |
| | ) |
| | logits = self.lm_head(hidden_states[:, slice_indices, :]) |
| |
|
| | loss = None |
| | if labels is not None: |
| | loss = self.loss_function( |
| | logits=logits, |
| | labels=labels, |
| | vocab_size=self.config.text_config.vocab_size, |
| | **kwargs, |
| | ) |
| |
|
| | return Lfm2VlCausalLMOutputWithPast( |
| | loss=loss, |
| | logits=logits, |
| | past_key_values=outputs.past_key_values, |
| | hidden_states=outputs.hidden_states, |
| | attentions=outputs.attentions, |
| | image_hidden_states=outputs.image_hidden_states, |
| | ) |
| |
|
| | def prepare_inputs_for_generation( |
| | self, |
| | input_ids, |
| | past_key_values=None, |
| | inputs_embeds=None, |
| | pixel_values=None, |
| | attention_mask=None, |
| | cache_position=None, |
| | logits_to_keep=None, |
| | **kwargs, |
| | ): |
| | |
| | model_inputs = super().prepare_inputs_for_generation( |
| | input_ids, |
| | past_key_values=past_key_values, |
| | inputs_embeds=inputs_embeds, |
| | attention_mask=attention_mask, |
| | cache_position=cache_position, |
| | logits_to_keep=logits_to_keep, |
| | **kwargs, |
| | ) |
| |
|
| | if cache_position[0] == 0: |
| | |
| | |
| | model_inputs["pixel_values"] = pixel_values |
| |
|
| | return model_inputs |
| |
|
| |
|
| | __all__ = ["Lfm2VlForConditionalGeneration", "Lfm2VlModel", "Lfm2VlPreTrainedModel"] |
| |
|