
    ^j=                        d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 ddl
mZmZmZ dd	lmZ dd
lmZmZmZ ddlmZmZ ddlmZ ddlmZmZmZmZmZmZm Z m!Z! ddl"m#Z#  ejH                  e%      Z& G d dejN                        Z( G d de      Z) G d de      Z* G d de      Z+ G d de      Z, G d de       Z-e G d de!             Z.e G d d e             Z/ ed!"       G d# d$e.             Z0g d%Z1y)&zHPyTorch ViViT model - modular file inheriting transformer core from ViT.    )IterableN)nn   )initialization)create_bidirectional_mask)BaseModelOutputBaseModelOutputWithPoolingImageClassifierOutput)Unpack)TransformersKwargsauto_docstringlogging)can_return_tuplemerge_with_config_defaults)capture_outputs   )PreTrainedModelViTAttentionViTEmbeddingsViTLayerViTMLPViTModel	ViTPoolerViTPreTrainedModel   )VivitConfigc                   `     e Zd ZdZdef fdZdej                  dej                  fdZ xZ	S )VivitTubeletEmbeddingsay  
    This class turns `pixel_values` of shape `(batch_size, num_frames, num_channels, height, width)` into the initial
    `hidden_states` (tubelet embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a
    Transformer encoder.

    The seq_length equals (num_frames // tubelet_size[0]) * (height // tubelet_size[1]) * (width // tubelet_size[2]).
    configc                 N   t         |           |j                  }|j                  }t	        |t
              r|n||f}|j                  |d   z  |d   |d   z  z  |d   |d   z  z  | _        || _        t        j                  |j                  |j                  ||      | _        y )Nr   r   r   )kernel_sizestride)super__init__tubelet_size
image_size
isinstancer   
num_framesnum_patchesr   Conv3dnum_channelshidden_size
projection)selfr   r%   r&   	__class__s       r/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/transformers/models/vivit/modular_vivit.pyr$   zVivitTubeletEmbeddings.__init__5   s    **&&
#-j(#CZ*V`Ia
 ,q/1!}Q/1!}Q/1 	
 %))!3!3Vb
    pixel_valuesreturnc                     |j                  dd      }| j                  |      j                  d      j                  dd      S )Nr   r   )	transposer-   flatten)r.   r2   s     r0   forwardzVivitTubeletEmbeddings.forwardE   s;    #--a3|,44Q7AA!QGGr1   )
__name__
__module____qualname____doc__r   r$   torchTensorr7   __classcell__r/   s   @r0   r   r   ,   s2    
{ 
 HELL HU\\ Hr1   r   c                        e Zd ZdZdef fdZdej                  dededej                  f fdZ	dd	ej                  d
e
dej                  fdZ xZS )VivitEmbeddingszY
    Construct the CLS token, position and tubelet patch embeddings for video input.
    r   c                    t         |           t        j                  t	        j
                  dd|j                              | _        t        |      | _	        | j                  j                  }t        j                  t	        j
                  d|dz   |j                              | _        |j                  dd  | _        | `y )Nr   )r#   r$   r   	Parameterr<   zerosr,   	cls_tokenr   patch_embeddingsr)   position_embeddingsr%   
patch_size
mask_token)r.   r   r)   r/   s      r0   r$   zVivitEmbeddings.__init__P   s    ekk!Q8J8J&KL 6v >++77#%<<A{QPVPbPb0c#d  --ab1Or1   
embeddingsheightwidthr3   c                 p    t         |   |||       || j                  d   z  }|| j                  d   z  }y )Nr   r   )r#   interpolate_pos_encodingrH   )r.   rJ   rK   rL   
new_height	new_widthr/   s         r0   rN   z(VivitEmbeddings.interpolate_pos_encoding[   s:    (VUCtq11
T__Q//	r1   r2   rN   c                    |j                   \  }}}}}| j                  |      }| j                  j                  |dd      }	t	        j
                  |	|fd      }|r|| j                  |||      z   }ne|| j                  d   k7  s|| j                  d   k7  r2t        d| d| d| j                  d    d| j                  d    d	      || j                  z   }| j                  |      }|S )	Nr   )dimr   zInput image size (*z) doesn't match model (z).)shaperF   rE   expandr<   catrN   r&   
ValueErrorrG   dropout)
r.   r2   rN   
batch_sizer(   r+   rK   rL   rJ   
cls_tokenss
             r0   r7   zVivitEmbeddings.forwarda   s   >J>P>P;
Jfe**<8
 ^^**:r2>
YY
J7Q?
##d&C&CJPVX]&^^J++u8J/J (% 9+,Adooa.@-AE  $d&>&>>J\\*-
r1   )F)r8   r9   r:   r;   r   r$   r<   r=   intrN   boolr7   r>   r?   s   @r0   rA   rA   K   sf    	{ 	05<< 0 0UX 0]b]i]i 0ELL D ]b]i]i r1   rA   c                       e Zd Zy)VivitAttentionNr8   r9   r:    r1   r0   r_   r_   x       r1   r_   c                       e Zd Zy)VivitMLPNr`   ra   r1   r0   rd   rd   |   rb   r1   rd   c                       e Zd Zy)
VivitLayerNr`   ra   r1   r0   rf   rf      rb   r1   rf   c                       e Zd Zy)VivitPoolerNr`   ra   r1   r0   rh   rh      rb   r1   rh   c                   V    e Zd ZU eed<   dZdZddgZ ej                         d        Z
y)VivitPreTrainedModelr   vivit)videorA   rf   c                     t        j                  | |       t        |t              r?t	        j
                  |j                         t	        j
                  |j                         yy)zInitialize the weightsN)r   _init_weightsr'   rA   initzeros_rE   rG   )r.   modules     r0   rn   z"VivitPreTrainedModel._init_weights   sG     	%%dF3fo.KK(()KK223 /r1   N)r8   r9   r:   r   __annotations__base_model_prefixinput_modalities_no_split_modulesr<   no_gradrn   ra   r1   r0   rj   rj      s9    !*L9U]]_4 4r1   rj   c                        e Zd Zddedef fdZe ed      e	 	 	 dde	j                  dz  ded	e	j                  dz  d
ee   def
d                     Z xZS )
VivitModelr   add_pooling_layerc                 D    t         |   |       t        |      | _        y)zv
        add_pooling_layer (bool, *optional*, defaults to `True`):
            Whether to add a pooling layer
        N)r#   r$   rA   rJ   )r.   r   ry   r/   s      r0   r$   zVivitModel.__init__   s    
 	 )&1r1   F)tie_last_hidden_statesNr2   rN   attention_maskkwargsr3   c                    | j                  ||      }t        | j                  ||      }|}| j                  D ]  } |||fi |} | j	                  |      }| j
                  | j                  |      nd}	t        ||	      S )a  
        Examples:

        ```python
        >>> import av
        >>> import numpy as np

        >>> from transformers import VivitImageProcessor, VivitModel
        >>> from huggingface_hub import hf_hub_download

        >>> np.random.seed(0)


        >>> def read_video_pyav(container, indices):
        ...     '''
        ...     Decode the video with PyAV decoder.
        ...     Args:
        ...         container (`av.container.input.InputContainer`): PyAV container.
        ...         indices (`list[int]`): List of frame indices to decode.
        ...     Returns:
        ...         result (np.ndarray): np array of decoded frames of shape (num_frames, height, width, 3).
        ...     '''
        ...     frames = []
        ...     container.seek(0)
        ...     start_index = indices[0]
        ...     end_index = indices[-1]
        ...     for i, frame in enumerate(container.decode(video=0)):
        ...         if i > end_index:
        ...             break
        ...         if i >= start_index and i in indices:
        ...             frames.append(frame)
        ...     return np.stack([x.to_ndarray(format="rgb24") for x in frames])


        >>> def sample_frame_indices(clip_len, frame_sample_rate, seg_len):
        ...     '''
        ...     Sample a given number of frame indices from the video.
        ...     Args:
        ...         clip_len (`int`): Total number of frames to sample.
        ...         frame_sample_rate (`int`): Sample every n-th frame.
        ...         seg_len (`int`): Maximum allowed index of sample's last frame.
        ...     Returns:
        ...         indices (`list[int]`): List of sampled frame indices
        ...     '''
        ...     converted_len = int(clip_len * frame_sample_rate)
        ...     end_idx = np.random.randint(converted_len, seg_len)
        ...     start_idx = end_idx - converted_len
        ...     indices = np.linspace(start_idx, end_idx, num=clip_len)
        ...     indices = np.clip(indices, start_idx, end_idx - 1).astype(np.int64)
        ...     return indices


        >>> # video clip consists of 300 frames (10 seconds at 30 FPS)
        >>> file_path = hf_hub_download(
        ...     repo_id="nielsr/video-demo", filename="eating_spaghetti.mp4", repo_type="dataset"
        ... )
        >>> container = av.open(file_path)

        >>> # sample 32 frames
        >>> indices = sample_frame_indices(clip_len=32, frame_sample_rate=1, seg_len=container.streams.video[0].frames)
        >>> video = read_video_pyav(container=container, indices=indices)

        >>> image_processor = VivitImageProcessor.from_pretrained("google/vivit-b-16x2-kinetics400")
        >>> model = VivitModel.from_pretrained("google/vivit-b-16x2-kinetics400")

        >>> # prepare video for the model
        >>> inputs = image_processor(list(video), return_tensors="pt")

        >>> # forward pass
        >>> outputs = model(**inputs)
        >>> last_hidden_states = outputs.last_hidden_state
        >>> list(last_hidden_states.shape)
        [1, 3137, 768]
        ```)rN   )r   inputs_embedsr|   N)last_hidden_statepooler_output)rJ   r   r   layers	layernormpoolerr	   )
r.   r2   rN   r|   r}   embedding_outputhidden_stateslayersequence_outputpooled_outputs
             r0   r7   zVivitModel.forward   s    j  ??<Rj?k2;;*)

 )[[ 	KE!-J6JM	K..78<8OO4UY)O[hiir1   )T)NFN)r8   r9   r:   r   r]   r$   r   r   r   r<   FloatTensorr=   r   r   r	   r7   r>   r?   s   @r0   rx   rx      s    2{ 2t 2  E2 26)..2	^j''$.^j #'^j t+	^j
 +,^j 
$^j  3  ^jr1   rx   a  
        ViViT Transformer model with a video classification head on top (a linear layer on top of the final hidden state of the
    [CLS] token) e.g. for Kinetics-400.

        <Tip>

            Note that it's possible to fine-tune ViT on higher resolution images than the ones it has been trained on, by
            setting `interpolate_pos_encoding` to `True` in the forward of the model. This will interpolate the pre-trained
            position embeddings to the higher resolution.

        </Tip>
    )custom_introc                        e Zd Zdef fdZee	 	 	 d
dej                  dz  dej                  dz  de
dee   def
d	              Z xZS )VivitForVideoClassificationr   c                 .   t         |   |       |j                  | _        t        |d      | _        |j                  dkD  r*t        j                  |j                  |j                        nt        j                         | _	        | j                          y )NF)ry   r   )r#   r$   
num_labelsrx   rk   r   Linearr,   Identity
classifier	post_init)r.   r   r/   s     r0   r$   z$VivitForVideoClassification.__init__  ss      ++%@
 OUN_N_bcNc"))F$6$68I8IJikititiv 	r1   Nr2   labelsrN   r}   r3   c                     | j                   |fd|i|}|j                  }| j                  |dddddf         }d}| | j                  ||| j                  fi |}t        |||j                  |j                        S )a  
        labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
            Labels for computing the image classification/regression loss. Indices should be in `[0, ...,
            config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
            `config.num_labels > 1` a classification loss is computed (Cross-Entropy).

        Examples:

        ```python
        >>> import av
        >>> import numpy as np
        >>> import torch

        >>> from transformers import VivitImageProcessor, VivitForVideoClassification
        >>> from huggingface_hub import hf_hub_download

        >>> np.random.seed(0)


        >>> def read_video_pyav(container, indices):
        ...     '''
        ...     Decode the video with PyAV decoder.
        ...     Args:
        ...         container (`av.container.input.InputContainer`): PyAV container.
        ...         indices (`list[int]`): List of frame indices to decode.
        ...     Returns:
        ...         result (np.ndarray): np array of decoded frames of shape (num_frames, height, width, 3).
        ...     '''
        ...     frames = []
        ...     container.seek(0)
        ...     start_index = indices[0]
        ...     end_index = indices[-1]
        ...     for i, frame in enumerate(container.decode(video=0)):
        ...         if i > end_index:
        ...             break
        ...         if i >= start_index and i in indices:
        ...             frames.append(frame)
        ...     return np.stack([x.to_ndarray(format="rgb24") for x in frames])


        >>> def sample_frame_indices(clip_len, frame_sample_rate, seg_len):
        ...     '''
        ...     Sample a given number of frame indices from the video.
        ...     Args:
        ...         clip_len (`int`): Total number of frames to sample.
        ...         frame_sample_rate (`int`): Sample every n-th frame.
        ...         seg_len (`int`): Maximum allowed index of sample's last frame.
        ...     Returns:
        ...         indices (`list[int]`): List of sampled frame indices
        ...     '''
        ...     converted_len = int(clip_len * frame_sample_rate)
        ...     end_idx = np.random.randint(converted_len, seg_len)
        ...     start_idx = end_idx - converted_len
        ...     indices = np.linspace(start_idx, end_idx, num=clip_len)
        ...     indices = np.clip(indices, start_idx, end_idx - 1).astype(np.int64)
        ...     return indices


        >>> # video clip consists of 300 frames (10 seconds at 30 FPS)
        >>> file_path = hf_hub_download(
        ...     repo_id="nielsr/video-demo", filename="eating_spaghetti.mp4", repo_type="dataset"
        ... )
        >>> container = av.open(file_path)

        >>> # sample 32 frames
        >>> indices = sample_frame_indices(clip_len=32, frame_sample_rate=4, seg_len=container.streams.video[0].frames)
        >>> video = read_video_pyav(container=container, indices=indices)

        >>> image_processor = VivitImageProcessor.from_pretrained("google/vivit-b-16x2-kinetics400")
        >>> model = VivitForVideoClassification.from_pretrained("google/vivit-b-16x2-kinetics400")

        >>> inputs = image_processor(list(video), return_tensors="pt")

        >>> with torch.no_grad():
        ...     outputs = model(**inputs)
        ...     logits = outputs.logits

        >>> # model predicts one of the 400 Kinetics-400 classes
        >>> predicted_label = logits.argmax(-1).item()
        >>> print(model.config.id2label[predicted_label])
        LABEL_116
        ```rN   Nr   )losslogitsr   
attentions)rk   r   r   loss_functionr   r
   r   r   )	r.   r2   r   rN   r}   outputsr   r   r   s	            r0   r7   z#VivitForVideoClassification.forward!  s    x $.4::$
3K$
OU$
 "33Aq!9:%4%%ffdkkLVLD$!//))	
 	
r1   )NNF)r8   r9   r:   r   r$   r   r   r<   r   
LongTensorr]   r   r   r
   r7   r>   r?   s   @r0   r   r     s    
{ 
  26*.).	i
''$.i
   4'i
 #'	i

 +,i
 
i
  i
r1   r   )rx   rj   r   )2r;   collections.abcr   r<   r    r   ro   masking_utilsr   modeling_outputsr   r	   r
   processing_utilsr   utilsr   r   r   utils.genericr   r   utils.output_capturingr   vit.modeling_vitr   r   r   r   r   r   r   r   configuration_vivitr   
get_loggerr8   loggerModuler   rA   r_   rd   rf   rh   rj   rx   r   __all__ra   r1   r0   <module>r      s   O $   & 6 b b & @ @ I 5	 	 	 - 
		H	%HRYY H>*m *Z	\ 		v 		 		) 	 4- 4 4 jj jj jjZ x
"6 x
x
v Pr1   