[Benchmark] Add vLLM-Omni Omni model online benchmark (#780)

Signed-off-by: wangyu31577 <wangyu31577@hundsun.com>
Signed-off-by: wangyu <53896905+yenuo26@users.noreply.github.com>
Co-authored-by: wangyu31577 <wangyu31577@hundsun.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
This commit is contained in:
authored and GitHub committed 2026-01-30 11:41:09 +08:00
1 parent c7fb59fd28
commit 7bfd3c069d
15 files changed
+1546 -1

No files matched your search

@@ -0,0 +1,152 @@
import base64
import io
import logging
from collections.abc import Mapping
from typing import Any
import numpy as np
import soundfile as sf
import torch
from vllm.benchmarks.datasets import RandomMultiModalDataset, process_image, process_video
logger = logging.getLogger(__name__)
def process_audio(audio: Any) -> Mapping[str, Any]:
"""
Process a single audio input and return a multimedia content dictionary.
Supports the following input types:
1. Dictionary with raw audio bytes: - Expects a dict with a 'bytes' key
containing raw audio data.
2. String input: - Treats the string as a URL or local file path. -
Prepends "file://" if the string doesn't start with "http://" or
"file://". - Returns a dictionary with the audio URL.
Raises:
ValueError: If the input is not a supported type.
"""
if isinstance(audio, dict) and "bytes" in audio:
audio_bytes = audio["bytes"]
audio_base64 = base64.b64encode(audio_bytes).decode("utf-8")
return {
"type": "audio_url",
"audio_url": {"url": f"data:audio/mpeg;base64,{audio_base64}"},
}
if isinstance(audio, str):
audio_url = audio if audio.startswith(("http://", "https://", "file://")) else f"file://{audio}"
return {"type": "audio_url", "audio_url": {"url": audio_url}}
raise ValueError(
f"Invalid audio input {audio}. Must be a string of local path/remote url, "
f"or a dictionary with raw audio bytes in the form of `{{'bytes': raw_audio_bytes}}`."
)
# -----------------------------------------------------------------------------
# MultiModalDataset Implementation
# -----------------------------------------------------------------------------
class OmniRandomMultiModalDataset(RandomMultiModalDataset):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def generate_synthetic_audio(
self,
duration: int, # seconds
num_channels: int, # 1:Mono,2:Stereo 5:5.1 surround sound
) -> dict[str, Any]:
"""Generate synthetic audio with random values.
Default use 48000Hz.
"""
sample_rate = 48000
num_samples = int(sample_rate * duration)
audio_data = self._rng.uniform(-0.5, 0.5, (num_samples, num_channels))
audio_data = np.clip(audio_data, -1.0, 1.0)
audio_tensor = torch.FloatTensor(audio_data.T)
audio_np = audio_tensor.numpy()
buffer = io.BytesIO()
sf.write(buffer, audio_np.T, sample_rate, format="wav")
buffer.seek(0)
audio_bytes = buffer.read()
buffer.close()
return {
"bytes": audio_bytes,
}
def generate_mm_item(
self,
mm_item_config: tuple[int, int, int],
) -> Mapping[str, Any]:
"""
Create synthetic images and videos and
apply process_image/process_video respectively.
This follows the OpenAI API chat completions
https://github.com/openai/openai-python
"""
if self.map_config_to_modality(mm_item_config) == "image":
return process_image(self.generate_synthetic_image(mm_item_config[1], mm_item_config[0]))
elif self.map_config_to_modality(mm_item_config) == "video":
return process_video(self.generate_synthetic_video(mm_item_config[1], mm_item_config[0], mm_item_config[2]))
elif self.map_config_to_modality(mm_item_config) == "audio":
return process_audio(self.generate_synthetic_audio(mm_item_config[1], mm_item_config[2]))
else:
raise ValueError(f"Invalid multimodal item configuration: {mm_item_config}")
def generate_synthetic_video(self, width: int, height: int, num_frames: int) -> Any:
"""Generate synthetic video with random values."""
import imageio
video_data = self._rng.integers(
0,
256,
(num_frames, height, width, 3),
dtype=np.uint8,
)
buffer = io.BytesIO()
writer_kwargs = {
"format": "mp4",
"fps": 30,
"codec": "libx264",
"quality": 7,
"pixelformat": "yuv420p",
"macro_block_size": 16,
"ffmpeg_params": [
"-preset",
"medium",
"-crf",
"23",
"-movflags",
"+faststart",
"-pix_fmt",
"yuv420p",
"-vf",
f"scale={width}:{height}",
],
}
with imageio.get_writer(buffer, **writer_kwargs) as writer:
for frame_idx in range(num_frames):
writer.append_data(video_data[frame_idx])
buffer.seek(0)
video_bytes = buffer.read()
return {
"bytes": video_bytes,
}
def map_config_to_modality(self, config: tuple[int, int, int]) -> str:
"""Map the configuration to the modality."""
if config[0] == 0:
return "audio"
elif config[-1] == 1:
return "image"
elif config[-1] > 1:
return "video"
else:
raise ValueError(f"Invalid multimodal item configuration: {config}")