[Spec] fold can_run_cuda_graph into EagleVerifyOutput; drop dead extend-after-decode check (#25566)
This commit is contained in:
@@ -1012,6 +1012,10 @@ class EagleVerifyOutput:
|
||||
num_correct_drafts_per_req_cpu: List[int]
|
||||
# Accepted indices from logits_output.next_token_logits
|
||||
accept_indices: torch.Tensor
|
||||
# Whether the target verify forward ran a captured cuda graph. Set by
|
||||
# the worker after `EagleVerifyInput.sample` returns; default kept so
|
||||
# idle / direct constructions don't have to pass it.
|
||||
can_run_cuda_graph: bool = False
|
||||
|
||||
@classmethod
|
||||
def create_idle(
|
||||
|
||||
@@ -5,7 +5,6 @@ from typing import List, Optional, Tuple
|
||||
|
||||
import torch
|
||||
|
||||
from sglang.srt.distributed import get_tp_group
|
||||
from sglang.srt.hardware_backend.npu.graph_runner.eagle_draft_npu_graph_runner import (
|
||||
EAGLEDraftNpuGraphRunner,
|
||||
)
|
||||
@@ -162,7 +161,7 @@ class EAGLEWorker(TpModelWorker):
|
||||
server_args=server_args,
|
||||
gpu_id=gpu_id,
|
||||
tp_rank=tp_rank,
|
||||
pp_rank=0, # FIXME
|
||||
pp_rank=0, # spec workers don't support pipeline parallelism
|
||||
dp_rank=dp_rank,
|
||||
moe_ep_rank=moe_ep_rank,
|
||||
attn_cp_rank=attn_cp_rank,
|
||||
@@ -492,8 +491,9 @@ class EAGLEWorker(TpModelWorker):
|
||||
set_time_batch(batch.reqs, "set_spec_draft_end_time", trace_only=True)
|
||||
set_time_batch(batch.reqs, "set_spec_verify_start_time", trace_only=True)
|
||||
|
||||
# Install verify_input as `batch.spec_info` for the verify forward.
|
||||
batch.spec_info = verify_input
|
||||
logits_output, verify_output, can_run_cuda_graph = self.verify(batch)
|
||||
verify_output = self.verify(batch)
|
||||
|
||||
if get_global_tracing_enabled():
|
||||
for idx, req in enumerate(batch.reqs):
|
||||
@@ -520,8 +520,9 @@ class EAGLEWorker(TpModelWorker):
|
||||
self.server_args.enable_dp_attention
|
||||
or draft_extend_input.input_ids.shape[0] > 0
|
||||
):
|
||||
# decode is not finished; stash for extend, then restash
|
||||
# the next-iter EagleDraftInput it returns.
|
||||
# decode is not finished; install draft_extend_input for
|
||||
# the extend forward, then install the next-iter
|
||||
# EagleDraftInput it returns.
|
||||
batch.spec_info = draft_extend_input
|
||||
next_draft_input = self.forward_draft_extend_after_decode(batch)
|
||||
batch.spec_info = next_draft_input
|
||||
@@ -542,31 +543,13 @@ class EAGLEWorker(TpModelWorker):
|
||||
)
|
||||
|
||||
return GenerationBatchResult(
|
||||
logits_output=logits_output,
|
||||
logits_output=verify_output.logits_output,
|
||||
next_token_ids=verify_output.accept_tokens,
|
||||
num_correct_drafts=sum(verify_output.num_correct_drafts_per_req_cpu),
|
||||
num_correct_drafts_per_req_cpu=verify_output.num_correct_drafts_per_req_cpu,
|
||||
can_run_cuda_graph=can_run_cuda_graph,
|
||||
can_run_cuda_graph=verify_output.can_run_cuda_graph,
|
||||
)
|
||||
|
||||
def check_forward_draft_extend_after_decode(self, verify_output: EagleVerifyOutput):
|
||||
local_need_forward = verify_output.draft_extend_input.input_ids.shape[0] > 0
|
||||
if not self.server_args.enable_dp_attention:
|
||||
return local_need_forward
|
||||
|
||||
global_need_forward = torch.tensor(
|
||||
[
|
||||
(local_need_forward),
|
||||
],
|
||||
dtype=torch.int64,
|
||||
)
|
||||
torch.distributed.all_reduce(
|
||||
global_need_forward, group=get_tp_group().cpu_group
|
||||
)
|
||||
global_need_forward_cnt = global_need_forward[0].item()
|
||||
need_forward = global_need_forward_cnt > 0
|
||||
return need_forward
|
||||
|
||||
def forward_target_extend(
|
||||
self, batch: ScheduleBatch
|
||||
) -> Tuple[LogitsProcessorOutput, torch.Tensor, Optional[torch.Tensor], bool]:
|
||||
@@ -1015,7 +998,8 @@ class EAGLEWorker(TpModelWorker):
|
||||
ForwardMode.DECODE if not batch.forward_mode.is_idle() else ForwardMode.IDLE
|
||||
)
|
||||
|
||||
return logits_output, res, can_run_cuda_graph
|
||||
res.can_run_cuda_graph = can_run_cuda_graph
|
||||
return res
|
||||
|
||||
def _mamba_verify_update(
|
||||
self,
|
||||
|
||||
@@ -154,7 +154,7 @@ class EagleDraftWorker(BaseDraftWorker):
|
||||
server_args=server_args,
|
||||
gpu_id=gpu_id,
|
||||
tp_rank=tp_rank,
|
||||
pp_rank=0, # FIXME
|
||||
pp_rank=0, # spec workers don't support pipeline parallelism
|
||||
dp_rank=dp_rank,
|
||||
moe_ep_rank=moe_ep_rank,
|
||||
attn_cp_rank=attn_cp_rank,
|
||||
|
||||
@@ -449,8 +449,9 @@ class FrozenKVMTPWorker(TpModelWorker):
|
||||
set_time_batch(batch.reqs, "set_spec_draft_end_time", trace_only=True)
|
||||
set_time_batch(batch.reqs, "set_spec_verify_start_time", trace_only=True)
|
||||
|
||||
# Install verify_input as `batch.spec_info` for the verify forward.
|
||||
batch.spec_info = verify_input
|
||||
logits_output, verify_output, can_run_cuda_graph = self.verify(batch)
|
||||
verify_output = self.verify(batch)
|
||||
|
||||
if get_global_tracing_enabled():
|
||||
for idx, req in enumerate(batch.reqs):
|
||||
@@ -470,18 +471,19 @@ class FrozenKVMTPWorker(TpModelWorker):
|
||||
self.server_args.enable_dp_attention
|
||||
or draft_extend_input.input_ids.shape[0] > 0
|
||||
):
|
||||
# Stash for the seed step; _run_assistant_seed_step swaps in
|
||||
# a fresh FrozenKVMTPDraftInput for next iter.
|
||||
# Install draft_extend_input as `batch.spec_info` for the seed
|
||||
# step; `_run_assistant_seed_step` replaces it with a fresh
|
||||
# `FrozenKVMTPDraftInput` for next iter.
|
||||
batch.spec_info = draft_extend_input
|
||||
self.forward_draft_extend_after_decode(batch)
|
||||
set_time_batch(batch.reqs, "set_spec_draft_extend_end_time", trace_only=True)
|
||||
|
||||
return GenerationBatchResult(
|
||||
logits_output=logits_output,
|
||||
logits_output=verify_output.logits_output,
|
||||
next_token_ids=verify_output.accept_tokens,
|
||||
num_correct_drafts=sum(verify_output.num_correct_drafts_per_req_cpu),
|
||||
num_correct_drafts_per_req_cpu=verify_output.num_correct_drafts_per_req_cpu,
|
||||
can_run_cuda_graph=can_run_cuda_graph,
|
||||
can_run_cuda_graph=verify_output.can_run_cuda_graph,
|
||||
)
|
||||
|
||||
def forward_target_extend(
|
||||
@@ -518,7 +520,7 @@ class FrozenKVMTPWorker(TpModelWorker):
|
||||
input_is_idle = batch.forward_mode.is_idle()
|
||||
|
||||
if not input_is_idle and draft_extend_input.input_ids.shape[0] == 0:
|
||||
# All reqs finished; stash an idle FrozenKVMTPDraftInput so the
|
||||
# All reqs finished. Install an idle FrozenKVMTPDraftInput so the
|
||||
# next-iter draft sees a valid spec_info.
|
||||
batch = batch.copy()
|
||||
batch.prepare_for_idle()
|
||||
@@ -775,4 +777,5 @@ class FrozenKVMTPWorker(TpModelWorker):
|
||||
)
|
||||
|
||||
del seq_lens_pre_verify
|
||||
return logits_output, res, can_run_cuda_graph
|
||||
res.can_run_cuda_graph = can_run_cuda_graph
|
||||
return res
|
||||
|
||||
@@ -18,7 +18,6 @@ from typing import TYPE_CHECKING, List, Optional, Tuple
|
||||
|
||||
import torch
|
||||
|
||||
from sglang.srt.distributed import get_tp_group
|
||||
from sglang.srt.layers.dp_attention import get_attention_tp_group
|
||||
from sglang.srt.layers.logits_processor import LogitsProcessorOutput
|
||||
from sglang.srt.layers.moe.utils import speculative_moe_backend_context
|
||||
@@ -136,7 +135,7 @@ class MultiLayerEagleWorker(TpModelWorker):
|
||||
server_args=server_args,
|
||||
gpu_id=gpu_id,
|
||||
tp_rank=tp_rank,
|
||||
pp_rank=0, # FIXME
|
||||
pp_rank=0, # spec workers don't support pipeline parallelism
|
||||
dp_rank=dp_rank,
|
||||
moe_ep_rank=moe_ep_rank,
|
||||
attn_cp_rank=attn_cp_rank,
|
||||
@@ -293,8 +292,9 @@ class MultiLayerEagleWorker(TpModelWorker):
|
||||
set_time_batch(batch.reqs, "set_spec_draft_end_time", trace_only=True)
|
||||
set_time_batch(batch.reqs, "set_spec_verify_start_time", trace_only=True)
|
||||
|
||||
# Install verify_input as `batch.spec_info` for the verify forward.
|
||||
batch.spec_info = verify_input
|
||||
logits_output, verify_output, can_run_cuda_graph = self.verify(batch)
|
||||
verify_output = self.verify(batch)
|
||||
|
||||
if get_global_tracing_enabled():
|
||||
for idx, req in enumerate(batch.reqs):
|
||||
@@ -320,8 +320,9 @@ class MultiLayerEagleWorker(TpModelWorker):
|
||||
self.server_args.enable_dp_attention
|
||||
or draft_extend_input.input_ids.shape[0] > 0
|
||||
):
|
||||
# decode is not finished; stash for extend, then restash
|
||||
# the next-iter EagleDraftInput it returns.
|
||||
# decode is not finished; install draft_extend_input for
|
||||
# the extend forward, then install the next-iter
|
||||
# EagleDraftInput it returns.
|
||||
batch.spec_info = draft_extend_input
|
||||
next_draft_input = self.forward_draft_extend_after_decode(batch)
|
||||
batch.spec_info = next_draft_input
|
||||
@@ -337,31 +338,13 @@ class MultiLayerEagleWorker(TpModelWorker):
|
||||
)
|
||||
|
||||
return GenerationBatchResult(
|
||||
logits_output=logits_output,
|
||||
logits_output=verify_output.logits_output,
|
||||
next_token_ids=verify_output.accept_tokens,
|
||||
num_correct_drafts=sum(verify_output.num_correct_drafts_per_req_cpu),
|
||||
num_correct_drafts_per_req_cpu=verify_output.num_correct_drafts_per_req_cpu,
|
||||
can_run_cuda_graph=can_run_cuda_graph,
|
||||
can_run_cuda_graph=verify_output.can_run_cuda_graph,
|
||||
)
|
||||
|
||||
def check_forward_draft_extend_after_decode(self, verify_output: EagleVerifyOutput):
|
||||
local_need_forward = verify_output.draft_extend_input.input_ids.shape[0] > 0
|
||||
if not self.server_args.enable_dp_attention:
|
||||
return local_need_forward
|
||||
|
||||
global_need_forward = torch.tensor(
|
||||
[
|
||||
(local_need_forward),
|
||||
],
|
||||
dtype=torch.int64,
|
||||
)
|
||||
torch.distributed.all_reduce(
|
||||
global_need_forward, group=get_tp_group().cpu_group
|
||||
)
|
||||
global_need_forward_cnt = global_need_forward[0].item()
|
||||
need_forward = global_need_forward_cnt > 0
|
||||
return need_forward
|
||||
|
||||
def forward_target_extend(
|
||||
self, batch: ScheduleBatch
|
||||
) -> Tuple[LogitsProcessorOutput, torch.Tensor, Optional[torch.Tensor], bool]:
|
||||
@@ -644,7 +627,8 @@ class MultiLayerEagleWorker(TpModelWorker):
|
||||
ForwardMode.DECODE if not batch.forward_mode.is_idle() else ForwardMode.IDLE
|
||||
)
|
||||
|
||||
return logits_output, res, can_run_cuda_graph
|
||||
res.can_run_cuda_graph = can_run_cuda_graph
|
||||
return res
|
||||
|
||||
def forward_draft_extend(
|
||||
self,
|
||||
|
||||
@@ -128,7 +128,7 @@ class MultiLayerEagleDraftWorker(BaseDraftWorker):
|
||||
server_args=server_args,
|
||||
gpu_id=gpu_id,
|
||||
tp_rank=tp_rank,
|
||||
pp_rank=0, # FIXME
|
||||
pp_rank=0, # spec workers don't support pipeline parallelism
|
||||
dp_rank=dp_rank,
|
||||
moe_ep_rank=moe_ep_rank,
|
||||
attn_cp_rank=attn_cp_rank,
|
||||
|
||||
@@ -232,9 +232,11 @@ class SpecInput(ABC):
|
||||
def __init__(self, spec_input_type: SpecInputType):
|
||||
self.spec_input_type = spec_input_type
|
||||
|
||||
# Cross-algorithm phase guards. Used by attention backends and
|
||||
# ForwardBatch padding logic to dispatch on phase without hardcoding the
|
||||
# specific algo class (EAGLE / FROZEN_KV_MTP / DFLASH / NGRAM each have
|
||||
# their own draft / verify SpecInput subclasses).
|
||||
def is_draft_input(self) -> bool:
|
||||
# FIXME: remove this function which is only used for assertion
|
||||
# or use another variable name like `draft_input` to substitute `spec_info`
|
||||
return self.spec_input_type in {
|
||||
SpecInputType.EAGLE_DRAFT,
|
||||
SpecInputType.EAGLE_DRAFT_EXTEND,
|
||||
|
||||
@@ -87,7 +87,7 @@ class StandaloneWorker(EAGLEWorker):
|
||||
server_args=server_args,
|
||||
gpu_id=gpu_id,
|
||||
tp_rank=tp_rank,
|
||||
pp_rank=0, # FIXME
|
||||
pp_rank=0, # spec workers don't support pipeline parallelism
|
||||
dp_rank=dp_rank,
|
||||
moe_ep_rank=moe_ep_rank,
|
||||
attn_cp_rank=attn_cp_rank,
|
||||
|
||||
@@ -93,7 +93,7 @@ class StandaloneDraftWorker(EagleDraftWorker):
|
||||
server_args=server_args,
|
||||
gpu_id=gpu_id,
|
||||
tp_rank=tp_rank,
|
||||
pp_rank=0, # FIXME
|
||||
pp_rank=0, # spec workers don't support pipeline parallelism
|
||||
dp_rank=dp_rank,
|
||||
moe_ep_rank=moe_ep_rank,
|
||||
attn_cp_rank=attn_cp_rank,
|
||||
|
||||
Reference in New Issue
Block a user