§
    [�’j÷¶  ã                   ó  — d dl mZ d dlmZ d dlm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 d
dlmZ d
dlmZmZmZ d
dlmZmZmZmZmZ  G d„ de¦  «        Z G d„ d¦  «        Z G d„ d¦  «        Z G d„ d¦  «        ZdS )é    )Únullcontext)Úpartial)Úrepeat)Ú	TypedDictN)ÚPretrainedConfig)ÚContinuousBatchingConfigé   )Úget_available_devicesé   )ÚPagedAttentionCache)Ú%ContinuousBatchingLogitsProcessorList)ÚTMP_TOKEN_IDÚFutureRequestStateÚlogger)ÚCudaGraphBufferÚaligned_divideÚattn_mask_is_neededÚbuild_attention_maskÚpad_to_pow2c                   ó~  — e Zd ZU dZej        ed<   ej        eeej        f         z  dz  ed<   ej        ed<   ej        ed<   ej        eeej        f         z  ed<   e	ed<   e	eee	f         z  ed	<   e
ej                 ed
<   e
ej                 ed<   ej        ed<   eed<   ej        dz  ed<   ej        ed<   eed<   dS )ÚPagedAttentionArgsa  The keyword arguments for a forward pass using paged attention, passed directly as model forward kwargs.

    Attributes:
        input_ids: Input token IDs tensor of shape `(1, total_query_tokens)`.
        attention_mask: Attention mask tensor or dictionary mapping layer types to masks. Can be `None` if the
            attention implementation doesn't require explicit masks.
        position_ids: Position IDs tensor of shape `(1, total_query_tokens)`.
        cu_seq_lens_q: Cumulative sequence lengths for queries, used for variable-length batching.
        cu_seq_lens_k: Cumulative sequence lengths for keys/values. Can be a tensor or dictionary mapping layer
            types (e.g., "full_attention", "sliding_attention") to tensors for hybrid models.
        max_seqlen_q: Maximum query sequence length in the batch.
        max_seqlen_k: Maximum key/value sequence length. Can be an int or dictionary for hybrid models.
        write_index: List of tensors indicating where to write new KV states in the cache, one per attention group.
        read_index: List of tensors indicating which cache positions to read from, one per attention group.
        logits_indices: Tensor indicating which positions in the output should be used for next-token prediction.
        cache: The [`PagedAttentionCache`] instance managing the KV cache.
        block_table: Block table for paged KV cache. If provided, uses `flash_attn_with_kvcache` for fused attention +
            cache update. More information in src/transformers/integrations/flash_paged.py
        logits_processor_args: List of tensors containing the arguments for the logits processors, one per request.
        use_cache: Whether to use caching (always `False` in continuous batching as the cache is managed externally).
    Ú	input_idsNÚattention_maskÚposition_idsÚcu_seq_lens_qÚcu_seq_lens_kÚmax_seqlen_qÚmax_seqlen_kÚwrite_indexÚ
read_indexÚlogits_indicesÚcacheÚblock_tableÚlogits_processor_argsÚ	use_cache)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚtorchÚTensorÚ__annotations__ÚdictÚstrÚintÚlistr   Úbool© ó    úgC:\Projects\DSCons\.venv\Lib\site-packages\transformers\generation\continuous_batching\input_outputs.pyr   r      s  € € € € € € ðð ð, Œ|ÐÐÑØ”L 4¨¨U¬\Ð(9Ô#:Ñ:¸TÑAÐAÐAÑAØ”,ÐÐÑØ”<ÐÐÑØ”< $ s¨E¬LÐ'8Ô"9Ñ9Ð9Ð9Ñ9ØÐÐÑØ˜˜S #˜XœÑ&Ð&Ð&Ñ&Ø�e”lÔ#Ð#Ð#Ñ#Ø�U”\Ô"Ð"Ð"Ñ"Ø”LÐ Ð Ñ ØÐÐÑØ” Ñ$Ð$Ð$Ñ$Ø œ<Ð'Ð'Ñ'Ø€O€O�O€O€Or3   r   c                   óž  — e Zd ZU dZdZeed<   dedede	de
j        de
j        d	ed
dfd„Zd	ed
dfd„Z	 d.dd de
j        j        ded
dfd„Z e
j        ¦   «         d.ded
dfd„¦   «         Zd/d„Zd
ee
j        eee
j        f         f         fd„Zde
j        de
j        de
j        d
dfd„Zd/d„Zd
eee         ee         ee          dz  f         fd„Z!dee         deded ed!ed"ed
dfd#„Z"d"ed
efd$„Z#d.d"ed
e$fd%„Z%d
ee
j        e
j        e
j        f         fd&„Z&d
eed'f         fd(„Z'd0d*ed
e
j        j(        dz  fd+„Z)d,e
j        j(        d
dfd-„Z*dS )1ÚContinuousBatchingIOszýA class to hold inputs and outputs for a continuous batching forward pass, using static tensors as storage. The
    class is meant to be self-contained, so once a set of inputs have been created, the class can be used to update the
    batch alone.
    é   Ústatic_inputsr"   ÚconfigÚcontinuous_batching_configÚdeviceÚmodel_dtypeÚlogit_processorÚreturnNc                 óÌ  — || _         || _        || _        || _        |j        | _        |j        d         | _        t          |dd¦  «        €dn|j        | _        |j	        | _	        d| _
        d| _        d| _        d„ t          |j        ¦  «        D ¦   «         | _        d„ t          |j        ¦  «        D ¦   «         | _        d| _        g | _        i | _        t)          ¦   «         | _        |j        | _        |j        | _        |                      |¬¦  «         |                      d	¬
¦  «         |j        dk    r%t:          j                             | j        ¬¦  «        nd| _         dS )a3  Initialize the continuous batching I/O manager. Args:
        - cache: The [`PagedAttentionCache`] instance managing the KV cache. Meant to be unique.
        - config: The model's pretrained configuration.
        - continuous_batching_config: The continuous batching configuration.
        - device: The device to allocate tensors on. If the device is CPU, then the memory is pinned.
        - model_dtype: The data type for model computations.
        - logit_processor: The [`ContinuousBatchingLogitsProcessorList`] object used to process the logits.
        r   Úsliding_windowNr   c                 ó   — g | ]}d ‘ŒS ©r   r2   ©Ú.0Ú_s     r4   ú
<listcomp>z2ContinuousBatchingIOs.__init__.<locals>.<listcomp>l   s   € ÐCÐCÐC a ÐCÐCÐCr3   c                 ó   — g | ]}d ‘ŒS rB   r2   rC   s     r4   rF   z2ContinuousBatchingIOs.__init__.<locals>.<listcomp>m   s   € Ð DÐ DÐ D q Ð DÐ DÐ Dr3   F)r=   T©Ú
full_resetÚcuda©r;   )!r"   r;   r9   r<   Úmax_requests_per_batchÚcuda_graph_booleansÚuse_cuda_graph_varlenÚgetattrr@   Úreturn_logprobsÚnum_q_tokensÚmax_kv_readÚnum_request_in_batchÚrangeÚ
num_groupsÚtrue_read_sizesÚtrue_write_sizesÚuse_block_tableÚrequests_in_batchÚreq_id_to_new_token_positionr   ÚgraphsÚread_trash_indexÚ_read_trash_indexÚwrite_trash_indexÚ_write_trash_indexÚ_setup_static_tensorsÚ_reset_static_tensorsÚtyper*   rJ   ÚStreamÚcompute_stream©Úselfr"   r9   r:   r;   r<   r=   s          r4   Ú__init__zContinuousBatchingIOs.__init__N   sc  € ð$ ˆŒ
ØˆŒØˆŒØ&ˆÔØ&@Ô&WˆÔ#Ø%?Ô%SÐTUÔ%VˆÔ"Ý#*¨6Ð3CÀTÑ#JÔ#JÐ#R˜a˜aÐX^ÔXmˆÔØ9ÔIˆÔàˆÔØˆÔØ$%ˆÔ!ØCÐC­5°Ô1AÑ+BÔ+BÐCÑCÔCˆÔØ DÐ D­E°%Ô2BÑ,CÔ,CÐ DÑ DÔ DˆÔØ$ˆÔà;=ˆÔØ<>ˆÔ)Ý'6Ñ'8Ô'8ˆŒØ!&Ô!7ˆÔØ"'Ô"9ˆÔà×"Ò"°?Ð"ÑCÔCÐCØ×"Ò"¨dÐ"Ñ3Ô3Ð3ØGMÄ{ÐV\ÒG\ÐG\�eœj×/Ò/°t´{Ð/ÑCÔCÐCÐbfˆÔÐÐr3   c                 ó€  — | j         j        }| j         j        }| j        }| j         j        | j         j        z  }| j        j        dk    ot          t          ¦   «         ¦  «        dk    }| j
        |j        z   }t          |dz   dd¦  «        }t          j        ||ft          j        | j        |¬¦  «        | _        t          j        |j        dft          j        | j        ¬¦  «        | _        |                     | j        ¦  «         | j        dd|…f         | _        | j        dd|…f         | _        | j        dd|dz   …f         | _        | j        d	d|…f         | _        | j        d
d|dz   …f         }	| j        dd|dz   …f         }
| j        dd|…f         | _        i | _        | j         j        r
|	| j        d<   | j         j        r
|
| j        d<   | j        rdnd}t          j        ||dz   ft          j        | j        |¬¦  «        | _        | j                             ¦   «          d| _        t>                                | j         !                    ¦   «         d¦  «        | _"        d| _#        t>                                | j         !                    ¦   «         d¦  «        | _$        tK          | j&        ¦  «        rUi | _'        | j         !                    ¦   «         D ]3}t          j        dd|||z   f| j(        | j        |¬¦  «        | j'        |<   Œ4nd| _'        | j         j)        dk    r|nd}t          j        ||| j         j)        ft          j        | j        |¬¦  «        | _*        t          j        ||ft          j+        | j        |¬¦  «        | _,        t          j        |||z   ft          j+        | j        |¬¦  «        | _-        dS )aí  Allocates static tensors for generation inputs and outputs. This is called only once at init time, to avoid
        repeated allocations and enable CUDA graphs. All tensors are allocated with maximum possible sizes.
        The allocated tensors are:

        - `_bulk_input_tensor`: Storage for all the small inputs: `input_ids`, `position_ids`, `cumulative_seqlens_q`,
          `logits_indices`, `cumulative_seqlens_k`, `carry_over_ids`.
        - `attention_mask`: Optional attention masks (only for eager/SDPA implementations)
        - `write_index` and `read_index` storage: Cache indexing tensors for each attention group
        - `output_ids`: Storage for generated token IDs and maybe log probabilities if return_logprobs is True
        Úcpur   é    )Údtyper;   Ú
pin_memory©rk   r;   r   Né   r	   é   é   é   Úfull_attentionÚsliding_attention)Úsizerk   r;   rl   ).r"   rU   Úmax_batch_tokensrL   Ú
num_blocksÚ
block_sizer;   rb   Úlenr
   r8   Útensors_requiredr   r*   ÚemptyÚint32Ú_bulk_input_tensorÚlogits_processors_defaultsÚfill_defaultsr   r   Úcumulative_seqlens_qr!   Úcarry_over_idsÚcumulative_seqlens_kÚnum_full_attention_groupsÚnum_sliding_attention_groupsrP   Ú
output_idsÚzero_Útotal_seqlen_qr-   ÚfromkeysÚkeysÚtotal_seqlen_kr   r   r   r9   r   r<   Úmax_blocks_per_requestr#   Úint64Úwrite_index_storageÚread_index_storage)rf   r=   rU   ru   rL   Ú	num_pagesrl   Ú
bulk_linesÚbulk_columnsÚ#full_attention_cumulative_seqlens_kÚ&sliding_attention_cumulative_seqlens_kÚnum_output_rowsÚ
layer_typeÚns                 r4   r`   z+ContinuousBatchingIOs._setup_static_tensorsz   s  € ð ”ZÔ*ˆ
Øœ:Ô6ÐØ!%Ô!<ÐØ”JÔ)¨D¬JÔ,AÑAˆ	à”[Ô%¨Ò.ÐSµ3Õ7LÑ7NÔ7NÑ3OÔ3OÐRSÒ3Sˆ
ð Ô'¨/Ô*JÑJˆ
Ý%Ð&6¸Ñ&:¸A¸rÑBÔBˆÝ"'¤+Ø˜Ð&­e¬kÀ$Ä+ÐZdð#
ñ #
ô #
ˆÔõ +0¬+ØÔ-¨qÐ1½¼ÈTÌ[ð+
ñ +
ô +
ˆÔ'ð 	×%Ò% dÔ&EÑFÔFÐFð Ô0°Ð4EÐ5EÐ4EÐ1EÔFˆŒØ Ô3°AÐ7HÐ8HÐ7HÐ4HÔIˆÔØ$(Ô$;¸AÐ?[ÐAWÐZ[ÑA[Ð?[Ð<[Ô$\ˆÔ!Ø"Ô5°aÐ9PÐ:PÐ9PÐ6PÔQˆÔØ.2Ô.EÀaÐIeÐKaÐdeÑKeÐIeÐFeÔ.fÐ+Ø15Ô1HÈÐLhÐNdÐghÑNhÐLhÐIhÔ1iÐ.Ø"Ô5°aÐ9JÐ:JÐ9JÐ6JÔKˆÔð >@ˆÔ!ØŒ:Ô/ð 	^Ø:]ˆDÔ%Ð&6Ñ7ØŒ:Ô2ð 	dØ=cˆDÔ%Ð&9Ñ:ð  $Ô3Ð:˜!˜!¸ˆåœ+ØÐ.°Ñ2Ð3½5¼;ÈtÌ{Ðgqð
ñ 
ô 
ˆŒð 	Œ×ÒÑÔÐØˆÔÝ.2¯mªm¸DÔ<U×<ZÒ<ZÑ<\Ô<\Ð^_Ñ.`Ô.`ˆÔØˆÔÝ,0¯MªM¸$Ô:S×:XÒ:XÑ:ZÔ:ZÐ\]Ñ,^Ô,^ˆÔõ ˜tœ{Ñ+Ô+ð 
	'Ø"$ˆDÔØ"Ô7×<Ò<Ñ>Ô>ð ð �
Ý27´+Ø˜QÐ 0°)Ð>NÑ2NÐOØÔ*Øœ;Ø)ð	3ñ 3ô 3�Ô# JÑ/Ð/ðð #'ˆDÔð œ*Ô;¸aÒ?Ð?ˆJˆJÀQˆÝ œ;ØÐ&¨¬
Ô(IÐJÝ”+Ø”;Ø!ð	
ñ 
ô 
ˆÔõ $)¤;ØÐ)Ð*µ%´+ÀdÄkÐ^hð$
ñ $
ô $
ˆÔ õ #(¤+Ø˜Ð%5Ñ5Ð6½e¼kÐRVÔR]Ðjtð#
ñ #
ô #
ˆÔÐÐr3   FÚotherÚstreamÚnon_blockingc                 óº  — | j         |_         | j        |_        | j        |_        | j        d d …         |_        | j        d d …         |_        | j        |_        | j        |_        t          | j        ¦  «        |_        | j	        |_	        t          | j
        ¦  «        |_
        |�t          j                             |¦  «        nt          ¦   «         }|5  |j                             | j        |¬¦  «         | j        r"|j                             | j        |¬¦  «         nM|j                             | j        |¬¦  «         | j        dk    r!|j                             | j        |¬¦  «         | j        �P|j        �I| j                             ¦   «         D ]/}|j        |                              | j        |         |¬¦  «         Œ0d d d ¦  «         d S # 1 swxY w Y   d S )N©r˜   r   )rQ   rR   rS   rV   rW   rX   r†   r-   r‰   r   r   r*   rJ   r—   r   r|   Úcopy_r#   rŒ   r�   r   rˆ   )rf   r–   r—   r˜   Úmaybe_streamr”   s         r4   Ú_transfer_inputsz&ContinuousBatchingIOs._transfer_inputsÔ   s1  € ð "Ô.ˆÔØ Ô,ˆÔØ%)Ô%>ˆÔ"Ø $Ô 4°Q°Q°QÔ 7ˆÔØ!%Ô!6°q°q°qÔ!9ˆÔØ $Ô 4ˆÔà#Ô2ˆÔÝ# DÔ$7Ñ8Ô8ˆÔØ!Ô.ˆÔÝ! $Ô"3Ñ4Ô4ˆÔà4:Ð4F•u”z×(Ò(¨Ñ0Ô0Ð0ÍKÉMÌMˆØð 	wð 	wØÔ$×*Ò*¨4Ô+BÐQ]Ð*Ñ^Ô^Ð^àÔ#ð gØÔ!×'Ò'¨Ô(8À|Ð'ÑTÔTÐTÐTð Ô)×/Ò/°Ô0HÐWcÐ/ÑdÔdÐdØÔ# aÒ'Ð'ØÔ,×2Ò2°4Ô3JÐYeÐ2ÑfÔfÐfàÔ"Ð.°5Ô3GÐ3SØ"&Ô"5×":Ò":Ñ"<Ô"<ð wð w�JØÔ(¨Ô4×:Ò:¸4Ô;NÈzÔ;ZÐiuÐ:ÑvÔvÐvÐvð	wð 	wð 	wñ 	wô 	wð 	wð 	wð 	wð 	wð 	wð 	wð 	wøøøð 	wð 	wð 	wð 	wð 	wð 	ws   ÃC/GÇGÇGrI   c                 ó  — |r| j                              d¦  «        n| j        }|r| j                             d¦  «        n| j        }|r
| j        dz   nt          | j        | j        ¦  «        }| j        d| j        …d|dz   …f          	                    ¦   «          |r| j
        | j        | j        d…<   d| _        | j        d|…          	                    ¦   «          | j        dd…d|…f          	                    ¦   «          | j        D ]n}d| j        |<   d| j        |<   | j        �Q| j        |         dd…dd…d|…d||z   …f                              t'          j        | j        ¦  «        j        ¦  «         Œo|r�| j        dd…d|…f                              d¦  «         | j         dd…d|…f                              | j        ¦  «         | j        dd…d||z   …f                              | j        ¦  «         dS | j        r(| j        dd…d|…f                              d¦  «         dS | j         dd…d|…f                              | j        ¦  «         | j        dd…d||z   …f                              | j        ¦  «         dS )a   Reset static tensors for the next batch. For efficiency, this only resets the portions of tensors that were
        actually used in the previous batch, using the attributes num_q_tokens and max_kv_read. If a (full_reset)
        is requested, the entire tensor storage is reset.
        éÿÿÿÿr   Nr   )rŒ   rt   rQ   r�   rR   rL   Úminr|   r8   r…   r}   r   r!   r„   r�   r   r‰   r   Úfill_r*   Úfinfor<   r#   r_   r]   rX   )rf   rI   Úq_lenÚkv_lenÚb_sizer”   s         r4   ra   z+ContinuousBatchingIOs._reset_static_tensorsô   sØ  € ð 6@ÐV�Ô(×-Ò-¨bÑ1Ô1Ð1ÀTÔEVˆØ5?ÐU�Ô(×-Ò-¨bÑ1Ô1Ð1ÀTÔEUˆØ4>Ðw�Ô,¨qÑ0Ð0ÅCÈÔHYÐ[_Ô[vÑDwÔDwˆð 	ÔÐ 4 $Ô"4Ð 4°k¸À¹	°kÐ AÔB×HÒHÑJÔJÐJØð 	\Ø<@Ô<[ˆDÔ# DÔ$6Ð$8Ð$8Ñ9ØˆÔð 	Ô˜G˜V˜GÔ$×*Ò*Ñ,Ô,Ð,ØŒ˜˜˜˜7˜F˜7˜
Ô#×)Ò)Ñ+Ô+Ð+ð Ô3ð 	ð 	ˆJØ,-ˆDÔ˜jÑ)Ø./ˆDÔ 
Ñ+ØÔ"Ð.ØÔ# JÔ/°°°°1°1°1°f°u°fÐ>NÀÈÁÐ>NÐ0NÔO×UÒUÝ”K Ô 0Ñ1Ô1Ô5ñô ð øð
 ð 
	WØÔ˜Q˜Q˜Q   ˜ZÔ(×.Ò.¨rÑ2Ô2Ð2ØÔ$ Q Q Q¨¨¨ YÔ/×5Ò5°dÔ6MÑNÔNÐNØÔ# A A AÐ'7¨°©Ð'7Ð$7Ô8×>Ò>¸tÔ?UÑVÔVÐVÐVÐVàÔ!ð 	WØÔ˜Q˜Q˜Q   ˜ZÔ(×.Ò.¨rÑ2Ô2Ð2Ð2Ð2ð Ô$ Q Q Q¨¨¨ YÔ/×5Ò5°dÔ6MÑNÔNÐNØÔ# A A AÐ'7¨°©Ð'7Ð$7Ô8×>Ò>¸tÔ?UÑVÔVÐVÐVÐVr3   c                 ó’   — |                       d¬¦  «         g | _        i | _        | j        �| j                             ¦   «          dS dS )z4Reset all relevant states for a new generation loop.TrH   N)ra   rY   rZ   rd   Úsynchronize©rf   s    r4   ÚresetzContinuousBatchingIOs.reset  sU   € à×"Ò"¨dÐ"Ñ3Ô3Ð3Ø!#ˆÔØ,.ˆÔ)ØÔÐ*ØÔ×+Ò+Ñ-Ô-Ð-Ð-Ð-ð +Ð*r3   c                 ó   — | j         | j        fS )z:Get the cumulative sequence lengths for the current batch.)r   r�   r¨   s    r4   Úget_cumulative_seqlensz,ContinuousBatchingIOs.get_cumulative_seqlens(  s   € àÔ(¨$Ô*CÐCÐCr3   r   r€   Úprev_output_idsc                 ó   — d S ©Nr2   )rf   r   r€   r¬   s       r4   Úcarry_over_tokensz'ContinuousBatchingIOs.carry_over_tokens,  s	   € ð 	ˆr3   c                 óJ   — | j         �| j                              ¦   «          d S d S r®   )rd   r§   r¨   s    r4   Úretrieve_device_outputsz-ContinuousBatchingIOs.retrieve_device_outputs1  s.   € ØÔÐ*ØÔ×+Ò+Ñ-Ô-Ð-Ð-Ð-ð +Ð*r3   c                 ó  — | j         dd | j        …f                              ¦   «         }| j        rG| j         dd | j        …f                              t
          j        ¬¦  «                             ¦   «         }nd }| j        ||fS )Nr   r   ©rk   )r„   rS   ÚtolistrP   Úviewr*   Úfloat32rY   )rf   Ú
new_tokensÚlogprobss      r4   Úprepare_batch_updatez*ContinuousBatchingIOs.prepare_batch_update5  s‡   € Ø”_ QÐ(C¨$Ô*CÐ(CÐ%CÔD×KÒKÑMÔMˆ
àÔð 	Ø” qÐ*E¨DÔ,EÐ*EÐ'EÔF×KÒKÕRWÔR_ÐKÑ`Ô`×gÒgÑiÔiˆHˆHð ˆHØÔ% z°8Ð;Ð;r3   rY   Úlogits_processorsÚuse_decode_fast_pathrQ   rR   Úuse_paddingc           	      ó0  — |st          d¦  «        ‚|o| j                             ¦   «         dk    | _        || _        | j        rdn|| _        t          |¦  «        | _        |                      ¦   «          d„ t          | j
        j        ¦  «        D ¦   «         | _        d„ t          | j
        j        ¦  «        D ¦   «         | _        g | _        i | _        g }g }dg}	g }
d„ | j                             ¦   «         D ¦   «         }d„ t          | j
        j        ¦  «        D ¦   «         }| j        dk    rdn"d„ t          | j
        j        ¦  «        D ¦   «         }t%          |¦  «        D �]â\  }}|j        }|j        }|j        }| j
                             ||¦  «        }|xj        |z  c_        |                     |j        ¦  «         |                     t          |||z   ¦  «        ¦  «         |	                     |	d	         |z   ¦  «         t5          | j        |¦  «        | _        |                     ¦   «         D ]R\  }}||                              ||         d	         |z   ¦  «         t5          | j        |         |¦  «        | j        |<   ŒS| j        r2| j
                             |j        ||| j        dd…|f         ¦  «         n#| j
                              |j        ||||¦  «         |j!        r@|
                     |	d	         d
z
  ¦  «         tD          g|_        |
d	         | j        |j        <   | j                             |¦  «         �Œä| #                    || j$        | j%        d…         ¬¦  «         |	d	         | _&        | j'        �E|                     ¦   «         D ]0\  }}tQ          | j'        |         |	||dk    r| j)        nd
¬¦  «         Œ1|rI|  *                    |¬¦  «        }|| j        z
  }|	                     tW          | j&        |¦  «        ¦  «         nd}tY          tZ          j.        tZ          j/        | j0        ¬¦  «        } ||¦  «        | j1        dt          |¦  «        …<    ||¦  «        | j2        dt          |¦  «        …<    ||	¦  «        | j3        dt          |	¦  «        …<    ||
¦  «        | j4        dt          |
¦  «        …<   |                     ¦   «         D ]b\  }}|d	         }|| j5        |<   |                     tW          ||¦  «        ¦  «          ||¦  «        | j        |         dt          |¦  «        …<   Œc| j        sÍtY          tZ          j.        tZ          j6        | j0        ¬¦  «        }t%          |¦  «        D ]@\  }} ||¦  «        | j7        |dt          |¦  «        …f<   t          |¦  «        | j        |<   ŒA|�Rt%          |¦  «        D ]D\  }} ||¦  «        | j8        |dt          |¦  «        …f<   t          |¦  «        | j        |<   ŒAdS dS dS )a´  Prepare tensors and metadata for the next model forward pass, using the given requests as data. This method:

        1. Resets the static tensors from the previous batch
        2. Iterates through requests to accumulate input_ids, position_ids, and sequence lengths
        3. Extends read/write indices for cache management
        4. Builds attention masks if needed (for eager/SDPA implementations)
        5. Converts accumulated lists to tensors and copies them to static storage

        This method also modifies the `position_offset` attribute of each request to track progress and adds a
        temporary token at the end of the requests for which there will a new token.
        zNo requests in batchr   c                 ó   — g | ]}d ‘ŒS rB   r2   rC   s     r4   rF   z?ContinuousBatchingIOs.prepare_batch_tensors.<locals>.<listcomp>a  s   € ÐHÐHÐH a ÐHÐHÐHr3   c                 ó   — g | ]}d ‘ŒS rB   r2   rC   s     r4   rF   z?ContinuousBatchingIOs.prepare_batch_tensors.<locals>.<listcomp>b  s   € Ð IÐ IÐ I q Ð IÐ IÐ Ir3   c                 ó   — i | ]}|d g“ŒS rB   r2   )rD   r”   s     r4   ú
<dictcomp>z?ContinuousBatchingIOs.prepare_batch_tensors.<locals>.<dictcomp>l  s   € ÐcÐcÐc°J 
¨Q¨CÐcÐcÐcr3   c                 ó   — g | ]}g ‘ŒS r2   r2   rC   s     r4   rF   z?ContinuousBatchingIOs.prepare_batch_tensors.<locals>.<listcomp>m  s   € Ð@Ð@Ð@˜a�rÐ@Ð@Ð@r3   Nc                 ó   — g | ]}g ‘ŒS r2   r2   rC   s     r4   rF   z?ContinuousBatchingIOs.prepare_batch_tensors.<locals>.<listcomp>n  s   € Ð8bÐ8bÐ8bÀ¸Ð8bÐ8bÐ8br3   rŸ   r   )rY   Úarg_storagers   )r   r   r�   r@   ©r¼   rm   )9Ú
ValueErrorr#   ÚnumelrX   rQ   rR   rx   rS   ra   rT   r"   rU   rV   rW   rY   rZ   r�   rˆ   Ú	enumerateÚstateÚposition_offsetÚquery_lengthÚget_seqlens_kÚextendÚtokens_to_processÚappendÚmaxr   Úitemsr   Úfill_block_tableÚ
request_idÚextend_read_and_write_indicesÚhas_new_tokenr   Úprepare_tensor_argsr|   r8   r†   r   r   r@   Ú_get_num_sequencesr   r   r*   Útensorr{   r;   r   r   r   r!   r‰   r‹   rŒ   r�   )rf   rY   rº   r»   rQ   rR   r¼   r   r   r   r!   r�   r   r    ÚiÚfuture_staterÉ   Úpast_lengthrË   Ú	seqlens_kr”   Úlayer_type_seqlen_kÚlayer_type_seqlens_kÚnum_sequences_in_next_batchÚfake_sequencesÚ	to_tensorr‰   Úto_index_tensorÚgroup_write_indicesÚgroup_read_indicess                                 r4   Úprepare_batch_tensorsz+ContinuousBatchingIOs.prepare_batch_tensors?  sÝ  € ð* !ð 	5ÝÐ3Ñ4Ô4Ð4ð  4ÐT¸Ô8H×8NÒ8NÑ8PÔ8PÐSTÒ8TˆÔà(ˆÔØ $Ô 4ÐE˜1˜1¸+ˆÔÝ$'Ð(9Ñ$:Ô$:ˆÔ!à×"Ò"Ñ$Ô$Ð$ð  IÐH­5°´Ô1FÑ+GÔ+GÐHÑHÔHˆÔØ IÐ I­E°$´*Ô2GÑ,HÔ,HÐ IÑ IÔ IˆÔØ!#ˆÔØ,.ˆÔ)ð ˆ	ØˆØ !˜sÐØˆØcÐcÀ$ÔB[×B`ÒB`ÑBbÔBbÐcÑcÔcÐØ@Ð@¥5¨¬Ô)>Ñ#?Ô#?Ð@Ñ@Ô@ˆØ!Ô-°Ò2Ð2�T�TÐ8bÐ8bÅUÈ4Ì:ÔK`ÑEaÔEaÐ8bÑ8bÔ8bˆ
õ  )Ð):Ñ;Ô;ð #	8ñ #	8‰OˆAˆ|à Ô&ˆEØÔ/ˆKØ'Ô4ˆLØœ
×0Ò0°¸lÑKÔKˆIð Ð!Ô! \Ñ1Ð!Ô!ð ×Ò˜UÔ4Ñ5Ô5Ð5Ø×Ò¥ k°;ÀÑ3MÑ NÔ NÑOÔOÐOØ ×'Ò'Ð(<¸RÔ(@À<Ñ(OÑPÔPÐPÝ # DÔ$5°|Ñ DÔ DˆDÔð 4=·?²?Ñ3DÔ3Dð hð hÑ/�
Ð/Ø$ ZÔ0×7Ò7Ð8LÈZÔ8XÐY[Ô8\Ð_rÑ8rÑsÔsÐsÝ03°DÔ4EÀjÔ4QÐSfÑ0gÔ0g�Ô! *Ñ-Ð-ð Ô#ð Ø”
×+Ò+¨EÔ,<¸kÈ<ÐY]ÔYiÐjkÐjkÐjkÐmnÐjnÔYoÑpÔpÐpÐpà”
×8Ò8ØÔ$ k°<ÀÈ[ñô ð ð
 Ô)ð YØ×%Ò%Ð&:¸2Ô&>ÀÑ&BÑCÔCÐCÝ+7¨.�Ô'ØFTÐUWÔFX�Ô1°%Ô2BÑCàÔ"×)Ò)¨,Ñ7Ô7Ð7Ñ7ð 	×-Ò-Ø/ØÔ/°Ô0BÐ0DÐ0DÔEð 	.ñ 	
ô 	
ð 	
ð 3°2Ô6ˆÔð ÔÐ*Ø4H×4NÒ4NÑ4PÔ4Pð ð Ñ0�
Ð0Ý$Ø#'Ô#6°zÔ#BØ)=Ø)=Ø:DÐH[Ò:[Ð:[ 4Ô#6Ð#6Ðabð	ñ ô ð ð ð ð 	Ø*.×*AÒ*AÈkÐ*AÑ*ZÔ*ZÐ'Ø8¸4Ô;TÑTˆNØ ×'Ò'­¨tÔ/BÀNÑ(SÔ(SÑTÔTÐTÐTð ˆNõ �EœLµ´ÀDÄKÐPÑPÔPˆ	ð ,5¨9°YÑ+?Ô+?ˆŒÐ'�˜Y™œÐ'Ñ(Ø1:°¸<Ñ1HÔ1HˆÔÐ-�C Ñ-Ô-Ð-Ñ.ØAJÀÐK_ÑA`ÔA`ˆÔ!Ð"=¥CÐ(<Ñ$=Ô$=Ð"=Ñ>Ø5>°Y¸~Ñ5NÔ5NˆÔÐ1�c .Ñ1Ô1Ð1Ñ2ð 1E×0JÒ0JÑ0LÔ0Lð 	qð 	qÑ,ˆJÐ,Ø1°"Ô5ˆNØ.<ˆDÔ 
Ñ+Ø ×'Ò'­¨~¸~Ñ(NÔ(NÑOÔOÐOØQZÐQZÐ[oÑQpÔQpˆDÔ% jÔ1Ð2MµCÐ8LÑ4MÔ4MÐ2MÑNÐNð Ô#ð 	FÝ%¥e¤l½%¼+ÈdÌkÐZÑZÔZˆOÝ*3°KÑ*@Ô*@ð Dð DÑ&�Ð&ØJYÈ/ÐZmÑJnÔJn�Ô(¨Ð,F­cÐ2EÑ.FÔ.FÐ,FÐ)FÑGÝ+.Ð/BÑ+CÔ+C�Ô% aÑ(Ð(ØÐ%Ý-6°zÑ-BÔ-Bð Fð FÑ)�AÐ)ØL[ÈOÐ\nÑLoÔLo�DÔ+¨AÐ/HµÐ5GÑ1HÔ1HÐ/HÐ,HÑIÝ.1Ð2DÑ.EÔ.E�DÔ(¨Ñ+Ð+ð	Fð 	Fð
 &Ð%ðFð Fr3   c                 óH   — |rt          | j        | j        ¦  «        S | j        S )zZGet the number of sequences for the current batch, accounting for padding if there is any.)r    rQ   rL   rS   )rf   r¼   s     r4   r×   z(ContinuousBatchingIOs._get_num_sequencesÎ  s*   € àð 	GÝ�tÔ(¨$Ô*EÑFÔFÐFØÔ(Ð(r3   c                 ó  ‡ — ‰ j         }‰ j        ‰ j         z   }‰                      |¬¦  «        }t          ‰ j        d|…                              d¦  «        ‰ j        d|…                              d¦  «        ‰ j        d|dz   …         ‰ j        ‰ j	        d|…         ‰ j
        ‰ j        d…d|…f         i i ‰ j        €dni g g ‰ j        ‰ j        r‰ j        dd…d|…f         ndd¬¦  «        }|r?|‰ _        ‰ j        s1‰ j        r*ˆ fd„‰ j                             ¦   «         D ¦   «         ‰ _        ‰ j        rdn‰ j        |d<   t'          ‰ j        j        ¦  «        D ]†}|r|n‰ j        |         }|d	                              ‰ j        |d|…f         ¦  «         ‰ j        dk    rd}n|r|n‰ j        |         }|d
                              ‰ j        |d|…f         ¦  «         Œ‡‰ j                             ¦   «         D ]u\  }	}
|
d|dz   …         |d         |	<   ‰ j        rdn‰ j        |	         |d         |	<   ‰ j        �4|r|n‰ j        |	         }‰ j        |	         dd|…d|…f         |d         |	<   Œvt;          ‰ j                             ¦   «         ¦  «        dk    rp|d                              ¦   «         d         |d<   |d                              ¦   «         d         |d<   ‰ j        �#|d                              ¦   «         d         |d<   |S )zÝGet model keyword arguments for the current batch, eventually padding the query dimension and KV dimensions
        if use_padding is True. The padding is only useful if we want static shapes, like when using cuda graphs.rÅ   Nr   r   F)r   r   r   r   r!   r$   r   r   r   r    r   r"   r#   r%   c                 ó^   •— i | ])}|t          ‰j        |         ‰j        j        d ¦  «        “Œ*S )i   )r   r   r"   rŽ   )rD   r”   rf   s     €r4   rÁ   z:ContinuousBatchingIOs.get_model_kwargs.<locals>.<dictcomp>ó  sE   ø€ ð %ð %ð %à"ð ¥¨DÔ,=¸jÔ,IÈ4Ì:ÔK_ÐaeÑ fÔ fð%ð %ð %r3   r   r   r    r   r   .r   )rQ   rR   r×   r   r   Ú	unsqueezer   r   r   r!   r|   r8   r   r"   rX   r#   rN   r   rˆ   rT   rU   rW   rÏ   rŒ   rV   r�   r�   rÑ   r‰   rx   Úpopitem)rf   r¼   Úq_sizeÚkv_sizeÚnum_sequencesÚkwargsrÙ   Úwrite_index_sizeÚread_index_sizer”   rÜ   Úk_lens   `           r4   Úget_model_kwargsz&ContinuousBatchingIOs.get_model_kwargsÔ  s¦  ø€ ð Ô"ˆØÔ" TÔ%6Ñ6ˆØ×/Ò/¸KÐ/ÑHÔHˆõ $Ø”n W f WÔ-×7Ò7¸Ñ:Ô:ØÔ*¨7¨F¨7Ô3×=Ò=¸aÑ@Ô@ØÔ3Ð4G°mÀaÑ6GÐ4GÔHØÔ*ØÔ.¨~°¨~Ô>Ø"&Ô"9¸$Ô:LÐ:NÐ:NÐP^ÐQ^ÐP^Ð:^Ô"_ØØØ#'Ô#6Ð#>˜4˜4ÀBØØØ”*Ø?CÔ?SÐ]˜Ô(¨¨¨¨N¨]¨NÐ):Ô;Ð;ÐY]Øð
ñ 
ô 
ˆð$ ð 	Ø &ˆDÔð Ô'ð ¨DÔ,Fð ð%ð %ð %ð %à&*Ô&7×&<Ò&<Ñ&>Ô&>ð%ñ %ô %�Ô!ð '+Ô&:Ð!Q  ÀÔ@Qˆˆ~Ñõ �t”zÔ,Ñ-Ô-ð 	Vð 	VˆAØ)4ÐR˜v˜v¸$Ô:OÐPQÔ:RÐØ�=Ô!×(Ò(¨Ô)AÀ!ÐEVÐFVÐEVÐBVÔ)WÑXÔXÐXàÔ 1Ò$Ð$Ø"#��à-8Ð"U ' '¸dÔ>RÐSTÔ>U�Ø�<Ô ×'Ò'¨Ô(?ÀÐCSÀOÐCSÐ@SÔ(TÑUÔUÐUÐUð &*Ô%>×%DÒ%DÑ%FÔ%Fð 	mð 	mÑ!ˆJ˜	Ø2;Ð<O¸mÈaÑ>OÐ<OÔ2PˆF�?Ô# JÑ/Ø6:Ô6JÐ1m°°ÐPTÔPaÐblÔPmˆF�>Ô" :Ñ.ØÔ"Ð.Ø#.ÐS˜˜°DÔ4GÈ
Ô4S�Ø7;Ô7JÈ:Ô7VÐWZÐ\cÐ]cÐ\cÐekÐfkÐekÐWkÔ7l�Ð'Ô(¨Ñ4øõ ˆtÔ(×-Ò-Ñ/Ô/Ñ0Ô0°AÒ5Ð5Ø&,¨_Ô&=×&EÒ&EÑ&GÔ&GÈÔ&JˆF�?Ñ#Ø%+¨NÔ%;×%CÒ%CÑ%EÔ%EÀaÔ%HˆF�>Ñ"ØÔ"Ð.Ø+1Ð2BÔ+C×+KÒ+KÑ+MÔ+MÈaÔ+P�Ð'Ñ(àˆr3   c                 ó*   — | j         | j        | j        fS )a.  Returns the tensors used inside the generation step that are not inputs to the model forward pass. In
        synchronous batching, there is no carry over, so the only tensor that will be used is output_ids, but we still
        return 3 tensors to have the same interface as when using async batching.)r€   r„   r¨   s    r4   Úget_cb_kwargsz#ContinuousBatchingIOs.get_cb_kwargs  s   € ð Ô" D¤O°T´_ÐDÐDr3   .c                 óp   — | j         r| j        fS | j        | j        g| j                             ¦   «         ¢R S r®   )rX   rQ   rR   r   Úvaluesr¨   s    r4   Ú_get_graph_keyz$ContinuousBatchingIOs._get_graph_key  sA   € àÔð 	(ØÔ%Ð'Ð'àÔ! 4Ô#3ÐQ°dÔ6G×6NÒ6NÑ6PÔ6PÐQÐQÐQr3   Ú Úprefixc                 ó˜   — |                       ¦   «         }| j                             |¦  «        }|€t          j        |› d|›�¦  «         |S )NzCreating graph for key = )r÷   r[   Ú	get_graphr   Úinfo)rf   rù   ÚkeyÚgraphs       r4   rû   zContinuousBatchingIOs.get_graph%  sP   € Ø×!Ò!Ñ#Ô#ˆØ”×%Ò% cÑ*Ô*ˆàˆ=ÝŒK˜6Ð>Ð>°cÐ>Ð>Ñ?Ô?Ð?Øˆr3   rþ   c                 ó’   — |                       ¦   «         }| j                             ||¦  «         t          j        d|›�¦  «         d S )NzSetting graph for key = )r÷   r[   Ú	set_graphr   rü   )rf   rþ   rý   s      r4   r   zContinuousBatchingIOs.set_graph-  sJ   € Ø×!Ò!Ñ#Ô#ˆØŒ×Ò˜c 5Ñ)Ô)Ð)ÝŒÐ1¨Ð1Ð1Ñ2Ô2Ð2Ð2Ð2r3   ©F©r>   N)rø   )+r&   r'   r(   r)   r8   r/   r,   r   r   r   r*   r;   rk   r   rg   r`   rJ   rc   r1   r�   Úno_gradra   r©   Útupler+   r-   r.   r«   r¯   r±   r0   r   Úfloatr¹   rå   r×   r   rò   rô   r÷   Ú	CUDAGraphrû   r   r2   r3   r4   r6   r6   F   sª  € € € € € € ðð ð
 €M�3ÐÐÑð*gà"ð*gð !ð*gð %=ð	*gð
 ”ð*gð ”[ð*gð ?ð*gð 
ð*gð *gð *gð *gðXW
Ð5Zð W
Ð_cð W
ð W
ð W
ð W
ðv _dðwð wØ,ðwØ6;´jÔ6GðwØW[ðwà	ðwð wð wð wð@ €U„]�_„_ð(Wð (W°ð (WÀð (Wð (Wð (Wñ „_ð(WðT.ð .ð .ð .ðD¨¨e¬l¸DÀÀeÄlÐARÔ<SÐ.SÔ(Tð Dð Dð Dð DðØœðØ7<´|ðØV[ÔVbðà	ðð ð ð ð
.ð .ð .ð .ð< e¨DÐ1CÔ,DÀdÈ3ÄiÐQUÐV[ÔQ\Ð_cÑQcÐ,cÔ&dð <ð <ð <ð <ðMFàÐ 2Ô3ðMFð AðMFð #ð	MFð
 ðMFð ðMFð ðMFð 
ðMFð MFð MFð MFð^)¨dð )°sð )ð )ð )ð )ðBð B¨Dð BÐ=Oð Bð Bð Bð BðHE˜u U¤\°5´<ÀÄÐ%MÔNð Eð Eð Eð EðR  c¨3 h¤ð Rð Rð Rð Rðð  ð ¨U¬ZÔ-AÀDÑ-Hð ð ð ð ð3˜uœzÔ3ð 3¸ð 3ð 3ð 3ð 3ð 3ð 3r3   r6   c                   óœ   — e Zd Zdedededej        dej        de	ddfd	„Z
dd
„Zdej        j        ddfd„Zdej        j        dz  ddfd„ZdS )ÚHostDeviceIOPairr"   r9   r:   r;   r<   r=   r>   Nc                 ó$  — t          |||t          j        d¦  «        ||¬¦  «        | _        t          ||||||¬¦  «        | _        t          j                             ¦   «         rt          j                             ¦   «         nd | _        t          j                             ¦   «         rt          j                             ¦   «         nd | _	        t          j                             ¦   «         rt          j                             ¦   «         nd | _
        d S )Nri   ©r"   r9   r:   r;   r<   r=   )r6   r*   r;   Úhost_ioÚ	device_iorJ   Úis_availableÚEventÚh2d_overÚcompute_overÚd2h_overre   s          r4   rg   zHostDeviceIOPair.__init__4  sï   € õ -ØØØ'AÝ”< Ñ&Ô&Ø#Ø+ð
ñ 
ô 
ˆŒõ /ØØØ'AØØ#Ø+ð
ñ 
ô 
ˆŒõ /4¬j×.EÒ.EÑ.GÔ.GÐQ�œ
×(Ò(Ñ*Ô*Ð*ÈTˆŒÝ27´*×2IÒ2IÑ2KÔ2KÐU�EœJ×,Ò,Ñ.Ô.Ð.ÐQUˆÔÝ.3¬j×.EÒ.EÑ.GÔ.GÐQ�œ
×(Ò(Ñ*Ô*Ð*ÈTˆŒˆˆr3   c                 óÄ   — | j                              ¦   «          | j                             ¦   «          | j        | j        | j        fD ]}|�|                     ¦   «          Œd S r®   )r  r©   r  r  r  r  r§   )rf   Úevents     r4   r©   zHostDeviceIOPair.resetS  sj   € ØŒ×ÒÑÔÐØŒ×ÒÑÔÐØ”m TÔ%6¸¼ÐFð 	$ð 	$ˆEØÐ Ø×!Ò!Ñ#Ô#Ð#øð	$ð 	$r3   r—   c                 óJ   — | j                              | j        |d¬¦  «         d S )NT)r—   r˜   )r  r�   r  )rf   r—   s     r4   Útransfer_inputs_h2dz$HostDeviceIOPair.transfer_inputs_h2dZ  s(   € ØŒ×%Ò% d¤n¸VÐRVÐ%ÑWÔWÐWÐWÐWr3   c                 óð   — |�t           j                             |¦  «        nt          ¦   «         }|5  | j        j                             | j        j        d¬¦  «         d d d ¦  «         d S # 1 swxY w Y   d S )NTrš   )r*   rJ   r—   r   r  r„   r›   r  )rf   r—   rœ   s      r4   Útransfer_outputs_d2hz%HostDeviceIOPair.transfer_outputs_d2h]  sÇ   € Ø4:Ð4F•u”z×(Ò(¨Ñ0Ô0Ð0ÍKÉMÌMˆØð 	Xð 	XØŒLÔ#×)Ò)¨$¬.Ô*CÐRVÐ)ÑWÔWÐWð	Xð 	Xð 	Xñ 	Xô 	Xð 	Xð 	Xð 	Xð 	Xð 	Xð 	Xð 	Xøøøð 	Xð 	Xð 	Xð 	Xð 	Xð 	Xs   ²,A+Á+A/Á2A/r  )r&   r'   r(   r   r   r   r*   r;   rk   r   rg   r©   rJ   rc   r  r  r2   r3   r4   r  r  3  sð   € € € € € ðRà"ðRð !ðRð %=ð	Rð
 ”ðRð ”[ðRð ?ðRð 
ðRð Rð Rð Rð>$ð $ð $ð $ðX¨%¬*Ô*;ð XÀð Xð Xð Xð XðX¨5¬:Ô+<¸tÑ+Cð XÈð Xð Xð Xð Xð Xð Xr3   r  c                   ó@  — e Zd ZdZdedededej        dej	        de
dd	fd
„Zdeej        eeej        f         f         fd„Zdee         de
dededededd	fd„Zdej        fd„Zd$dedefd„Zdeej        ej        ej        f         fd„Zdej        dej        dej        dd	fd„Zedej        fd„¦   «         Zdej        j        d	z  fd„Zdej        j        dd	fd„Z edefd„¦   «         Z!d%d „Z"d%d!„Z#deee         ee         ee$         d	z  f         fd"„Z%d%d#„Z&d	S )&ÚContinuousBatchingAsyncIOsuÿ  A class to handle the inputs and outputs for the asynchronous API. It uses two IO pairs to avoid race conditions
    between the two batches, which means twice as more VRAM is used for static input tensors and CUDA graph. If your GPU
    is large enough or you want to generate long sequences, this is a good trade-off to make.

    Asynchronous batching works by creating two pairs of host - device inputs and outputs:

                                    inputs
                      â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”� â”€â”€â”€â”€â”€â”€â”€â”€â–º â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”�
    IO pair object:   â”‚ Host IOs â”‚           â”‚ Device IOs â”‚       (for a CUDA system, Host = CPU and Device = GPU)
                      â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜ â—„â”€â”€â”€â”€â”€â”€â”€â”€ â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜
                                    outputs

    Each pair is separate from the other. This means that each pairs has its own CUDA graphs set, because CUDA graphs
    need to have static addresses for input tensors. To have a unique set of CUDA graph, we would need to copy the input
    tensors to a third device-side buffer. This could limit the memory cost of CUDA graphs but would slow down the
    forward pass.
    But the CUDA streams orchestrating the transfer from host to device (H2D) and device to host (D2H) are the same for
    both pairs. Same for the compute stream.
    The order of steps in async batching looks like this (for 3 batches of compute):

         â”‚ â”Œâ”€â”€â”€â”€â”¬â”€â”€â”€â”€â”�                  â”Œâ”€â”€â”€â”€â”¬â”€â”€â”€â”€â”�     â”Œâ”€â”€â”€â”€â”¬â”€â”€â”€â”€â”�       â”Œâ”€â”€â”€â”€â”�          â”Œâ”€â”€â”€â”€â”�
    CPU  â”‚ â”‚PR 0â”‚PR 1â”‚                  â”‚UP 0â”‚PR 2â”‚     â”‚UP 1â”‚PR 3â”‚       â”‚UP 2â”‚          â”‚UP 3â”‚
         â”‚ â””â”€â”€â”€â”€â”¼â”€â”€â”€â”¬â”´â”€â”€â”�               â””â”€â”€â”€â”€â”´â”€â”€â”€â”€â”¼â”€â”€â”€â”� â””â”€â”€â”€â”€â”´â”€â”€â”€â”€â”¼â”€â”€â”€â”�   â””â”€â”€â”€â”€â”˜          â””â”€â”€â”€â”€â”˜
    H2D  â”‚      â”‚0->â”‚1->â”‚               Â¦         â”‚2->â”‚ Â¦         â”‚3->â”‚   Â¦               Â¦
         â”‚      â””â”€â”€â”€â”¼â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”¬â”€â”¼â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”¼â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”�   Â¦
    GPU  â”‚          â”‚   COMPUTE 0   â”‚   COMPUTE 1   â”‚â–ˆâ”‚   COMPUTE 2   â”‚   COMPUTE 3   â”‚   Â¦
         â”‚          â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¼â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¼â”€â”´â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¼â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¼â”€â”€â”€â”¤
    D2H  â”‚                          â”‚0<-â”‚           â”‚1<-â”‚             â”‚2<-â”‚           â”‚3<-â”‚
         â”‚                          â””â”€â”€â”€â”˜           â””â”€â”€â”€â”˜             â””â”€â”€â”€â”˜           â””â”€â”€â”€â”˜

    with: - CPU: actions happening on the CPU (host-side)
          - GPU: actions happening on the GPU (device-side)
          - H2D: host to device transfer
          - D2H: device to host transfer
    and:
          - PR N: preparation of batch N
          - ->N: host to device transfer of batch N
          - COMPUTE N: compute step for batch N
          - <-N: device to host transfer of batch N
          - UP N: update of batch N

    You can see that the GPU is almost always busy, except where the â–ˆ is.
    Proper ordering of steps is ensured through the use of CUDA events and streams.
    r"   r9   r:   r;   r<   r=   r>   Nc                 ó°  ‡‡‡‡‡‡— t           j                             ¦   «         s.t          dt           j                             ¦   «         ›�¦  «        ‚d| _        ˆˆˆˆˆˆfd„t          d¦  «        D ¦   «         | _        t           j                             ‰¬¦  «        | _        t           j                             ‰¬¦  «        | _	        t           j                             ‰¬¦  «        | _
        d | j        d         j        _
        d | j        d         j        _
        d | j        d         j        _
        d | j        d         j        _
        ‰j        | _        d S )Nz>Async batching requires CUDA, but torch.cuda.is_available() = r   c           
      ó:   •— g | ]}t          ‰‰‰‰‰‰¬ ¦  «        ‘ŒS )r
  )r  )rD   rE   r"   r9   r:   r;   r=   r<   s     €€€€€€r4   rF   z7ContinuousBatchingAsyncIOs.__init__.<locals>.<listcomp>Ÿ  sL   ø€ ð 

ð 

ð 

ð õ ØØØ+EØØ'Ø /ðñ ô ð

ð 

ð 

r3   rn   rK   r   )r*   rJ   r  ÚRuntimeErrorÚcurrent_pairrT   Úio_pairsrc   Ú
h2d_streamÚ
d2h_streamrd   r  r  ru   re   s    ``````r4   rg   z#ContinuousBatchingAsyncIOs.__init__‘  sC  øøøøøø€ õ Œz×&Ò&Ñ(Ô(ð 	dÝÐbÅEÄJ×D[ÒD[ÑD]ÔD]ÐbÐbÑcÔcÐcàˆÔð

ð 

ð 

ð 

ð 

ð 

ð 

ð 

ð 

õ ˜1‘X”Xð

ñ 

ô 

ˆŒõ  œ*×+Ò+°6Ð+Ñ:Ô:ˆŒÝœ*×+Ò+°6Ð+Ñ:Ô:ˆŒÝ#œj×/Ò/°vÐ/Ñ>Ô>ˆÔà26ˆŒ�aÔÔ Ô/Ø48ˆŒ�aÔÔ"Ô1Ø26ˆŒ�aÔÔ Ô/Ø48ˆŒ�aÔÔ"Ô1à %Ô 6ˆÔÐÐr3   c                 óT   — | j         | j                 j                             ¦   «         S r®   )r  r  r  r«   r¨   s    r4   r«   z1ContinuousBatchingAsyncIOs.get_cumulative_seqlens·  s!   € ØŒ}˜TÔ.Ô/Ô7×NÒNÑPÔPÐPr3   rY   rº   r»   rQ   rR   r¼   c                 óÊ   — | j         | j                 }|j                             ||||||¦  «         |j        j                             |                      ¦   «         ¦  «         d S r®   )r  r  r  rå   r€   r›   Úinfer_carry_over_ids)rf   rY   rº   r»   rQ   rR   r¼   Úio_pairs           r4   rå   z0ContinuousBatchingAsyncIOs.prepare_batch_tensors»  sk   € ð ”- Ô 1Ô2ˆØŒ×-Ò-ØÐ0Ð2FÈÐVaÐcnñ	
ô 	
ð 	
ð 	ŒÔ&×,Ò,¨T×-FÒ-FÑ-HÔ-HÑIÔIÐIÐIÐIr3   c                 óz  — | j         | j                 j        j        }| j         d| j        z
           j        j        }d„ t	          | j        ¦  «        D ¦   «         }t          |                     ¦   «         ¦  «        D ]!\  }}|                     |¦  «        }|�|||<   Œ"t          j
        |t          j        ¬¦  «        S )a�  Infers the ids of the tokens to carry over from batch N to batch N+1. In asynchronous batching mode, we can
        schedule a request for batch N+1 without knowing the token predicted for that request in batch N. For that
        reason, we might need to carry over tokens just predicted in batch N before launching the forward pass of batch
        N+1. This method computes the ids of the tokens to carry over.r   c                 ó   — g | ]}d ‘ŒS )rŸ   r2   rC   s     r4   rF   zCContinuousBatchingAsyncIOs.infer_carry_over_ids.<locals>.<listcomp>Ñ  s   € ÐCÐCÐC ˜"ÐCÐCÐCr3   Nr³   )r  r  r  rZ   rT   ru   rÈ   rˆ   Úgetr*   rØ   r{   )rf   Ú!next_req_id_to_new_token_positionÚ!prev_req_id_to_new_token_positionr€   rÙ   Úreq_idÚnew_token_positions          r4   r#  z/ContinuousBatchingAsyncIOs.infer_carry_over_idsÊ  sº   € ð
 -1¬M¸$Ô:KÔ,LÔ,TÔ,qÐ)Ø,0¬M¸!¸dÔ>OÑ:OÔ,PÔ,XÔ,uÐ)ØCÐC¥e¨DÔ,AÑ&BÔ&BÐCÑCÔCˆõ #Ð#D×#IÒ#IÑ#KÔ#KÑLÔLð 	7ð 	7‰IˆAˆvØ!B×!FÒ!FÀvÑ!NÔ!NÐØ!Ð-Ø56�Ð1Ñ2øÝŒ|˜Nµ%´+Ð>Ñ>Ô>Ð>r3   Fc                 ó  — | j         | j                 }|                     | j        ¦  «         | j                             |j        ¦  «         | j                             |j        ¦  «         |j         	                    |¬¦  «        S )NrÅ   )
r  r  r  r  Úrecord_eventr  rd   Ú
wait_eventr  rò   )rf   r¼   r$  s      r4   rò   z+ContinuousBatchingAsyncIOs.get_model_kwargsÞ  st   € Ø”- Ô 1Ô2ˆØ×#Ò# D¤OÑ4Ô4Ð4ØŒ×$Ò$ WÔ%5Ñ6Ô6Ð6ØÔ×&Ò& wÔ'7Ñ8Ô8Ð8ØÔ ×1Ò1¸kÐ1ÑJÔJÐJr3   c                 ó–   — | j         | j                 }| j         d| j        z
           }|j        j        |j        j        |j        j        fS )a  Returns the tensors used inside the generation step that are not inputs to the model forward pass. Those
        tensors could be retrieved using this object, but it would trigger a recompile if using torch.compile. They are:
        - output_ids: the output ids of the current batch
        - prev_output_ids: the output ids of the previous batch, required to carry over outputs tokens of the previous
            batch to the input tokens of the next batch.
        - carry_over_ids: a mask representing how to carry over tokens.
        r   )r  r  r  r€   r„   )rf   r  Úprevious_pairs      r4   rô   z(ContinuousBatchingAsyncIOs.get_cb_kwargså  sL   € ð ”} TÔ%6Ô7ˆØœ a¨$Ô*;Ñ&;Ô<ˆàÔ"Ô1ØÔ#Ô.ØÔ"Ô-ð
ð 	
r3   r   r€   r¬   c                 óì   — |d|f         }|dk                          ¦   «         }|d|                     d¦  «        …         }|d|                     d¦  «        …         }||z  |d         d|z
  z  z   |d<   dS )a  As explained in the infer_carry_over_ids method, we might need to carry over tokens just predicted in batch N
        before launching the forward pass of batch N+1. This method performs the carry over, and is recorded in CUDA
        graphs if they are enabled.r   rŸ   Nr   )r/   rt   )rf   r   r€   r¬   Úcarried_over_idsÚcarried_over_masks         r4   r¯   z,ContinuousBatchingAsyncIOs.carry_over_tokensö  sŒ   € ð +¨1¨nÐ+<Ô=ÐØ+¨rÒ1×6Ò6Ñ8Ô8Ðà+Ð,?¨i¯nªn¸QÑ.?Ô.?Ð,?Ô@ÐØ-Ð.A°	·²¸qÑ0AÔ0AÐ.AÔBÐà'Ð*;Ñ;¸iÈ¼lÈaÐRcÑNcÑ>dÑdˆ	�!‰ˆˆr3   c                 ó:   — | j         | j                 j        j        S r®   )r  r  r  r„   r¨   s    r4   r„   z%ContinuousBatchingAsyncIOs.output_ids	  s   € ð Œ}˜TÔ.Ô/Ô9ÔDÐDr3   c                 ón   — d| j         › d�}| j        | j                  j                             |¬¦  «        S )Nz(IO ú))rù   )r  r  r  rû   )rf   rù   s     r4   rû   z$ContinuousBatchingAsyncIOs.get_graph  s9   € Ø,˜Ô)Ð,Ð,Ð,ˆØŒ}˜TÔ.Ô/Ô9×CÒCÈ6ÐCÑRÔRÐRr3   rþ   c                 óZ   — | j         | j                 j                             |¦  «         d S r®   )r  r  r  r   )rf   rþ   s     r4   r   z$ContinuousBatchingAsyncIOs.set_graph  s)   € ØŒ�dÔ'Ô(Ô2×<Ò<¸UÑCÔCÐCÐCÐCr3   c                 ó:   — | j         | j                 j        j        S r®   )r  r  r  rX   r¨   s    r4   rX   z*ContinuousBatchingAsyncIOs.use_block_table  s   € àŒ}˜TÔ.Ô/Ô7ÔGÐGr3   c                 ó@  — | j         | j                 }| j                             |j        ¦  «         | j                             |j        ¦  «         |                     | j        ¦  «         | j                             |j        ¦  «         |  	                    ¦   «          d S r®   )
r  r  rd   r-  r  r   r.  r  r  Úswap_io_pairs©rf   r$  s     r4   r±   z2ContinuousBatchingAsyncIOs.retrieve_device_outputs  s‹   € Ø”- Ô 1Ô2ˆàÔ×(Ò(¨Ô)=Ñ>Ô>Ð>ØŒ×"Ò" 7Ô#7Ñ8Ô8Ð8à×$Ò$ T¤_Ñ5Ô5Ð5ØŒ×$Ò$ WÔ%5Ñ6Ô6Ð6à×ÒÑÔÐÐÐr3   c                 ó$   — d| j         z
  | _         dS )zeSwitch to the other IO pair so the next batch reads from / writes into a fresh set of static buffers.r   N)r  r¨   s    r4   r:  z(ContinuousBatchingAsyncIOs.swap_io_pairs%  s   € à Ô 1Ñ1ˆÔÐÐr3   c                 óŠ   — | j         | j                 }|j                             ¦   «          |j                             ¦   «         S r®   )r  r  r  r§   r  r¹   r;  s     r4   r¹   z/ContinuousBatchingAsyncIOs.prepare_batch_update*  s:   € Ø”- Ô 1Ô2ˆØÔ×$Ò$Ñ&Ô&Ð&ØŒ×3Ò3Ñ5Ô5Ð5r3   c                 óæ   — d| _         | j        D ]}|                     ¦   «          Œ| j                             ¦   «          | j                             ¦   «          | j                             ¦   «          dS )zWReset all state for a new generation session. Used in persistent mode between sessions.r   N)r  r  r©   r  r§   r   rd   r;  s     r4   r©   z ContinuousBatchingAsyncIOs.reset/  sm   € àˆÔØ”}ð 	ð 	ˆGØ�MŠM‰OŒOˆOˆOØŒ×#Ò#Ñ%Ô%Ð%ØŒ×#Ò#Ñ%Ô%Ð%ØÔ×'Ò'Ñ)Ô)Ð)Ð)Ð)r3   r  r  )'r&   r'   r(   r)   r   r   r   r*   r;   rk   r   rg   r  r+   r-   r.   r«   r0   r   r1   r/   rå   r#  r   rò   rô   r¯   Úpropertyr„   rJ   r  rû   r   rX   r±   r:  r  r¹   r©   r2   r3   r4   r  r  c  s
  € € € € € ð+ð +ðZ#7à"ð#7ð !ð#7ð %=ð	#7ð
 ”ð#7ð ”[ð#7ð ?ð#7ð 
ð#7ð #7ð #7ð #7ðLQ¨¨e¬l¸DÀÀeÄlÐARÔ<SÐ.SÔ(Tð Qð Qð Qð QðJàÐ 2Ô3ðJð AðJð #ð	Jð
 ðJð ðJð ðJð 
ðJð Jð Jð Jð? e¤lð ?ð ?ð ?ð ?ð(Kð K¨Dð KÐ=Oð Kð Kð Kð Kð
˜u U¤\°5´<ÀÄÐ%MÔNð 
ð 
ð 
ð 
ð"eà”<ðeð œðeð œð	eð
 
ðeð eð eð eð& ðE˜EœLð Eð Eð Eñ „XðEðS˜5œ:Ô/°$Ñ6ð Sð Sð Sð SðD˜uœzÔ3ð D¸ð Dð Dð Dð Dð ðH ð Hð Hð Hñ „XðHð	ð 	ð 	ð 	ð2ð 2ð 2ð 2ð
6 e¨DÐ1CÔ,DÀdÈ3ÄiÐQUÐV[ÔQ\Ð_cÑQcÐ,cÔ&dð 6ð 6ð 6ð 6ð
*ð *ð *ð *ð *ð *r3   r  ) Ú
contextlibr   Ú	functoolsr   Ú	itertoolsr   Útypingr   r*   Ú transformers.configuration_utilsr   Ú+transformers.generation.configuration_utilsr   Úutilsr
   r"   r   Úcb_logits_processorsr   Úrequestsr   r   r   r   r   r   r   r   r   r6   r  r  r2   r3   r4   ú<module>rI     sÃ  ðð #Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à €€€à =Ð =Ð =Ð =Ð =Ð =Ø PÐ PÐ PÐ PÐ PÐ Pà *Ð *Ð *Ð *Ð *Ð *Ø &Ð &Ð &Ð &Ð &Ð &Ø GÐ GÐ GÐ GÐ GÐ GØ >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ø jÐ jÐ jÐ jÐ jÐ jÐ jÐ jÐ jÐ jÐ jÐ jÐ jÐ jð$ð $ð $ð $ð $˜ñ $ô $ð $ðNj3ð j3ð j3ð j3ð j3ñ j3ô j3ð j3ðZ-Xð -Xð -Xð -Xð -Xñ -Xô -Xð -Xð`S*ð S*ð S*ð S*ð S*ñ S*ô S*ð S*ð S*ð S*r3   