Skip to main content
Omni-modal

Qwen-Omni

The Qwen-Omni model accepts multimodal input and generates text or speech responses. It produces human-like voices and supports speech output in multiple languages and dialects. Use cases include content moderation, text creation, visual recognition, and audio-video interaction.

Supported regions:Singapore, Beijing. Use the API key for your region.

Getting started

Prerequisites This example sends a text prompt to the Qwen-Omni API and returns a streaming response with both text and audio.
import os
import base64
import soundfile as sf
import numpy as np
from openai import OpenAI

# 1. Initialize the client
client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),  # Confirm that the environment variable is set
    # Singapore region. Replace {WorkspaceId} with your Bailian workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

# 2. Send the request
try:
    completion = client.chat.completions.create(
        model="qwen3.5-omni-plus",
        messages=[{"role": "user", "content": "Who are you?"}],
        modalities=["text", "audio"],  # Specify text and audio output
        audio={"voice": "Tina", "format": "wav"},
        stream=True,  # Must be set to True
        stream_options={"include_usage": True},
    )

    # 3. Process the streaming response and decode the audio
    print("Model response:")
    audio_base64_string = ""
    for chunk in completion:
        # Process the text part
        if chunk.choices and chunk.choices[0].delta.content:
            print(chunk.choices[0].delta.content, end="")

        # Collect the audio part
        if chunk.choices and hasattr(chunk.choices[0].delta, "audio") and chunk.choices[0].delta.audio:
            audio_base64_string += chunk.choices[0].delta.audio.get("data", "")

    # 4. Save the audio file
    if audio_base64_string:
        wav_bytes = base64.b64decode(audio_base64_string)
        audio_np = np.frombuffer(wav_bytes, dtype=np.int16)
        sf.write("audio_assistant.wav", audio_np, samplerate=24000)
        print("\nAudio file saved to: audio_assistant.wav")

except Exception as e:
    print(f"Request failed: {e}")
After you run the Python or Node.js code, the text response appears in the console and an audio file named audio_assistant.wav is saved in the same directory as your code file.
Model response:
I am a large language model developed by Alibaba Cloud. My name is Qwen. How can I help you?
Running HTTP code returns text and Base64-encoded audio data directly in the audio field.
data: {"choices":[{"delta":{"content":"I"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1757647879,"system_fingerprint":null,"model":"qwen3.5-omni-plus","id":"chatcmpl-a68eca3b-c67e-4666-a72f-73c0b4919860"}
data: {"choices":[{"delta":{"content":"am"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1757647879,"system_fingerprint":null,"model":"qwen3.5-omni-plus","id":"chatcmpl-a68eca3b-c67e-4666-a72f-73c0b4919860"}
......
data: {"choices":[{"delta":{"audio":{"data":"/v8AAAAAAAAAAAAAAA...","expires_at":1757647879,"id":"audio_a68eca3b-c67e-4666-a72f-73c0b4919860"}},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1757647879,"system_fingerprint":null,"model":"qwen3.5-omni-plus","id":"chatcmpl-a68eca3b-c67e-4666-a72f-73c0b4919860"}
data: {"choices":[{"finish_reason":"stop","delta":{"content":""},"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1764763585,"system_fingerprint":null,"model":"qwen3.5-omni-plus","id":"chatcmpl-e8c82e9e-073e-4289-a786-a20eb444ac9c"}
data: {"choices":[],"object":"chat.completion.chunk","usage":{"prompt_tokens":207,"completion_tokens":103,"total_tokens":310,"completion_tokens_details":{"audio_tokens":83,"text_tokens":20},"prompt_tokens_details":{"text_tokens":207}},"created":1757940330,"system_fingerprint":null,"model":"qwen3.5-omni-plus","id":"chatcmpl-9cdd5a26-f9e9-4eff-9dcc-93a878165afc"}

Model selection

  • Qwen3.5-Omni series: Best for long video analysis, meeting summaries, caption generation, content moderation, and audio-video interaction.
    • Input limits: Up to 3 hours of audio or 1 hour of video
    • Audio control: Supports adjusting volume, speaking rate, and emotion through instructions
    • Visual capability: Matches the level of Qwen3.5. Understands images, speech, sound effects, and other multimodal input
    • Combined multimodal input: Supports any combination of text with images, audio, and video in a single request
    • Voice cloning: Supports custom voices (only qwen3.5-omni-plus and qwen3.5-omni-flash; snapshot versions are not supported). For details, see Voice cloning
  • Qwen3-Omni-Flash series: Best for short video analysis and cost-sensitive scenarios.
    • Input limits: Audio and video input up to 150 seconds
    • Thinking mode: The only Qwen-Omni series model that supports thinking mode
    • Input modality: Supports only a combination of text with a single other modality (image, audio, or video).
  • Qwen-Omni-Turbo series This series is no longer updated and has limited features. We recommend migrating to the Qwen3.5-Omni or Qwen3-Omni-Flash series.
SeriesAudio-video descriptionDeep thinkingWeb searchInput audio languagesOutput audio languagesSupported voices
Qwen3.5-OmniLatest-generation omni-modal modelStrongNot supportedSupported113
Languages: Chinese, English, German, French, Italian, Czech, Indonesian, Thai, Korean, Polish, Japanese, Vietnamese, Finnish, Portuguese, Spanish, Dutch, Russian, Malay, Catalan, Swedish, Turkish, Ukrainian, Romanian, Slovak, Danish, Icelandic, Norwegian (Bokmål), Macedonian, Greek, Hungarian, Galician, Filipino, Croatian, Bosnian, Slovenian, Bulgarian, Kazakh, Belarusian, Latvian, Estonian, Azerbaijani, Uyghur, Swahili, Hindi, Esperanto, Kyrgyz, Tajik, Cebuano, Afrikaans, Arabic, Lithuanian, Javanese, Bengali, Persian, Hebrew, Punjabi, Gujarati, Mongolian, Asturian, Kannada, Marathi, Interlingua, Malayalam, Maltese, Norwegian Nynorsk, Telugu, Urdu, Georgian, Basque, Tamil, Odia, Serbian, MaoriDialects:
Northeastern Mandarin, Guizhou dialect, Cantonese, Henan dialect, Hong Kong Cantonese, Shanghainese, Shaanxi dialect, Tianjin dialect, Taiwanese Hokkien, Yunnan dialect, Anhui dialect, Fujian dialect, Gansu dialect, Guangdong dialect, Hubei dialect, Hunan dialect, Jiangxi dialect, Shandong dialect, Shanxi dialect, Sichuan dialect, Guangxi dialect, Hainan dialect, Chongqing dialect, Changsha dialect, Hangzhou dialect, Hefei dialect, Yinchuan dialect, Zhengzhou dialect, Shenyang dialect, Wenzhou dialect, Wuhan dialect, Kunming dialect, Taiyuan dialect, Nanchang dialect, Jinan dialect, Lanzhou dialect, Nanjing dialect, Hakka, Southern Min

36
Languages:Chinese, English, German, Italian, Portuguese, Spanish, Japanese, Korean, French, Russian, Thai, Indonesian, Arabic, Vietnamese, Turkish, Finnish, Polish, Hindi, Dutch, Czech, Urdu, Tagalog, Swedish, Danish, Hebrew, Icelandic, Malay, Norwegian, Persian
Dialects:Sichuan dialect, Beijing dialect, Tianjin dialect, Nanjing dialect, Shaanxi dialect, Cantonese, Southern Min
55
Qwen3-Omni-FlashHybrid thinking modelWeakerSupportedNot supported19
Language:Chinese, English, German, French, Italian, Thai, Korean, Japanese, Russian, Spanish, PortugueseDialects:Sichuan dialect, Shanghainese, Cantonese, Southern Min, Shaanxi dialect, Nanjing dialect, Tianjin dialect, Beijing dialect
19
Language:Chinese, English, German, French, Italian, Thai, Korean, Japanese, Russian, Spanish, PortugueseDialects:Sichuanese, Shanghainese, Cantonese, Hokkien, Shaanxi dialect, Nanjing dialect, Tianjin dialect, Beijing dialect
17 to 49
Varies by version
Qwen-Omni-TurboNo longer updatedNoneNot supportedNot supportedChinese, EnglishChinese, English4
For model names, context windows, pricing, and snapshot versions, check in the Model Studio console. For rate limits, see Rate limiting.

Model performance

Audio and video content analysis

Generate a comprehensive timestamped description of this video.
00:00.000 – 00:02.500A rain-soaked city street fills the widescreen frame. Long-exposure photography creates streaks of red and blue car lights on wet pavement. A solitary man in a dark knee-length trench coat and light shirt with a tie walks toward the camera along the right sidewalk. Raindrops cling to his shoulders and hair. Each step makes a muffled plop on damp concrete. A low, ominous electronic hum underscores ambient sounds, while steady rain crackles all around. Colorful graffiti covers the brick wall beside him, and neon signs glow in the distance—one clearly displays orange-red cursive script reading "Nice," while another vertical sign shows the letters "AT" at its bottom.......00:12.300 – 00:14.533The camera tilts down. Inside a flashlight beam, a yellowed, aged single sheet lies in a shallow puddle, its edges charred and corners curled. Inked paragraphs cover most of its surface, but moisture and scorch marks make the text unreadable. The man kneels, extending gloved fingers toward the document. Ripples spread outward as his hand nears. Sirens peak then begin to fade slightly, while the ambient hum remains steady. The scene freezes just before the trembling paper is touched, ending the clip.
Only partial timestamps are shown.

Multidialect understanding

Describe the vocal characteristics, emotional state, and full lyrics for singers in different Chinese dialects.
This audio features rap performances by singers from various regions of China, showcasing rich dialect diversity. The following are detailed descriptions of each singer's vocal traits, emotional state, and corresponding lyrics:Hangzhou dialect (Wu)Vocal traits:The male singer's voice is soft and gentle, with the distinctive smoothness and warmth of the Wu dialect. His intonation rises and falls gently, and his rhythm is light and quick, creating a relaxed storytelling effect.Emotional state:Relaxed, comfortable, and full of everyday life. He describes Hangzhou's slow-paced lifestyle and urban changes, expressing affection for his hometown and reflections on modern development. Overall, he feels cozy and familiar.Lyrics:> Hangzhou dialect, listen up! Our culture includes local erhua pronunciation.> Like flowers blooming by West Lake, no cultural survey needed—we understand it best.> None of you understand. 'San bu da men', 'ge'r', 'lao'r', 'fen'r', 'ya'r'... how is an outsider supposed to tell any of these apart?> Let's go! Transport is fast—subways everywhere. We'll check it out.> Welcoming Southeast Asia and Thailand, watching "Thirteen Ta" shows. Proud of our city, direct in personality.> So you only came for the "bridge-crossing" experience, and because the flavor is different, you're not returning?
Only partial results are shown.

Lyric caption generation

Transcribe the song lyrics and provide timestamps for each line in this format:[00:00:15,020 --> 00:00:28,085] : When you walk through a storm, hold your head up high.[00:00:28,085 --> 00:00:40,200] And don't be afraid of the dark. ......
[00:00:12,680 --> 00:00:16,960] Cat thread sways past moonlight on trees.[00:00:18,400 --> 00:00:22,800] Radiators hum 1998 chart hits.[00:00:24.160 → 00:00:28.080] Time parts the mist-like heat waves.[00:00:28,920 --> 00:00:33,000] Neon from the screen shines on my nose bridge.......[00:03:16,720 --> 00:03:21,680] We nestle in the softest ring of the tree trunk.[00:03:22,400 --> 00:03:27,000] Breathing turns residual warmth into honey-sugar.[00:03:28,160 --> 00:03:33,200] The sofa sinks into cloud-fluff shape.[00:03:34,000 --> 00:03:38,800] Every pore soaks in sunshine.[00:04:09,000 --> 00:04:10,020] (End)
Only partial results are shown.

Audio-video programming

Usage

Streaming output

All requests to Qwen-Omni must set stream=True.

Model configuration

Configure parameters, prompts, and media lengths to balance cost, speed, and quality.
  • Audio-video understanding
  • Audio understanding
Use caseRecommended video lengthRecommended promptRecommended max_pixels
Fast review, low cost≤60 minutesSimple prompt within 50 words230,400
Content extraction (long video segmentation)≤60 minutes921,600~2,073,600
Standard analysis (short video tagging)≤4 minutesUse the structured prompt below
921,600~2,073,600
Fine-grained analysis (multiple speakers/complex scenes)≤2 minutes2,073,600
You can segment long videos first to obtain fine-grained descriptions.

Combined multimodal input

Combined multimodal input is supported only by the Qwen3.5-Omni series. You can provide data in multiple modalities, such as any combination of image, audio, and text, or video, image, and text, in the same request.
The following example shows how to provide an image and audio in a single request for multimodal analysis.
  • OpenAI compatible
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen3.5-omni-plus",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"
                    },
                },
                {
                    "type": "input_audio",
                    "input_audio": {
                        "data": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250211/tixcef/cherry.wav",
                        "format": "wav"
                    },
                },
                {"type": "text", "text": "Describe the image content and tell me what the audio is about."},
            ],
        },
    ],
    modalities=["text", "audio"],
    audio={"voice": "Tina", "format": "wav"},
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)

Single modality input

Each request contains text and one other modality (video, audio, or image). All Qwen-Omni models support this.
  • Video and text input
  • Audio and text input
  • Image and text input
Provide the video as an image list or a video file (with audio support).
  • Video file (supports audio in the video)
  • Image list format
  • Number of files:
    • Qwen3.5-Omni series: Up to 512 files using public URLs and up to 250 files using Base64 encoding.
    • Qwen3-Omni-Flash and Qwen-Omni-Turbo series: Only one file is allowed.
  • File size:
    • Using public URLs:
      • Qwen3.5-Omni series: Up to 2 GB
      • Qwen3-Omni-Flash: Up to 256 MB
      • Qwen-Omni-Turbo: Up to 150 MB
    • Using Base64 encoding: The encoded Base64 string must be smaller than 10 MB
  • Duration limits:
    • Qwen3.5-Omni series: 1 hour
    • Qwen3-Omni-Flash: 150 seconds
    • Qwen-Omni-Turbo: 40 seconds
  • File formats: MP4, AVI, MKV, MOV, FLV, and WMV.
  • Visual and audio information in the video file are billed separately.
  • OpenAI compatible
import os
from openai import OpenAI

client = OpenAI(
    # API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen3.5-omni-plus", # For Qwen3-Omni-Flash, run in non-thinking mode.
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "video_url",
                    "video_url": {
                        "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241115/cqqkru/1.mp4"
                    },
                },
                {"type": "text", "text": "What is the video about?"},
            ],
        },
    ],
    # Set the output modality. Two options are currently supported: ["text","audio"] and ["text"]
    modalities=["text", "audio"],
    audio={"voice": "Tina", "format": "wav"},
    # stream must be set to True, otherwise an error occurs.
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
The Qwen3.5-Omni series supports web search to retrieve real-time information and perform reasoning.
  • Web search is supported only in the Qwen3.5-Omni series. The search_strategy parameter only accepts agent.
  • For billing, see the agent policy in Billing.
To enable web search, set enable_search and search_strategy to agent:
  • OpenAI compatible
# Prerequisites:
# pip install openai

import os
from openai import OpenAI

# Initialize the client
client = OpenAI(
    # API Keys differ between Singapore and Beijing regions. Get API Key:https://www.alibabacloud.com/help/en/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

# Send request (with web search enabled)
try:
    completion = client.chat.completions.create(
        model="qwen3.5-omni-plus",
        messages=[{
            "role": "user",
            "content": "What is today's date and day of the week, and what important holidays are there today?"
        }],
        stream=True,
        stream_options={"include_usage": True},
        # Enable web search
        extra_body={
            "enable_search": True
        }
    )

    print("Model response (with real-time information):")
    for chunk in completion:
        if chunk.choices and chunk.choices[0].delta.content:
            print(chunk.choices[0].delta.content, end="")
    print()

except Exception as e:
    print(f"Request failed:{e}")

Enable/disable thinking mode

In the Qwen-Omni series, only the Qwen3-Omni-Flash model is a hybrid thinking model. You can use the enable_thinking parameter to enable or disable the thinking mode:
  • true
  • false (default)
In thinking mode, audio output is not supported.
  • OpenAI compatible
import os
from openai import OpenAI

client = OpenAI(
    # API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen3-omni-flash",
    messages=[{"role": "user", "content": "Who are you?"}],

    # Enable or disable thinking mode. Audio output is not supported in thinking mode. Qwen-Omni-Turbo does not support enable_thinking.
    extra_body={'enable_thinking': True},

    # Set the output modality. Two options are supported in non-thinking mode: ["text","audio"] and ["text"]. Only ["text"] is supported in thinking mode.
    modalities=["text"],

    # Set the voice. The audio parameter is not supported in thinking mode.
    # audio={"voice": "Tina", "format": "wav"},
    # stream must be set to True, otherwise an error occurs.
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
data: {"choices":[{"delta":{"content":null,"role":"assistant","reasoning_content":""},"index":0,"logprobs":null,"finish_reason":null}],"object":"chat.completion.chunk","usage":null,"created":1757937336,"system_fingerprint":null,"model":"qwen3-omni-flash","id":"chatcmpl-ce3d6fe5-e717-4b7e-8b40-3aef12288d4c"}
data: {"choices":[{"finish_reason":null,"logprobs":null,"delta":{"content":null,"reasoning_content":"Hmm"},"index":0}],"object":"chat.completion.chunk","usage":null,"reated":1757937336,"system_fingerprint":null,"model":"qwen3-omni-flash","id":"chatcmpl-ce3d6fe5-e717-4b7e-8b40-3aef12288d4c"}
data: {"choices":[{"delta":{"content":null,"reasoning_content":","},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"reated":1757937336,"system_fingerprint":null,"model":"qwen3-omni-flash","id":"chatcmpl-ce3d6fe5-e717-4b7e-8b40-3aef12288d4c"}
......
data: {"choices":[{"delta":{"content":"Tell me"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1757937336,"tem_fingerprint":null,"model":"qwen3-omni-flash","id":"chatcmpl-ce3d6fe5-e717-4b7e-8b40-3aef12288d4c"}
data: {"choices":[{"delta":{"content":"!"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1757937336,"systm_fingerprint":null,"model":"qwen3-omni-flash","id":"chatcmpl-ce3d6fe5-e717-4b7e-8b40-3aef12288d4c"}
data: {"choices":[{"finish_reason":"stop","delta":{"content":"","reasoning_content":null},"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1757937336,"system_fingerprint":null,"model":"qwen3-omni-flash","id":"chatcmpl-ce3d6fe5-e717-4b7e-8b40-3aef12288d4c"}
data: {"choices":[],"object":"chat.completion.chunk","usage":{"prompt_tokens":11,"completion_tokens":363,"total_tokens":374,"completion_tokens_details":{"reasoning_tokens":195,"text_tokens":168},"prompt_tokens_details":{"text_tokens":11}},"created":1757937336,"system_fingerprint":null,"model":"qwen3-omni-flash","id":"chatcmpl-ce3d6fe5-e717-4b7e-8b40-3aef12288d4c"}

Multi-turn conversation

When using Qwen-Omni models for multi-turn conversations, note the following:
  • Assistant Message Assistant messages in the messages array can contain only text data.
  • User Message A user message can contain text and one other modality. In multi-turn conversations, you can input different modalities in different user messages.
  • OpenAI compatible
import os
from openai import OpenAI

client = OpenAI(
    # API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen3.5-omni-plus", # For Qwen3-Omni-Flash, run in non-thinking mode.
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "input_audio",
                    "input_audio": {
                        "data": "https://dashscope.oss-cn-beijing.aliyuncs.com/audios/welcome.mp3",
                        "format": "mp3",
                    },
                },
                {"type": "text", "text": "What is this audio about"},
            ],
        },
        {
            "role": "assistant",
            "content": [{"type": "text", "text": "This audio says: Welcome to Alibaba Cloud"}],
        },
        {
            "role": "user",
            "content": [{"type": "text", "text": "Tell me about this company."}],
        },
    ],
    # Set the output modality. Two options are currently supported: ["text","audio"] and ["text"]
    modalities=["text"],
    # stream must be set to True, otherwise an error occurs.
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)

Parsing output Base64-encoded audio data

Qwen-Omni models output audio as streaming Base64-encoded data. During generation, maintain a string variable and append the Base64-encoded data from each returned chunk. After generation completes, Base64-decode the complete string to get the audio file. Alternatively, decode and play each chunk in real time.
# Installation instructions for pyaudio:
# APPLE Mac OS X
#   brew install portaudio
#   pip install pyaudio
# Debian/Ubuntu
#   sudo apt-get install python-pyaudio python3-pyaudio
#   or
#   pip install pyaudio
# CentOS
#   sudo yum install -y portaudio portaudio-devel && pip install pyaudio
# Microsoft Windows
#   python -m pip install pyaudio

import os
from openai import OpenAI
import base64
import numpy as np
import soundfile as sf

client = OpenAI(
    # API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen3.5-omni-plus", # For Qwen3-Omni-Flash, run in non-thinking mode.
    messages=[{"role": "user", "content": "Who are you?"}],
    # Set the output modality. Two options are currently supported: ["text","audio"] and ["text"]
    modalities=["text", "audio"],
    audio={"voice": "Tina", "format": "wav"},
    # stream must be set to True, otherwise an error occurs.
    stream=True,
    stream_options={"include_usage": True},
)

# Method 1: Decode after generation is complete
audio_string = ""
for chunk in completion:
    if chunk.choices:
        if hasattr(chunk.choices[0].delta, "audio"):
            try:
                audio_string += chunk.choices[0].delta.audio["data"]
            except Exception as e:
                print(chunk.choices[0].delta.content)
    else:
        print(chunk.usage)

wav_bytes = base64.b64decode(audio_string)
audio_np = np.frombuffer(wav_bytes, dtype=np.int16)
sf.write("audio_assistant_py.wav", audio_np, samplerate=24000)

# Method 2: Decode while generating (comment out the code for Method 1 to use Method 2)
# # Initialize PyAudio
# import pyaudio
# import time
# p = pyaudio.PyAudio()
# # Create an audio stream
# stream = p.open(format=pyaudio.paInt16,
#                 channels=1,
#                 rate=24000,
#                 output=True)

# for chunk in completion:
#     if chunk.choices:
#         if hasattr(chunk.choices[0].delta, "audio"):
#             try:
#                 audio_string = chunk.choices[0].delta.audio["data"]
#                 wav_bytes = base64.b64decode(audio_string)
#                 audio_np = np.frombuffer(wav_bytes, dtype=np.int16)
#                 # Play the audio data directly
#                 stream.write(audio_np.tobytes())
#             except Exception as e:
#                 print(chunk.choices[0].delta.content)

# time.sleep(0.8)
# # Clean up resources
# stream.stop_stream()
# stream.close()
# p.terminate()

Input Base64-encoded local file

When using Base64 encoding to send files, the encoded Base64 string must be smaller than 10 MB.
  • Images
  • Audio
  • Video
This example uses the locally saved file eagle.png.
import os
from openai import OpenAI
import base64

client = OpenAI(
    # API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

# Base64 encoding format
def encode_image(image_path):
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode("utf-8")

base64_image = encode_image("eagle.png")

completion = client.chat.completions.create(
    model="qwen3.5-omni-plus", # For Qwen3-Omni-Flash, run in non-thinking mode.
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url": f"data:image/png;base64,{base64_image}"},
                },
                {"type": "text", "text": "What scene is depicted in the image?"},
            ],
        },
    ],
    # Set the output modality. Two options are currently supported: ["text","audio"] and ["text"]
    modalities=["text", "audio"],
    audio={"voice": "Tina", "format": "wav"},
    # stream must be set to True, otherwise an error occurs.
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)

API reference

For input and output parameters, see OpenAI compatible - Chat.

Billing and rate limits

Billing rules Qwen-Omni is billed based on tokens consumed across modalities (audio, image, and video). Check billing details in the console.
  • Audio
  • Images
  • Video
  • Qwen3.5-Omni series:
    • Input audio formula: Total tokens = Audio duration (seconds) * 7
    • Output audio formula: Total tokens = Audio duration (seconds) * 12.5
  • Qwen3-Omni-Flash: For both input and output audio, Total tokens = Audio duration (seconds) * 12.5
  • Qwen-Omni-Turbo: For both input and output audio, Total tokens = Audio duration (seconds) * 25
If the audio duration is less than 1 second, it is counted as 1 second.
Free quota To claim, query, or use your free quota, see Free quota for new users. Rate limits For rate limiting rules and FAQ, see Rate limiting.

Error codes

If the model call fails and returns an error message, see Error codes for resolution.

Voice list

For a list of voices for the Qwen-Omni model, see Voice list.
Token Plan
Model Playground
Statistics and Monitoring
Support