Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b9c2a56

Browse files
zixi-qihouseroad
andauthored
[Spec Decode] Defer clearing KV connector metadata for EAGLE3 speculative decode + prefill / decode disagg setup (vllm-project#34529)
Signed-off-by: qizixi <[email protected]> Co-authored-by: Lu Fang <[email protected]>
1 parent dd8c3a7 commit b9c2a56

3 files changed

Lines changed: 38 additions & 5 deletions

File tree

vllm/v1/worker/gpu/kv_connector.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ def pre_forward(self, scheduler_output: "SchedulerOutput") -> None:
7777
self.kv_connector.start_load_kv(get_forward_context())
7878

7979
def post_forward(
80-
self, scheduler_output: "SchedulerOutput", wait_for_save: bool = True
80+
self,
81+
scheduler_output: "SchedulerOutput",
82+
wait_for_save: bool = True,
83+
clear_metadata: bool = True,
8184
) -> KVConnectorOutput | None:
8285
if self._disabled:
8386
return None
@@ -91,9 +94,15 @@ def post_forward(
9194
output.invalid_block_ids = self.kv_connector.get_block_ids_with_load_errors()
9295
output.kv_connector_stats = self.kv_connector.get_kv_connector_stats()
9396
output.kv_cache_events = self.kv_connector.get_kv_connector_kv_cache_events()
94-
self.kv_connector.clear_connector_metadata()
97+
if clear_metadata:
98+
self.kv_connector.clear_connector_metadata()
9599
return output
96100

101+
def clear_metadata(self) -> None:
102+
"""Clear the connector metadata. Call this after draft model runs."""
103+
if not self._disabled:
104+
self.kv_connector.clear_connector_metadata()
105+
97106
def no_forward(self, scheduler_output: "SchedulerOutput") -> ModelRunnerOutput:
98107
if self._disabled:
99108
return EMPTY_MODEL_RUNNER_OUTPUT

vllm/v1/worker/gpu_model_runner.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3524,6 +3524,9 @@ def execute_model(
35243524

35253525
# Run the model.
35263526
# Use persistent buffers for CUDA graphs.
3527+
# When spec decode is enabled, delay clearing connector metadata
3528+
# until after draft model runs in sample_tokens.
3529+
clear_kv_metadata = self.speculative_config is None
35273530
with (
35283531
set_forward_context(
35293532
attn_metadata,
@@ -3537,7 +3540,9 @@ def execute_model(
35373540
skip_compiled=has_encoder_input,
35383541
),
35393542
record_function_or_nullcontext("gpu_model_runner: forward"),
3540-
self.maybe_get_kv_connector_output(scheduler_output) as kv_connector_output,
3543+
self.maybe_get_kv_connector_output(
3544+
scheduler_output, clear_metadata=clear_kv_metadata
3545+
) as kv_connector_output,
35413546
):
35423547
model_output = self._model_forward(
35433548
input_ids=input_ids,
@@ -3765,6 +3770,12 @@ def propose_draft_token_ids(sampled_token_ids):
37653770
# tokens on the CPU, so they are run after bookkeeping.
37663771
propose_draft_token_ids(valid_sampled_token_ids)
37673772

3773+
# Clear KV connector metadata after draft model runs (if spec decode).
3774+
# This was deferred from target model forward to allow draft model
3775+
# to also save its KV cache.
3776+
if self.speculative_config is not None:
3777+
self.clear_kv_connector_metadata()
3778+
37683779
with record_function_or_nullcontext("gpu_model_runner: eplb"):
37693780
self.eplb_step()
37703781

vllm/v1/worker/kv_connector_model_runner_mixin.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,12 @@ def kv_connector_no_forward(
6767
@staticmethod
6868
def maybe_get_kv_connector_output(
6969
scheduler_output: "SchedulerOutput",
70+
clear_metadata: bool = True,
7071
) -> AbstractContextManager[KVConnectorOutput | None]:
7172
return (
72-
KVConnectorModelRunnerMixin._get_kv_connector_output(scheduler_output)
73+
KVConnectorModelRunnerMixin._get_kv_connector_output(
74+
scheduler_output, clear_metadata=clear_metadata
75+
)
7376
if has_kv_transfer_group()
7477
else nullcontext()
7578
)
@@ -79,7 +82,9 @@ def maybe_get_kv_connector_output(
7982
@staticmethod
8083
@contextmanager
8184
def _get_kv_connector_output(
82-
scheduler_output: "SchedulerOutput", wait_for_save: bool = True
85+
scheduler_output: "SchedulerOutput",
86+
wait_for_save: bool = True,
87+
clear_metadata: bool = True,
8388
) -> Generator[KVConnectorOutput, None, None]:
8489
output = KVConnectorOutput()
8590

@@ -108,6 +113,14 @@ def _get_kv_connector_output(
108113
output.kv_connector_stats = kv_connector.get_kv_connector_stats()
109114
output.kv_cache_events = kv_connector.get_kv_connector_kv_cache_events()
110115

116+
if clear_metadata:
117+
kv_connector.clear_connector_metadata()
118+
119+
@staticmethod
120+
def clear_kv_connector_metadata() -> None:
121+
"""Clear the KV connector metadata. Call after draft model runs."""
122+
if has_kv_transfer_group():
123+
kv_connector = get_kv_transfer_group()
111124
kv_connector.clear_connector_metadata()
112125

113126
@staticmethod

0 commit comments

Comments
 (0)