[Diffusion][HunyuanImage3] Add request paged prefix caching (#7719)
Signed-off-by: zwhzzz0821 <2831474076@qq.com>
This commit is contained in:
1 parent
9a1a05facd
commit
205aa01c7b
49 files changed
+2889
-127
No files matched your search
@@ -13,7 +13,7 @@ from __future__ import annotations
|
||||
import copy
|
||||
import gc
|
||||
import time
|
||||
from collections.abc import Callable
|
||||
from collections.abc import Callable, Sequence
|
||||
from contextlib import AbstractContextManager, nullcontext
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
@@ -97,9 +97,10 @@ def _dit_any_rank_failed(local_failed: bool) -> bool:
|
||||
if not torch.distributed.is_initialized():
|
||||
return local_failed
|
||||
try:
|
||||
from vllm_omni.diffusion.distributed.parallel_state import get_dit_group
|
||||
from vllm_omni.diffusion.distributed import parallel_state
|
||||
|
||||
group = get_dit_group()
|
||||
get_dit_group = getattr(parallel_state, "get_dit_group", None)
|
||||
group = get_dit_group() if get_dit_group is not None else None
|
||||
except (AssertionError, ImportError):
|
||||
group = None
|
||||
if group is None:
|
||||
@@ -489,6 +490,7 @@ class DiffusionModelRunner(DiffusionStagePayloadMixin):
|
||||
def prepare_kv_for_forward(self, scheduler_output: DiffusionSchedulerOutput):
|
||||
from vllm_omni.diffusion.diffusion_kv.kv_connector import wait_for_kv_load
|
||||
|
||||
assert self.od_config.kv_transfer_config is not None
|
||||
timeout = self.od_config.kv_transfer_config.kv_connector_extra_config.get("transfer_timeout", 60.0)
|
||||
if self._kv_receive_progress is not None:
|
||||
return self._kv_receive_progress.prepare(self._kv_connector, scheduler_output, timeout)
|
||||
@@ -505,7 +507,7 @@ class DiffusionModelRunner(DiffusionStagePayloadMixin):
|
||||
) -> int:
|
||||
return self.diffusion_kv_backend.get_diffusion_kv_row(request_id, sequence_id, context_id)
|
||||
|
||||
def remove_diffusion_kv_requests(self, request_ids: list[str | tuple[str, int]]) -> int:
|
||||
def remove_diffusion_kv_requests(self, request_ids: Sequence[str | tuple[str, int]]) -> int:
|
||||
return self.diffusion_kv_backend.remove_diffusion_kv_requests(request_ids)
|
||||
|
||||
def refresh_diffusion_kv_block_table_layout(self) -> None:
|
||||
@@ -538,13 +540,19 @@ class DiffusionModelRunner(DiffusionStagePayloadMixin):
|
||||
f"request={request_metadata.request_id!r}, sequence={sequence.sequence_id}, "
|
||||
f"active={active_seq_len}, allocated={sequence.seq_len}"
|
||||
)
|
||||
# Imported AR KV and local hits have separate owners.
|
||||
kv_start_pos = (
|
||||
sequence.num_computed_tokens
|
||||
if getattr(self.od_config, "kv_transfer_config", None) is not None
|
||||
else sequence.cached_prefix_len
|
||||
)
|
||||
prefill_rows.append(
|
||||
DiffusionPagedAttentionRow(
|
||||
request_id=request_metadata.request_id,
|
||||
sequence_id=sequence.sequence_id,
|
||||
query_len=sequence.seq_len - sequence.num_computed_tokens,
|
||||
kv_start_pos=kv_start_pos,
|
||||
query_len=sequence.seq_len - kv_start_pos,
|
||||
seq_len=sequence.seq_len,
|
||||
kv_start_pos=sequence.num_computed_tokens,
|
||||
)
|
||||
)
|
||||
denoise_rows.append(
|
||||
@@ -800,17 +808,48 @@ class DiffusionModelRunner(DiffusionStagePayloadMixin):
|
||||
"Diffusion KV metadata count must match the request batch: "
|
||||
f"metadata={len(diffusion_kv_metadata)}, requests={len(reqs)}"
|
||||
)
|
||||
for req, metadata in zip(reqs, diffusion_kv_metadata, strict=True):
|
||||
req.kv_computed_tokens = tuple(seq.num_computed_tokens for seq in metadata.sequences)
|
||||
native_kv_transfer = getattr(self.od_config, "kv_transfer_config", None) is not None
|
||||
if native_kv_transfer:
|
||||
for req, metadata in zip(reqs, diffusion_kv_metadata, strict=True):
|
||||
# This field is consumed by Hunyuan only for native
|
||||
# AR->DiT transfer. Local prefix hits must still run
|
||||
# their VAE/ViT conditioning path.
|
||||
req.kv_computed_tokens = tuple(seq.num_computed_tokens for seq in metadata.sequences)
|
||||
paged_metadata = self._build_paged_attention_metadata(diffusion_kv_metadata)
|
||||
paged_kv_cached_prefix_len = 0
|
||||
if not native_kv_transfer:
|
||||
cached_prefix_lens = {row.kv_start_pos for row in paged_metadata.prefill_rows}
|
||||
if len(cached_prefix_lens) != 1:
|
||||
raise ValueError(
|
||||
"One paged request-level forward requires a uniform cached prefix boundary; "
|
||||
f"got {sorted(cached_prefix_lens)}"
|
||||
)
|
||||
paged_kv_cached_prefix_len = next(iter(cached_prefix_lens))
|
||||
paged_kv_runtime, paged_kv_context = self.diffusion_kv_backend.activate_paged_attention_metadata(
|
||||
paged_metadata
|
||||
)
|
||||
if is_primary:
|
||||
# Trace the boundary actually passed to the model, not a
|
||||
# speculative lookup. Useful for warm-cache regressions.
|
||||
for request_metadata in diffusion_kv_metadata:
|
||||
for sequence in request_metadata.sequences:
|
||||
logger.debug(
|
||||
"Diffusion prefix prefill: request_id=%s sequence_id=%d "
|
||||
"cached_prefix_len=%d prefix_len=%d query_len=%d",
|
||||
request_metadata.request_id,
|
||||
sequence.sequence_id,
|
||||
sequence.cached_prefix_len,
|
||||
sequence.prefix_len,
|
||||
sequence.seq_len - sequence.cached_prefix_len,
|
||||
)
|
||||
else:
|
||||
paged_kv_cached_prefix_len = 0
|
||||
with (
|
||||
set_forward_context(
|
||||
vllm_config=self.vllm_config,
|
||||
omni_diffusion_config=od_config,
|
||||
paged_kv_runtime=paged_kv_runtime,
|
||||
paged_kv_cached_prefix_len=paged_kv_cached_prefix_len,
|
||||
in_diffusion_kv_memory_profile=in_diffusion_kv_memory_profile,
|
||||
),
|
||||
paged_kv_context,
|
||||
@@ -1054,7 +1093,10 @@ class DiffusionModelRunner(DiffusionStagePayloadMixin):
|
||||
prepared_layout=getattr(sched_new_req.req, "prepared_layout", None),
|
||||
external_req_id=getattr(sched_new_req.req, "external_req_id", None),
|
||||
)
|
||||
if sched_new_req.diffusion_kv_metadata is not None:
|
||||
if (
|
||||
sched_new_req.diffusion_kv_metadata is not None
|
||||
and getattr(self.od_config, "kv_transfer_config", None) is not None
|
||||
):
|
||||
new_state.extra["kv_computed_tokens"] = tuple(
|
||||
seq.num_computed_tokens for seq in sched_new_req.diffusion_kv_metadata.sequences
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user