[Rebase] Rebase to vLLM 0.29.0 (#7230)

Signed-off-by: tzhouam <tzhouam@connect.ust.hk>
Signed-off-by: Zhou Taichang <tzhouam@connect.ust.hk>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Zhou TaichangandClaude Opus 5 authored and GitHub committed 2026-09-10 12:08:28 +08:00
1 parent 333f14e97e
commit aff7d64948
120 files changed
+2958 -1690

No files matched your search

@@ -279,17 +279,17 @@ def _install_native_modules(monkeypatch: pytest.MonkeyPatch, events: list[tuple]
group = SimpleNamespace(get_metadata_builder=lambda _index: SimpleNamespace(reorder_batch_threshold=None))
return [[group], [group]], "cg-support", [4, 8]
# vLLM 0.29 dropped attn_groups and cache_dtype from init_kv_cache: the
# layout now rides on the resolved CacheConfig.kv_cache_layout instead.
def init_cache(
runner_kv_caches,
forward_context,
kv_cache_config,
attn_groups,
device,
cache_dtype,
kernel_block_sizes,
vllm_config,
):
events.append(("cache", kv_cache_config, attn_groups, kernel_block_sizes))
events.append(("cache", kv_cache_config, kernel_block_sizes))
runner_kv_caches.extend(["cache-0", "cache-1"])
return {"layer-0": "tensor-0", "layer-1": "tensor-1"}
@@ -299,8 +299,10 @@ def test_minus_one_max_model_len_is_auto_fitted_by_native_cache_sizing() -> None
)
assert vllm_config.model_config.original_max_model_len == -1
# Sixteen physical pages provide ``16 * block_size`` tokens. The native
# backend chooses the block geometry, so keep this assertion backend
# Sixteen physical pages provide ``(16 - 1) * block_size`` tokens: vLLM 0.29
# subtracts the null block that BlockPool permanently holds back before
# sizing (check_enough_kv_cache_memory), so only 15 pages are usable. The
# native backend chooses the block geometry, so keep this assertion backend
# independent instead of assuming the generic 16-token block size.
expected_max_model_len = min(model_limit, spec.block_size * 16)
expected_max_model_len = min(model_limit, spec.block_size * (16 - 1))
assert vllm_config.model_config.max_model_len == expected_max_model_len
+147
View File
@@ -0,0 +1,147 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
"""Physical KV cache layout selection and propagation for the Diffusion cache."""
from __future__ import annotations
from types import SimpleNamespace
import pytest
import torch
from vllm.config import CacheConfig
from vllm.v1.kv_cache_interface import FullAttentionSpec
from vllm.v1.kv_cache_layout import KVCacheLayout
from vllm_omni.diffusion.diffusion_kv.layout import (
DEFAULT_DIFFUSION_KV_CACHE_LAYOUT,
adopt_kv_cache_layout,
assert_backend_layout_supported,
build_kv_cache_tensor,
resolve_diffusion_kv_cache_layout,
)
pytestmark = [pytest.mark.core_model, pytest.mark.cpu, pytest.mark.diffusion]
def _config():
return SimpleNamespace(cache_config=CacheConfig())
class _DenseBackend:
@classmethod
def indexes_kv_by_block_stride(cls) -> bool:
return False
class _BlockStrideBackend:
@classmethod
def indexes_kv_by_block_stride(cls) -> bool:
return True
def test_default_layout_is_not_block_outermost() -> None:
"""The default reproduces the pre-0.29 indexes_kv_by_block_stride=False."""
vllm_config = _config()
layout = resolve_diffusion_kv_cache_layout(vllm_config)
assert layout is DEFAULT_DIFFUSION_KV_CACHE_LAYOUT
assert layout.is_block_outermost is False
assert vllm_config.cache_config.get_resolved_kv_cache_layout() is layout
def test_block_stride_backend_selects_block_outermost_layout() -> None:
layout = resolve_diffusion_kv_cache_layout(_config(), indexes_kv_by_block_stride=True)
assert layout.is_block_outermost is True
def test_resolution_is_idempotent() -> None:
vllm_config = _config()
assert resolve_diffusion_kv_cache_layout(vllm_config) is resolve_diffusion_kv_cache_layout(vllm_config)
def test_contradicting_requirement_raises_instead_of_misaddressing() -> None:
vllm_config = _config()
resolve_diffusion_kv_cache_layout(vllm_config)
with pytest.raises(ValueError, match="contradicts the attention"):
resolve_diffusion_kv_cache_layout(vllm_config, indexes_kv_by_block_stride=True)
def test_preset_layout_is_honoured() -> None:
vllm_config = _config()
vllm_config.cache_config.kv_cache_layout = KVCacheLayout.BLNHC.name
layout = resolve_diffusion_kv_cache_layout(vllm_config, indexes_kv_by_block_stride=True)
assert layout is KVCacheLayout.BLNHC
def test_backend_assertion_is_quiet_until_the_layout_is_resolved() -> None:
"""Workers collect specs before the control plane hands them the layout."""
vllm_config = _config()
assert_backend_layout_supported(vllm_config, _BlockStrideBackend) # unresolved: nothing to check
resolve_diffusion_kv_cache_layout(vllm_config)
assert_backend_layout_supported(vllm_config, _DenseBackend)
assert_backend_layout_supported(vllm_config, None)
with pytest.raises(ValueError, match="contradicts the attention"):
assert_backend_layout_supported(vllm_config, _BlockStrideBackend)
def test_worker_adopts_the_layout_carried_on_the_kv_cache_config() -> None:
"""Diffusion workers receive only a KVCacheConfig, so the name rides on it."""
worker = _config()
shipped = SimpleNamespace(kv_cache_layout=KVCacheLayout.BLNHC.name)
assert adopt_kv_cache_layout(worker, shipped) is KVCacheLayout.BLNHC
assert worker.cache_config.get_resolved_kv_cache_layout() is KVCacheLayout.BLNHC
def test_worker_without_a_carried_layout_falls_back_to_the_same_default() -> None:
worker = _config()
assert adopt_kv_cache_layout(worker, SimpleNamespace(kv_cache_layout=None)) is DEFAULT_DIFFUSION_KV_CACHE_LAYOUT
def test_worker_disagreeing_with_the_control_plane_raises() -> None:
worker = _config()
resolve_diffusion_kv_cache_layout(worker)
with pytest.raises(ValueError, match="disagrees with the layout"):
adopt_kv_cache_layout(worker, SimpleNamespace(kv_cache_layout=KVCacheLayout.BLNHC.name))
def test_block_stride_requirement_propagates_control_plane_to_worker() -> None:
"""A block-stride backend must reach the worker as a block-outermost layout.
Covers the whole seam: the control plane resolves with the requirement, the
name rides on each rank-local KVCacheConfig, the worker adopts it, and the
backend contract check then passes instead of raising.
"""
control_plane = _config()
layout = resolve_diffusion_kv_cache_layout(control_plane, indexes_kv_by_block_stride=True)
assert layout.is_block_outermost is True
shipped = SimpleNamespace(kv_cache_layout=layout.name)
worker = _config()
assert adopt_kv_cache_layout(worker, shipped) is layout
# The worker's own backend requirement now agrees with what it was handed.
assert_backend_layout_supported(worker, _BlockStrideBackend)
with pytest.raises(ValueError, match="contradicts the attention"):
assert_backend_layout_supported(worker, _DenseBackend)
def test_tensor_strides_come_from_the_upstream_derivation() -> None:
spec = FullAttentionSpec(block_size=16, num_kv_heads=2, head_size=8, dtype=torch.bfloat16)
tensor = build_kv_cache_tensor(spec, 4, ["layer0", "layer1"])
assert tensor.layers == ["layer0", "layer1"]
assert tensor.size == spec.page_size_bytes * 2 * 4
# Layer-outermost: each layer owns a contiguous run of its own blocks.
assert tensor.layer_stride == spec.page_size_bytes * 4
assert tensor.block_stride == spec.page_size_bytes
+4 -3
View File
@@ -1,11 +1,12 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
import pytest
import torch
import vllm.v1.core.single_type_kv_cache_manager as native_kv_managers
from vllm.v1.kv_cache_interface import FullAttentionSpec, KVCacheConfig, KVCacheGroupSpec, KVCacheTensor
from vllm.v1.kv_cache_interface import FullAttentionSpec, KVCacheConfig, KVCacheGroupSpec
from tests.helpers.kv_layout import build_kv_cache_tensor
from vllm_omni.diffusion.diffusion_kv.manager import DiffusionKVAdmissionError, DiffusionKVCacheManager
from vllm_omni.diffusion.diffusion_kv.request import DiffusionKVContext, DiffusionKVRequest
@@ -24,7 +25,7 @@ def _config(num_blocks: int) -> KVCacheConfig:
)
return KVCacheConfig(
num_blocks=num_blocks,
kv_cache_tensors=[KVCacheTensor(size=spec.page_size_bytes * num_blocks, shared_by=["layer0"])],
kv_cache_tensors=[build_kv_cache_tensor(spec, num_blocks, ["layer0"])],
kv_cache_groups=[KVCacheGroupSpec(layer_names=["layer0"], kv_cache_spec=spec)],
)
@@ -15,6 +15,7 @@ import torch
from torch import nn
from vllm.v1.kv_cache_interface import FullAttentionSpec
from tests.helpers.kv_layout import layout_for_backend
from vllm_omni.diffusion.attention.backends.flash_attn import FlashAttentionImpl
from vllm_omni.diffusion.attention.layer import Attention
from vllm_omni.diffusion.diffusion_kv import paged_attention_adapter as adapter_module
@@ -1239,7 +1240,8 @@ def test_layer_adapter_accepts_platform_native_backend_and_uses_rank_local_heads
assert native_layer.num_heads == 4
assert native_layer.num_kv_heads == 2
assert native_layer.spec.num_kv_heads == 2
assert native_layer.spec.indexes_kv_by_block_stride is True
# 0.29: the flag no longer rides on the spec, it selects the layout.
assert layout_for_backend(native_layer.attn_backend).is_block_outermost is True
assert native_layer._q_scale_float == 1.0
assert native_layer._k_scale_float == 1.0
assert native_layer._v_scale_float == 1.0
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
from __future__ import annotations
@@ -10,12 +10,14 @@ import torch
from torch import nn
from torch.nn import functional as F
from vllm.config import AttentionConfig, CacheConfig, VllmConfig, set_current_vllm_config
from vllm.v1.kv_cache_interface import FullAttentionSpec, KVCacheConfig, KVCacheGroupSpec, KVCacheTensor
from vllm.v1.kv_cache_interface import FullAttentionSpec, KVCacheConfig, KVCacheGroupSpec
from vllm.v1.worker.gpu.attn_utils import init_attn_backend, init_kv_cache
from vllm.v1.worker.gpu.block_table import BlockTables
from tests.helpers.kv_layout import build_kv_cache_tensor
from vllm_omni.diffusion.attention.backends.abstract import AttentionMetadata
from vllm_omni.diffusion.attention.backends.flash_attn import FlashAttentionImpl
from vllm_omni.diffusion.diffusion_kv.layout import resolve_diffusion_kv_cache_layout
from vllm_omni.diffusion.diffusion_kv.paged_attention_adapter import (
DiffusionPagedAttentionAdapter,
DiffusionPagedAttentionLayerAdapter,
@@ -88,12 +90,7 @@ def test_adapter_executes_native_paged_attention_on_non_contiguous_blocks() -> N
canonical_spec = native_layer.spec
kv_cache_config = KVCacheConfig(
num_blocks=4,
kv_cache_tensors=[
KVCacheTensor(
size=canonical_spec.page_size_bytes * 4,
shared_by=[_LAYER_NAME],
)
],
kv_cache_tensors=[build_kv_cache_tensor(canonical_spec, 4, [_LAYER_NAME])],
kv_cache_groups=[
KVCacheGroupSpec(
layer_names=[_LAYER_NAME],
@@ -101,6 +98,9 @@ def test_adapter_executes_native_paged_attention_on_non_contiguous_blocks() -> N
)
],
)
# 0.29 reads the resolved physical layout when allocating; the diffusion
# control plane pins it, so this standalone harness must too.
resolve_diffusion_kv_cache_layout(vllm_config)
with set_current_vllm_config(vllm_config):
attn_groups, _, kernel_block_sizes = init_attn_backend(
kv_cache_config,
@@ -108,13 +108,13 @@ def test_adapter_executes_native_paged_attention_on_non_contiguous_blocks() -> N
device,
)
runner_kv_caches: list[torch.Tensor | list[torch.Tensor]] = []
# vLLM 0.29 dropped attn_groups and cache_dtype here: the layout now
# comes from the resolved CacheConfig.kv_cache_layout inside the call.
init_kv_cache(
runner_kv_caches,
vllm_config.compilation_config.static_forward_context,
kv_cache_config,
attn_groups,
device,
vllm_config.cache_config.cache_dtype,
kernel_block_sizes,
vllm_config,
)
+3 -3
View File
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
import pytest
import torch
@@ -10,10 +10,10 @@ from vllm.v1.kv_cache_interface import (
FullAttentionSpec,
KVCacheConfig,
KVCacheGroupSpec,
KVCacheTensor,
)
from vllm.v1.request import RequestStatus
from tests.helpers.kv_layout import build_kv_cache_tensor
from vllm_omni.diffusion.diffusion_kv.request import DiffusionKVContext, DiffusionKVRequest
pytestmark = [pytest.mark.core_model, pytest.mark.cpu, pytest.mark.diffusion]
@@ -119,7 +119,7 @@ def _manager(*, enable_caching: bool) -> KVCacheManager:
group = KVCacheGroupSpec(layer_names=["layer0"], kv_cache_spec=spec)
config = KVCacheConfig(
num_blocks=8,
kv_cache_tensors=[KVCacheTensor(size=spec.page_size_bytes * 8, shared_by=["layer0"])],
kv_cache_tensors=[build_kv_cache_tensor(spec, 8, ["layer0"])],
kv_cache_groups=[group],
)
return KVCacheManager(
@@ -8,9 +8,10 @@ from unittest.mock import Mock
import pytest
import torch
from torch import nn
from vllm.v1.kv_cache_interface import FullAttentionSpec, KVCacheConfig, KVCacheGroupSpec, KVCacheTensor
from vllm.v1.kv_cache_interface import FullAttentionSpec, KVCacheConfig, KVCacheGroupSpec
import vllm_omni.diffusion.worker.diffusion_worker as diffusion_worker_module
from tests.helpers.kv_layout import build_kv_cache_tensor, layout_for_backend
from vllm_omni.diffusion.attention.layer import Attention
from vllm_omni.diffusion.diffusion_kv.config import DiffusionKVCacheMode
from vllm_omni.diffusion.worker.diffusion_model_runner import DiffusionModelRunner
@@ -79,7 +80,9 @@ def test_runner_discovers_native_spec_from_loaded_attention() -> None:
assert spec.num_kv_heads == 2
assert spec.head_size == 8
assert spec.dtype is torch.bfloat16
assert spec.indexes_kv_by_block_stride is True
# vLLM 0.29 moved the block-stride decision off the spec onto the resolved
# physical layout; the backend's declaration must still select one.
assert layout_for_backend(_Backend).is_block_outermost is True
assert spec.non_causal is True
@@ -112,7 +115,7 @@ def test_runner_retains_matching_rank_local_config() -> None:
spec = runner.get_kv_cache_spec()["image_attention"]
config = KVCacheConfig(
num_blocks=8,
kv_cache_tensors=[KVCacheTensor(size=spec.page_size_bytes * 8, shared_by=["image_attention"])],
kv_cache_tensors=[build_kv_cache_tensor(spec, 8, ["image_attention"])],
kv_cache_groups=[KVCacheGroupSpec(layer_names=["image_attention"], kv_cache_spec=spec)],
)
@@ -126,7 +129,7 @@ def test_runner_rejects_rank_local_config_for_different_layers() -> None:
spec = runner.get_kv_cache_spec()["image_attention"]
config = KVCacheConfig(
num_blocks=8,
kv_cache_tensors=[KVCacheTensor(size=spec.page_size_bytes * 8, shared_by=["other_attention"])],
kv_cache_tensors=[build_kv_cache_tensor(spec, 8, ["other_attention"])],
kv_cache_groups=[KVCacheGroupSpec(layer_names=["other_attention"], kv_cache_spec=spec)],
)