[Benchmark] Add local OmniInteract realtime benchmark (#6522)

Signed-off-by: natureofnature <wzliu@connect.hku.hk>
This commit is contained in:
NATURE authored and GitHub committed 2026-08-25 15:32:58 +00:00
1 parent c608910d20
commit 497c537c6f
16 files changed
+3025 -149

No files matched your search

+81 -3
View File
@@ -1,3 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
import asyncio
import base64
import wave
from urllib.parse import parse_qs, urlsplit
@@ -20,7 +24,7 @@ pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
def test_realtime_client_builds_explicit_native_duplex_url():
url = build_realtime_url(
"ws://localhost:8099/v1/realtime?custom=1",
"ws://localhost:8099/v1/realtime?custom=1&duplex=0&model=stale&minicpmo45_native_duplex=0&session_id=stale",
"openbmb/MiniCPM-o-4_5",
session_id="session-a",
)
@@ -50,7 +54,7 @@ def test_seed_tts_initial_text_is_part_of_native_duplex_context():
def test_realtime_client_builds_resume_only_url_when_autostart_disabled():
url = build_realtime_url(
"ws://localhost:8099/v1/realtime?duplex=1",
"ws://localhost:8099/v1/realtime?duplex=1&autostart=1",
"openbmb/MiniCPM-o-4_5",
autostart=False,
)
@@ -73,10 +77,15 @@ async def test_realtime_client_configure_omits_ref_audio_by_default():
client = Client()
await client.configure("openbmb/MiniCPM-o-4_5", timeout_s=1)
await client.configure(
"openbmb/MiniCPM-o-4_5",
idle_timeout_s=900,
timeout_s=1,
)
session = client.sent[0]["session"]
assert "ref_audio" not in session
assert session["idle_timeout_s"] == 900
@pytest.mark.asyncio
@@ -100,6 +109,74 @@ async def test_realtime_client_configure_sends_explicit_ref_audio():
session = client.sent[0]["session"]
assert session["ref_audio"] == "data:audio/wav;base64,AAAA"
assert "idle_timeout_s" not in session
@pytest.mark.asyncio
async def test_realtime_client_reports_reader_exit_to_event_waiters():
client = RealtimeDuplexClient("ws://unused")
async def stopped():
return None
client._reader_task = asyncio.create_task(stopped())
await client._reader_task
with pytest.raises(ConnectionError, match="closed before"):
client.raise_if_reader_stopped()
@pytest.mark.asyncio
async def test_realtime_client_configure_reports_reader_failure_immediately():
class Client(RealtimeDuplexClient):
async def send(self, event):
async def fail():
raise RuntimeError("reader failed")
self._reader_task = asyncio.create_task(fail())
await asyncio.sleep(0)
client = Client("ws://unused")
with pytest.raises(ConnectionError, match="reader failed"):
await client.configure("model", timeout_s=10.0)
@pytest.mark.asyncio
async def test_realtime_client_close_reports_reader_cancellation_immediately():
class Client(RealtimeDuplexClient):
async def send(self, event):
async def wait_forever():
await asyncio.Future()
self._reader_task = asyncio.create_task(wait_forever())
self._reader_task.cancel()
with pytest.raises(asyncio.CancelledError):
await self._reader_task
client = Client("ws://unused")
with pytest.raises(ConnectionError, match="reader was cancelled"):
await client.close_session(timeout_s=10.0)
@pytest.mark.asyncio
async def test_realtime_client_close_waits_for_a_new_session_closed_event():
class Client(RealtimeDuplexClient):
async def send(self, event):
assert event["type"] == "session.close"
async def acknowledge_close():
await asyncio.sleep(0.02)
self.events.add({"type": "session.closed"})
asyncio.create_task(acknowledge_close())
client = Client("ws://unused")
client.events.add({"type": "session.closed", "reason": "old"})
started_at = asyncio.get_running_loop().time()
await client.close_session(timeout_s=0.2)
assert asyncio.get_running_loop().time() - started_at >= 0.01
@pytest.mark.asyncio
@@ -235,6 +312,7 @@ def test_realtime_event_collector_reports_engine_token_and_audio_intervals():
"output_token_count": 4,
"ttft_ms": 120.0,
"tpot_ms": 15.0,
"itls_ms": [10.0, 14.0, 18.0],
"inter_token_interval_ms": {
"count": 3,
"mean": 14.0,