From 1f4e1badc631ab326a162c6d649d4cd6536b6a32 Mon Sep 17 00:00:00 2001 From: Zhou Taichang Date: Thu, 18 Dec 2025 11:51:37 +0800 Subject: [PATCH] [Benchmark] Benchmark Running Samples for Qwen3 Omni and Dataset Preparation (#212) Signed-off-by: tzhouam Signed-off-by: Zhou Taichang --- benchmarks/README.md | 42 +++ .../download_process_data_seedtts.md | 82 ++++++ .../build_dataset/extract_tts_prompts.py | 73 +++++ benchmarks/qwen3-omni/README.md | 86 ++++++ .../eval_qwen3_moe_omni_transformers.sh | 26 ++ .../transformers/qwen3_omni_moe_model.py | 265 +++++++++++++++++ .../qwen3_omni_moe_transformers.py | 275 ++++++++++++++++++ benchmarks/qwen3-omni/vllm-omni-vs-hf.png | Bin 0 -> 117520 bytes .../vllm_omni/eval_qwen3_moe_omni.sh | 37 +++ .../offline_inference/qwen3_omni/end2end.py | 13 + 10 files changed, 899 insertions(+) create mode 100644 benchmarks/README.md create mode 100644 benchmarks/build_dataset/download_process_data_seedtts.md create mode 100644 benchmarks/build_dataset/extract_tts_prompts.py create mode 100644 benchmarks/qwen3-omni/README.md create mode 100644 benchmarks/qwen3-omni/transformers/eval_qwen3_moe_omni_transformers.sh create mode 100644 benchmarks/qwen3-omni/transformers/qwen3_omni_moe_model.py create mode 100644 benchmarks/qwen3-omni/transformers/qwen3_omni_moe_transformers.py create mode 100644 benchmarks/qwen3-omni/vllm-omni-vs-hf.png create mode 100644 benchmarks/qwen3-omni/vllm_omni/eval_qwen3_moe_omni.sh diff --git a/benchmarks/README.md b/benchmarks/README.md new file mode 100644 index 000000000..5ff270b7f --- /dev/null +++ b/benchmarks/README.md @@ -0,0 +1,42 @@ +# Benchmarks Overview and Architecture + +This document explains the benchmark architecture across all benchmark assets in this repo. It describes what we measure, and where to find or plug in new scenarios. Per-task details remain in subfolder READMEs (e.g., `benchmarks//README.md`). + +## Scope and goals +- Establish repeatable latency/throughput measurements for multimodal LLM pipelines. +- Provide both HF Transformers (offline) and vLLM-Omni (multi-stage/pipeline) baselines. +- Make it easy to plug in new datasets and models with minimal changes to the runner scripts. + +## Dataset and inputs +- Default example: SeedTTS top-100 prompts (`benchmarks/build_dataset/top100.txt`) via `benchmarks/build_dataset/`. +- Extensible: drop in new prompt files or modality-aligned payloads; keep the expected format for the consuming scripts (e.g., one prompt per line). +- If you add a new dataset, document it under `benchmarks//README.md` and point scripts to your data path. + +## Directory layout +- `benchmarks/build_dataset/` — dataset prep utilities (e.g., SeedTTS top100). +- `benchmarks//vllm_omni/` — vLLM-Omni pipeline benchmarks, logs, outputs. +- Add new tasks under `benchmarks//...` with the same pattern: `transformers/`, `vllm_omni/`, task-specific README, and (optionally) dataset prep notes. + +## Reference workflows +- **HF Transformers (offline, single process)** + Script (example): `benchmarks//transformers/eval_qwen3_moe_omni_transformers.sh` + Outputs: `benchmark_results/perf_stats.json`, `benchmark_results/results.json`, `benchmark_results/audio/` (if audio is produced). + +- **vLLM-Omni end-to-end pipeline** + Script (example): `benchmarks//vllm_omni/eval_qwen3_moe_omni.sh` + Outputs: `vllm_omni/logs/*.stats.jsonl` (per-stage/overall latency & TPS), `vllm_omni/logs/stage*.log`, `vllm_omni/outputs/` (text/audio artifacts). + +- **Adding a new task/model** + 1) Create `benchmarks//transformers/` and/or `benchmarks//vllm_omni/` with scripts referencing your model and dataset. + 2) Add a task README describing dataset, configs, and expected outputs. + 3) Keep the output/log structure similar for easy comparison (perf_stats/results/audio or text outputs; stats.jsonl/logs for pipeline). + +## Metrics to watch +- **Throughput**: `overall_tps`, `*_tps_avg` per stage. +- **Latency distribution**: look for long tails in `*.stats.jsonl`. +- **Quality/completeness**: missing outputs or errors in stage logs indicate pipeline failures or misconfigurations. + +## Troubleshooting +- Verify GPU/driver/FlashAttention2 requirements for your chosen model/config. +- Ensure network access for dataset/model downloads (Google Drive, Hugging Face, etc.). +- If outputs are missing or slow, inspect per-stage logs and `*.stats.jsonl` for errors, stragglers, or contention. diff --git a/benchmarks/build_dataset/download_process_data_seedtts.md b/benchmarks/build_dataset/download_process_data_seedtts.md new file mode 100644 index 000000000..54bb0f9c9 --- /dev/null +++ b/benchmarks/build_dataset/download_process_data_seedtts.md @@ -0,0 +1,82 @@ +# Benchmark Dataset Preparation Guide + +This guide describes how to download and prepare the SeedTTS test dataset for benchmarking Qwen-Omni models. + +## Prerequisites + +- Python 3.8+ +- `gdown` for downloading from Google Drive +- Access to the benchmark scripts + +## Steps + +### 1. Navigate to the Dataset Directory + +```bash +cd benchmarks/build_dataset +``` + +### 2. Install Dependencies + +```bash +pip install gdown +``` + +### 3. Download the SeedTTS Test Dataset + +Download the dataset from Google Drive: + +```bash +gdown --id 1GlSjVfSHkW3-leKKBlfrjuuTGqQ_xaLP +``` + +### 4. Extract the Dataset + +```bash +tar -xf seedtts_testset.tar +``` + +### 5. Prepare the Metadata File + +Copy the English metadata file to the working directory: + +```bash +cp seedtts_testset/en/meta.lst meta.lst +``` + +### 6. Extract Prompts + +Extract the first N prompts from the metadata file: + +```bash +# Extract top 100 prompts (adjust -n for different amounts) +python extract_tts_prompts.py -i meta.lst -o top100.txt -n 100 +``` + +**Options:** +- `-i, --input`: Input metadata file (default: `meta.lst`) +- `-o, --output`: Output prompts file (default: `prompts.txt`) +- `-n, --num_lines`: Number of prompts to extract (required) + +### 7. Clean Up (Optional) + +Remove temporary files to save disk space: + +```bash +rm -rf seedtts_testset +rm seedtts_testset.tar +rm meta.lst +``` + +## Quick Start (All-in-One) + +```bash +# Full setup and benchmark +cd benchmarks/build_dataset +pip install gdown +gdown --id 1GlSjVfSHkW3-leKKBlfrjuuTGqQ_xaLP +tar -xf seedtts_testset.tar +cp seedtts_testset/en/meta.lst meta.lst +python extract_tts_prompts.py -i meta.lst -o top100.txt -n 100 +rm -rf seedtts_testset seedtts_testset.tar meta.lst +``` diff --git a/benchmarks/build_dataset/extract_tts_prompts.py b/benchmarks/build_dataset/extract_tts_prompts.py new file mode 100644 index 000000000..4ca3d1908 --- /dev/null +++ b/benchmarks/build_dataset/extract_tts_prompts.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +""" +Extract prompts from meta.lst and save them to a txt file. + +Each line in meta.lst has the format: +ID|prompt_text|audio_path|target_text + +This script extracts the prompt_text (second field) from the first N lines. +""" + +import argparse +from pathlib import Path + + +def extract_prompts(input_file: str, output_file: str, num_lines: int) -> None: + """ + Extract prompts from meta.lst and save to output file. + + Args: + input_file: Path to the meta.lst file + output_file: Path to the output txt file + num_lines: Number of lines to process + """ + prompts = [] + + with open(input_file, encoding="utf-8") as f: + for i, line in enumerate(f): + if i >= num_lines: + break + + line = line.strip() + if not line: # Skip empty lines + continue + + parts = line.split("|") + if len(parts) >= 2: + prompt = parts[1] # The prompt is the second field + prompts.append(prompt) + + # Write prompts to output file + with open(output_file, "w", encoding="utf-8") as f: + for prompt in prompts: + f.write(prompt + "\n") + + # Print result stats + print(f"Extracted {len(prompts)} prompts from first {num_lines} lines") + print(f"Saved to: {output_file}") + + +def main(): + parser = argparse.ArgumentParser(description="Extract prompts from meta.lst file") + parser.add_argument( + "-i", "--input", type=str, default="meta.lst", help="Input meta.lst file path (default: meta.lst)" + ) + parser.add_argument( + "-o", "--output", type=str, default="prompts.txt", help="Output txt file path (default: prompts.txt)" + ) + parser.add_argument( + "-n", "--num_lines", type=int, required=True, help="Number of lines to extract from the beginning" + ) + + args = parser.parse_args() + + # Check if input file exists + if not Path(args.input).exists(): + print(f"Error: Input file '{args.input}' not found") + return + + extract_prompts(args.input, args.output, args.num_lines) + + +if __name__ == "__main__": + main() diff --git a/benchmarks/qwen3-omni/README.md b/benchmarks/qwen3-omni/README.md new file mode 100644 index 000000000..fdc385445 --- /dev/null +++ b/benchmarks/qwen3-omni/README.md @@ -0,0 +1,86 @@ +# Benchmarks Guide + +This README explains how to (1) prepare benchmark datasets and (2) run the provided Qwen3-Omni benchmarks. + +## 1) Prepare the dataset (SeedTTS top100) + +```bash +cd benchmarks/build_dataset +pip install gdown + +# Download SeedTTS test set from Google Drive +gdown --id 1GlSjVfSHkW3-leKKBlfrjuuTGqQ_xaLP + +# Extract +tar -xf seedtts_testset.tar + +# Copy metadata and extract top-100 prompts +cp seedtts_testset/en/meta.lst meta.lst +python extract_prompts.py -i meta.lst -o top100.txt -n 100 + +# (Optional) clean up to save space +rm -rf seedtts_testset seedtts_testset.tar meta.lst +``` + +Artifacts: +- `benchmarks/build_dataset/top100.txt` — 100 text prompts (one per line). + +## 2) Run benchmarks + +All commands assume repo root (`vllm-omni`). + +### A. Transformers benchmark (offline, HF Transformers) + +``` +bash benchmarks/qwen3-omni/transformers/eval_qwen3_moe_omni_transformers.sh +``` + +What it does: +- Runs `qwen3_omni_moe_transformers.py` over `top100.txt` with `--num_prompts 100`. +- Outputs to `benchmarks/qwen3-omni/transformers/benchmark_results/`: + - `perf_stats.json` — aggregated & per-prompt TPS/latency (thinker/talker/code2wav/overall). + - `results.json` — per-prompt outputs and audio paths. + - `audio/` — ~100 generated `.wav` files. + +Key checks: +- `overall_tps` and `*_tps_avg` should be non-zero and reasonably stable. +- Investigate any 0/NaN or unusually low TPS / long-tail latency. + +### B. vLLM Omni end-to-end benchmark (pipeline) + +``` +bash benchmarks/qwen3-omni/vllm_omni/eval_qwen3_moe_omni.sh +``` + +What it does: +- Runs `examples/offline_inference/qwen3_omni/end2end.py` with `--enable-stats`. +- Uses `benchmarks/build_dataset/top100.txt` and writes to: + - Logs: `benchmarks/qwen3-omni/vllm_omni/logs/` + - `omni_llm_pipeline_text.orchestrator.stats.jsonl` — per-stage latency stats. + - `omni_llm_pipeline_text.overall.stats.jsonl` — end-to-end latency/TPS. + - `omni_llm_pipeline_text.stage{0,1,2}.log` — per-stage detailed logs/errors. + - Outputs: `benchmarks/qwen3-omni/vllm_omni/outputs/` — ~100 text and `.wav` files. + +Key checks: +- Overall stats: end-to-end latency/TPS should be reasonable. +- Orchestrator stats: per-stage latency should be stable; investigate long tails. +- Stage logs: ensure no errors and no unusually slow stages. + + +## Performance snapshot + +The chart below summarizes our measured Qwen3-Omni MoE end-to-end benchmark, comparing vLLM-Omni against HF Transformers. It shows the overall throughput advantage for vLLM-Omni. These are actual experiment results—please refer to this performance when evaluating or reproducing the benchmark. + +![vLLM-Omni vs HF](./vllm-omni-vs-hf.png) + +## Directory layout +- `benchmarks/build_dataset/` — dataset prep utilities (e.g., SeedTTS top100). +- `benchmarks//vllm_omni/` — vLLM-Omni pipeline benchmarks, logs, outputs. +- Add new tasks under `benchmarks//...` with the same pattern: `transformers/`, `vllm_omni/`, task-specific README, and (optionally) dataset prep notes. +- `benchmarks//vllm-omni-vs-hf.png` — current performance snapshot (overall throughput comparison). +- `benchmarks//transformers/` — HF Transformers benchmarks (offline reference). + +## Troubleshooting +- Make sure GPU/driver/FlashAttention2 requirements are met for the chosen model. +- If downloads fail, confirm network access to Google Drive (`gdown`) and Hugging Face. +- If audio files are missing, check for errors in stage logs or model generation.*** diff --git a/benchmarks/qwen3-omni/transformers/eval_qwen3_moe_omni_transformers.sh b/benchmarks/qwen3-omni/transformers/eval_qwen3_moe_omni_transformers.sh new file mode 100644 index 000000000..2679adf4f --- /dev/null +++ b/benchmarks/qwen3-omni/transformers/eval_qwen3_moe_omni_transformers.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Qwen3-Omni Transformers Benchmark Evaluation Script +# This script must be run from the vllm-omni root directory + +# Get the directory where this script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Navigate to vllm-omni root directory (4 levels up from script location) +VLLM_OMNI_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" +cd "$VLLM_OMNI_ROOT" || { echo "Error: Failed to navigate to vllm-omni directory"; exit 1; } + +echo "Working directory: $(pwd)" +# Verify we're in the correct directory and run benchmark +if [[ ! -f "benchmarks/qwen3-omni/transformers/qwen3_omni_moe_transformers.py" ]]; then + echo "Error: Not in vllm-omni root directory. Please run from vllm-omni folder." +else + cd benchmarks/qwen3-omni/transformers + + python qwen3_omni_moe_transformers.py --prompts_file ../../build_dataset/top100.txt --num_prompts 100 + + echo "Logs and outputs are saved to $(pwd)/benchmark_results:" + echo " - perf_stats.json Aggregated/per-prompt TPS and latency (thinker/talker/code2wav/overall)" + echo " - results.json Per-prompt outputs and audio paths" + echo " - audio/ Generated wav files, there should be 100 wav file generated" + echo "Key checks: overall_tps and *_tps_avg should be non-zero and stable; investigate 0/NaN or unusually low TPS/long-tail latency." +fi diff --git a/benchmarks/qwen3-omni/transformers/qwen3_omni_moe_model.py b/benchmarks/qwen3-omni/transformers/qwen3_omni_moe_model.py new file mode 100644 index 000000000..43b56f3e9 --- /dev/null +++ b/benchmarks/qwen3-omni/transformers/qwen3_omni_moe_model.py @@ -0,0 +1,265 @@ +import time + +import torch +from transformers import Qwen3OmniMoeForConditionalGeneration + + +class Qwen3OmniMoeForConditionalGenerationWithLogging(Qwen3OmniMoeForConditionalGeneration): + @torch.no_grad() + def generate( + self, + input_ids: torch.Tensor | None = None, + speaker: str = "Ethan", + use_audio_in_video: bool = False, + return_audio: bool | None = None, + thinker_max_new_tokens: int = 1024, + thinker_eos_token_id: int = 151645, + talker_max_new_tokens: int = 4096, + talker_do_sample: bool = True, + talker_top_k: int = 50, + talker_top_p: float = 1.0, + talker_temperature: float = 0.9, + talker_repetition_penalty: float = 1.05, + **kwargs, + ): + total_t0 = time.time() + perf_stats = { + "thinker_tokens": 0, + "thinker_time_s": 0.0, + "thinker_tps": 0.0, + "talker_tokens": 0, + "talker_time_s": 0.0, + "talker_tps": 0.0, + "code2wav_tokens": 0, + "code2wav_time_s": 0.0, + "code2wav_tps": 0.0, + "total_tokens": 0, + "total_time_s": 0.0, + "total_tps": 0.0, + } + if return_audio and not self.has_talker: + raise ValueError( + "Cannot use talker when talker module not initialized. " + "Use `enable_talker` method or set enable_talker in config " + "to enable talker." + ) + if return_audio is None: + return_audio = self.has_talker + + shared_kwargs = {"use_audio_in_video": use_audio_in_video} + thinker_kwargs = { + "max_new_tokens": thinker_max_new_tokens, + "eos_token_id": thinker_eos_token_id, + } + + talker_kwargs = {} + token2wav_kwargs = {} + if return_audio: + speaker_id = self.config.talker_config.speaker_id.get(speaker.lower()) + if speaker_id is None: + raise NotImplementedError(f"Speaker {speaker} not implemented") + if input_ids.shape[0] != 1: + raise NotImplementedError("Qwen3-Omni currently does not support batched inference with audio output") + talker_suppressed_tokens = [ + i + for i in range( + self.config.talker_config.text_config.vocab_size - 1024, + self.config.talker_config.text_config.vocab_size, + ) + if i != self.config.talker_config.codec_eos_token_id + ] # Suppress additional special tokens, should not be predicted + talker_kwargs = { + "max_new_tokens": talker_max_new_tokens, + "do_sample": talker_do_sample, + "top_k": talker_top_k, + "top_p": talker_top_p, + "temperature": talker_temperature, + "eos_token_id": self.config.talker_config.codec_eos_token_id, + "repetition_penalty": talker_repetition_penalty, + "suppress_tokens": talker_suppressed_tokens, + "output_hidden_states": True, + "return_dict_in_generate": True, + } + token2wav_kwargs = {} + + for key, value in kwargs.items(): + if key.startswith("thinker_"): + thinker_kwargs[key[len("thinker_") :]] = value + elif key.startswith("talker_"): + talker_kwargs[key[len("talker_") :]] = value + elif key.startswith("token2wav_"): + token2wav_kwargs[key[len("token2wav_") :]] = value + # Process special input values + elif key == "feature_attention_mask": + thinker_kwargs[key] = value + talker_kwargs["audio_feature_lengths"] = torch.sum(value, dim=1) + elif key in ("input_features", "attention_mask"): + thinker_kwargs[key] = value + # Put other key to shared kwargs + else: + shared_kwargs[key] = value + + # Merge kwargs + for key, value in shared_kwargs.items(): + if key not in thinker_kwargs: + thinker_kwargs[key] = value + if key not in talker_kwargs and key in ["image_grid_thw", "video_grid_thw", "video_second_per_grid"]: + talker_kwargs[key] = value + if key not in token2wav_kwargs: + token2wav_kwargs[key] = value + + # 1. Generate from thinker module + generate_audio = return_audio and self.has_talker + if generate_audio: + thinker_kwargs["output_hidden_states"] = True + thinker_kwargs["return_dict_in_generate"] = True + + t0 = time.time() + thinker_result = self.thinker.generate(input_ids=input_ids, **thinker_kwargs) + t1 = time.time() + perf_stats["thinker_time_s"] = max(0.0, t1 - t0) + try: + prompt_len = int(input_ids.shape[1]) if input_ids is not None else 0 + total_len = int(thinker_result.sequences.shape[-1]) + thinker_out_len = max(0, total_len - prompt_len) + except Exception: + thinker_out_len = 0 + perf_stats["thinker_tokens"] = thinker_out_len + perf_stats["thinker_tps"] = ( + (thinker_out_len / perf_stats["thinker_time_s"]) if perf_stats["thinker_time_s"] > 0 else 0.0 + ) + + if not generate_audio: + perf_stats["total_tokens"] = perf_stats["thinker_tokens"] + perf_stats["total_time_s"] = time.time() - total_t0 + perf_stats["total_tps"] = ( + (perf_stats["total_tokens"] / perf_stats["total_time_s"]) if perf_stats["total_time_s"] > 0 else 0.0 + ) + # attach stats to self + setattr(self, "_perf_stats_last", perf_stats) + if not hasattr(self, "_perf_stats_history"): + setattr(self, "_perf_stats_history", []) + self._perf_stats_history.append(perf_stats) + return thinker_result, None + + # 2. Prepare talker input + thinker_embed = torch.cat([hidden_states[0] for hidden_states in thinker_result.hidden_states], dim=1).to( + self.talker.device + ) # [1 t d] + thinker_hidden = torch.cat( + [ + hidden_states[self.config.talker_config.accept_hidden_layer] + for hidden_states in thinker_result.hidden_states + ], + dim=1, + ).to(self.talker.device) # [1 t d] + + im_start_indexes = torch.cat( + ( + torch.nonzero(input_ids[0] == self.config.im_start_token_id).squeeze(), + torch.tensor([thinker_result.sequences.shape[-1]], device=input_ids.device, dtype=input_ids.dtype), + ), + dim=-1, + ).to(self.talker.device) # Shape [n_starts + 1]; Take batch 0 since batched inference is not supported here. + multimodal_mask = ( + (thinker_result.sequences == self.config.thinker_config.audio_token_id) | + (thinker_result.sequences == self.config.thinker_config.image_token_id) | + (thinker_result.sequences == self.config.thinker_config.video_token_id) + ).to(self.talker.device) # [1 t] # fmt: skip + + talker_special_tokens = torch.tensor( + [[self.config.tts_bos_token_id, self.config.tts_eos_token_id, self.config.tts_pad_token_id]], + device=self.thinker.device, + dtype=input_ids.dtype, + ) + tts_bos_embed, tts_eos_embed, tts_pad_embed = ( + self.talker.text_projection(self.thinker.get_input_embeddings()(talker_special_tokens)) + .to(self.talker.device) + .chunk(3, dim=1) + ) # 3 * [1 1 d] + + talker_input_embeds = [] # [1 t d] + talker_input_ids = [] + # For every chatml parts + for i in range(len(im_start_indexes) - 1): + im_start_index = im_start_indexes[i] + segment_end_index = im_start_indexes[i + 1] + role_token = input_ids[0][im_start_index + 1] + # Talker should ignore thinker system prompt + if role_token == self.config.system_token_id: + continue + # Talker takes word embeddings for tokens and hidden state from `accept_hidden_layer` for multimodal inputs + elif role_token == self.config.user_token_id: + talker_user_part = self._get_talker_user_parts( + im_start_index, segment_end_index, multimodal_mask, thinker_hidden, thinker_embed + ) + talker_input_embeds.append(talker_user_part) + talker_input_ids.append(thinker_result.sequences[:, im_start_index:segment_end_index]) + # Take assistant output (for now) + elif role_token == self.config.assistant_token_id and i == len(im_start_indexes) - 2: + talker_assistant_embeds, talker_assistant_ids, trailing_text_hidden = self._get_talker_assistant_parts( + im_start_index, + segment_end_index, + speaker_id, + thinker_embed, + tts_pad_embed, + tts_bos_embed, + tts_eos_embed, + ) + talker_input_embeds.append(talker_assistant_embeds) + talker_input_ids.append(talker_assistant_ids) + # History assistant output (ignore for now) + elif role_token == self.config.assistant_token_id and i != len(im_start_indexes) - 2: + continue + else: + raise AssertionError("Expect role id after <|im_start|> (assistant, user, system)") + talker_input_embed = torch.cat([embed.to(self.talker.device) for embed in talker_input_embeds], dim=1) + talker_input_id = torch.cat([embed.to(self.talker.device) for embed in talker_input_ids], dim=1) + t2 = time.time() + talker_result = self.talker.generate( + inputs_embeds=talker_input_embed, + trailing_text_hidden=trailing_text_hidden, + tts_pad_embed=tts_pad_embed, + talker_input_ids=talker_input_id, # Not use input_ids to prevent repetition penalty out of bound + **talker_kwargs, + ) + t3 = time.time() + perf_stats["talker_time_s"] = max(0.0, t3 - t2) + talker_codes = ( + torch.stack([hid[-1] for hid in talker_result.hidden_states if hid[-1] is not None], dim=1) + .transpose(1, 2) + .to(self.code2wav.device) + ) + try: + # codes shape: (B, num_quantizers, T). We log T as token length. + perf_stats["talker_tokens"] = int(talker_codes.shape[-1]) + except Exception: + perf_stats["talker_tokens"] = 0 + perf_stats["talker_tps"] = ( + (perf_stats["talker_tokens"] / perf_stats["talker_time_s"]) if perf_stats["talker_time_s"] > 0 else 0.0 + ) + t4 = time.time() + talker_wavs = self.code2wav.chunked_decode(talker_codes, chunk_size=300, left_context_size=25).float() + t5 = time.time() + perf_stats["code2wav_time_s"] = max(0.0, t5 - t4) + perf_stats["code2wav_tokens"] = perf_stats["talker_tokens"] # same T, not times 16 + perf_stats["code2wav_tps"] = ( + (perf_stats["code2wav_tokens"] / perf_stats["code2wav_time_s"]) + if perf_stats["code2wav_time_s"] > 0 + else 0.0 + ) + perf_stats["total_tokens"] = perf_stats["thinker_tokens"] + perf_stats["talker_tokens"] + perf_stats["total_time_s"] = time.time() - total_t0 + perf_stats["total_tps"] = ( + (perf_stats["total_tokens"] / perf_stats["total_time_s"]) if perf_stats["total_time_s"] > 0 else 0.0 + ) + setattr(self, "_perf_stats_last", perf_stats) + if not hasattr(self, "_perf_stats_history"): + setattr(self, "_perf_stats_history", []) + self._perf_stats_history.append(perf_stats) + return thinker_result, talker_wavs.float() + + +__all__ = [ + "Qwen3OmniMoeForConditionalGenerationWithLogging", +] diff --git a/benchmarks/qwen3-omni/transformers/qwen3_omni_moe_transformers.py b/benchmarks/qwen3-omni/transformers/qwen3_omni_moe_transformers.py new file mode 100644 index 000000000..68ab2a1e3 --- /dev/null +++ b/benchmarks/qwen3-omni/transformers/qwen3_omni_moe_transformers.py @@ -0,0 +1,275 @@ +import argparse +import json +import os + +import soundfile as sf +from qwen3_omni_moe_model import Qwen3OmniMoeForConditionalGenerationWithLogging +from qwen_omni_utils import process_mm_info +from tqdm import tqdm +from transformers import Qwen3OmniMoeProcessor + +MODEL_PATH = "Qwen/Qwen3-Omni-30B-A3B-Instruct" +# MODEL_PATH = "Qwen/Qwen3-Omni-30B-A3B-Thinking" + + +def load_prompts(prompts_file: str) -> list[str]: + """Load prompts from a text file, one prompt per line.""" + prompts = [] + with open(prompts_file, encoding="utf-8") as f: + for line in f: + line = line.strip() + if line: + prompts.append(line) + return prompts + + +def run_benchmark( + model, + processor, + prompts: list[str], + output_dir: str = "benchmark_results", + speaker: str = "Ethan", + use_audio_in_video: bool = True, +): + """ + Run benchmark on a list of prompts and collect performance stats. + + Args: + model: The Qwen3OmniMoe model + processor: The Qwen3OmniMoe processor + prompts: List of text prompts to process + output_dir: Directory to save results + speaker: Speaker voice for audio output + use_audio_in_video: Whether to use audio in video + + Returns: + tuple: (aggregated_stats, results, audio_outputs) + - aggregated_stats: dict with aggregated performance statistics + - results: list of dicts with per-prompt results + - audio_outputs: list of audio tensors/arrays (or None if no audio) + """ + os.makedirs(output_dir, exist_ok=True) + audio_dir = os.path.join(output_dir, "audio") + os.makedirs(audio_dir, exist_ok=True) + + all_stats = [] + results = [] + audio_outputs = [] + + for idx, prompt in enumerate(tqdm(prompts, desc="Processing prompts")): + conversation = [ + { + "role": "user", + "content": [{"type": "text", "text": prompt}], + }, + ] + + # Preparation for inference + text = processor.apply_chat_template(conversation, add_generation_prompt=True, tokenize=False) + audios, images, videos = process_mm_info(conversation, use_audio_in_video=use_audio_in_video) + inputs = processor( + text=text, + audio=audios, + images=images, + videos=videos, + return_tensors="pt", + padding=True, + use_audio_in_video=use_audio_in_video, + ) + inputs = inputs.to(model.device).to(model.dtype) + + # Inference: Generation of the output text and audio + text_ids, audio = model.generate( + **inputs, speaker=speaker, thinker_return_dict_in_generate=True, use_audio_in_video=use_audio_in_video + ) + + # Decode output text + output_text = processor.batch_decode( + text_ids.sequences[:, inputs["input_ids"].shape[1] :], + skip_special_tokens=True, + clean_up_tokenization_spaces=False, + )[0] + + # Collect performance stats + perf_stats = None + if hasattr(model, "_perf_stats_last"): + perf_stats = model._perf_stats_last.copy() + perf_stats["prompt_idx"] = idx + perf_stats["prompt"] = prompt + all_stats.append(perf_stats) + + # Save audio and collect audio output + audio_path = None + audio_data = None + if audio is not None: + audio_data = audio.reshape(-1).detach().cpu().numpy() + audio_path = os.path.join(audio_dir, f"output_{idx:04d}.wav") + sf.write( + audio_path, + audio_data, + samplerate=24000, + ) + audio_outputs.append(audio_data) + else: + audio_outputs.append(None) + + # Save result + result = { + "idx": idx, + "prompt": prompt, + "output": output_text, + "audio_path": audio_path, + "perf_stats": perf_stats, + } + results.append(result) + + # Aggregate statistics + aggregated_stats = aggregate_stats(all_stats) + + # Save all results + results_path = os.path.join(output_dir, "results.json") + with open(results_path, "w", encoding="utf-8") as f: + json.dump(results, f, ensure_ascii=False, indent=2) + + # Save aggregated stats + stats_path = os.path.join(output_dir, "perf_stats.json") + with open(stats_path, "w", encoding="utf-8") as f: + json.dump({"aggregated": aggregated_stats, "per_prompt": all_stats}, f, ensure_ascii=False, indent=2) + + # Count saved audio files + num_audio_saved = sum(1 for a in audio_outputs if a is not None) + print(f"\nSaved {num_audio_saved} audio files to {audio_dir}/") + + return aggregated_stats, results, audio_outputs + + +def aggregate_stats(all_stats: list[dict]) -> dict: + """Aggregate performance statistics from multiple runs.""" + if not all_stats: + return {} + + keys = [ + "thinker_tokens", + "thinker_time_s", + "thinker_tps", + "talker_tokens", + "talker_time_s", + "talker_tps", + "code2wav_tokens", + "code2wav_time_s", + "code2wav_tps", + "total_tokens", + "total_time_s", + "total_tps", + ] + + aggregated = { + "num_samples": len(all_stats), + } + + for key in keys: + values = [s.get(key, 0) for s in all_stats if key in s] + if values: + aggregated[f"{key}_sum"] = sum(values) + aggregated[f"{key}_avg"] = sum(values) / len(values) + aggregated[f"{key}_min"] = min(values) + aggregated[f"{key}_max"] = max(values) + + # Calculate overall throughput + total_tokens = aggregated.get("total_tokens_sum", 0) + total_time = aggregated.get("total_time_s_sum", 0) + if total_time > 0: + aggregated["overall_tps"] = total_tokens / total_time + + return aggregated + + +def print_stats(stats: dict): + """Print performance statistics in a formatted way.""" + print("\n" + "=" * 60) + print("Performance Statistics Summary") + print("=" * 60) + + print(f"\nNumber of samples: {stats.get('num_samples', 0)}") + + print("\n--- Thinker ---") + print(f" Total tokens: {stats.get('thinker_tokens_sum', 0):.0f}") + print(f" Total time: {stats.get('thinker_time_s_sum', 0):.2f}s") + print(f" Avg TPS: {stats.get('thinker_tps_avg', 0):.2f}") + print(f" Min TPS: {stats.get('thinker_tps_min', 0):.2f}") + print(f" Max TPS: {stats.get('thinker_tps_max', 0):.2f}") + + print("\n--- Talker ---") + print(f" Total tokens: {stats.get('talker_tokens_sum', 0):.0f}") + print(f" Total time: {stats.get('talker_time_s_sum', 0):.2f}s") + print(f" Avg TPS: {stats.get('talker_tps_avg', 0):.2f}") + print(f" Min TPS: {stats.get('talker_tps_min', 0):.2f}") + print(f" Max TPS: {stats.get('talker_tps_max', 0):.2f}") + + print("\n--- Code2Wav ---") + print(f" Total tokens: {stats.get('code2wav_tokens_sum', 0):.0f}") + print(f" Total time: {stats.get('code2wav_time_s_sum', 0):.2f}s") + print(f" Avg TPS: {stats.get('code2wav_tps_avg', 0):.2f}") + print(f" Min TPS: {stats.get('code2wav_tps_min', 0):.2f}") + print(f" Max TPS: {stats.get('code2wav_tps_max', 0):.2f}") + + print("\n--- Overall ---") + print(f" Total tokens: {stats.get('total_tokens_sum', 0):.0f}") + print(f" Total time: {stats.get('total_time_s_sum', 0):.2f}s") + print(f" Overall TPS: {stats.get('overall_tps', 0):.2f}") + print(f" Avg TPS: {stats.get('total_tps_avg', 0):.2f}") + print(f" Min TPS: {stats.get('total_tps_min', 0):.2f}") + print(f" Max TPS: {stats.get('total_tps_max', 0):.2f}") + + print("=" * 60 + "\n") + + +def main(): + parser = argparse.ArgumentParser(description="Qwen3-Omni Benchmark Script") + parser.add_argument( + "--prompts_file", + type=str, + default="benchmark/build_dataset/top100.txt", + help="Path to the prompts file (one prompt per line)", + ) + parser.add_argument( + "--output_dir", type=str, default="benchmark_results", help="Directory to save benchmark results" + ) + parser.add_argument("--model_path", type=str, default=MODEL_PATH, help="Path to the model") + parser.add_argument("--speaker", type=str, default="Ethan", help="Speaker voice for audio output") + parser.add_argument("--num_prompts", type=int, default=None, help="Number of prompts to process (default: all)") + args = parser.parse_args() + + # Load model and processor + print(f"Loading model from {args.model_path}...") + model = Qwen3OmniMoeForConditionalGenerationWithLogging.from_pretrained( + args.model_path, + dtype="auto", + device_map="auto", + attn_implementation="flash_attention_2", + ) + processor = Qwen3OmniMoeProcessor.from_pretrained(args.model_path) + + # Benchmark mode + print(f"Loading prompts from {args.prompts_file}...") + prompts = load_prompts(args.prompts_file) + + if args.num_prompts: + prompts = prompts[: args.num_prompts] + + print(f"Running benchmark on {len(prompts)} prompts...") + + aggregated_stats, results, audio_outputs = run_benchmark( + model=model, + processor=processor, + prompts=prompts, + output_dir=args.output_dir, + speaker=args.speaker, + ) + + print_stats(aggregated_stats) + print(f"\nResults saved to {args.output_dir}/") + + +if __name__ == "__main__": + main() diff --git a/benchmarks/qwen3-omni/vllm-omni-vs-hf.png b/benchmarks/qwen3-omni/vllm-omni-vs-hf.png new file mode 100644 index 0000000000000000000000000000000000000000..e47079335be717c3f1f296559745794b69dcea26 GIT binary patch literal 117520 zcmeFYby(D0*ES4_K?#C@5+WcS1JYdrA|Tx{gmjlQBT9&rD4hxd(%muANDbW~-8l?3 z%*^}4>$>mz`tIlX{`rpY&le7k+3da7&b9Ym>s;rAtG!Yn#G}N+!ong{eDPcZ3k$~= z3+u-I-P=IU@TMyz78Zeut*oq?qO9x_H8*D~TL()ltQX<&x_9(6f01VxYS7`_4W?&2 zVfyd__X%S#xvv6o{3o2dj9tNB%@rtgU5Y>4O&~MArM~<21EJ@5yj*!>Lg%~Q-iA7^ zH)|?)zxK5pH(#{W!xtfgSMG!Lyk`s8Zx=cfU&7T?u#OpTRn&dLn)n{4MV^004eQY+ zHdc~N~04LmfD^I(sAM%dl zhiusJ4eM|sH=3%t!n7` z)GcFX@K%kIcz*_aXNiF_1UtHMFM^hcsif0be?@$JSiw5@;10W^DSGIoD>ew*Jm7=9 z-0|0Qy3{WfTdwW!g`PN9Vc9F*7KfobIcRG+CwhgP7+dQIZ`sQvP4zc2&pNa|+{Eux zR42BVqGp6e5z$sCviGjb6VCQLaP8IOpi2mUN{7uBP(-guPA&Kv$_|#G7Jc)~us?#b zO&70%R7ShL?J@rOdvv>AnM7>x7oj4C&#E6EM$56_5omNqf06s#;Y}8^qlABBSllbE&z4+?K>%`1G_$y)E8!k;ADhPDn5;7%13xMHD^=d_QH%*cK|JT}!n#rOp# zq1s%Ykn(h}gj&BI4&w}$?vOHP;YqRyqgrmM6MT$aiY{yT?J(yq6b(8JW)6PUCfnvI zL$P$q=UVO%ml*pMfBO#68uQA|)$a+lQ9`1h0bfP5x{~YYTsn-G#Hi|@#c;kW%^3Pb)0zBEqG^Os5F9tc+BTcOsfbb2*mm%-f}t5JoPzsme9>sM)GTOy81eZ4fai zK1iz_a4SpyR_{PhI#)U;skJ3Vnb2Vbo%zwz8+qj%6xI}iSaFNA<2!rWyT83|nbkm+ z$T4_tVc|hRLD}HCGE%JFv$v(e3}7Kcfvc(?*e>V~QgrNEu64&UZ=LUn%mv*3iKB;Q z_%H_F<<7!STAUzmVnPxryd=D4Sm=(?ZL4?nruSK}EltVv?iBnaFC!d#C;l7D=0@@F z2j};Va1vWRUG9`*I2}@-1Wo?F`R>Wn;81Sjn;j3zWvGcMf}_sqrC;EXgnfUq^@5yU z`azG;YaWfzBI$xp#V=?oXocUU$#6YM?{Qqk9(jKi-lV{zMKdlPrEc#*-77C_Bb4&? zm2~CMBb)mTIL1LbS^S$$Rrke1OrDo!8*jQ-(cVm=?CR*}R)~ypEw|wy>+5(u?WVV(r6CFxi@dn9r z(+d$d-4$zlDno9@^etFTdP-VISqT43LvV>d_Qh)w#}AKPK)J;3AKX9mg{OY-3ug{b z?@;InBnf{l<@V&_Qo+wLPe>@A%)RJ=)jspWgW`CZ_r!0?4a#o?-nRl8&U z4SOB?$HPte)1{q5l%-_F@uk&9_K6d>imhj!I@<3&ar|~lvgbIHS53>q9eV41A2ByM zZw>F@vj)!(A_5{}>D1}Z(#1t+L;@OS8cG@z8!9~tJ!7`s@bKjFf9dYGD0%(ZbiuS` zl6PWdGyEiBi+|I2*e_dBei01*4laP|Vj9qXHxr~kNtd+Ry=Qvw7h3nN*{oxfXtn zT&`TbT&i4VPQK;$HKRV?K5!9>jzghCAwp-PXhCmQkJ%7Z?NkwHmF?VK$y$+LTW_ya ziKt9BGqmsmj>8qZ7?KScjjxw1{h;mCNa_G-g4B7v%%bHp*h1I-%( zKVf7Ob1Uyp_aN)S4N;I+>5bBxCJ=8?-woe`<3NF7t1O%4)9@Jo{(y4{!+-{V{g$nk zMdX`{7`Gy2Ki z*N(3RUy-frt@^Eq)&M#uI(L~@p(HZxvbtdltB>F~O(G`XB!#J_GTx=_rK2V7B_f7h zhS&EwV{KmRt1VQwE4x5@9WU)EI`lFXCnU)jE5%wfvef3cTI z&F3?}y3bcz^|^{l(;>G%#m%f>X{;%~J9jwmD33;&`8#vo!And}%=+XZlGpnY74IdE zQLAsO`!{Hr(G&0uQp53)ert3o9dV$>nbNs@No<-n$C)iwX3Vq+~~Fg(4x^xRn3lmBo#X3~3- z%Os{@!H40ft2otGu+a(ES-dgb3%Ldgf%?}~9&#-?ZHW)~k)1{DPhQ!b?JRJel~@qn zpskXOgm`bn{vL*RA9vF>CW?I%&-b>wtlCfRtDMOAozVwXK^G(IPcFh1J}*`WE}plY zc7Bt*!q^<7j!mL8PThXP)=CLX_OAL6r8VdzG_n*9hIngUPW*P<6FqHoKlrjJiQz@Gwo5M3^w2*1bZmLm3dSa2i4jP~x~eC|GQh(k@OJwCN++G@4t|!%=so(w z%(86)VZAwQo41&g^5(;XbtWui%}rB6#Fi~q#}L+wL!8ZETn5i`4ngmIEpmD>D*wzQ zRtCwNSE*SdUjo<8HpyAEjaxTQ!9hXqaV+1SI|Kejf~B6Km5K@$8<4(>bqkvW>n4!G z27a-yDY0(-Nn>HX#HRXpS_7Nq?>aZIu)=JyaQ?1i0DNBmd;Ayd3eh$UD1N=t< z`~`o#@vquAzF%+tD}7@hD8rK0lvPv&J~b`eEG?bfZJa%ZUk|4M8MrPl^xd(r$QiHy zuoX3)9sh&z9`@q&dMav9WS!kCp9pYqb8*v4;5~WrM9l5Am59c3`M<@1|HSES zJUm=PKp-zKFD@@$E@wAu5Rb61Fo^pZ=-D$)pa!SAkCTU)H>Z<3!(Wa3tDWbT?iOyg zE*`edPEW4eH8Xei^bn_~zwYSYKYxwW(%bewJvq7mJuP5@pz9J44;MG+e-rbtwfcV% zyDs@l?9aUZ>Q3ysF%dOeZ%YTg=eCZ(QUgPi;NjsD5c|{5|0w#;NdFSmcDHnsb#??K zJtY3KS$_-vv+%zK|MaQd!7o-NL;>ltKtsN}&?L85wGY@bl`1WqyqOBwh_*R=Y z*;f~}Hhy{ejttR|VB))VxCVmMvmB{MHC-L|Eqy(JNH$$e7zRc}fLgq#AQ+TnL9Hmq z{!UJ!3EmwV4>fP(UM=ckE8zmjpzMmFrOi}l&Y_85V!++W`F{E-(M2Qh~0ro4dZjTn--}IrDFu-vGueBJv5AeUg{QS3?Y{p^9 zsOEhydw;EMK{3=pny-Wz(*jO~xrWBFsw~cuz#*PGLpvJLe(z|NZ&pxv${{x(OZea< zrr-?GgC<^TNE_(mX=%&lHVv*gk>pjGtElK)Ad+S&KQDs-CI(kdvP{r#>y|hzU#>jv zWe*$9R+tRB?|#E;-cwg-DVP+GGW{6{@B4?~42u}?iIPi6$Ux0a@Yw?txRiZ@HRvnH zNt*xhFFEb%7D^da>6L7!S8_X#J{THLt_vy^ut)-Si@rv=$(lFoZT6c zA!JdwkmV!hmgU?BP?n7e``(*xEABq%%enHkYW}GppyLF+Y3r9qBz~fHzO4(TENMFK z4HRJWfe#2$Z1MJU%bpL%pqY0oVJ+Wk6O$KiJ&br^z^Vz_AQXR`2@Bl->3$~NqgKf8 z43@`4d695lO2Ruo)EWtH#7G3qVQ5jJ>1{f*)WybqPX_Po9*PT;3zlbtmo1#3Zvf) zLMA?lc=>Nxa>$USbguoZHkmm*^UbF6 zfvbw;TI<4WeWUwOpxG-HKbnCsBc~J+-c%}{rc!=RnCv!YX?|wVFfZ1FG9(F_w~^`$ z==0!_87}r+tw=yYIz`gfWv*|ZXq=PfV%==vjSTi8Oy&;qZrrk5Lw&0+={~=`-|)ar z+H2By^_iFK#c^LGMmDZWGG-5m4d#x-&*n&LW}O-jFL#{1oj5_}uXXh~dNgE4xJiZ$ z>J}zqr#(hh+8t}>$#YYqF#>VmHe)T@*2XVSi(?ov);9PgAs6*=ZvmKhBe?sqUlFnM zQ~0jUPIW*3q!DURUo#fVyyd-aVA8$!~uI`m-h6w{SajvxpOn%zwG8CtJUgR;4X2fP>KPNXC&W zJTSWAdB&u8pW}ej*bjBHRL2@Z%n_}9u(q!8I2;X}{}794VJ4#h#P}OW`TS*EFV#cD z>r+5Kb;fnsiiv%j#?>G0-u{^1gG9>%pd8L%l z$#Gl~CC;UT+4(Vy)=f3Nfhfx!F0NZkfBVk`|L=!{dw}%EB?fuN4ihCf_i(>% zk;R8}s0@QnM_U#?4Pv&ot1VX%n0|V-OaZ;?w_C1&G9JaFaqFQo0~Ce`4wHlkl&;oG z++bEoN}()J^lkKBYNmbd zl`6tXOe{H@PG{^nDO?BF3cR?O`c*=56+D^k#XQUN@h9^?6KN?>II)fhV=0)bYd$ddm4s3vPX!OBsy^T!G)3 zrma##rmZvQ=WPk&fm@LMY9+*1jT~Y}9i&V1UWR8c>TubP$ z+|&@y34QA!KjGbO$$Jp7o&M1I45m4Lx?soKTm{8582_WrrGqyIn84-5rM=pPQ{<%1 zULR*|nzJFa|5+b_kzy|yyfMn>-avn~TvKkc_{Hj%CE%XF2OnTx#}9)!)|pL>B-#5K zKvp>pM<3`F1B2!o*EnM+%F z8K>2uV=U*~Zl~uDjVSh#I`i`mW{D-;L?bsv@6%~(ar8(8sMDH* zr@mDWCbSZnQ9Gug6gI94<{bZt`{#~7A!5P)lX$|dLNaAnSZsINl7%@%T33(jq?+$d zc`XKfp@kp{XdqWd)q;!umAM|IW*_~^1Y>>0<`X&73`H?laM1=q(nvcvOc1Od1{EzF z%t{xp4k0(_*=bx)v8SAYUTzl(o|jci*p0%tWz`e6)lliT{pu&*K8DkvX5VxGk1U`+0MiedeQs z(E8@I)5f#iMUx(T$mM9J-J}sb=60&p`o#kCE&48_l;8T^TD+iL8*;rMQOq}JFqLbr)%UY$C?N6$P75c#UQ{KGCsC069;i`PrKLZ z&I9sg%6O^HH9kUXahkgn0;ru|td!D68BzC+3p}`Izi})V-oIlKa9p}&Slp(mDo!?0 zCYMemy30-5s#y~|TLBpd6nHX3wYW*+`~nuJBd|wNi;3eur*Mxd8U8>Vg;v{~M0d#6 zP-62vgdYT+H4a|cT9`y;sdWa9;x-Bo_Y@4IUHn?WJWIBtJBmST+zi_`A}S^u$N~Eg z>&@6iOJXiyCSOKot1+xpJk_yLpBt7!scxUyk!@|5!Nku_JkwJ$B@wpn+}I$0;Eo_V zlXS_nCWA#7*L!LrF-I}>4jwS(Jz*Qn)oaND_KA&dt4Yq%KC~g__vcX(2A1*K@8v5V ze9QMK*vS-Jq@GwbegAcs58)6|ZTijEzeA_NcsjLbg~7rc+<8Dd&B~{HH1~;&oH(q7qHKnu9nUXBZ3gmcTGO zVLk*zShNA}|HaFF@Yt>^77BdIaCa;H@LhllM%$kR!=r3dBrWtjZ0=1NcOA!Kk()X;Be=>)|q zafDW_>UxM!Y(brJX9`>Gj z$=bt98uuw5`)+u?)ySvLNyRGWtc7v8K$%T5xRZeg_u3W=d9}dP zLyP($akx?0-5ge$z5DpiP}G~|%z;Zn(#H-RiK+oJZ)P2-dM81>Xw8iY-r24S2!EdO z5Nx636kg`15fc!wU6_7*zfh}Numv3ziq<`Dg2N~-7Y-^V{9m;@^jFh1rKfNSk1F$qj=mBV zA6FCkrF>>0RL%QlnWCv}C$l4GPU(9KwzcwPie#SAt;A<*A;G_I=M*{{q z0&{|#mEzvB_!zQDr?YtVs{FI#mtub3$B^BluLw`4`ZXPjcmCw>DI)1(Cywiny3kPD zN#|XntA(>&IW`|fLc_oivbL>L8N|<la!Ar z!|9$dSI13HU{;^qoe< zecB_)*aVMlrx8P-LxDceN2yz#kc+iMBI~rkP#(yWCWo`Yi$##&dZVw&G$dMe%iVu# zTq*DZ_X^7-wP2V9uNdOK6haZYvD;~~)1&NfYA&>%WYOj^s=7FYIa~C~ba&dBN3uPQ zRRCQkn4-I)4Cf|=X6#Fw+a_C1tF!7ls2s^MWt~b9*5vSuAt9c<{~M(&&}a-lvw~Cn8T%fd_p4ps_{BCHOKYN)R^@99Um0cM@6Z z>b_sUF_rQhT%l2K`Iys>k~`y8-W8mAWlERA2i%Sz)+eY*ZPYj<|xukTWj~D6Bt6tzPc8EE0~Y3TDl{bLn~nwb%DTqko|^X>U#Y zQxumf#o@hohY3%%)IL5sC~2zEEdeizU%v9|kf4bYV7FtuaeYmklbSw<9UfR1+`ZPR z8#v3U(*b9TJDO7F?-9rG3sW5AayO%lf8^~jazW2Gi;SA5iW>JD%0G^%^OJ#0bV3%) z;%nf8jZ@1%pwS?MUnUXZ+u5D3Rw9bV(|V2kkHBq|_C@Li!Z<3%KH8&M9`<-vO#=dk z$gv`Q2lYwn2}9@RuQBpNyEU_dyE#{Tab&a8b`UFyf5_e#fk6V}a^x@#m}-gU1bpr_$El5UFB8bpcw5Wjd6!eo;eld#vCgizA=ar5UnNMGab7H=fmmIW&@tfUt>SMCKI`jW!XhOagIzG9%nhjj%Y{AhgKM~A z%q(vl71OZULGzgtwWVb}rR8_I_lT`6n)`vCBN*~4Mw0#7#X#vm%J-L&d1H`4_m{Jk zP79QuyKh*cE&Ws;`OW0APsnmo18x#ZewU-7hh92@q0dB8^b5cfCdo2e!` z_b&I(f2jtVM^KmUYt}6IE#@kvH1Eqvme$DYP0zI`tyrFdpYrKdLwm9`U1O{a(C7+8 z7v7x)=kN&wj`Y7U8qT{@kavGMUsyr5pMUBYI$2`oCkqwOn@|k-q@lru(Q3Dc-~I9{ zrdbciELkOTgD2H28;G+p2a2yL#R?-M63jCqf;mY1YQWaxvA&qj{9Is0dW#b=!=9c5>MlmFUr z2RfPUmB@>tj!(+lFwIMU)2kmy4zFJ) zfnQcu7=-ns>J?ESfx=>mHFB)UflKrLd;qe>p{0LHkcXk6NURKQ7 zV(@^~7lQzv^-I{8at+Iw)R`@Vf?W-%G0J*e&yH@j^<75hfWTsZX6BVc%8*tiYb>GM z_(tcMR4USmKjdG0dp#?`fTn{yZuve=NmBg+BmskZs)C zW*+|A&DL@6xCU~$HNV&O)UdWLsw-K}$`_|m6o<6O2sN$EfY!27?9}V3df)<0g&7O?URewdv zb+|%HyS{~rRKoSKw>n_9C}CAxb1C3~EZr)m%O>{Q`28vw#^X1PX{gm?PM&`{+V$pyc4Y8NbY{Q=Ii54sHY{@j_Q+=G06r)RQmKC__*xQj z4NJ_XxQAwB9?%?$H$FgZ!qCn;n#~m|t~xc^2LoI)#;Y}vt0Ll+3u$dSnsX+8q-7~8@7gAu9)LAJ+u6C% z*){MCUep?#6Y5sX#W%on8_F6n(Pm8gGD6MI3g0w;>}%e=76?OW14g7z+P?cbrXaO; zm*5H{zvePz`Ugx-nz;MmKxK`p)+>l!yqV(M^D^C|edmSmbnn3<0g`V$_F~+54$|uXg@TD%c9cJ{1SrOX1af$Zr=1;xnppFS~JbHHKDlArhi8nbXwEtJLD@`30&;5gl7wWrQk%AePZFOce!64XmXK2id#q6egs0vDyi%> zKURs3nwoWz={Rg+*7=Q`RQj7A7kb^=$$ph=AN7hw*qub^gKI^RKeGuM09m}VIws;d#trQ0d(%TruM7@!`9zrdqjjfAE zqE1ENT&F{RTeraWX{Uzs3;P}$FEb09xcCf=6+7qd9-Z(6%jjS zM2scoBh2Q8dS1X9*FaFOElojSt9K#_6SkLN%}{um%+JhGH6(Kl!jv$lzQ04OZ0|m< zX~A*f{L0CznAPC|2@24x;p5D`%Qi_@&Bt*6&k>5mvOhU|_y=|W$)_Y$%8}wn3|^Bd zV^v$4bB7^LH*bkSAD$ORnMmxe71N1NzZOle4mkTscWLOGpL0h*sotV1@+k2$KvA)u z`#A4#+@}$EVUT015*3ujfhy0Tn#r8yQA>8qAb&P7LkGp64ps(@G9H0({B}bnZ9(N5 zY3{G|%)=RbJH-M4Z;pAVCp)jUn<8=|YZ#9(4Pj?X|9&Cey&;&b81{L#SWY|jy@R;q zBhKov&jU=HrPU^i93%(DKAds=V(X!0+jfQ3MS0rhJTDm+&$YZ)B4MvusOAwvvfxMG z$r2B_r|#bOiT$a2x=6upR~Iy^3-tC!sc{S)F>64d&hmIEr*nY+isG>RuoHey_Nxn7mWcXu|6CdviodFu*#l zHQ}RO?8YwGiQL%3Lm_}4xhpWkaVy?_T9+}CKCgIOl(3JZF_Lp%;#Yt18>Hxw^sH^^ zgI*LfCKmGRtBMxPtST|c6*O;wp)ZH7aE>Vzw?=14on3l-x=!WT z;7@M(zYVo9R~wQQtNY+VP8qI@R4d-+Gl$MDHPYL29A}NIneq|vneMI7W1;aQ_UdKvhDdc^FV8$-I z3>0eL#L9W0J1Pj=cc;o}=H)MZqBxL9RSVOP3a-C8?@+9c-ARV-+bY@~yW0b9wh6Kl`ziV|IUXpO<@Q zKdSjMwZo0=B2L!7Hgr6fHkT0{W;Ga#Ii?hs$B5_b^>i2+4kn_ALh9dWTyo2Nc|9@D zxp|>9M`7S?1AE1ccE`k&?bY4EcjbGrZ7hnQ7`j~|t%=tsJsXtxJ|#bo+4qC)+SQw* zvjvD`l$gC^tXx~#?60ak2hp9PN=is0g>Htq?rPH;>v>F8ga_C2F5hK17_()o?&o`t zucBmh=qmkCc@~jUff=-`xm7do@*`k8@yz|8pHS!8XJ?ap%kRrJKF>!EDB;gT`k|}T z#r2(E(=%6w)}@v3vn~((BeL9!&K>?)jrkqU@jSU$Q9@^^qhUZ|o9W)CBI@4hEwLExT zpzbyXc=w=|7i^`bCUzLLBqbIN7@rE)?E4(=cZ2ER|-=CYw5wSt|$byK?ux~ zKk#xX^i+Pnw>Pe~s?@qFh96&a;D*tPR`JODv6h!GA0Xa0(oW?kRLe;*3fJ6+6nl=@ zCi$!<8%knS$ew2+n2RnRr}RfC)sjMx-nuWe>?lUyrNuj$m+J%j&juTy;jVUNE zg99aVli*W&^;WuzQc^ZN((7m$R?u?*;}FC91L$)Pkg%XvG7W~FbSbavtR+6=q)e&) z_^rVv@L)uy*5IZbD8`p@v`@e9me#D$aV%?2Q_u{iofge~br=>Fw?E&MJX*h=#(uS_ zAcZ<(HC*IGuXAMLR@kpi`Rl7d4PH%@7v?n?C?se` z_gO^COWd`M@BL!32d{&cjM8~0dA|ndBKrisz~_dn;JV(q3MsfCzulO( zt1k&zsC_e5{|)t~c*Cf1wLa=w+1`Zvurv%Nrnykg;cKhSa!K7#wXrs%JG;SXlfQEs6EGqrI)+a+CMAJh;Up)^FyGx$1sN*^g*TFC3GK)e#`PwJQUIX)>LB*F8Jz$&TSmCGbZ5 ze4Z+@xyQo`hkAb*%5H05rmY)UZ?V+8M^cpKz0Ihp&)p~)Sy-1DE}*0Wo#$fhZ8CN3UPGMXPS*nseR$BS;|;gTn`;XuOkAk zN|ey)>d0*|g?|13{!>k^UH)ng{nN#fx6l9BU@kY5=a;4bHlY)w%H`jitQL{UVraYt zRbomh*F3?u3v$pTMWT@h-j+zlL?e0=gPH`>=Iw&Q-sziNrH$x@EQiKZd(L!Yuj$U+ z3XC^~In)28&|cMOBZ<%Im{(@+frSo&7bcc!@^*!j@J-Xnh*Cf;C|qr(rP*hXG#)lS z$?$%BCe4{&C~4|6E!FFOM2Z}z5#ag>+YiAB1?N6Fb#Ln+ID=!P*&lrj+6GDeFtsoY z)rfZpNM59ychAPW$!77;4Ya0N$Oz8p2cPkyFONh#A3PlqzZzoj%e1j|O^&)c2+7TR-;)Y;mz`Y6zop0nmC0%twScbMiNIPXb1 zDGZpN4>%L22^XJdtiWZMI{8F!FEoh+HyKY`4f$z3J$p(2_bc!imt)xk3_9e*D?_D6d zsDAd#ce@rb(>Aj6iMnd|n2Tf#hwk2}nmCNREsd_+31}$mIZSR6>220Wp#9LdwkqM zWLzE5C%`k^be6&SOiT({ojQ;V5vy#4PApHOQWqUG?Kggr`1%{iea2)*ORzNok&X8{ z6^m$O$Z-P~KB(^Z+nrzn>{?{B=b3f7vx9|&$-R`*NmlsTVr^$d1l2QIxhA8P)rg(W zrhR(o_gZH|QCN8}jc1=M%K{AI%j$eWdceJCUGGe_x2>CroZI+F;d`VDL>M3@f;Ob1 zDMERff%3iD7BW-j5uD4FdThLyEBvw2{#_nY`Aon4dS3%gWqTYNAo7?{;Kwr5acEpS?k8wq(1t^SR;iQYDG>C9MgA&y*%6*KonseZ%)|pj zfkAWV1#xEVM{2}uqV(6;{?~T^m5Oa@i|^V=|LH>a8)SBw3Av1c21i{3jZ4`y#wnvF z!0`^Pa?pHr(A{HlKBs*=4uU$qi)ZV75ZmSp1n}?;ohwzEPHU5hxf(XJ4y#K8`Bxpo z@K+whvbZ)m2JMq2&MZ230buKF9GfAQKs^mlmLRpuPwW9JV`F>i`Ro{p8L*K%3MPh% zbewN-^aixoa3Y_g>i~j5E|n%4QNlI-YRjM9-2V~3D-uv1@n$PWDW;zGbYV_Ul> z34+=IJHzIl-`z8qI9~wW&&@xcs`%yCzo)C&;6V{FJ&eBR8LYMbeb$Ct!d!NgFjvQG zM3pkA@_p2*MvsaJDsr?PjXYTFQn-65jM}x9G&I1PzML|m^%#==<&NUB>Nmfr!M_7A zecXql!2?Ubm@^5e9IMp5QBji-Mc%4Wdm8J$JH-?U`c}!WnUmc<0E-T0 zjStr(9WaqIUkfSKiM1g?oz*;;G>B)*+qwXzSHW_Xw|kRFjN8bylWeU`&PcKkpjPOg zCr0^x@d-q?0J}>rApFd#KZ&~9{pw=YXT#Xw83l#46TMzgcHKOEju!YXaLpMnfgkxC zo!w^O`op99iCgxNm*~c|)qGcZ7U!eayNp8^1kD?n;vUy*an2qN4JLE7&sj)Zj(FJ{ zQ_9s_uIkV8Yur{#<|3pzuXd6%%d&=&+PFlPai+PHCh&Y|NfmOb>D^tU1mn;2?`2&I zS5yrJU^F_Lh7W;;CH&6@g;ogs%CA%k3T-~sN}uW6n>0ZZH5M(F*E~8))M~sR#W&I{ z$244+sGA|JVe&eDzo+DE_N;N~&K=BGmv6%_G8Z@DOCZRF($dB|e9+y((w5MJ!|LUi z?4hm}-52JCDI)Fw;F0Sou`HhN+!al;vaG6Z%ldg*_yPNJcJ|AQ_i`&1zl*o6DU&m4 z7Xp!-eGzBw$EA?Hh@<^7)IGE6ab5Ry!3A%N*JudzXyYXaM&d;;Xk1+a&1@(7{F^8y zW1eW8bHUwz1di{gP^*2s*egNufgtSNN?H3o{A;(@dxbFS25;{A2D9WvcmzH8qF1-A zm%Wtw8bNdcK-bXg$UQT9xr2MD1UC>r8N-z7Kq7JROZBvoQ-v^Xf&4CHgN7<-O`LpJ zxLL@dto63Q4V%8QtK&>QsPlPT^Oskbp58~D6ju|YqYI@iXIoQb;Fq7l zGc>u(@JAs8jXZ{JBwfJ(52JllRg$Kp`LyAh$MA?rnR{L5sU*arD;if4wWW%jf19K# zi1Ju!_Hz9GEy?gvfZ+3W!>N;owfFwUmOG!)Jw_C}u5z>#nrIQwMc19#d-zi<#mBHk zfRy#H<*fPO!YgIpCyIY!(@XW~HAwM;4WN=1oQmy*0xv7K5pLYVgXM_#jOSDdCR$@Q z#F>cE-_HllYSedol9u~)1Xl!CVQlezn@qa;Y2A^JRu~>t-SQ2*qq)wQc-1Kx zV#b=)u+FDmXlCzn!5VVsagvR06dK`Xc&h#^MqPV&T_PYaJNE{_j&i8GOet*NDb;Vr z(>Vq9=$@ftb$p}xY;%KKdN{^oH0rK(hEJ}uJ`KL$V=5CD?Ur(%sIHts4r2Zj2rF2f zXVDpY5Q@3T#FQ6$yNjSZlN6R->I{6dl37k0Z1PS>QOO;vUNrYdyCFljUxK!ed_KsG zf9hq%6!&^p3%BozG(+Xc^*a=j*6s`Mw>haV$4J}^xw=yFuq6YS3MF5MpOQT2m4q1J zzkt~nS{tDiVjdgMgbW<~03%3*h$PNUXMgQ~3T>iN`7q8L_PntbvJS#HQqXYCb-ieZ zNtZNrPS^Xz8kK~^em3yOGy`~|#7i}M-)eKxQ9HBHN7e)z8GcTEnfg47o{7c`@HUkJ zZ?J_uxA7OJuKi*x(k}qs5nGj=i1#a?38VE@D8N5CCQK51Wepvagw$gwj6H@mpk#6% z{_G(KcCM3l&5o_mwL!EbCFM+T)cg%ItN7sIT-yTPa=gitE0wmsYO!@e}L(u%79jnXKoTf|ie%j1tv$v$HMc2cqTqf>!x1WOC5r=z_i zoTzJr5G`sC)%{J@Jp*_AUJ&u+O<4mX!LU6~qFN)CoI(G$trO%#65h{?e37iJqo0#+ z1Yi4!PA&GN5#~FEu#4i_Uo$t7%q|~oPv>LAzvZI<-cup3s@H3#{3yhTCYO%aOlhX5 zD`loG{~%k1<_65Upm`OVDQUfa2WA&|4>_Gk!WVz=U>4g6xX8ovO;p_0^W4NzSS(+W z&Y^+GWas?iOGJD&^lA;%4$v^>PT(~}p(Mjbez z-eCjr0um6a=@*#{(Vtkf&m^1t z=eP9eB-3@!FD7At8*@xdp}iTq5vP5DM23wvXY*dVe7AXRYqP)Q>TCn1Ujz@0s6GW- z<8OlNmmCjx$qR=1s;;rZpWKYxqsm8e`RD}=$gLO7m7Su-^SO^B^tLT4YIqyNSq98} zDQ@;ppbJ8U*ORiRzpr@)+Ws<8h^C$%c@^&Gzhk)6%U(i&&!Gk$tNKLJ^llSkNvZ%u zeaXQ{hJCIFg$^aioJ8<;0m?Fy@QC0?{w;$fpR4mDiKr~DCsTx}0Zv{LFbSl?((I{B z@qA#-g6~dl3MB|ZZ!~5~7D;J2dMtvwkmHFNFzVIbl!G6$a|x~saCY?NM~u!Fe0%`D z&@2oFsFIx50YWo@*4kOY(m6=;9n`IpJ13eKkCz5Ae^V0nX9;)n7 zvb=aObSVs2X4Xla&l?_^BX`z({kLN#Y(xg-^R_nfcPq91-1Uoj+-p_rXY3D}9oeRi z=>ip2jpqGhRIrW2uV!*_On|#}!OJq`?�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 literal 0 HcmV?d00001 diff --git a/benchmarks/qwen3-omni/vllm_omni/eval_qwen3_moe_omni.sh b/benchmarks/qwen3-omni/vllm_omni/eval_qwen3_moe_omni.sh new file mode 100644 index 000000000..61e46f8c3 --- /dev/null +++ b/benchmarks/qwen3-omni/vllm_omni/eval_qwen3_moe_omni.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# Qwen3-Omni Benchmark Evaluation Script +# This script must be run from the vllm-omni root directory + +# Get the directory where this script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Navigate to vllm-omni root directory (4 levels up from script location) +VLLM_OMNI_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" +cd "$VLLM_OMNI_ROOT" || { echo "Error: Failed to navigate to vllm-omni directory"; exit 1; } + +echo "Working directory: $(pwd)" + +# Verify we're in the correct directory and run benchmark +if [[ ! -d "benchmarks/qwen3-omni/vllm_omni" ]]; then + echo "Error: Not in vllm-omni root directory. Please run from vllm-omni folder." +else + log_dir=benchmarks/qwen3-omni/vllm_omni/logs + outputs_dir=benchmarks/qwen3-omni/vllm_omni/outputs + end2end_script_path=examples/offline_inference/qwen3_omni/end2end.py + build_dataset_path=benchmarks/build_dataset/top100.txt + + python $end2end_script_path --output-wav $outputs_dir \ + --query-type text \ + --txt-prompts $build_dataset_path \ + --enable-stats \ + --log-dir $log_dir + echo "Logs and outputs are saved in ${log_dir} and ${outputs_dir} respectively:" + echo " - omni_llm_pipeline_text run dir/base name" + echo " - omni_llm_pipeline_text.orchestrator.stats.jsonl orchestrator-stage latency stats" + echo " - omni_llm_pipeline_text.overall.stats.jsonl overall latency/TPS stats" + echo " - omni_llm_pipeline_text.stage0.log per-stage detailed logs" + echo " - omni_llm_pipeline_text.stage1.log" + echo " - omni_llm_pipeline_text.stage2.log" + echo "Key checks: overall.stats.jsonl for end-to-end latency/TPS; orchestrator.stats.jsonl for stable per-stage latency; stage*.log for errors or long tails." + echo " - outputs/ Generated txt and wav files, there should be 100 text and wav files generated respectively" +fi diff --git a/examples/offline_inference/qwen3_omni/end2end.py b/examples/offline_inference/qwen3_omni/end2end.py index a2496fe8e..eb580bcf9 100644 --- a/examples/offline_inference/qwen3_omni/end2end.py +++ b/examples/offline_inference/qwen3_omni/end2end.py @@ -170,9 +170,16 @@ def main(args): else: query_result = query_func() + if not args.enable_stats: + log_file = None + else: + log_file = os.path.join(args.log_dir, f"omni_llm_pipeline_{args.query_type}") + omni_llm = Omni( model=model_name, stage_configs_path=args.stage_configs_path, + log_file=log_file, + log_stats=args.enable_stats, ) thinker_sampling_params = SamplingParams( @@ -364,6 +371,12 @@ def parse_args(): default=16000, help="Sampling rate for audio loading (default: 16000).", ) + parser.add_argument( + "--log-dir", + type=str, + default="logs", + help="Log directory (default: logs).", + ) parser.add_argument( "--modalities", type=str,