@@ -436,12 +436,14 @@ class SpecMetadata:
436436 # Always set by model_engine.forward() before any downstream code reads it.
437437 runtime_draft_len : int = 0
438438
439- # For non-greedy sampling on 1-model.
440439 # Auto-detected per step from populated sampling params:
441- # True if any request needs temp/top_k/top_p, False if all greedy.
440+ # True if every request is greedy (no temp/top_k/top_p) and we can take
441+ # the argmax fast-path. False if any request needs sampling.
442442 # Used as part of the CUDA graph key so we capture two variants
443443 # (greedy fast-path vs advanced sampling) and dispatch at replay.
444- uses_advanced_sampling : bool = False
444+ # Defaults to True so non-one-engine paths (where populate is a no-op)
445+ # never accidentally select the advanced graph variant.
446+ is_all_greedy_sample : bool = True
445447 # Whether to use rejection sampling for one-model speculative decoding.
446448 use_rejection_sampling : bool = False
447449 # Sampling parameters for non-greedy sampling (per-request)
@@ -524,7 +526,7 @@ def populate_sampling_params_for_one_model(
524526 Phase 1: scan request sampling configs to compute skip_*/has_greedy
525527 flags and decide whether the batch is all-greedy. No per-token
526528 list construction.
527- Phase 2 (only when uses_advanced_sampling=True ): build per-token /
529+ Phase 2 (only when is_all_greedy_sample=False ): build per-token /
528530 per-request lists and issue 6 H->D copies into the sampling
529531 parameter buffers.
530532
@@ -631,11 +633,11 @@ def _normalize_request_sampling_params(
631633 self .skip_top_k = not top_k_enabled
632634 self .skip_top_p = not top_p_enabled
633635 self .has_greedy_requests = has_greedy_requests
634- # Advanced sampling is needed iff any sampling param is active.
635- # When all skip_* flags are True, the entire batch can run argmax fast-path.
636+ # All-greedy iff no sampling param is active across the whole batch .
637+ # When True, the sampler takes the argmax fast-path.
636638 # This boolean is part of the CUDA graph key so we capture both variants.
637- self .uses_advanced_sampling = not (self .skip_temperature and
638- self . skip_top_k and self .skip_top_p )
639+ self .is_all_greedy_sample = (self .skip_temperature and self . skip_top_k
640+ and self .skip_top_p )
639641
640642 tokens_per_request = (self .max_total_draft_tokens + 1 if
641643 self .is_spec_dec_tree else self .max_draft_len + 1 )
@@ -668,7 +670,7 @@ def _normalize_request_sampling_params(
668670 # ===== Fast-path: all-greedy batch skips list build + H->D copies =====
669671 # The sampler will take the argmax branch and never read these buffers,
670672 # so leaving their values stale is safe.
671- if not self .uses_advanced_sampling :
673+ if self .is_all_greedy_sample :
672674 return
673675
674676 # ===== Phase 2: build per-token / per-request lists and copy to GPU =====
@@ -1321,7 +1323,7 @@ def _sample_tokens_for_batch(
13211323 Returns:
13221324 sampled_tokens: [num_tokens] - Sampled token ids
13231325 """
1324- if spec_metadata .uses_advanced_sampling :
1326+ if not spec_metadata .is_all_greedy_sample :
13251327 num_gens = batch_size - num_contexts
13261328 num_tokens = num_contexts + num_gens * (
13271329 spec_metadata .runtime_draft_len + 1 )
0 commit comments