From 2fbde2adcfaab575be539494ccacb301b29a5135 Mon Sep 17 00:00:00 2001 From: ZenAlexa Date: Thu, 3 Sep 2026 02:04:11 -0700 Subject: [PATCH 1/2] [Bugfix][Frontend] Clear the P0 multimodal cache through the renderer Route AsyncOmni cache clearing through the renderer's serialized async path. This keeps frontend hash state aligned with EngineCore after sleep and cache-clearing pauses. Signed-off-by: ZenAlexa --- .../test_async_omni_pause_sleep_routing.py | 24 ++++++++++++++++++- vllm_omni/entrypoints/async_omni.py | 19 +++++---------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/tests/entrypoints/test_async_omni_pause_sleep_routing.py b/tests/entrypoints/test_async_omni_pause_sleep_routing.py index 9600b990d23..ab895b687c2 100644 --- a/tests/entrypoints/test_async_omni_pause_sleep_routing.py +++ b/tests/entrypoints/test_async_omni_pause_sleep_routing.py @@ -1,12 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project + """Unit tests for AR EngineCore vs diffusion worker pause/sleep routing.""" from __future__ import annotations import asyncio from types import SimpleNamespace -from unittest.mock import AsyncMock, call +from unittest.mock import AsyncMock, call, create_autospec import pytest +from vllm.renderers import BaseRenderer +from vllm.v1.engine.input_processor import InputProcessor from vllm_omni.diffusion.data import CuMemTag, OmniACK from vllm_omni.entrypoints.async_omni import AsyncOmni @@ -37,6 +42,23 @@ def _make_omni(*, stage_types: list[str]) -> AsyncOmni: return omni +@pytest.mark.cpu +def test_reset_mm_cache_clears_renderer_cache(): + async def run() -> None: + omni = object.__new__(AsyncOmni) + renderer = create_autospec(BaseRenderer, instance=True) + renderer.clear_mm_cache_async = AsyncMock() + input_processor = create_autospec(InputProcessor, instance=True) + input_processor.renderer = renderer + omni.input_processor = input_processor + + await omni.reset_mm_cache() + + renderer.clear_mm_cache_async.assert_awaited_once_with() + + asyncio.run(run()) + + @pytest.mark.cpu def test_split_stage_ids_by_type(): omni = _make_omni(stage_types=["llm", "diffusion", "llm"]) diff --git a/vllm_omni/entrypoints/async_omni.py b/vllm_omni/entrypoints/async_omni.py index 8ac0fde564d..4707592bff5 100644 --- a/vllm_omni/entrypoints/async_omni.py +++ b/vllm_omni/entrypoints/async_omni.py @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project + """ AsyncOmni - Refactored async orchestrator using AsyncOmniEngine. @@ -1421,19 +1424,9 @@ async def reset_mm_cache(self) -> None: ``EngineCore.sleep(level>=1)`` already clears the P1 receiver cache. Clearing P0 avoids hash-only follow-up requests after that reset. """ - processor = getattr(self, "input_processor", None) - if processor is None: - processor = getattr(self.engine, "input_processor", None) - cache = getattr(processor, "mm_processor_cache", None) - if cache is None: - logger.debug("[AsyncOmni] reset_mm_cache: no frontend mm_processor_cache") - return - for name in ("clear", "reset", "clear_cache"): - fn = getattr(cache, name, None) - if callable(fn): - fn() - return - logger.debug("[AsyncOmni] reset_mm_cache: cache has no clear/reset method") + renderer = self.renderer + if renderer is not None: + await renderer.clear_mm_cache_async() async def reset_encoder_cache(self) -> None: """Reset the encoder cache for all stages. From d4531d1023e5cdce291a5535b632fdb0acbb0261 Mon Sep 17 00:00:00 2001 From: ZenAlexa Date: Fri, 4 Sep 2026 10:55:35 -0700 Subject: [PATCH 2/2] [Test] Use pytest-mock for cache reset regression Align the L1 test with repository mocking conventions and name it for the routed behavior it verifies. Signed-off-by: ZenAlexa --- tests/entrypoints/test_async_omni_pause_sleep_routing.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/entrypoints/test_async_omni_pause_sleep_routing.py b/tests/entrypoints/test_async_omni_pause_sleep_routing.py index ab895b687c2..38ec4016384 100644 --- a/tests/entrypoints/test_async_omni_pause_sleep_routing.py +++ b/tests/entrypoints/test_async_omni_pause_sleep_routing.py @@ -7,7 +7,7 @@ import asyncio from types import SimpleNamespace -from unittest.mock import AsyncMock, call, create_autospec +from unittest.mock import AsyncMock, call import pytest from vllm.renderers import BaseRenderer @@ -43,12 +43,11 @@ def _make_omni(*, stage_types: list[str]) -> AsyncOmni: @pytest.mark.cpu -def test_reset_mm_cache_clears_renderer_cache(): +def test_reset_mm_cache_routes_through_renderer(mocker): async def run() -> None: omni = object.__new__(AsyncOmni) - renderer = create_autospec(BaseRenderer, instance=True) - renderer.clear_mm_cache_async = AsyncMock() - input_processor = create_autospec(InputProcessor, instance=True) + renderer = mocker.create_autospec(BaseRenderer, instance=True) + input_processor = mocker.create_autospec(InputProcessor, instance=True) input_processor.renderer = renderer omni.input_processor = input_processor