
    g                     \    d dl Z d dlmZmZ d dlZ e j
                  e      Z G d d      Zy)    N)ListTuplec                       e Zd ZdZeddefd       Zed        Zed        Zede	e	e
j                        fd       Zedde	e
j                     d	efd
       Zedde	e	e
j                        fd       Zy)PastKeyValuesHelperzEHelper functions to process past key values for encoder-decoder modelpresentc                     g }g }t        |       D ]L  }|j                  |r
d| d| gn	d| d| g       |j                  |r
d| d| gn	d| d| g       N ||z   S )	Npresent_key_self_present_value_self_past_key_self_past_value_self_present_key_cross_present_value_cross_past_key_cross_past_value_cross_)rangeextend)
num_layersr   past_self_namespast_cross_namesis        c/var/www/openai/venv/lib/python3.12/site-packages/onnxruntime/transformers/models/t5/past_helper.pyget_past_namesz"PastKeyValuesHelper.get_past_names   s    z"A"" %QC(,?s*CD&qc*.>qc,BC
 ## &aS)-A!+EF's+/@-DE # !111    c                     g }g }t        |       D ]S  \  }}t        |      dk(  sJ dt        |              |\  }}}}|j                  ||g       |j                  ||g       U ||fS )a  Split present state from grouped by layer to grouped by self/cross attention.
        Before: (past_key_self_0, past_value_self_0, past_key_cross_0, past_value_cross_0), (past_key_self_1, past_value_self_1, past_key_cross_1, past_value_cross_1), ...
        After: (past_key_self_0, past_value_self_0, past_key_self_1, past_value_self_1, ...), (past_key_cross_0, past_value_cross_0, past_key_cross_1, past_value_cross_1, ...)

           !Expected to have four items. Got 	enumeratelenr   )	present_key_valuespresent_selfpresent_cross_ipresent_layer_ipresent_key_selfpresent_value_selfpresent_key_crosspresent_value_crosss	            r   group_by_self_or_crossz*PastKeyValuesHelper.group_by_self_or_cross#   s     #,-?#@B'1,h0QRUVeRfQg.hh,   "!#!13E FG  "35H!IJ $A ]**r   c                 h     t               dz  k(  sJ t         fdt              D              S )a  Reorder past state from grouped by self/cross attention to grouped by layer.
        Before: past_key_self_0, past_value_self_0, past_key_self_1, past_value_self_1, ..., past_key_cross_0, past_value_cross_0, past_key_cross_1, past_value_cross_1, ...
        After: (past_key_self_0, past_value_self_0, past_key_cross_0, past_value_cross_0), (past_key_self_1, past_value_self_1, past_key_cross_1, past_value_cross_1),
        r   c              3   ~   K   | ]4  }d |z     d |z  dz      d z  d |z  z      d z  d |z  z   dz      g 6 yw)      N ).0r   r   pasts     r   	<genexpr>z5PastKeyValuesHelper.group_by_layer.<locals>.<genexpr>?   sh      
 ' QUQUQYQ^a!e+,Q^a!e+a/0	 's   :=)r   tupler   )r0   r   s   ``r   group_by_layerz"PastKeyValuesHelper.group_by_layer8   s<     4yA
N*** 
 :&
 
 	
r   past_key_valuesc                     d}t        |       dz  }t        t        |       dz        D ])  }d|z  }|| |   | |dz      | ||z      | ||z   dz      ffz  }+ |S )a  Categorize present_key_values from self and cross attention to layer by layer.

        Reorder past state from grouped by self/cross attention to grouped by layer.
        Before: past_key_self_0, past_value_self_0, past_key_self_1, past_value_self_1, ...,
                past_key_cross_0, past_value_cross_0, past_key_cross_1, past_value_cross_1, ...
        After: (past_key_self_0, past_value_self_0, past_key_cross_0, past_value_cross_0),
                (past_key_self_1, past_value_self_1, past_key_cross_1, past_value_cross_1),

        Args:
            present_key_values: From past_key_values of a model (group by self and cross attention)

        Returns:
            past_tuples: present key and values grouped by layer.
        r.   r,   r   r-   )r   r   )r4   past_tupleshalf_idxr   idxs        r   back_group_by_layerz'PastKeyValuesHelper.back_group_by_layerI   s      '1,s?+q01Aa%C#C(#C!G,#HsN3#HsNQ$67	 K 2 r   r    concatc                     g }g }t        |       D ]S  \  }}t        |      dk(  sJ dt        |              |\  }}}}	|j                  ||g       |j                  ||	g       U |r||z   S ||fS )a  Categorize present_key_values into self and cross attention.

        Split present state from grouped by layer to grouped by self/cross attention.
        Before: (past_key_self_0, past_value_self_0, past_key_cross_0, past_value_cross_0),
                (past_key_self_1, past_value_self_1, past_key_cross_1, past_value_cross_1), ...
        After: (past_key_self_0, past_value_self_0, past_key_self_1, past_value_self_1, ...),
                (past_key_cross_0, past_value_cross_0, past_key_cross_1, past_value_cross_1, ...)

        Args:
            present_key_values: From past_key_values of a model (group by layer)
            concat: If concat self attention with cross attention key/value to return

        Returns:
            present_self (Tuple[torch.Tensor]): present key and values from self attention
            present_cross (Tuple[torch.Tensor]): present key and values from cross attention
        r   r   r   )
r    r:   r!   r"   _r$   r%   r&   r'   r(   s
             r   group_by_self_and_crossz+PastKeyValuesHelper.group_by_self_and_crossg   s    $ ,.,."+,>"?A'1,h0QRUVeRfQg.hh,[jX02CEX!13E FG  "35H!IJ	 #@
 -//..r   c                 H   g }|rt        |       dz  n
t        |       }|sdnd}t        |      D ],  }|j                  d| d| fD cg c]  }||z   	 c}       . t        |      D ],  }|j                  d| d| fD cg c]  }||z   	 c}       . |S c c}w c c}w )zProcess input names of model wrapper.

        Args:
            past_key_values: Consider `self` and `cross` past_key_values

        Returns:
            names (List[string]): input names
        r   past_present_	key_self_value_self_
key_cross_value_cross_)r   r   r   )r4   encodernamesr   prefixr   ss          r   get_input_namesz#PastKeyValuesHelper.get_input_names   s     29S)Q.s??S
 'Zz"ALL1#+aS@Q.RS.R&1*.RST #z"ALLA3/?<PQsAS.TU.T&1*.TUV # TUs   	B
B
N)F)T)__name__
__module____qualname____doc__staticmethodboolr   r)   r3   r   torchTensorr9   r=   rI   r.   r   r   r   r      s    O2D 2 2  + +( 
 
  U53F-G  : /E%,,4G /QU / /: uU\\/B)C  r   r   )	loggingtypingr   r   rP   	getLoggerrJ   loggerr   r.   r   r   <module>rV      s.      			8	$G Gr   