Ë
    ÜÓ^jl8  ã            
       ó(  — d Z ddlZddlmZ ddlmZmZ ddlm	Z	m
Z
mZ ddlmZmZ ddlmZ  G d	„ d
e	d¬«      Zdee   dedeee      fd„Zdeeee         deee      dededej*                  f
d„Zdedededefd„Ze G d„ de
«      «       ZdgZy)zProcessor class for Mllama.é    Né   )ÚBatchFeature)Ú
ImageInputÚmake_nested_list_of_images)ÚProcessingKwargsÚProcessorMixinÚUnpack)ÚPreTokenizedInputÚ	TextInput)Úauto_docstringc                   ó   — e Zd ZdddiiZy)ÚMllamaProcessorKwargsÚimage_kwargsÚmax_image_tilesé   N)Ú__name__Ú
__module__Ú__qualname__Ú	_defaults© ó    úw/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/transformers/models/mllama/processing_mllama.pyr   r      s   „ àØ˜qð
ð�Ir   r   F)ÚtotalÚ	input_idsÚimage_token_idÚreturnc                 ó”  — t        | «      D ��cg c]  \  }}||k(  sŒ|‘Œ }}}t        |«      dk(  rg S t        |«      dk(  r|d   dggS t        |dd |dd «      D ��cg c]	  \  }}||g‘Œ }}}|j                  |d   t        | «      g«       |d   d   }|ddd…   D ]  }	|	d   |	d   dz
  k(  r||	d<   |	d   }Œ |S c c}}w c c}}w )aó  
    Generate a cross-attention token mask for image tokens in the input sequence.

    This function identifies the positions of image tokens in the input sequence and creates
    a mask that defines which subsequent tokens each image token should attend to.

    Args:
        input_ids (list[int]): A list of token ids representing the input sequence.
        image_token_id (int): The id of the token used to represent images in the sequence.

    Returns:
        list[list[int]]: A list of [start, end] pairs, where each pair represents the range
        of tokens an image token should attend to.

    Notes:
        - If no image tokens are present, an empty list is returned.
        - For a single image token, it attends to all subsequent tokens until the end of the sequence.
        - For multiple image tokens, each attends to tokens up to the next image token or the end of the sequence.
        - Consecutive image tokens are treated as a group and attend to all subsequent tokens together.
    r   é   éÿÿÿÿN)Ú	enumerateÚlenÚzipÚappend)
r   r   ÚiÚtokenÚimage_token_locationsÚloc1Úloc2Úvision_masksÚlast_mask_endÚvision_masks
             r   Úget_cross_attention_token_maskr,   "   s  € ô, 09¸Ó/C×_¡8 1 eÀuÐP^ÓG^šQÐ_ÐÑ_ä
Ð Ó! QÒ&Øˆ	ô Ð Ó! QÒ&Ø& qÑ)¨2Ð.Ð/Ð/ä36Ð7LÈSÈbÐ7QÐShÐijÐikÐSlÓ3m×n¡Z T¨4�T˜4’LÐn€LÑnð ×ÑÐ.¨rÑ2´C¸	³NÐCÔDð
 ! Ñ$ QÑ'€MØ#¡D b DÑ)ò 'ˆØ�q‰>˜[¨™^¨aÑ/Ò/Ø*ˆK˜‰NØ# A™‰ð'ð
 Ðùó/ `ùó os   �B>�B>ÁCÚcross_attention_token_maskÚ	num_tilesÚmax_num_tilesÚlengthc           	      óz  — t        | «      }t        d„ | D «       «      }t        j                  ||||ft        j                  ¬«      }t        t        | |«      «      D ]\  \  }\  }}	t        t        ||	«      «      D ]<  \  }
\  }}t        |«      dk(  sŒ|\  }}t        ||«      }|dk(  r|}d||||…|
d|…f<   Œ> Œ^ |S )a  
    Convert the cross attention mask indices to a cross attention mask 4D array.

    This function takes a sparse representation of cross attention masks and converts it to a dense 4D numpy array.
    The sparse representation is a nested list structure that defines attention ranges for each image in each batch item.

    Args:
        cross_attention_token_mask (list[list[list[int]]]): A nested list structure where:
            - The outer list represents the batch dimension.
            - The middle list represents different images within each batch item.
            - The inner list contains pairs of integers [start, end] representing token ranges for each image.
        num_tiles (list[list[int]]): A nested list structure specifying the number of tiles for each image in each batch item.
        max_num_tiles (int): The maximum possible number of tiles.
        length (int): The total sequence length of the input.

    Returns:
        np.ndarray: A 4D numpy array of shape (batch_size, length, max_num_images, max_num_tiles)
            The array contains `1` where attention is allowed and `0` where it is not.

    Note:
        - Special handling is done for cases where the end token is -1, which is interpreted as attending to the end of the sequence.
    c              3   ó2   K  — | ]  }t        |«      –— Œ y ­w©N©r!   )Ú.0Úmaskss     r   ú	<genexpr>z?convert_sparse_cross_attention_mask_to_dense.<locals>.<genexpr>p   s   è ø€ ÒL¨œ˜UŸÑLùó   ‚)ÚshapeÚdtypeé   r   r   N)r!   ÚmaxÚnpÚzerosÚint64r    r"   Úmin)r-   r.   r/   r0   Ú
batch_sizeÚmax_num_imagesÚcross_attention_maskÚ
sample_idxÚsample_masksÚsample_num_tilesÚmask_idxÚ	locationsÚmask_num_tilesÚstartÚends                  r   Ú,convert_sparse_cross_attention_mask_to_denserL   R   sè   € ô: Ð/Ó0€JÜÑLÐ1KÔLÓL€NäŸ8™8Ø˜6 >°=ÐAÜ�h‰hôÐô
 9BÄ#ÐF`ÐbkÓBlÓ8mò [Ñ4ˆ
Ñ4�\Ð#3Ü5>¼sÀ<ÐQaÓ?bÓ5cò 	[Ñ1ˆHÑ1�y .Ü�9‹~ Ó"Ø&‘
��sÜ˜#˜vÓ&�Ø˜"’9Ø �CØYZÐ$ Z°°s°¸HÀoÀ~ÀoÐ%UÒVñ	[ð[ð  Ðr   ÚpromptÚ	bos_tokenÚimage_tokenc                 ó”   — || v r| S d}| j                  |«      r%| t        |«      d } |dz  }| j                  |«      rŒ%||z  › |› | › �S )a\  
    Builds a string from the input prompt by adding `bos_token` if not already present.

    Args:
        prompt (`str`):
            The input prompt string.
        bos_token (`str`):
            The beginning of sentence token to be added.
        image_token (`str`):
            The image token used to identify the start of an image sequence.

    Returns:
        str: The modified prompt string with the `bos_token` added if necessary.

    Examples:
        >>> build_string_from_input("Hello world", "<begin_of_text>", "<|image|>")
        '<begin_of_text>Hello world'

        >>> build_string_from_input("<|image|>Hello world", "<begin_of_text>", "<|image|>")
        '<|image|><begin_of_text>Hello world'

        >>> build_string_from_input("<begin_of_text>Hello world", "<begin_of_text>", "<|image|>")
        '<begin_of_text>Hello world'
    r   Nr   )Ú
startswithr!   )rM   rN   rO   Únum_image_tokens_on_starts       r   Úbuild_string_from_inputrS   ‚   sn   € ð4 �FÑØˆà !ÐØ
×
Ñ
˜KÔ
(Øœ˜KÓ(Ð*Ð+ˆØ! QÑ&Ð!ð ×
Ñ
˜KÕ
(ð Ð5Ñ5Ð6°y°kÀ&ÀÐJÐJr   c            
       ó<  ‡ — e Zd ZeZdˆ fd„	Ze	 	 ddedz  dee	z  e
e   z  e
e	   z  dz  dee   defd„«       Z	 	 ddedz  dee	z  e
e   z  e
e	   z  dz  fˆ fd„Z	 	 ddedz  dee	z  e
e   z  e
e	   z  dz  dee   fˆ fd	„Zd
ededefd„Z	 dd„Zed„ «       Zˆ xZS )ÚMllamaProcessorNc                 óF  •— t        |d«      s(d| _        |j                  | j                  «      | _        n"|j                  | _        |j                  | _        d| _        |j                  | j                  «      | _        |j                  | _        t        ‰| �!  |||¬«       y )NrO   z	<|image|>z<|python_tag|>)Úchat_template)	ÚhasattrrO   Úconvert_tokens_to_idsr   Úpython_tokenÚpython_token_idrN   ÚsuperÚ__init__)ÚselfÚimage_processorÚ	tokenizerrW   Ú	__class__s       €r   r]   zMllamaProcessor.__init__«   sŒ   ø€ Ü�y -Ô0Ø*ˆDÔØ"+×"AÑ"AÀ$×BRÑBRÓ"SˆDÕà(×4Ñ4ˆDÔØ"+×":Ñ":ˆDÔà,ˆÔØ(×>Ñ>¸t×?PÑ?PÓQˆÔØ"×,Ñ,ˆŒÜ‰Ñ˜¨)À=ÐÕQr   ÚimagesÚtextÚkwargsr   c           
      óŒ  — | j                  ||¬«      \  }} | j                  d||dœ|¤Ž  | j                  t        fd| j                  j
                  i|¤Ž}|d   j                  dd«      }i }|�+ | j                  |fi |d   ¤Ž}| j                  ||dg¬«       i }|�* | j                  |fi |d   ¤Ž\  }}|j                  d	«      }	|�c|�a|d
   D �
cg c]  }
t        |
| j                  «      ‘Œ }}
t        |	| j                  j                  t        d„ |d
   D «       «      ¬«      }||d<   t        i |¥|¥|¬«      S c c}
w )a—  
        Returns:
            [`BatchFeature`]: A [`BatchFeature`] with the following fields:

            - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`.
            - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when
              `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not
              `None`).
            - **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`.
            TODO: add aspect_ratio_ids and aspect_ratio_mask and cross_attention_mask
        ©rb   rc   Útokenizer_init_kwargsÚtext_kwargsÚreturn_tensorsNÚimage)Ú
modalitiesÚimages_kwargsr.   r   c              3   ó2   K  — | ]  }t        |«      –— Œ y ­wr3   r4   )r5   r   s     r   r7   z+MllamaProcessor.__call__.<locals>.<genexpr>è   s   è ø€ ÒT¨iœ3˜yŸ>ÑTùr8   )r.   r/   r0   rC   )ÚdataÚtensor_typer   )Úprepare_inputs_layoutÚvalidate_inputsÚ_merge_kwargsr   r`   Úinit_kwargsÚpopÚ_check_special_mm_tokensÚ_process_imagesr,   r   rL   r_   r   r<   r   )r^   rb   rc   rd   Úoutput_kwargsri   Útext_inputsÚimage_inputsÚ_r.   Ú	token_idsr-   rC   s                r   Ú__call__zMllamaProcessor.__call__¸   s™  € ð$ ×1Ñ1¸ÀdÐ1ÓK‰ˆ�Øˆ×ÑÐ@ F°Ñ@¸Ò@à*˜×*Ñ*Ü!ñ
à"&§.¡.×"<Ñ"<ð
ð ñ
ˆð
 ' }Ñ5×9Ñ9Ð:JÈDÓQˆàˆØÐØ(˜$Ÿ.™.¨ÑN°¸}Ñ1MÑNˆKØ×)Ñ)¨$°ÈÈ	Ð)ÔRàˆØÐØ2˜d×2Ñ2°6Ñ\¸]È?Ñ=[Ñ\‰OˆL˜!Ø$×(Ñ(¨Ó5ˆIð Ð $Ð"2ð "-¨[Ñ!9ö*àô /¨y¸$×:MÑ:MÕNð*Ð&ð *ô $PØ*Ø#Ø"×2Ñ2×BÑBÜÑT¸;À{Ñ;SÔTÓTô	$Ð ð 3GˆKÐ.Ñ/äÐ!@ KÐ!@°<Ð!@ÈnÔ]Ð]ùò*s   ÃEc                 óº   •— t        ‰| �  d||dœ|¤Ž^}}}|�t        |«      }|�.|D �cg c]#  }t        || j                  | j
                  «      ‘Œ% }}||fS c c}w )Nrf   r   )r\   rp   r   rS   rN   rO   )r^   rb   rc   rd   rz   Ú	text_itemra   s         €r   rp   z%MllamaProcessor.prepare_inputs_layoutî   sv   ø€ ô !™7Ñ8Ð\ÀÈTÑ\ÐU[Ñ\Ðˆ��qð ÐÜ/°Ó7ˆFàÐØjnÖoÐ]fÔ+¨I°t·~±~Àt×GWÑGWÕXÐoˆDÐoà�tˆ|Ðùò ps   ª(Ac                 óä  •— t        ‰	| �  ||fi |¤Ž |�Ò|D �cg c]  }|j                  | j                  «      ‘Œ }}t	        |«      dkD  r|€t        d«      ‚|�Œt        |«      }|D �cg c]  }t        |«      ‘Œ }}t        d„ |D «       «      rt        d„ |D «       «      st        d«      ‚||k7  r4d}t	        |«      t	        |«      k(  r||k7  rd}t        d|› d	|› d
|› �«      ‚y y y c c}w c c}w )Nr   z@No image were provided, but there are image tokens in the promptc              3   ó&   K  — | ]	  }|d k(  –— Œ y­w©r   Nr   ©r5   Ú	batch_imgs     r   r7   z2MllamaProcessor.validate_inputs.<locals>.<genexpr>  s   è ø€ ÒH¨)�y A•~ÑHùó   ‚c              3   ó&   K  — | ]	  }|d k(  –— Œ y­wr�   r   r‚   s     r   r7   z2MllamaProcessor.validate_inputs.<locals>.<genexpr>  s   è ø€ ò UØ'0�I •NñUùr„   zaIf a batch of text is provided, there should be either no images or at least one image per sampleÚ zZMake sure to pass your images as a nested list, where each sub-list holds images per batchz)The number of image tokens in each text (zA) should be the same as the number of provided images per batch (z). )
r\   rq   ÚcountrO   ÚsumÚ
ValueErrorr   r!   ÚanyÚall)
r^   rb   rc   rd   ÚtÚn_images_in_textÚsampleÚn_images_in_imagesÚadd_messagera   s
            €r   rq   zMllamaProcessor.validate_inputsÿ   s@  ø€ ô 	‰Ñ ¨Ñ7°Ò7àÐØCGÖH¸a §¡¨×(8Ñ(8Õ 9ÐHÐÐHäÐ#Ó$ qÒ(¨V¨^Ü Ð!cÓdÐdØÐ#Ü3°FÓ;�Ø@FÖ%G°f¤c¨&¥kÐ%GÐ"Ð%GäÑHÐ7GÔHÔHÔQTñ UØ4DôUô Rô %Ø{óð ð &Ð)9Ò9Ø"$�KÜÐ-Ó.´#Ð6FÓ2GÒGÐL^ÐbrÒLrð 'C˜ä$ØCÐDTÐCUð V@Ø@RÐ?SÐSVÐWbÐVcðeóð ð :ð $ð ùÚHùò &Hs   ™"C(Á)C-ry   Ú	image_idxc                 ó   — | j                   S r3   )rO   )r^   ry   r‘   s      r   Úreplace_image_tokenz#MllamaProcessor.replace_image_token!  s   € ð ×ÑÐr   c                 óB   —  | j                   j                  |f||dœ|¤ŽS )aš  
        Post-process the output of the model to decode the text.

        Args:
            generated_outputs (`torch.Tensor` or `np.ndarray`):
                The output of the model `generate` function. The output is expected to be a tensor of shape `(batch_size, sequence_length)`
                or `(sequence_length,)`.
            skip_special_tokens (`bool`, *optional*, defaults to `True`):
                Whether or not to remove special tokens in the output. Argument passed to the tokenizer's `batch_decode` method.
            clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`):
                Whether or not to clean up the tokenization spaces. Argument passed to the tokenizer's `batch_decode` method.
            **kwargs:
                Additional arguments to be passed to the tokenizer's `batch_decode method`.

        Returns:
            `list[str]`: The decoded text.
        )Úskip_special_tokensÚclean_up_tokenization_spaces)r`   Úbatch_decode)r^   Úgenerated_outputsr•   r–   rd   s        r   Úpost_process_image_text_to_textz/MllamaProcessor.post_process_image_text_to_text&  s5   € ð( +ˆt�~‰~×*Ñ*Øð
à 3Ø)Eñ
ð ñ	
ð 	
r   c                 ó²   — | j                   j                  }| j                  j                  }|D �cg c]
  }|dk7  sŒ	|‘Œ }}t        ||z   dgz   «      S c c}w )Nr.   rC   )r`   Úmodel_input_namesr_   Úlist)r^   Útokenizer_input_namesÚimage_processor_input_namesÚnames       r   r›   z!MllamaProcessor.model_input_namesA  se   € à $§¡× @Ñ @ÐØ&*×&:Ñ&:×&LÑ&LÐ#ð 9TÖ&k°ÐW[Ð_jÓWj¢tÐ&kÐ#Ð&kÜÐ)Ð,GÑGÐKaÐJbÑbÓcÐcùò 'ls
   ±
A¼Ar3   )NN)TF)r   r   r   r   Úvalid_processor_kwargsr]   r   r   r   r
   rœ   r	   r   r|   rp   r   rq   ÚdictÚintÚstrr“   r™   Úpropertyr›   Ú__classcell__)ra   s   @r   rU   rU   §   sX  ø„ à2ÐõRð ð %)Øaeñ3^à˜TÑ!ð3^ð Ð+Ñ+¨d°9©oÑ=ÀÐEVÑ@WÑWÐZ^Ñ^ð3^ð Ð.Ñ/ð	3^ð
 
ò3^ó ð3^ðn %)Øaeñà˜TÑ!ðð Ð+Ñ+¨d°9©oÑ=ÀÐEVÑ@WÑWÐZ^Ñ^õð& %)Øaeñ à˜TÑ!ð ð Ð+Ñ+¨d°9©oÑ=ÀÐEVÑ@WÑWÐZ^Ñ^ð ð Ð)Ñ*õ	 ðD °ð  Àð  Èó  ð Y^ó
ð6 ñdó ôdr   rU   )Ú__doc__Únumpyr=   Úfeature_extraction_utilsr   Úimage_utilsr   r   Úprocessing_utilsr   r   r	   Útokenization_utils_baser
   r   Úutilsr   r   rœ   r¢   r,   ÚndarrayrL   r£   rS   rU   Ú__all__r   r   r   ú<module>r¯      sú   ðñ "ã å 4ß Aß HÑ Hß CÝ #ôÐ,°Eõ ð-¨d°3©ið -Èð -ÐQUÐVZÐ[^ÑV_ÑQ`ó -ð`- Ø $ T¨$¨s©)¡_Ñ 5ð- à�D˜‘I‰ð- ð ð- ð ð	- ð
 ‡Z�Zó- ð`"K Cð "K°Cð "KÀcð "KÈcó "KðJ ôad�nó adó ðadðH Ð
�r   