[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

@@ -1,3 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
"""Minimal single-input MiniCPM-o 4.5 Realtime duplex demo.
Run this after starting the duplex server. Strict lifecycle, overlap, and
@@ -19,8 +22,8 @@ if str(REPO_ROOT) not in sys.path:
sys.path.insert(0, str(REPO_ROOT))
from vllm_omni.experimental.fullduplex.client import ( # noqa: E402
PCM16_BYTES_PER_SAMPLE,
PCM16_SAMPLE_RATE,
PCM16_BYTES_PER_SAMPLE, # noqa: F401 - compatibility export
PCM16_SAMPLE_RATE, # noqa: F401 - compatibility export
RealtimeDuplexClient,
RealtimeEventCollector,
build_realtime_url,
@@ -28,6 +31,13 @@ from vllm_omni.experimental.fullduplex.client import ( # noqa: E402
wait_for,
write_pcm16_wav,
)
from vllm_omni.experimental.fullduplex.client import chunk_period_ms as _chunk_period_ms # noqa: E402
from vllm_omni.experimental.fullduplex.client import ( # noqa: E402
has_residual_model_unit as _has_residual_model_unit,
)
from vllm_omni.experimental.fullduplex.client import ( # noqa: E402
reference_audio_data_url as _ref_audio_data_url,
)
class _StreamingOutputWriter:
@@ -133,25 +143,6 @@ def _latest_model_decision(
return decision
def _chunk_period_ms(events: list[dict[str, object]]) -> int:
for event in reversed(events):
session = event.get("session")
if not isinstance(session, dict):
continue
capabilities = session.get("capabilities")
if not isinstance(capabilities, dict):
continue
chunk_period_ms = capabilities.get("chunk_period_ms")
if isinstance(chunk_period_ms, int) and chunk_period_ms > 0:
return chunk_period_ms
return 1000
def _has_residual_model_unit(pcm16: bytes, *, chunk_period_ms: int) -> bool:
unit_bytes = PCM16_SAMPLE_RATE * PCM16_BYTES_PER_SAMPLE * chunk_period_ms // 1000
return bool(unit_bytes > 0 and len(pcm16) % unit_bytes)
def _response_in_progress(events: list[dict[str, object]]) -> bool:
return sum(event.get("type") == "response.created" for event in events) > sum(
event.get("type") == "response.done" for event in events
@@ -168,13 +159,6 @@ def _event_count_after(
return sum(event.get("type") == event_type for event in events[index + 1 :])
def _ref_audio_data_url(path: str | None) -> str | None:
if path is None:
return None
ref_path = Path(path).expanduser()
return "data:audio/wav;base64," + base64.b64encode(ref_path.read_bytes()).decode("ascii")
async def run_demo(args: argparse.Namespace) -> dict[str, object]:
input_pcm16 = read_pcm16_wav(Path(args.input_wav))
if not input_pcm16: