Qwen3-Omni Chat Sample
Preview: The Qwen3-Omni API (
OmniPipelineand related types) is a preview feature and is subject to change in future releases.
Interactive multimodal chat with Qwen3-Omni models supporting text, image, audio, and video input, and text/speech output.
Description
Demonstrates ov::genai::OmniPipeline for end-to-end multimodal conversations. Qwen3-Omni models accept text, images, audio, and video inputs, generating text and optionally synthesized speech responses.
Key features:
- Multi-turn conversations with image and video context
- Optional speech synthesis (talker mode)
- Separate generation configs for text decoding and speech output
- Interactive CLI interface
Prerequisites
Prepare image files (JPG, PNG), audio files (16kHz mono WAV) and a video file for testing.
This image can be used as a sample image.
Download an example 16kHz mono WAV file:
wget https://storage.openvinotoolkit.org/models_contrib/speech/2021.2/librispeech_s5/how_are_you_doing_today.wav
Download an example video file:
wget https://storage.openvinotoolkit.org/repositories/openvino_notebooks/data/data/video/Coco%20Walking%20in%20Berkeley.mp4
Usage
omni_chat <MODEL_DIR> <IMAGE_FILE_OR_DIR> <AUDIO_FILE> <VIDEO_FILE>
Parameters:
<MODEL_DIR>— Path to exported Qwen3-Omni OpenVINO model directory<IMAGE_FILE_OR_DIR>— Path to input image(s) for visual context<AUDIO_FILE>— Path to input audio file (16kHz mono WAV)<VIDEO_FILE>— Path to an input video file
This sample takes exactly one audio file. The Python sample takes several through a repeatable --audio flag.
Example:
./build/samples/cpp/omni/omni_chat /models/qwen3-omni-ov ./coco.jpg ./audio.wav "./Coco Walking in Berkeley.mp4"
Interactive usage:
- Images, video and audio are loaded once at startup and sent with the first question
- Type questions and press Enter
- Model responds with streaming text; when speech output is enabled, each turn's audio is saved to
output_audio_<turn>.wav - Continue the conversation across multiple turns
- Press Ctrl+D to exit
Model Support
Compatible with Qwen3-Omni models exported to OpenVINO format.
Export using Optimum Intel CLI or Python API.
Configuration
Text Generation
GenerationConfig controls text decoding (the "thinker" phase):
ov::genai::GenerationConfig text_config;
text_config.max_new_tokens = 256;
Speech Synthesis
OmniTalkerSpeechConfig controls talker and speech output:
ov::genai::OmniTalkerSpeechConfig talker_speech_config(models_path);
talker_speech_config.return_audio = true; // Enable speech synthesis
talker_speech_config.speaker = "Cherry"; // Select voice (optional)
Available voices vary by checkpoint. MoE models typically expose: "Ethan", "Chelsie", "Aiden", "Cherry". Check talker_config.speaker_id in the model's config.json for the full list. Leaving speaker empty selects the default voice.
Speech output: 24kHz mono PCM samples returned in OmniDecodedResults.speech_result.waveforms and saved to output_audio_<turn>.wav for each turn.
GPU Inference
Important: Qwen3-Omni speech synthesis requires FP32 precision on GPU. FP16 causes numerical drift → codec token corruption → distorted audio. The pipeline enforces INFERENCE_PRECISION_HINT=f32 automatically for GPU devices. Change the device argument in OmniPipeline constructor:
ov::genai::OmniPipeline pipe(models_path, "GPU");
MoE models (30B-A3B) may exceed available GPU memory. Use CPU for MoE inference.
Speaker API Features
The main sample demonstrates speaker enumeration and voice blending at startup:
- List speakers — shows all named voices in the model
- Voice blending — when 2+ speakers are available, creates a 50/50 blend and uses it for generation
Custom blending: Retrieve speaker embeddings via pipe.get_talker()->get_speaker_embedding(name), mix with custom ratios (e.g., 0.75A + 0.25B), and pass via OmniTalkerSpeechConfig::speaker.