@@ -99,15 +99,17 @@ def _init_dynamic_sampling_tensors(self):
9999 max_requests = context .max_total_requests
100100
101101 model_config = get_model_config (self .inference_wrapped_model .model )
102- sampling_backend = model_config .sampling_backend
102+ self ._sampling_backend = model_config .sampling_backend
103+ self ._enable_cuda_graph = model_config .enable_cuda_graph
104+ if self ._enable_cuda_graph :
105+ self ._recording_graph : bool = False
106+ self ._sampling_graph_map : Dict [int , torch .cuda .CUDAGraph ] = {}
103107
104108 device = torch .cuda .current_device ()
105109 logits_dtype = self .inference_wrapped_model .inference_wrapper_config .params_dtype
106110 # Use padded vocab size because tokenizer vocab size might pad to nearest power of 2.
107111 vocab_size = self .inference_wrapped_model .inference_wrapper_config .padded_vocab_size
108112
109- self ._sampling_backend = "torch"
110-
111113 # Keep track of request metadata.
112114 self ._active_request_count = None
113115 self ._request_metadata : Dict [str , Tensor ] = {}
@@ -590,10 +592,12 @@ def _dynamic_step_context_init(
590592
591593 # Get flat tokens, position ids.
592594 if construct_graph_dimensions is not None :
595+ self ._recording_graph = True
593596 return context .current_input_and_position_ids (
594597 num_warmup_tokens = construct_graph_dimensions .token_count
595598 )
596599 else :
600+ self ._recording_graph = False
597601 return context .current_input_and_position_ids ()
598602
599603 def _dynamic_step_forward_logits (self , input_ids : Tensor , position_ids : Tensor ) -> Tensor :
@@ -679,9 +683,6 @@ def _dynamic_step_sample_logits(self):
679683 """Sample tokens from logits for dynamic batching."""
680684 # TODO(ksanthanam): Evaluate whether it makes more sense to sample on 1 rank
681685 # and then broadcast the sampled tokens rather than broadcasting the raw logits.
682- context = self .inference_wrapped_model .inference_context
683- active_request_count = context .total_request_count - context .paused_request_count
684-
685686 if self ._sampling_backend == "torch" :
686687 # Concatenate the outputs once to prevent repeated small writes.
687688 token_list = []
@@ -699,7 +700,24 @@ def _dynamic_step_sample_logits(self):
699700 sampled_indices = torch .cat (indices_list , dim = 0 )
700701 self ._sampled_tokens_cuda .index_copy_ (0 , sampled_indices , sampled_tokens )
701702 elif self ._sampling_backend == "flashinfer" :
702- self .flashinfer_sampling_func (active_request_count )
703+ if self ._enable_cuda_graph :
704+ if self ._recording_graph :
705+ g = torch .cuda .CUDAGraph ()
706+ with torch .cuda .graph (g ):
707+ self .flashinfer_sampling_func (self ._active_request_count )
708+ self ._sampling_graph_map [self ._active_request_count ] = g
709+ else :
710+ # Find the appropriate graph to replay.
711+ graph_size = next (
712+ (
713+ size
714+ for size in self ._sampling_graph_map .keys ()
715+ if size >= self ._active_request_count
716+ ),
717+ None ,
718+ )
719+ assert graph_size is not None
720+ self ._sampling_graph_map [graph_size ].replay ()
703721
704722 def _dynamic_step_log_probs_bookkeeping (self ) -> Tuple [bool , bool ]:
705723 """Perform bookkeeping necessary to compute log probs for dynamic batching.
0 commit comments