
    Wi                        d dl 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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 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" ddl#m$Z$m%Z%m&Z&m'Z' ddl(m)Z)m*Z*m+Z+ 	 dZ,dZ-de.de.de.de.fdZ/ G d dej`                        Z1 e        G d d             Z2 e        G d  d!             Z3 G d" d#      Z4y)$    N)abstractmethod)	Generator)contextmanager)ceil)perf_counter)nn)tqdm)logging_redirect_tqdm   )PretrainedConfig)CompileConfigGenerationConfig)LogitsProcessorList)logging)ContinuousBatchProcessorMetricsattach_tracertraced   )PagedAttentionCache)ContinuousBatchingIOsattn_mask_is_needed)GenerationOutputRequestStateRequestStatuslogger)SCHEDULER_MAPPINGFIFOScheduler	Scheduler      size	max_valuenb_intervalsreturnc                 b    ||z  }|dk(  r|S | dkD  rt        | |z        |z  n|}t        ||      S )zRReturn the smallest multiple of (max_value) // (nb_intervals) greater than (size).r   )r   min)r!   r"   r#   interval_sizepaddeds        /home/sietch6/trending-topics-pipeline/venv/lib/python3.12/site-packages/transformers/generation/continuous_batching/continuous_api.pypad_by_intervalsr*   >   sC    -M;?!8T$&'-7Fvy!!    c                       e Zd ZU eed<   ej                  ed<   ej                  ed<   ede	ddfd       Z
ededefd	       Zy)
ProtoPretrainedModelconfigdtypedeviceattn_implementationr$   Nc                      y N )selfr1   s     r)   set_attn_implementationz,ProtoPretrainedModel.set_attn_implementationM       r+   generation_configc                      y r3   r4   )r5   r8   s     r)   _get_logits_processorz*ProtoPretrainedModel._get_logits_processorQ   r7   r+   )__name__
__module____qualname__r   __annotations__torchr/   r0   r   strr6   r   r   r:   r4   r+   r)   r-   r-   H   s`    ;;LL3 4   7G L_  r+   r-   c                      e Zd Zdedededej                  dej                  dej                  de
j                  de
j                  d	ed
ededededdfdZdefdZed,d       Zedededdfd       Zd,dZedefd       Zededdfd       Zed,d       Zedefd       Zed        Zededdfd       Ze e
j>                         de jB                  de"deddfd               Z#ede jB                  d!e$de"deddf
d"       Z% ed#$      de jB                  d!e$de
jL                  fd%       Z' ed&$      d!e$d'e
jL                  de"de
jL                  fd(       Z( ed)$      d*e
jL                  d!e$deddfd+       Z)y)-ContinuousBatchProcessorcacher.   r8   input_queueoutput_queue
stop_eventmodel_devicemodel_dtype	schedulermanual_evictionuse_cuda_graphq_padding_intervalskv_padding_intervalsr$   Nc                    || _         || _        || _        || _        || _        || _        || _        || _        |	| _        |
| _	        t        |dd      dn|j                  | _        g | _        || _        || _        |ri nd| _        t        |dd      | _        d| _        |xs' | j                   duxr | j                   j$                   | _        |j(                  | _        t+        |j(                        | _        t/        ||||      | _        y)a  Initialize the continuous batch processor.

        Args:
            cache: A [`PagedAttentionCache`] object
            config: The model configuration
            generation_config: The generation configuration
            input_queue: Queue for incoming requests
            output_queue: Queue for outgoing results
            stop_event: Event to signal processing should stop
            model_device: Device for model inputs/outputs
            model_dtype: Data type for model inputs/outputs
            scheduler: The [`Scheduler`] to use
            manual_eviction: Whether to manually evict blocks from the cache
            use_cuda_graph: Whether to use cuda graphs or not during CB. Check the docstring at the top of the file for
                more details.
        sliding_windowNr   compile_configF)rC   r.   r8   rD   rE   rF   rG   rH   rI   rJ   getattrrO   requests_in_batchrL   rM   _graphsrP   '_forward_process_and_sample_is_compileddynamic_pad_inputsmax_batch_tokensr   metricsr   inputs_and_outputs)r5   rC   r.   r8   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   s                 r)   __init__z!ContinuousBatchProcessor.__init__Y   s   @ 
!2&($(&". $+63CT#J#RaX^XmXm57#6 $8!Q_2ei4;<MO_ae4f7<4)rd.A.A.M.qVZViViVqVqRq !& 6 66u7M7MN #8v|U`"ar+   c           	          d| j                    d| j                   d| j                  j                   d| j                  j                   d	| j
                  j                         j                         z   S )Nz%ContinuousBatchProcessor(input_queue=z, output_queue=z, active_requests=z, waiting_requests=))rD   rE   rI   active_requestswaiting_requestsrY   get_model_kwargs__repr__r5   s    r)   r`   z!ContinuousBatchProcessor.__repr__   sx    3D4D4D3E_UYUfUfTg h#~~==>>QRVR`R`RqRqQrrsu%%668AACD	
r+   c                    | j                   j                         sU	 | j                   j                         }|8| j                  j	                  |       | j                   j                         sTyy# t
        j                  $ r Y yt        $ rQ}t        j                  d| d       t               j                  d      }|| j                  ||       Y d}~d}~ww xY w)z?Pull new requests from the input queue and add to waiting list.NzError processing new request: Texc_infostate)rD   empty
get_nowaitrI   add_waiting_requestqueueEmpty	Exceptionr   errorlocalsget_handle_request_error)r5   re   es      r)   _get_new_requestsz*ContinuousBatchProcessor._get_new_requests   s     ""((*9((335=2259 ""((* ;;  9=aSADQ&,hll7&;$..q%8	9s#   A1 A1 1CCACCrl   re   c                    t         j                  |_        t        |      |_        t        |j                  t              r+| j                  j                  |j                        |_	        ng |_	        | j                  j                  |j                  |j                         | j                  j                  |j                                y)z(Handle general request processing error.N)r   FAILEDstatusr@   rl   
isinstance
request_idrI   !get_active_request_static_outputsgenerated_tokensrX   record_request_completioncreated_timerE   putto_generation_output)r5   rl   re   s      r)   ro   z.ContinuousBatchProcessor._handle_request_error   s     %++%j e&&,%)^^%U%UV[VfVf%gE"%'E"..u/A/A5CSCSTe88:;r+   c           
      .   | j                   j                  r(| j                   j                  j                         \  }}n9t	        t        | j                   j                  j                                     \  }}t        j                  d| dt        |j                         dt        |j                         d       |j                         }| j                   j                  |d       | j                   j                  |       d| j                   _        y)a  Soft resets one active request by removing it from active requests and re-adding it to the waiting queue.

        The generated tokens are kept as part of the new request's initial prompt. When `block_new_requests` is False,
        the oldest request is offloaded; when True, the newest request is offloaded. This method also sets
        `block_new_requests` to True to prevent infinite loops of offloading and re-scheduling requests.
        zSoft resetting request z with z initial tokens and z generated tokensTevict_from_cacheN)rI   block_new_requestsr]   popitemnextiteritemsr   infoleninitial_tokensrx   !create_equivalent_initial_requestfinish_requestrh   )r5   rv   re   	new_states       r)   soft_reset_one_requestz/ContinuousBatchProcessor.soft_reset_one_request   s     >>,, $ > > F F HJ $T$..*H*H*N*N*P%Q RJ%j\E<P<P8Q7RRf5))*++<>	

 ;;=	%%j4%H**95 -1)r+   c                    | j                          | j                  j                          | j                  j                         sy| j                  j                  t        | j                  j                        t        | j                  j                               | j                  j                  | j                  | j                  j                        }|>t        | j                  j                        dkD  r| j                          yt        d      || _        | j                  sy| j                  j!                  | j                         | j"                  j%                  |       | j                  j'                  | j                         t)        j*                  t,        j.                        r| j"                  j0                  }| j"                  j2                  t5        fdD              }t)        j6                  dt        | j                         dt        | j                  j                         dt        | j                  j                         d|d	    d
| d| j                  j9                                 y)zPrepare tensors and metadata for the next model forward pass. Returns True if there are requests to process,
        False otherwise.Fr   z=No requests can be scheduled and no request can be offloaded.c              3   .   K   | ]  }|   d      yw)Nr4   ).0
layer_typecumulative_seqlens_ks     r)   	<genexpr>z>ContinuousBatchProcessor.prepare_next_batch.<locals>.<genexpr>   s     aj)*5b9a   zScheduled: z, Waiting: z
, Active: z	. cum Q: r   z
. cum KV: z, free blocks: T)rq   rI   clear_cancelled_requestshas_pending_requestsrX   record_queue_metricsr   r]   r^   schedule_batchrW   rC   	num_pagesr   RuntimeErrorrR   record_batch_metricsrY   prepare_batch_tensorsrecord_kv_cache_memory_metricsr   isEnabledForr   DEBUGcumulative_seqlens_qr   maxdebugget_num_free_blocks)r5   rR   r   ckr   s       @r)   prepare_next_batchz+ContinuousBatchProcessor.prepare_next_batch   s    	 //1~~224))#dnn.L.L*MsSWSaSaSrSrOst !NN99$:O:OQUQ[Q[QeQef $4>>112Q6++-"#bcc!2%% 	))$*@*@A556GH 	33DJJ?w}}-#'#:#:#O#O #'#:#:#O#O aL`aaBLLc$"8"89:+c$..JiJiFjEk lt~~==>?yI]^`IaHb c$odjj.L.L.N-OQ
 r+   c                     |j                   s|j                  t        j                  k(  r*| j                  j                  |j                                yy)zCSend output to the queue based on streaming mode and request state.N)	streamingrt   r   FINISHEDrE   r{   r|   )r5   re   s     r)   _maybe_send_outputz+ContinuousBatchProcessor._maybe_send_output  s?     ??ellm.D.DD!!%"<"<">? Er+   c                 N   | j                   j                  dt        | j                         j	                         }d}| j                  D ]  }t        |j
                        dk(  r|j                         dk(  rE| j                  j                  |j                  |j                         t        j                  |_        ||   }|g|_        |dz  }|j                  |      }| j                   j#                  |       |rs| j                  j%                  |j                  |j                         | j&                  j)                  |j                  | j*                          d| j&                  _        | j/                  |       ;|j                  t        j0                  k(  r2| j                   j#                  |       t        j2                  |_        t5        d|j                   d|j                          g g }}| j&                  j6                  r| j&                  j6                  j9                         }|j:                  }	d|_        t=        |	      D 
cg c]  }
|j                   d|
  }}
|D ]*  }|j?                  |      | j&                  j@                  |<   , | j                   jC                  |j                  |      \  }}|jE                  |       |jE                  |       | j&                  j6                  r|r| j                   jG                  ||       yyc c}
w )	z0Update request states based on generated tokens.Nr   r   r~   FzRequest z is in an unexpected state: z__child#)$rY   
output_idsr   rR   tolistremaining_prefill_tokensgenerated_lenrX   record_ttft_metricrz   rv   r   DECODINGrt   tokens_to_processupdate_and_check_completionrC   !mark_shareable_blocks_as_completery   rI   r   rJ   r   r   PREFILLING_SPLITSPLIT_PENDING_REMAINDER
ValueError_requests_to_forkpopnum_childrenrangeforkr]   fork_requestextend
copy_cache)r5   
new_tokenscurrent_logits_indexre   tokenis_finishedcopy_sourcecopy_destinationstate_to_forkr   inew_request_idsnew_request_idcopy_srccopy_dsts                  r)   update_batchz%ContinuousBatchProcessor.update_batch  s    ,,778U#d>T>T:UV]]_
 ++ 	jE5112a7&&(A-LL33E4F4FHXHXY#0#9#9EL"#78+0''$)$ $??F

<<UCLL::5;M;MuO_O_`NN11%2B2BZ^ZnZnVn1p8=DNN5''.!?!??

<<UC,DD 8E,<,<+==YZ_ZfZfYg!hii5	j: )+B%nn.. NN<<@@BM(55L)*M&QVWcQdeA-":":!;8A3GeOe"1 dANASASTbAc..~>d "&!8!89Q9QSb!cHhx(##H- nn..  JJ!!+/?@  fs   L"c                 6    | j                   j                         S )z2Check if there are any active or waiting requests.)rI   r   ra   s    r)   r   z-ContinuousBatchProcessor.has_pending_requestsD  s     ~~2244r+   c                     | j                   }|D ]9  }| j                  ||       | j                  j                  |j                         ; y)z&Handle errors during batch processing.N)rR   ro   rI   r   rv   )r5   rl   failed_reqsreqs       r)   handle_batch_errorz+ContinuousBatchProcessor.handle_batch_errorI  sD     ,, 	:C&&uc2NN))#..9	:r+   c                    t        | j                  j                  j                               }|D ]9  }| j	                  ||       | j                  j                  |j                         ; t        | j                  j                  j                               D ]9  }| j                  j                  j                  |      }| j	                  ||       ; | j                  j                  j                          y)zFail all active requests with the given error.

        Args:
            error: The error to report in the failure message
        N)listrI   r]   valuesro   r   rv   r^   keysr   waiting_requests_orderclear)r5   rl   requestsre   req_ids        r)   fail_all_requestsz*ContinuousBatchProcessor.fail_all_requestsQ  s     66==?@ 	<E&&ue4NN))%*:*:;	<
 4>>::??AB 	5FNN3377?E&&ue4	5
 	--335r+   modellogit_processor	do_samplec                 n   | j                   | j                  st        j                  | j                  | j                   j
                  | j                   j                  | j                   j                  | j                   j                  | j                   j                        | _        d| _        | j                  r| j                  j                  }| j                  j                  t        || j                  | j                         }t#        fdt%        | j&                  j(                        D              }t        || j&                  j*                  | j,                        }nd\  }}| j                  j/                  ||      }| j0                  | j	                  ||||       y| j0                  j3                  ||f      }	|	|	j5                          yt7        j8                  d||f       t        j:                  j=                  |j>                        }
|
jA                  t        j:                  jC                                t        j:                  jE                  |
      5  | j	                  ||||       ddd       t        j:                  jC                         jA                  |
       t        j:                  jG                         }	t        j:                  jI                  |	|
      5  | j	                  ||||       ddd       |	| j0                  ||f<   y# 1 sw Y   xY w# 1 sw Y   'xY w)	z!Perform a single generation step.N)	fullgraphmoderU   backendoptionsTc              3   .   K   | ]  }|   d      yw)r   Nr4   )r   r   actual_index_sizess     r)   r   z<ContinuousBatchProcessor._generation_step.<locals>.<genexpr>|  s     %e1&8&;A&>%er   )r   r   z8Creating graph for (padded_q, padded_read_index_size) = )r0   )stream)%rP   rT   r?   compile_forward_process_and_sampler   r   rU   r   r   rV   rY   actual_query_lengthr   r*   rW   rL   r   r   rC   
num_groupsr   rM   r_   rS   rn   replayr   r   cudaStreamr0   wait_streamcurrent_streamr   	CUDAGraphgraph)r5   r   r   r   r   padded_qmax_read_index_sizepadded_read_index_size
batch_datar   r   r   s              @r)   _generation_stepz)ContinuousBatchProcessor._generation_stepf  s    *43_3_/4}}00--77((--++33++33++330D, <@D8 "&"9"9"M"M!%!8!8!K!K'(;T=R=RTXTlTlmH"%%edjjNcNcHd%e"e%5#TZZ%9%94;T;T&" 04,H,,,==hH^_
 <<,,UJQZ[   (,B!CDLLN 	O85K*L)PQR""%,,"75::4467ZZv& 	\,,UJQZ[	\

!!#//7

$$&ZZeF3 	\,,UJQZ[	\;@h 678	\ 	\
	\ 	\s   'L0L+L(+L4r   c                 t    | j                  ||      }| j                  |||      }| j                  |||       y)zThis function performs the forward pass, logits processing, and sampling; which are broken down into smaller
        function to be easier to trace with OpenTelemetry.N)_model_forward_process_logit_sample)r5   r   r   r   r   logitsprobss          r)   r   z4ContinuousBatchProcessor._forward_process_and_sample  s:     $$UJ7##JHUJ	2r+   model_forward	span_namec                 &     |di |j                   S )Nr4   )r   )r5   r   r   s      r)   r   z'ContinuousBatchProcessor._model_forward  s    "z")))r+   logit_processingr   c                     t        |d      r|j                  |d   |d          |j                  \  }}}|j                  ||z  |      }|d   j                  ||z        } |||      }	|	j                  |||      S )Nset_continuous_batching_contextlogits_indicescu_seq_lens_q	input_ids)hasattrr   shapeview)
r5   r   r   r   
batch_sizeseq_len
vocab_size	logits_2dinput_ids_2dprocessed_logits_2ds
             r)   r   z'ContinuousBatchProcessor._process_logit  s    
 ?$EF;;JGW<XZdetZuv +1,,'
GZKK
W 4jA	!+.33J4HI-lIF"''
GZHHr+   samplingr   c                 z   |rKt         j                  j                  |d      }t        j                  |d   d      j                  d      }n(t        j                  |d      }|j                  d      }|j                  d      }|d   d | }||   }| j                  j                  d | j                  |       y )Nr   )dimr   r   )num_samplesr  )r   
functionalsoftmaxr?   multinomialsqueezeargmaxr!   rY   r   copy_)r5   r   r   r   next_tokenstokensindicess          r)   r   z ContinuousBatchProcessor._sample  s    MM))%R)8E++E!H!DLLRPK,,u"5K%--a0K!!!$-.w7!'***7F399+Fr+   r$   N)*r;   r<   r=   r   r   r   ri   Queue	threadingEventr?   r0   r/   r   boolintrZ   r@   r`   r   rq   rk   r   ro   r   r   r   r   r   r   r   no_gradr   Moduler   r   dictr   Tensorr   r   r   r4   r+   r)   rB   rB   W   s   >b">b !>b ,	>b
 [[>b kk>b OO>b ll>b [[>b >b >b >b !>b ">b 
>b@
# 
 9 9" <9 <\ <d < < 12 )D ) )V @ @ @ @
 3A 3Aj 5d 5 5 : : 6y 6T 6 6( U]]_5Abii 5ABU 5Abf 5Ako 5A  5An 3YY3,03CV3cg3	3 3 o&*BII *4 *ELL * '* ()II(-IGZI	I *I" j!GU\\ Gt G GQU G "Gr+   rB   c                      e Zd ZdZ	 	 	 	 	 d+dededededededed	d
fdZded
z  dedede	d
z  d	ef
dZ
ed,d       Zd	efdZd-deded
z  d	d
fdZd.deded
z  d	d
fdZ	 	 	 	 d/dee   ded
z  ded
z  deded	efdZ	 	 	 d0deee      ded
z  deded	d
f
dZded	d
fdZd1ded
z  ded
z  d	ed
z  fdZd  Zded	ee   fd!Zed,d"       Zd,d#Z ed$%      d&ed	d
fd'       Zed(ed&ed
z  d	d
fd)       Z eded	d
fd*       Z!y
)2ContinuousBatchingManagerzManager for handling continuous batching of generation requests.

    This class provides the user interface for submitting generation requests,
    retrieving results, and managing the background generation thread.
    r   r8   rJ   max_queue_sizenum_q_padding_intervalsnum_kv_padding_intervalsallow_block_sharingr$   Nc           
         d|j                   j                  vr(|j                  d|j                   j                          |j                         | _        || _        || _        || _        t        j                  |      | _
        t        j                         | _        t        j                         | _        d| _        d| _        d| _        t        j$                         | _        ||j(                  n|}|| _        t+        |dd      | _        t+        |dd      | _        | j                  j1                  |      | _        t+        |d	d      }||nd
| _        | j7                  t+        |dd      ||t+        |dd            | _        |dkD  r|nt:        | _        |dkD  r|nt>        | _         | j,                  rtC        d      y)aS  Initialize the continuous batching manager.

        Args:
            model: The language model for generation
            generation_config: Configuration for generation parameters
            max_queue_size: Maximum size of the request queue (0 = unlimited)
            num_q_padding_intervals: (optional) Number of intervals used to pad the query dimension
            num_kv_padding_intervals: (optional) Number of intervals used to pad the keys/values dimension
            allow_block_sharing: (optional) Whether to allow block sharing if the model has some full attention layers
        zpaged|)maxsizeNr   log_prob_generationFr   Tnum_return_sequencesr   rK   rP   )rK   r'  r(  rP   z(log_prob_generation is not supported yet)"r.   _attn_implementationr6   evalr   rJ   _allow_block_sharing_use_prefix_sharingri   r  rD   rE   r  r  rF   batch_processor_generation_thread_request_counterLock_request_lockr8   rQ   r,  r   r:   r   r-  _decide_use_cuda_graphsrK   NUM_Q_PADDING_INTERVALSrL   NUM_KV_PADDING_INTERVALSrM   NotImplementedError)	r5   r   r8   rJ   r&  r'  r(  r)  r-  s	            r)   rZ   z"ContinuousBatchingManager.__init__  s   * 5<<<<<))F5<<3T3T2U*VW ZZ\
.$7!#6  ;;~>!KKM#//+@D"& !&^^- 8I7PE33Vg!2#*+<>SUZ#[  !2KF48JJ4T4TUf4g&'8:PRVW<P<\$8bc!
 #::"#46FM$;%="#46FM	 ; 
 ?VXY>Y#:_v (@1(D$Jb 	!
 ##%&PQQ $r+   rK   rP   c                    t         j                  j                         s8|r5t        j                  dt         j                  j                         d       y||S |dkD  s|dkD  ry||t         j
                  j                         j                  |j                  |j                        }|j                  dd      }|r#t        j                  d|j                  d       | S t        | j                  j                         }t        j                  d	|d
| j                  j                  j                  d       |S )a  Returns whether or not to use cuda graphs for continuous batching, depending on the following criteria:
        - (use_cuda_graph) which is the user choice
        - (num_q_padding_intervals) or (num_kv_padding_intervals) which is used to pad inputs: if it was specified by
            the user, it's probable they want to use cuda graphs so inputs need to be padded
        - (compile_config): if compile is on, turn on cuda graphs unless the compile mode uses its own cudagraphs
        If none of the above criteria are met, we use a default heuristic based on the attention implementation: we turn
        on cuda graphs if and only if no attention mask is needed.
        z7use_cuda_graph is True but torch.cuda.is_available() = z: turning off cuda graphs.Fr   Tztriton.cudagraphsz%Compile config compile_config.mode = z uses cudagraphs, which usually does not work well with continuous batching. We recommend using mode 'default' or 'max-autotune-no-cudagraphs' instead.zINo behavior specified for use_cuda_graph, defaulting to use_cuda_graph = z2 because self.model.config._attn_implementation = zc. If you want to save memory, turn off cuda graphs, but they tend to improve performances by a lot.)r?   r   is_availabler   warning	_inductorlist_mode_optionsrn   r   r   r   r   r.   r.  )r5   rK   r'  r(  rP   r   compile_uses_cudagraphss          r)   r7  z1ContinuousBatchingManager._decide_use_cuda_graphs  s1     zz&&(!YUZZ=T=T=V<ZZtuv%!!"Q&*BQ*F%oo779==n>Q>QSaSiSijG&-kk2Eu&M#&<n&9&9%= >v v /.. 11B1BCCX~FY Z9zz  559 :::	

 r+   c                     | j                   0| j                   j                         rt        j                  d       yt	        j
                  | j                        | _         | j                   j                          y)z'Start the background generation thread.Nz"Manager thread is already running.)target)r3  is_aliver   r=  r  Thread_run_generation_loopstartra   s    r)   rF  zContinuousBatchingManager.startK  s\     "".43J3J3S3S3UNN?@"+"2"2$:S:S"T%%'r+   c                 V    | j                   duxr | j                   j                         S )z5Check if the background generation thread is running.N)r3  rC  ra   s    r)   
is_runningz$ContinuousBatchingManager.is_runningU  s'    &&d2Yt7N7N7W7W7YYr+   blocktimeoutc                    | j                   t        j                  d       nV| j                   j                  j                  r6t        j
                  d| j                   j                  j                          | j                  t        j                  d       yt               }| j                  j                         s/| j                  j                          t        j
                  d       |r| j                  ||       d| _         y)zSignal the background thread to stop.

        Args:
            block: Whether to wait for the thread to stop
            timeout: Maximum time to wait for the thread to stop
        Nz%
Batch processor was not initialized.z-
Prefix sharing was on. Total prefix length: zManager not started.z'Stopping continuous batching manager...)r2  r   r=  rC   use_prefix_sharingr   _total_prefix_lengthr3  r   rF   is_setsetjoin)r5   rI  rJ  stop_trigger_times       r)   stopzContinuousBatchingManager.stopZ  s     'NNCD##))<<DTEYEYE_E_EtEtDuv ""*NN12(N%%'OO!KKABII'1#r+   rQ  c                    | j                   | j                   j                  |       | j                   j                         rt        j                  d| d       yt               }t        j                  d||z
  dd       d| _         yy)zWait for the background thread to finish.

        Args:
            timeout: Maximum time to wait for the thread to stop
        NrJ  z3Generation thread did not exit after join timeout (z).z*Continuous Batching Manager stopped after z.2fzs.)r3  rP  rC  r   r=  r   r   )r5   rQ  rJ  ends       r)   rP  zContinuousBatchingManager.joinw  s     "".##(((9&&//1!TU\T]]_`a"nHO`I`adHeeghi*.' /r+   r  rv   max_new_tokensr   record_timestampsc           
         |9| j                   5  d| j                   }| xj                  dz  c_        ddd       || j                  j                  n|}t	        |t        |      | j                  dz
  |t        |      || j                  j                  |      }| j                  j                  |dd       |S # 1 sw Y   xY w)a/  Add a new generation request to the queue.

        Args:
            input_ids: Input token IDs to use as prompt
            request_id: Optional custom request ID (auto-generated if None)
            **kwargs: Additional generation parameters

        Returns:
            str: The request ID
        Nreq_r   )rv   r   r   rW  r   rV  eos_token_idr   T
   rI  rJ  )
r6  r4  r8   rV  r   r   r-  rZ  rD   r{   )r5   r  rv   rV  r   rW  re   s          r)   add_requestz%ContinuousBatchingManager.add_request  s    $ ## +#D$9$9#:;
%%*%+ CQBX//>>^l !	?22Q6/"9o)//<<	
 	U$;)+ +s   %B<<Cinputsc                    | j                   5  t        | j                  | j                  t        |      z         D cg c]  }d| 	 }}| xj                  t        |      z  c_        d d d        t	        t        |            }| j                  rt        |d d      }|D ]  \  }}	| j                  |	||||        y c c}w # 1 sw Y   ^xY w)NrY  c                     | d   S )Nr   r4   )xs    r)   <lambda>z8ContinuousBatchingManager.add_requests.<locals>.<lambda>  s
    !A$ r+   T)keyreverse)	r6  r   r4  r   r   zipr1  sortedr]  )
r5   r^  rV  r   rW  r   request_idsids_and_inputsrv   r  s
             r)   add_requestsz&ContinuousBatchingManager.add_requests  s      	1/4T5J5JDLaLadghndoLo/pq!T!:qKq!!S[0!	1 c+v67###NPTUN%3 	b!J	Y
NIO`a	b r	1 	1s   /CC  C CCc                 h    | j                   &| j                   j                  j                  |       yy)zkCancel a request by its ID.

        Args:
            request_id: The ID of the request to cancel
        N)r2  rI   set_request_cancellationr5   rv   s     r)   cancel_requestz(ContinuousBatchingManager.cancel_request  s/     +  **CCJO ,r+   c                    | j                   | j                  j                         ry	 | j                  j                  d|      }|+|j                  |k7  r| j                  j                  |       y|S # t        j                  $ r Y yw xY w)zRetrieve one result from the output queue.

        Args:
            timeout: Maximum time to wait for a result

        Returns:
            Optional[GenerationOutput]: The result data or None if timeout
        NTr\  )r3  rE   rf   rn   rv   r{   ri   rj   )r5   rv   rJ  results       r)   
get_resultz$ContinuousBatchingManager.get_result  s     ""*t/@/@/F/F/H	&&**w*GF%&*;*;z*I!!%%f-M{{ 		s   A	A5 3A5 5B
Bc              #      K   | j                   \| j                   j                         rA| j                  d      }|| | j                   | j                   j                         r?yyyyw)z.Iterate over results as they become available.N皙?rT  )r3  rC  rp  )r5   ro  s     r)   __iter__z"ContinuousBatchingManager.__iter__  sf     %%1d6M6M6V6V6X__S_1F! %%1d6M6M6V6V6X16X1s   A%A,(A,c              #   P  K   d}| j                   | j                   j                         ry|sv| j                  |d      }|| | j                  %| j                  j                  j                  |      }| j                   | j                   j                         r|ssyyyyyyw)zMIterate over results matching a specific request id as they become available.FNrr  )rv   rJ  )r3  rC  rp  r2  rI   request_is_cancelled)r5   rv   request_cancelledro  s       r)   request_id_iterz)ContinuousBatchingManager.request_id_iter  s     !%%1d6M6M6V6V6Xar__
C_HF!##/$($8$8$B$B$W$WXb$c! %%1d6M6M6V6V6Xar6X1ar6X1s   BB& B&c                     | j                   t        d      | j                   j                  | j                  | j                  | j
                         y)z=Perform a single generation step. This is mostly cuda graphedNzNTried to perform a generation step before the batch processor was initialized.)r2  r   r   r   r   r   ra   s    r)   r   z*ContinuousBatchingManager._generation_step  sE     'opp--djj$:N:NPTP^P^_r+   c                    d}	 t               }t        | j                  j                  | j                  | j                  j
                  | j                  j                  t        | j                  dd      | j                        }|j                  | _
        t        j                  dt               |z
   d       d}t        | j                  d      rLt        j                  | j                  j                   d      }|&t        j"                  d| d       t$        }nt$        }t               }t'        || j                  j                  | j                  | j(                  | j*                  | j,                  | j                  j
                  | j                  j                   ||| j.                        | j.                  | j0                  | j2                  | j4                  	      }|| _        d
| _        t        j                  dt               |z
   d       | j,                  j;                         r|j=                         rR| j?                  |       | xj8                  dz  c_        | j,                  j;                         sA|j=                         rRt        jF                  d       y# t@        $ r6}t        jB                  d| d       | jE                  ||       Y d}~Pd}~ww xY w# t        jF                  d       w xY w)z6Main processing loop running in the background thread.N_tp_size)tp_sizer)  zPagedAttentionCache created in z secondsrI   zScheduler 'z ' not found. Defaulting to FIFO.)rC   r.   r8   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   r   zbatch_processor created in r   zError in generation loop: Trc   zGeneration loop finished.)$r   r   r   r.   r8   r0   r/   rQ   r0  rL  r1  r   r   r  r   rn   rI   r=  r   rB   rD   rE   rF   rJ   rK   rL   rM   r2  current_batchrN  r   _inner_generation_looprk   rl   _handle_critical_errorr   )r5   r2  t0paged_attention_cacherI   t1rp   s          r)   rE  z.ContinuousBatchingManager._run_generation_loop  sd   ;?2	5B$7

!!&&

!!

  

J=$($=$=%! (='O'OD$LL:<>B;N:OxXYIt--{;-11$2H2H2R2RTXY	$NN[;[#\] -I *	B6+zz(("&"8"8 ,,!..??!ZZ.. JJ,,#$94;O;OP $ 4 4#22$($<$<%)%>%>O $3D !"DLL6|~7J6K8TU--/O4X4X4Z++O<""a'" --/O4X4X4Z KK34	  	<LL5aS9DI''?;;	< KK34s0   I:J& ?J& &	K%/,K K(  K%%K( (K?generation_loopr   r2  c                     t         j                  j                         rt         j                  j                          |j	                         sy | j                          |j                          y r3   )r?   r   r<  synchronizer   r   r   )r5   r2  s     r)   r}  z0ContinuousBatchingManager._inner_generation_loop1  sK     ::""$JJ""$113$$&r+   rl   c                     | j                   j                          	 	 | j                  j                         }||j	                  ||       /# t
        j                  $ r Y nw xY w||j                  |       yy)z:Handle critical errors that terminate the generation loop.N)rF   rO  rD   rg   ro   ri   rj   r   )r5   rl   r2  req_datas       r)   r~  z0ContinuousBatchingManager._handle_critical_error<  s~     		++668".#99%J  {{ 		 &--e4 's   0A A"!A"c                     | j                   st        d      | j                  &| j                  j                  j	                  |       yy)zSEvict a request from the cache. It is assumed that the request is already finished.z0Manual eviction is not enabled for this manager.N)rJ   r   r2  rI   r   rl  s     r)   evict_request_from_cachez2ContinuousBatchingManager.evict_request_from_cacheO  sD     ##QRR+  **99*E ,r+   )Fr   r   r   Tr  )TNr3   )NNFF)NFF)NN)"r;   r<   r=   __doc__r-   r   r  r  rZ   r   r7  r   rF  rH  floatrR  rP  r   r@   r]  ri  rm  r   rp  rs  r   rw  r   rE  rB   r}  rk   r~  r  r4   r+   r)   r%  r%    s    !&'(()$(AR#AR ,AR 	AR
 AR "%AR #&AR "AR 
ARF-t- "%- #&	-
 &,- 
-^ ( (ZD Z
$$ $ $ $:/e /edl /d /$ "&%)"''9' $J' d
	'
 '  ' 
'X &*"'bT#Yb d
b 	b
  b 
b&P P PS4Z  YilpYp *d# d)<L2M d ` `55n '('6N 'SW ' )' 5I 5H`cgHg 5lp 5 5$ F3 F4 F Fr+   r%  c                   2   e Zd ZU dZeed<   e	 	 	 	 	 	 	 	 ddedz  dededededed	ed
e	dz  de
e   fd       Z	 	 	 	 	 	 ddedz  dedededededefdZe ej                          	 	 	 	 	 	 ddeee      dedz  dedededededeeef   fd              Zy)ContinuousMixinz?Mixin class for models to add continuous batching capabilities.r8   NrJ   r&  num_q_cuda_graphsnum_kv_cuda_graphsr)  rI  rJ  r$   c	              #     K   | j                  ||||||      }	|	j                          	 |	 t        j                  d       |	j	                  ||       y # t        j                  d       |	j	                  ||       w xY ww)Nz!Continuous batching loop finishedr\  )init_continuous_batchingrF  r   r   rR  )
r5   r8   rJ   r&  r  r  r)  rI  rJ  managers
             r)   #continuous_batching_context_managerz3ContinuousMixin.continuous_batching_context_manager]  s      //
 		7MLL3 LLugL6 LL3 LLugL6s   'BA )B*BBr'  r(  c           	         t        | d      rt        | d      rt        | d      st        d      ||n| j                  }|t        d      |j                  t        j                  d       d|_        t        | ||||||      S )	a  Initialize a manager for continuous batching inference.

        Args:
            generation_config: An optional generation configuration, which may contain a CompileConfig object
            manual_eviction: Whether to manually evict requests from the cache
            max_queue_size: Maximum size of the input request queue
            num_q_padding_intervals: Number of intervals used to pad the query dimension
            num_kv_padding_intervals: Number of intervals used to pad the keys/values dimension
            allow_block_sharing: A flag to allow block sharing if the model has some full attention layers

        Returns:
            `ContinuousBatchingManager`: The manager instance to add requests and retrieve results.
        r.   r0   r/   z;Model must have 'config', 'device', and 'dtype' attributes.z8A GenerationConfig must be provided or set in the model.zE`eos_token_id` not set in GenerationConfig. Setting to -1 (disabled).r   )r   r8   rJ   r&  r'  r(  r)  )r  AttributeErrorr8   r   rZ  r   r=  r%  )r5   r8   rJ   r&  r'  r(  r)  
gen_configs           r)   r  z(ContinuousMixin.init_continuous_batching{  s    , tX&gdH.EWUY[bMc !^__*;*G&TMcMc
WXX""*NNbc&(J# )(+)$;%= 3
 	
r+   r^  rW  progress_barc           	      X   |si S t        j                         t        j                  k  rt        j                  d       d}i }	|| j
                  n|}
t        |      |
j                  |
j                  ndz  }| j                  ||||dd      }t        t         g      }t        || d| d	d
      }|5 }|5  |5 }	 |j                  ||j                  d      |       d}||k  r|j                  d      }|r8|j                  }|j                         rM||	|<   |dz  }|j!                  d       n1|j#                         s!t        j$                  d       t'        d       n||k  rddd       ddd       ddd       i }t+        t        |            D ]:  }|	j                  d|       }|	||d| <   "t        j$                  d| d       < |S # t(        $ r$}t        j$                  d| d       Y d}~d}~ww xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)a_  Generate sequences for a batch of prompts using continuous batching.

        Args:
            inputs: List of input token sequences (prompts)
            generation_config: Optional generation configuration
            num_q_padding_intervals: Number of intervals used to pad the query dimension
            num_kv_padding_intervals: Number of intervals used to pad the keys/values dimension
            allow_block_sharing: A flag to allow block sharing if the model has some full attention layers
            record_timestamps: If set to true, the requests will have a timestamp for each token generated
            progress_bar: If set to true, a progress bar will be displayed
            **kwargs: Additional generation parameters

        Returns:
            `dict[str, GenerationOutput]`: a dictionary of request ids to GenerationOutput objects
        z=Progress bar is disabled when logger level is less than DEBUGFNr   T   )r8   r  r  r)  rI  rJ  zSolving z	 requestsrequest)totaldisabledescunitrV  )r^  rV  rW  r   rT  z*Generation thread terminated unexpectedly.zCReturning results of generate_batch despite unexpected termination.zError during batch generation: rc   rY  zRequest req_z not found in results.)r   getEffectiveLevelr   r   r=  r8   r   r-  r  r
   r	   ri  rn   rp  rv   r   updaterH  rl   printrk   r   )r5   r^  r8   r'  r(  r)  rW  r  kwargsresultsgen_cfgnum_requests
manager_cm
logging_cmpbar_cmr  pbarfinished_countro  r   rp   reordered_resultsr   s                          r)   generate_batchzContinuousMixin.generate_batch  sj   8 I##%6NNZ[ L ,=,E$((K\6{gFbFbFng&B&Btuv==/57 3 > 

 +F84
%%L>3	
  	S7J 	S 	S4S$$!&**=M2Nbs %  "#$|3$///:F!'!2!2!--/.4GFO*a/N KKN&113"LL)UV!"gh! %|3	S 	S 	S0 s6{# 	GA[[4s,F!06!D*-|A3.DEF	G !   S>qcBTRRS+	S 	S 	S 	S 	S 	Ssa   6H 9H<H>B,G+H3H 	H	!H 	;H H	HHHH	H  H))NFr   r   r   TTN)NFr   r   r   T)Nr   r   TFT)r;   r<   r=   r  r   r>   r   r  r  r  r   r%  r  r  r   r?   inference_moder   r"  r@   r   r  r4   r+   r)   r  r  X  s   I'' 6: %!""#$( $7+d27 7 	7
 7  7 "7 7 7 
,	-7 7> 6: %'(()$(*
+d2*
 *
 	*

 "%*
 #&*
 "*
 
#*
Z U 6:'(()$("'!U!T#YU! ,d2U! "%	U!
 #&U! "U!  U! U! 
c##	$U!  U!r+   r  )5ri   r  abcr   collections.abcr   
contextlibr   mathr   timer   r?   r   r	   tqdm.contrib.loggingr
   configuration_utilsr   generation.configuration_utilsr   r   generation.logits_processr   utils.loggingr   utils.metricsr   r   r   rC   r   input_ouputsr   r   r   r   r   r   r   rI   r   r   r   r8  r9  r  r*   r!  r-   rB   r%  r  r4   r+   r)   <module>r     s       % %      6 3 M < $ S S & D K K B B&   "3 "3 "c "c "299  uG uG uGr CF CF CFLg! g!r+   