o
    3Ih                     @   s,   d dl Z d dlZe eZG dd dZdS )    Nc                   @   s   e Zd ZdZeddefddZedd Zedd	 Zed
e	e	e
j  fddZedde	e
j defddZedd
e	e	e
j  fddZdS )PastKeyValuesHelperzEHelper functions to process past key values for encoder-decoder modelFpresentc                 C   s   g }g }t | D ]4}||rd| d| gn	d| d| g ||r1d| d| gn	d| d| g q|| 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i r   d/home/air/sanwanet/gpt-api/venv/lib/python3.10/site-packages/onnxruntime/transformers/past_helper.pyget_past_names   s   z"PastKeyValuesHelper.get_past_namesc           	      C   sh   g }g }t | D ]'\}}t|dksJ dt| |\}}}}|||g |||g q||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_crossr   r   r   group_by_self_or_cross"   s   z*PastKeyValuesHelper.group_by_self_or_crossc                    s0   t d  ks
J t fd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   sT    | ]%}d |  d | d  d   d |   d   d |  d  gV  qdS )      Nr   ).0r   r   pastr   r   	<genexpr>>   s    

z5PastKeyValuesHelper.group_by_layer.<locals>.<genexpr>)r   tupler   )r(   r   r   r'   r   group_by_layer7   s   z"PastKeyValuesHelper.group_by_layerpast_key_valuesc                 C   sd   d}t | d }tt | d D ]}d| }|| | | |d  | ||  | || d  ff7 }q|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   )r,   past_tupleshalf_idxr   idxr   r   r   back_group_by_layerH   s   

z'PastKeyValuesHelper.back_group_by_layerr   concatc           
      C   st   g }g }t | D ]'\}}t|dksJ dt| |\}}}}	|||g |||	g q|r6|| 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   r1   r   r   _r   r   r    r!   r"   r   r   r   group_by_self_and_crossf   s   z+PastKeyValuesHelper.group_by_self_and_crossTc                    s   g }|r
t | d nt | }|sdnd t|D ]}| fddd| d| fD  qt|D ]}| fddd	| d
| fD  q3|S )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_c                       g | ]} | qS r   r   r&   sprefixr   r   
<listcomp>       z7PastKeyValuesHelper.get_input_names.<locals>.<listcomp>	key_self_value_self_c                    r6   r   r   r7   r9   r   r   r;      r<   
key_cross_value_cross_)r   r   r   )r,   encodernamesr   r   r   r9   r   get_input_names   s   
**z#PastKeyValuesHelper.get_input_namesN)F)T)__name__
__module____qualname____doc__staticmethodboolr   r#   r+   r*   torchTensorr0   r3   rC   r   r   r   r   r      s    

 r   )loggingrJ   	getLoggerrD   loggerr   r   r   r   r   <module>   s   
