Use Qwen-Omni over HTTP to understand text, images, audio, and video. Choose Qwen3.8-Omni-Flash for text analysis and Qwen3.5-Omni for speech output.
Getting started
Choose an example by output type: Qwen3.8-Omni-Flash for text analysis, or Qwen3.5-Omni for speech generation.
Text output (Qwen3.8-Omni-Flash)
Configure your API key and install the OpenAI SDK. Set the DASHSCOPE_BASE_URL environment variable to the base_url for your workspace from the Chat Completions endpoints. Set AUDIO_URL to an accessible WAV audio URL. Use an API key from the selected region.
In a macOS or Linux terminal, install the dependency and set the following variables. Replace the endpoint and audio URL with your values; configure DASHSCOPE_API_KEY using the instructions linked above.
python3 -m pip install openai
export DASHSCOPE_BASE_URL="<workspace-base-url>"
export AUDIO_URL="<accessible-wav-url>"
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["DASHSCOPE_API_KEY"],
base_url=os.environ["DASHSCOPE_BASE_URL"],
)
completion = client.chat.completions.create(
model="qwen3.8-omni-flash",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Summarize the main points of this recording."},
{"type": "input_audio", "input_audio": {
"data": os.environ["AUDIO_URL"],
"format": "wav",
}},
],
}],
stream=True,
stream_options={"include_usage": True},
)
output_section = None
for chunk in completion:
if not chunk.choices:
if chunk.usage:
print("\nUsage:", chunk.usage)
continue
delta = chunk.choices[0].delta
if getattr(delta, "reasoning_content", None):
if output_section != "thinking":
print("\nThinking:")
output_section = "thinking"
print(delta.reasoning_content, end="", flush=True)
if delta.content:
if output_section != "answer":
print("\nAnswer:")
output_section = "answer"
print(delta.content, end="", flush=True)
Audio output (Qwen3.5-Omni)
Prerequisites- Obtain an API key and set the API key as an environment variable.
- The audio-output examples below use OpenAI-compatible invocation. You must install the latest SDK. The minimum required versions are 1.52.0 for the OpenAI Python SDK and 4.68.0 for the Node.js SDK.
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}")
// Before you run this code:
// For Windows/Mac/Linux:
// 1. Ensure Node.js version >= 14 is installed.
// 2. Run the following command to install necessary dependencies:
// npm install openai wav
import OpenAI from "openai";
import { createWriteStream } from 'node:fs';
import { Writer } from 'wav';
// Define a function to convert a Base64 string and save it as a standard WAV audio file
async function convertAudio(audioString, audioPath) {
try {
// Decode the Base64 string into a Buffer
const wavBuffer = Buffer.from(audioString, 'base64');
// Create a WAV file write stream
const writer = new Writer({
sampleRate: 24000, // Sample rate
channels: 1, // Mono
bitDepth: 16 // 16-bit depth
});
// Create an output file stream and establish a pipe connection
const outputStream = createWriteStream(audioPath);
writer.pipe(outputStream);
// Write PCM data and end writing
writer.write(wavBuffer);
writer.end();
// Use a Promise to wait for the file to finish writing
await new Promise((resolve, reject) => {
outputStream.on('finish', resolve);
outputStream.on('error', reject);
});
// Add extra wait time to ensure audio integrity
await new Promise(resolve => setTimeout(resolve, 800));
console.log(`\nAudio file saved to: ${audioPath}`);
} catch (error) {
console.error('Error during processing:', error);
}
}
// 1. Initialize the client
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
// 2. Send the request
const completion = await openai.chat.completions.create({
model: "qwen3.5-omni-plus",
messages: [
{
"role": "user",
"content": "Who are you?"
}],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text", "audio"],
audio: { voice: "Tina", format: "wav" }
});
let audioString = "";
console.log("Model response:")
// 3. Process the streaming response and decode the audio
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
// Process text content
if (chunk.choices[0].delta.content) {
process.stdout.write(chunk.choices[0].delta.content);
}
// Process audio content
if (chunk.choices[0].delta.audio) {
if (chunk.choices[0].delta.audio["data"]) {
audioString += chunk.choices[0].delta.audio["data"];
}
}
}
}
// 4. Save the audio file
convertAudio(audioString, "audio_assistant.wav");
# ======= Important note =======
# API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Delete this comment before execution ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.5-omni-plus",
"messages": [
{
"role": "user",
"content": "Who are you?"
}
],
"stream":true,
"stream_options":{
"include_usage":true
},
"modalities":["text","audio"],
"audio":{"voice":"Tina","format":"wav"}
}'
Response
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
For audio/video understanding, meeting summaries, subtitles, and text answers, use Qwen3.8-Omni-Flash. It supports thinking, tool calling, and web search; see the invocation examples. For generated speech responses, use Qwen3.5-Omni below.
Qwen3.8-Omni-Flash
Supported regions: China (Beijing), Singapore, China (Hong Kong), Japan (Tokyo), Germany (Frankfurt), and US (Virginia). Use an API key from the selected region.
qwen3.8-omni-flash is designed for audio and video understanding, meeting summaries, and content analysis.
| Model | Input | Output | APIs |
|---|---|---|---|
qwen3.8-omni-flash | Text, images, audio, video | Text | Chat Completions, Responses |
- The context length is 1M tokens.
- Audio input supports 113 languages and dialects, the same as Qwen3.5-Omni. See the Qwen3.5-Omni input audio languages in Model selection for the full list.
- Supports Function Calling and web search. The only supported built-in Responses tool is currently
web_search.
Qwen3.5-Omni: audio output and multimodal interaction
Supported regions: China (Beijing) and Singapore. Use an API key from the selected region.
-
Qwen3.5-Omni series: Supports audio/video understanding, speech responses, and audio control.
- 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
Other models and specifications
-
Qwen3-Omni-Flash series:
- Input limits: Audio and video input up to 150 seconds
- Thinking mode: Use
enable_thinkingto enable or disable thinking - 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. For text analysis, migrate to Qwen3.8-Omni-Flash; for audio output, use Qwen3.5-Omni.
| Series | Audio-video description | Deep thinking | Web search | Input audio languages | Output audio languages | Supported voices |
Qwen3.5-Omni Omni-modal model with audio output | Strong | Not supported | Supported | 113 74 languages and 39 dialects 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, Maori Dialects: | 36 29 languages and 7 dialects 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-Flash Hybrid thinking model | Weaker | Supported | Not supported | 19 11 languages and 8 dialects Language: Chinese, English, German, French, Italian, Thai, Korean, Japanese, Russian, Spanish, Portuguese Dialects:Sichuan dialect, Shanghainese, Cantonese, Southern Min, Shaanxi dialect, Nanjing dialect, Tianjin dialect, Beijing dialect | 19 11 languages and 8 dialects Language: Chinese, English, German, French, Italian, Thai, Korean, Japanese, Russian, Spanish, Portuguese Dialects:Sichuanese, Shanghainese, Cantonese, Hokkien, Shaanxi dialect, Nanjing dialect, Tianjin dialect, Beijing dialect | 17 to 49
|
Qwen-Omni-Turbo No longer updated | None | Not supported | Not supported | Chinese, English | Chinese, English | 4 |
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
| 00:00.000 – 00:02.500 A 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.
|
Multidialect understanding
| 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?
|
Lyric caption generation
| [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)
|
Audio-video programming
Usage
Streaming output
The Qwen3.5-Omni, Qwen3-Omni-Flash, and Qwen-Omni-Turbo examples below require stream=True.
Responses: audio and video input
The following examples use Qwen3.8-Omni-Flash with the Responses API to process audio and video input and generate text responses.
Reuse the API key, DASHSCOPE_BASE_URL, and AUDIO_URL from the quick-start example. Responses uses input, with the audio URL in audio_url, rather than the Chat Completions input_audio.data structure. Audio and video input is allowed only in user messages.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["DASHSCOPE_API_KEY"],
base_url=os.environ["DASHSCOPE_BASE_URL"],
)
response = client.responses.create(
model="qwen3.8-omni-flash",
input=[{
"role": "user",
"content": [
{"type": "input_text", "text": "Summarize the main points of this recording."},
{"type": "input_audio", "audio_url": os.environ["AUDIO_URL"], "format": "wav"},
],
}],
stream=False,
)
print(response.output_text)
To analyze a video, set VIDEO_URL to an accessible video URL and replace input[0].content in the quick-start example with:
[
{"type": "input_text", "text": "Describe the visuals and sounds in the video."},
{"type": "input_video", "video_url": os.environ["VIDEO_URL"]},
]
For two-channel or four-channel spatial audio, add "use_multichannel": True (Python) to the audio content object above, alongside audio_url and format. The default is False, which processes audio as single-channel audio.
For Base64 audio input, field definitions, and tool scope, see Create a response.
Model configuration
The following configuration recommendations apply to Qwen3.5-Omni. Adjust parameters, prompts, and media lengths for your use case. For Qwen3.8-Omni-Flash, see Recommended prompts.
Audio-video understanding
| Use case | Recommended video length | Recommended prompt | Recommended max_pixels |
Fast review, low cost | ≤60 minutes | Simple prompt within 50 words | 230,400 |
Content extraction (long video segmentation) | ≤60 minutes | 921,600~2,073,600 | |
Standard analysis (short video tagging) | ≤4 minutes | Use the structured prompt below Recommended prompt | 921,600~2,073,600 |
Fine-grained analysis (multiple speakers/complex scenes) | ≤2 minutes | 2,073,600 |
NoteYou can segment long videos first to obtain fine-grained descriptions.
Audio understanding
You can balance cost and quality by controlling the audio length and prompt complexity.
| Use case | Recommended audio length | Recommended prompt |
Fast review, low cost | ≤60 minutes | Simple prompt within 50 words |
Content extraction (segment long audio) | ≤60 minutes | |
Standard analysis (audio tagging) | ≤2 minutes | Use a structured prompt Structured prompt |
Fine-grained analysis (multiple speakers/complex scenes) | ≤1 minute |
NoteYou can segment long audio first to obtain fine-grained descriptions.
Recommended prompts
These prompts apply to qwen3.8-omni-flash. Choose a prompt for your task, use it as the Chat Completions system message, and provide the audio or video to analyze in the user message. Output format instructions in the prompts guide the generated content.
Detailed audiovisual description: chronological narrative
Combine visual and audio information in a chronological account with time ranges for locating events in the video.
You are a rigorous audio-visual description expert. Your task is to watch and analyze the entire video and produce a highly detailed, coherent, evidence-grounded description that reconstructs, as accurately as possible, what is actually visible, audible, and readable in the video.
Produce a complete, directly usable video description — not an analysis report, not a checklist, not a rough summary. The description must cover the main content of the video from beginning to end, organized in chronological order into naturally coherent, information-dense paragraphs. Level of detail must always yield to factual accuracy: details that cannot be confirmed may be omitted, but you must never guess, fill in, or fabricate anything in order to make the description richer.
## Core Principles
1. Cover the main content of the video from beginning to end, including the opening, the main process, scene changes, important actions, speech, on-screen text, sound, and the ending. Removing redundancy applies only to attributes that have not changed — clothing, room layout, aspect ratio, a continuing music bed — which are described once and then revisited only when they change. It does not license coarser event granularity: you must not skip or compress new actions, text, sounds, or state changes.
2. Every statement must be grounded in what is actually visible, audible, or readable in the video. Do not add background knowledge, common sense, prior assumptions, or speculation from outside the video. Do not treat "seems plausible" as "the video has proven it."
3. Prioritize preserving clearly discernible concrete facts, including people, animals, objects, appearance, clothing, colors, quantities, positions, actions, interactions, on-screen text, subtitles, speech, ambient sound, music, sound effects, camera changes, scene cuts, and state changes.
4. Track people, animals, and objects continuously. Once an entity has been clearly identified, keep its identity consistent in later appearances; if multiple similar entities cannot be reliably distinguished, use positional descriptions such as "the device on the left" or "the person in the center of the frame" rather than forcing a name onto them. Avoid ambiguous references such as "he," "she," "it," "this person," or "that thing."
5. Do not invent a person's identity, age, occupation, emotion, intention, relationship, or the reason behind an action. You may describe visible facial expressions and body movements, but do not interpret an expression directly as a mental state. For example, write "the corners of his mouth turn up and he smiles" rather than "he feels happy."
6. When the identity of an entity, an action, a quantity, text, speech, a temporal relationship, a sound source, or a causal relationship cannot be confirmed, and that uncertainty affects understanding, use brief, specific, conservative wording, for example "the on-screen text is small and cannot be fully made out" or "voices can be heard, but the exact lines are unclear." For unimportant unclear details, simply omit them; do not repeatedly pile up "possibly," "seemingly," and "appears to be."
7. When speech, subtitles, or on-screen text are clearly discernible, preserve the original wording as far as possible, especially for personal names, place names, numbers, brands, labels, proper nouns, formulas, code, and key statements. Do not translate, rewrite, or correct the original text on your own initiative.
8. Distinguish facts directly observed in the footage from opinions expressed by people in the video, by narration, or by subtitles. If a host or narrator offers an evaluation, explanation, recommendation, or causal judgment, write it explicitly as "the host states," "the narration explains," or "the subtitle says"; do not rewrite an opinion voiced in the video as the describer's own objective conclusion.
9. When level of detail and reliability conflict, reliability comes first. It is better to write fewer unconfirmable details than to hallucinate in order to fill up information.
## Description Granularity
The unit of segmentation is a change in information, not a fixed number of seconds. Begin a new event wherever the subject, object, or goal changes; an action enters a new stage; contact is made or released; direction, speed, or trajectory changes noticeably; an observable state change occurs; the speaker turn changes; the sound or music structure changes; the scene, shot, or narrative layer changes; or the interface focus, control, parameter, or result state changes.
For each significant action, write as much of the following as the video actually supports: the subject, its state before the action, the action itself, the object or point of contact, which hand, body part, or tool is used, the direction and trajectory, the speed or manner, any intermediate stage, the resulting state, and the observable consequence. A named action on its own is a label, not a description. "She opens the bottle" is insufficient; "she steadies the bottle with her left hand, then twists the metal cap counter-clockwise with her right, and once the cap is free she sets it down to the right of the bottle" carries the actual granularity. The same applies to a state change: give both ends of it, since "the waveform is narrower after he applies the setting" carries the change while "he adjusts the audio" does not.
Granularity does not degrade with video length. A long or repetitive video receives the same local event granularity as a short one. Length may add chapter-level organization, but it must never replace a sequence of distinct actions with a single coarser generalizing verb.
Before using left, right, in front, or behind, make the frame of reference unambiguous, distinguishing the viewer's left and right within the frame, a person's own left and right, and the left and right inside a software window or interface. When a visual event and a sound belong to the same occurrence, write them together and make the relation explicit rather than listing picture and sound separately for the reader to pair up. Whenever you give a number, make the basis of the count explicit: what is being counted, over which time window, and whether you are counting instantaneous on-screen quantity, distinct entities across the whole video, completed actions, attempts, or sound occurrences.
## Scope of Content Coverage
Describe the following whenever the video actually contains them:
* the video type, subject, narrative line, and overall visual form;
* the main people, animals, and objects, and their identities or roles;
* appearance, clothing, colors, materials, quantities, and spatial positions;
* actions, interactions, operating steps, and their order;
* the scene environment, foreground, middle ground, background, lighting, left-right relationships, and spatial changes;
* camera viewpoint, shot size, focus, push/pull/pan/tilt, following shots, transitions, and frame layout;
* titles, subtitles, labels, interface text, numbers, formulas, code, tables, and charts;
* speech, narration, language, speakers, discernible original spoken content, and obvious tonal characteristics;
* background music, ambient sound, sound effects, and the onset, end, and obvious changes of sounds;
* the entrance, exit, movement, contact, operation, and state changes of the subjects;
* professional procedures, tools, terminology, and conclusions explicitly demonstrated or explicitly stated in the video;
* temporal continuity, location changes, and time jumps between different scenes.
Do not infer a music track's specific BPM, genre, instrumentation, key, mixing, compression, or reverb from listening impression alone. When the sound source cannot be confirmed, use neutral wording such as "an impact sound is heard" or "a short electronic sound effect occurs." Attribute a sound to a specific object only when the sound clearly corresponds to an action visible in the frame.
For OCR, numbers, and charts, transcribe verbatim only when the content is clear enough. Do not guess content from blurry text, and do not estimate values from the heights of bars or lines in a chart. If it cannot be read reliably, omit the specific value or state that part of the text cannot be made out.
## Timestamp Rules
Describe the video in chronological order, and start a new paragraph at shot cuts, scene changes, changes of main activity, the appearance of a new subject, speaker changes, the appearance of key text, or obvious state changes.
Begin each time segment with the following format:
[hh:mm:ss:xxx-hh:mm:ss:xxx]
For example:
[00:00:04:000-00:00:12:000] The shot cuts to ...
Timestamps must be safe time intervals backed by evidence. Timing may be determined from clear shot cuts, subtitle appearances, speech onset and offset points, ASR timestamps, or stably locatable visual events. Do not generate timings from paragraph length, average shot duration, or guesswork, and do not fabricate millisecond-level precision merely to satisfy the millisecond format.
Match precision to the evidence available. Chapters and long scenes take ranges of seconds to minutes; shot boundaries and ordinary actions are locatable to roughly half a second to a second; dialogue turns to a few tenths of a second; clicks, contacts, impacts, and cue tones to around a tenth of a second. If an event can only be confirmed as falling somewhere near a given second, write an approximate range rather than a fabricated millisecond timestamp.
Write an additional precise time point inside a paragraph only when that event can genuinely be located reliably. Otherwise, describe only the order in which events occur and the time segment they fall in. Adjacent time segments must not overlap, and do not manufacture unreliable time boundaries in the pursuit of precision.
Distinguish a new event from a repeated action, a slow-motion pass, a replay, or a flashback. A replayed sequence keeps the same clothing, action order, and target, and should be identified as a replay rather than described as further new events.
## Output Format
Write one concise overview paragraph followed by multiple chronologically ordered description paragraphs.
Open with a short overview introducing the video type, core subjects, main scenes, visual style, and overall auditory environment. Then describe the concrete content in chronological order, integrating visuals, speech, on-screen text, and audio within the same time segment; do not mechanically split by modality into "visual," "audio," "OCR," and so on.
Add a brief closing paragraph only when the video genuinely has a clear overall outcome or concluding development. The closing must not introduce new information absent from the preceding text, and must not offer your own evaluation of the video.
Do not use tables, bullet points, numbered lists, XML, JSON, analytical subheadings, or mechanical headings such as "Scene 1" or "Shot 2.3." Do not output your analysis process, observation process, evidence lists, tool-call records, quality assessments, or any explanation unrelated to the video.
The final output should be natural, fluent, specific, coherent, and information-dense without excessive repetition, and must at all times obey the principles of "evidence first, timing grounded, details reliable."
Please describe this video in detail.
Detailed audiovisual description: separate transcripts and on-screen text
Return separate sections for events, on-screen text, and speech transcripts. Preserve the original wording, speakers, and time ranges for search and verification.
Provide a detailed description of the video.
Make sure your description covers every one of the following dimensions:
Visual
- Subjects and characters: appearance, clothing, gender/age cues, identity, distinctive features
- Actions and events in chronological order, and how the scene evolves over time
- Setting and background: location, environment, time of day
- Spatial layout and relations between subjects/objects; counts and quantities
- On-screen text: captions, titles, subtitles, logos, UI — exact content and appearance
- Visual style: colors, lighting, camera shots, angles, and camera movement
Audio
- Speech: the exact spoken content, transcribed verbatim
- Speakers: who is speaking (mapped to the on-screen person or voice-over), with accent, tone, gender/age cues
- Speaking state: prosody, emotion, volume, and speaking style
- Music: presence, genre/mood, and lyrics if any
- Sound effects and ambient/background sounds
- Non-speech vocalizations: laughter, crying, applause, etc.
Audio-visual correspondence
- Which speech or sound aligns with which on-screen person or visual event
- The timing of each event, expressed with timestamps
It should explicitly include three sections:
1. A structured chronological storyline of **every noticeable audio and visual details**
2. A structured list of all visible text. For each text element, include start timestamp, end timestamp, the exact text content, the appearance characteristics. If no text appears, explicitly state so.
3. A structured speech-to-text transcription, include speaker(Corresponding to the character or voice‑over in Section 1, including their accent and tone), exact spoken content, start timestamp, end timestamp, and speaking state (prosody, emotion, and style). If no speech appears, explicitly state so.
Aside from these three required sections, you are free to organize any additional content in any way you find helpful. This additional content can include global information about the entire video or localized information about specific moments. You may choose the topic of this extra content freely.
Rules:
- Add as much descriptive detail as possible.
- Do not use Markdown bold formatting.
- Carefully look at frames and listen to the audio, making sure no detail is overlooked.
Output Format:
Structured audiovisual description
Return JSON organized into scenes and events. Include both the task instructions and the complete JSON Schema in the prompt to define fields, types, required properties, and constraints.
Describe the audio and visual content in detail in English, organized into scenes and events, following the JSON Schema below.
All timestamps must be relative to the beginning of the video. End times must not precede start times or exceed the video duration. Each event must fall within the time range of its parent scene.
Include only information directly supported by the audio or video. Do not guess or invent details. Do not infer causality merely because a sound and an action occur at the same time.
Return only valid JSON, without Markdown fences or commentary.
JSON Schema:
{
"$defs": {
"Event": {
"additionalProperties": false,
"properties": {
"time_range": {
"$ref": "#/$defs/TimeRange",
"description": "Time range of the event"
},
"participants": {
"description": "People, animals, or objects involved, named by observable features; use consistent names for the same participant",
"items": {
"type": "string"
},
"title": "Participants",
"type": "array"
},
"action": {
"description": "Specific actions, interactions, and observable outcomes",
"title": "Action",
"type": "string"
},
"sounds": {
"description": "Sounds heard during the event; use an empty list if none are discernible",
"items": {
"type": "string"
},
"title": "Sounds",
"type": "array"
}
},
"required": [
"time_range",
"participants",
"action",
"sounds"
],
"title": "Event"
,
"type": "object"
},
"Scene": {
"additionalProperties": false,
"properties": {
"time_range": {
"$ref": "#/$defs/TimeRange",
"description": "Time range of the scene"
},
"setting": {
"description": "Environment, spatial layout, and main visual features",
"title": "Setting",
"type": "string"
},
"events": {
"description": "Events in chronological order; use an empty list if there are none",
"items": {
"$ref": "#/$defs/Event"
},
"title": "Events",
"type": "array"
}
},
"required": [
"time_range",
"setting",
"events"
],
"title": "Scene",
"type": "object"
},
"TimeRange": {
"additionalProperties": false,
"properties": {
"start_seconds": {
"description": "Start time in seconds relative to the beginning of the video",
"minimum": 0,
"title": "Start Seconds",
"type": "number"
},
"end_seconds": {
"description": "End time in seconds; must not precede the start time",
"minimum": 0,
"title": "End Seconds",
"type": "number"
}
},
"required": [
"start_seconds",
"end_seconds"
],
"title": "TimeRange",
"type": "object"
}
},
"additionalProperties": false,
"properties": {
"summary": {
"description": "An overview of the main content of the video",
"title": "Summary",
"type": "string"
},
"scenes": {
"description": "Scenes in chronological order; group continuous footage with a consistent setting into one scene",
"items": {
"$ref": "#/$defs/Scene"
},
"title": "Scenes",
"type": "array"
}
},
"required": [
"summary",
"scenes"
],
"title": "CaptionResult",
"type": "object"
}
Highly dynamic audiovisual content
Describe rapidly changing visuals, actions, and events. Adjust the video sampling frame rate to the dynamics of the content. The model maintains stable results with input sampled at up to 15 fps, capturing finer actions and temporal changes. Higher frame rates increase processing costs, so choose a rate that suits the task.
You are a rigorous audio-visual description expert. Your task is to watch and analyze the entire video and produce a highly detailed, coherent, evidence-grounded description that reconstructs, as accurately as possible, what is actually visible, audible, and readable in the video.
Produce a complete, directly usable video description — not an analysis report, not a checklist, not a rough summary. The description must cover the main content of the video from beginning to end, organized in chronological order into naturally coherent, information-dense paragraphs. Level of detail must always yield to factual accuracy: details that cannot be confirmed may be omitted, but you must never guess, fill in, or fabricate anything in order to make the description richer.
## Core Principles
1. Cover the main content of the video from beginning to end, including the opening, the main process, scene changes, important actions, speech, on-screen text, sound, and the ending. Removing redundancy applies only to attributes that have not changed — clothing, room layout, aspect ratio, a continuing music bed — which are described once and then revisited only when they change. It does not license coarser event granularity: you must not skip or compress new actions, text, sounds, or state changes.
2. Every statement must be grounded in what is actually visible, audible, or readable in the video. Do not add background knowledge, common sense, prior assumptions, or speculation from outside the video. Do not treat "seems plausible" as "the video has proven it."
3. Prioritize preserving clearly discernible concrete facts, including people, animals, objects, appearance, clothing, colors, quantities, positions, actions, interactions, on-screen text, subtitles, speech, ambient sound, music, sound effects, camera changes, scene cuts, and state changes.
4. Track people, animals, and objects continuously. Once an entity has been clearly identified, keep its identity consistent in later appearances; if multiple similar entities cannot be reliably distinguished, use positional descriptions such as "the device on the left" or "the person in the center of the frame" rather than forcing a name onto them. Avoid ambiguous references such as "he," "she," "it," "this person," or "that thing."
5. Do not invent a person's identity, age, occupation, emotion, intention, relationship, or the reason behind an action. You may describe visible facial expressions and body movements, but do not interpret an expression directly as a mental state. For example, write "the corners of his mouth turn up and he smiles" rather than "he feels happy."
6. When the identity of an entity, an action, a quantity, text, speech, a temporal relationship, a sound source, or a causal relationship cannot be confirmed, and that uncertainty affects understanding, use brief, specific, conservative wording, for example "the on-screen text is small and cannot be fully made out" or "voices can be heard, but the exact lines are unclear." For unimportant unclear details, simply omit them; do not repeatedly pile up "possibly," "seemingly," and "appears to be."
7. When speech, subtitles, or on-screen text are clearly discernible, preserve the original wording as far as possible, especially for personal names, place names, numbers, brands, labels, proper nouns, formulas, code, and key statements. Do not translate, rewrite, or correct the original text on your own initiative.
8. Distinguish facts directly observed in the footage from opinions expressed by people in the video, by narration, or by subtitles. If a host or narrator offers an evaluation, explanation, recommendation, or causal judgment, write it explicitly as "the host states," "the narration explains," or "the subtitle says"; do not rewrite an opinion voiced in the video as the describer's own objective conclusion.
9. When level of detail and reliability conflict, reliability comes first. It is better to write fewer unconfirmable details than to hallucinate in order to fill up information.
## Description Granularity
The unit of segmentation is a change in information, not a fixed number of seconds. Begin a new event wherever the subject, object, or goal changes; an action enters a new stage; contact is made or released; direction, speed, or trajectory changes noticeably; an observable state change occurs; the speaker turn changes; the sound or music structure changes; the scene, shot, or narrative layer changes; or the interface focus, control, parameter, or result state changes.
For each significant action, write as much of the following as the video actually supports: the subject, its state before the action, the action itself, the object or point of contact, which hand, body part, or tool is used, the direction and trajectory, the speed or manner, any intermediate stage, the resulting state, and the observable consequence. A named action on its own is a label, not a description. "She opens the bottle" is insufficient; "she steadies the bottle with her left hand, then twists the metal cap counter-clockwise with her right, and once the cap is free she sets it down to the right of the bottle" carries the actual granularity. The same applies to a state change: give both ends of it, since "the waveform is narrower after he applies the setting" carries the change while "he adjusts the audio" does not.
Granularity does not degrade with video length. A long or repetitive video receives the same local event granularity as a short one. Length may add chapter-level organization, but it must never replace a sequence of distinct actions with a single coarser generalizing verb.
Before using left, right, in front, or behind, make the frame of reference unambiguous, distinguishing the viewer's left and right within the frame, a person's own left and right, and the left and right inside a software window or interface. When a visual event and a sound belong to the same occurrence, write them together and make the relation explicit rather than listing picture and sound separately for the reader to pair up. Whenever you give a number, make the basis of the count explicit: what is being counted, over which time window, and whether you are counting instantaneous on-screen quantity, distinct entities across the whole video, completed actions, attempts, or sound occurrences.
## Scope of Content Coverage
Describe the following whenever the video actually contains them:
* the video type, subject, narrative line, and overall visual form;
* the main people, animals, and objects, and their identities or roles;
* appearance, clothing, colors, materials, quantities, and spatial positions;
* actions, interactions, operating steps, and their order;
* the scene environment, foreground, middle ground, background, lighting, left-right relationships, and spatial changes;
* camera viewpoint, shot size, focus, push/pull/pan/tilt, following shots, transitions, and frame layout;
* titles, subtitles, labels, interface text, numbers, formulas, code, tables, and charts;
* speech, narration, language, speakers, discernible original spoken content, and obvious tonal characteristics;
* background music, ambient sound, sound effects, and the onset, end, and obvious changes of sounds;
* the entrance, exit, movement, contact, operation, and state changes of the subjects;
* professional procedures, tools, terminology, and conclusions explicitly demonstrated or explicitly stated in the video;
* temporal continuity, location changes, and time jumps between different scenes.
Do not infer a music track's specific BPM, genre, instrumentation, key, mixing, compression, or reverb from listening impression alone. When the sound source cannot be confirmed, use neutral wording such as "an impact sound is heard" or "a short electronic sound effect occurs." Attribute a sound to a specific object only when the sound clearly corresponds to an action visible in the frame.
For OCR, numbers, and charts, transcribe verbatim only when the content is clear enough. Do not guess content from blurry text, and do not estimate values from the heights of bars or lines in a chart. If it cannot be read reliably, omit the specific value or state that part of the text cannot be made out.
## Timestamp Rules
Describe the video in chronological order, and start a new paragraph at shot cuts, scene changes, changes of main activity, the appearance of a new subject, speaker changes, the appearance of key text, or obvious state changes.
Begin each time segment with the following format:
`[hh:mm:ss:xxx-hh:mm:ss:xxx]`
For example:
`[00:00:04:000-00:00:12:000] The shot cuts to ...`
Timestamps must be safe time intervals backed by evidence. Timing may be determined from clear shot cuts, subtitle appearances, speech onset and offset points, ASR timestamps, or stably locatable visual events. Do not generate timings from paragraph length, average shot duration, or guesswork, and do not fabricate millisecond-level precision merely to satisfy the millisecond format.
Match precision to the evidence available. Chapters and long scenes take ranges of seconds to minutes; shot boundaries and ordinary actions are locatable to roughly half a second to a second; dialogue turns to a few tenths of a second; clicks, contacts, impacts, and cue tones to around a tenth of a second. If an event can only be confirmed as falling somewhere near a given second, write an approximate range rather than a fabricated millisecond timestamp.
Write an additional precise time point inside a paragraph only when that event can genuinely be located reliably. Otherwise, describe only the order in which events occur and the time segment they fall in. Adjacent time segments must not overlap, and do not manufacture unreliable time boundaries in the pursuit of precision.
Distinguish a new event from a repeated action, a slow-motion pass, a replay, or a flashback. A replayed sequence keeps the same clothing, action order, and target, and should be identified as a replay rather than described as further new events.
## Output Format
- Write one concise overview paragraph followed by multiple chronologically ordered description paragraphs.
- Open with a short overview introducing the video type, core subjects, main scenes, visual style, and overall auditory environment. Then describe the concrete content in chronological order, integrating visuals, speech, on-screen text, and audio within the same time segment; do not mechanically split by modality into "visual," "audio," "OCR," and so on.
- Add a brief closing paragraph only when the video genuinely has a clear overall outcome or concluding development. The closing must not introduce new information absent from the preceding text, and must not offer your own evaluation of the video.
- Do not use tables, bullet points, numbered lists, XML, JSON, analytical subheadings, or mechanical headings such as "Scene 1" or "Shot 2.3." Do not output your analysis process, observation process, evidence lists, tool-call records, quality assessments, or any explanation unrelated to the video.
- The final output should be natural, fluent, specific, coherent, and information-dense without excessive repetition, and must at all times obey the principles of "evidence first, timing grounded, details reliable."
Please describe this video in a super detail manner.
Audiovisual analysis with multiple speakers
Use audio and video to identify speakers and produce a timestamped transcript. When video is provided, the model can use visual information to analyze the correspondence between speakers and speech.
Transcribe the dialogue with speaker identification and timestamps. Output format: <soc><sos><start_time>text<end_time><speakerX><eos>...<eoc>.
Audio event localization
Locate a specified sound event. Replace [audio event label] in the prompt with the target event, such as dog_barking. The result contains the event type and start and end times in seconds.
Detect the timestamps of the following sound event in the audio: [audio event label]. Output the result strictly as a JSON array. Each element must contain exactly these keys: "type" (the event label, copied verbatim from the request), "start_time" and "end_time" (both MUST be decimal numbers in seconds, e.g. 4.5 or 12.0, NOT strings, and NOT in mm:ss or hh:mm:ss format). If the same event occurs multiple times, output one element per occurrence, all sharing the same "type", inside the SAME JSON array. Do not include any text outside the JSON array. Example: [{"type": "dog_barking", "start_time": 1.23, "end_time": 4.56}]
Combined multimodal input
Qwen3.8-Omni-Flash and Qwen3.5-Omni support combining text, images, audio, and video in the same request. The examples below use Qwen3.8-Omni-Flash to analyze an image and audio and generate a text response. To generate speech, use Qwen3.5-Omni. See the audio output example.
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.8-omni-flash",
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"],
stream=True,
stream_options={"include_usage": True},
)
for chunk in completion:
if chunk.choices:
print(chunk.choices[0].delta)
else:
print(chunk.usage)
import OpenAI from "openai";
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const completion = await openai.chat.completions.create({
model: "qwen3.8-omni-flash",
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." }
]
}
],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text"],
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
console.log(chunk.choices[0].delta);
} else {
console.log(chunk.usage);
}
}
# API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.8-omni-flash",
"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."
}
]
}
],
"stream": true,
"stream_options": {
"include_usage": true
},
"modalities": ["text"]
}'
Single modality input
Each request contains text and one other modality (video, audio, or image). The examples use Qwen3.8-Omni-Flash to return text through Chat Completions.
Video and text input
Provide the video as an image list or a video file (with audio support).
Video file (supports audio in the video)
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/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.8-omni-flash",
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?"},
],
},
],
modalities=["text"],
stream=True,
stream_options={"include_usage": True},
)
for chunk in completion:
if chunk.choices:
print(chunk.choices[0].delta)
else:
print(chunk.usage)
import OpenAI from "openai";
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const completion = await openai.chat.completions.create({
model: "qwen3.8-omni-flash",
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?" }]
}],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text"],
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
console.log(chunk.choices[0].delta);
} else {
console.log(chunk.usage);
}
}
# ======= Important note =======
# API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Delete this comment before execution ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.8-omni-flash",
"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"
}
]
}
],
"stream":true,
"stream_options": {
"include_usage": true
},
"modalities":["text"]
}'
Input limits for Qwen3.5-Omni, Qwen3-Omni-Flash, and Qwen-Omni-Turbo
-
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.
Image list format
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/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.8-omni-flash",
messages=[
{
"role": "user",
"content": [
{
"type": "video",
"video": [
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg",
],
},
{"type": "text", "text": "Describe the process shown in this video"},
],
}
],
modalities=["text"],
stream=True,
stream_options={"include_usage": True},
)
for chunk in completion:
if chunk.choices:
print(chunk.choices[0].delta)
else:
print(chunk.usage)
import OpenAI from "openai";
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const completion = await openai.chat.completions.create({
model: "qwen3.8-omni-flash",
messages: [{
role: "user",
content: [
{
type: "video",
video: [
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg"
]
},
{
type: "text",
text: "Describe the process shown in this video"
}
]
}],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text"],
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
console.log(chunk.choices[0].delta);
} else {
console.log(chunk.usage);
}
}
# ======= Important note =======
# API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Delete this comment before execution ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.8-omni-flash",
"messages": [
{
"role": "user",
"content": [
{
"type": "video",
"video": [
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg"
]
},
{
"type": "text",
"text": "Describe the process shown in this video"
}
]
}
],
"stream": true,
"stream_options": {
"include_usage": true
},
"modalities": ["text"]
}'
Input limits for Qwen3.5-Omni, Qwen3-Omni-Flash, and Qwen-Omni-Turbo
- Qwen3.5-Omni series: A minimum of 2 images and a maximum of 2048 images
- Qwen3-Omni-Flash: A minimum of 2 images and a maximum of 128 images
- Qwen-Omni-Turbo: A minimum of 4 images and a maximum of 80 images
Audio and text input
This example uses a public audio URL. To use a local file, see Send local files with Base64 encoding. The following example uses streaming output.
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/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.8-omni-flash",
messages=[
{
"role": "user",
"content": [
{
"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": "What is this audio about"},
],
},
],
modalities=["text"],
stream=True,
stream_options={"include_usage": True},
)
for chunk in completion:
if chunk.choices:
print(chunk.choices[0].delta)
else:
print(chunk.usage)
import OpenAI from "openai";
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const completion = await openai.chat.completions.create({
model: "qwen3.8-omni-flash",
messages: [
{
"role": "user",
"content": [{
"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": "What is this audio about" }]
}],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text"],
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
console.log(chunk.choices[0].delta);
} else {
console.log(chunk.usage);
}
}
# ======= Important note =======
# API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Delete this comment before execution ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.8-omni-flash",
"messages": [
{
"role": "user",
"content": [
{
"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": "What is this audio about"
}
]
}
],
"stream":true,
"stream_options":{
"include_usage":true
},
"modalities":["text"]
}'
Input limits for Qwen3.5-Omni, Qwen3-Omni-Flash, and Qwen-Omni-Turbo
-
Number of files:
- Qwen3.5-Omni series: Up to 2048 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 100 MB
- Qwen-Omni-Turbo: Up to 10 MB
-
Using Base64 encoding: The encoded Base64 string must be smaller than 10 MB
-
-
Duration limits:
- Qwen3.5-Omni series: Up to 3 hours
- Qwen3-Omni-Flash: Up to 20 minutes
- Qwen-Omni-Turbo: Up to 3 minutes
-
File formats: AMR, WAV, 3GP, 3GPP, AAC, and MP3.
Image and text input
This example uses a public image URL. To use a local file, see Input Base64-encoded local file. The following example uses streaming output.
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/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.8-omni-flash",
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": "text", "text": "What scene is depicted in the image?"},
],
},
],
modalities=["text"],
stream=True,
stream_options={
"include_usage": True
}
)
for chunk in completion:
if chunk.choices:
print(chunk.choices[0].delta)
else:
print(chunk.usage)
import OpenAI from "openai";
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const completion = await openai.chat.completions.create({
model: "qwen3.8-omni-flash",
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": "text", "text": "What scene is depicted in the image?" }]
}],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text"],
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
console.log(chunk.choices[0].delta);
} else {
console.log(chunk.usage);
}
}
# ======= Important note =======
# API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Delete this comment before execution ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.8-omni-flash",
"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": "text",
"text": "What scene is depicted in the image?"
}
]
}
],
"stream":true,
"stream_options":{
"include_usage":true
},
"modalities":["text"]
}'
Input limits for Qwen3.5-Omni, Qwen3-Omni-Flash, and Qwen-Omni-Turbo
The Qwen-Omni models support multiple images per request. Image requirements:
-
Number of images:
- Using a public URL: Up to 2048 images
- Using Base64 encoding: Up to 250 images
-
Image size:
-
Using public URLs:
- Qwen3.5-Omni series: Each image file must not exceed 20 MB
- Qwen3-Omni-Flash and Qwen-Omni-Turbo series: Each image file must not exceed 10 MB
-
Using Base64 encoding: The encoded Base64 string must be smaller than 10 MB.
-
-
Both width and height must exceed 10 pixels. The aspect ratio must not exceed 200:1 or 1:200.
-
Supported image types: See Image and video understanding.
Multichannel audio
qwen3.8-omni-flash supports two-channel stereo and four-channel FOA spatial audio (WYZX channel order). These inputs retain spatial information for audio understanding.
use_multichannel defaults to false, which parses all audio as mono. When it is true and the input has two channels (left and right) or four channels (FOA, in WYZX order), the model parses spatial audio information.
In the Chat Completions quick-start example, set AUDIO_URL to the corresponding multichannel WAV audio and add the following argument to client.chat.completions.create(). In an HTTP request, use_multichannel is a top-level request body field.
extra_body={"use_multichannel": True},
Web search
Qwen3.8-Omni-Flash supports web search to retrieve current information and generate text answers.
Qwen3.8-Omni-Flash uses the web_search tool through Responses. Qwen3.8-Omni-Flash and Qwen3.5-Omni use the agent search strategy through Chat Completions. For fees, see Web search billing.
The following Chat Completions examples use Qwen3.8-Omni-Flash with enable_search=True and search_options={"search_strategy": "agent"} to enable web search and reasoning_effort="none" to disable thinking, then read streamed text responses.
# 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/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.8-omni-flash",
reasoning_effort="none",
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,
"search_options": {"search_strategy": "agent"}
}
)
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}")
// Prerequisites:
// npm install openai
import OpenAI from "openai";
// Initialize the client
const openai = new OpenAI({
// API Keys differ between Singapore and Beijing regions. Get API Key:https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
});
// Send request (with web search enabled)
const completion = await openai.chat.completions.create({
model: "qwen3.8-omni-flash",
reasoning_effort: "none",
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
enable_search: true,
search_options: { search_strategy: "agent" }
});
console.log("Model response (with real-time information):");
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
if (chunk.choices[0].delta.content) {
process.stdout.write(chunk.choices[0].delta.content);
}
}
}
console.log();
# ======= Important =======
# API Keys differ between Singapore and Beijing regions. Get API Key:https://www.alibabacloud.com/help/model-studio/get-api-key
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Remove this comment before running ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.8-omni-flash",
"reasoning_effort": "none",
"messages": [
{
"role": "user",
"content": "What is today\u0027s date and day of the week, and what important holidays are there today?"
}
],
"stream": true,
"stream_options": {
"include_usage": true
},
"enable_search": true,
"search_options": {"search_strategy": "agent"}
}'
Enable/disable thinking mode
Qwen3.8-Omni-Flash
Thinking is enabled by default for qwen3.8-omni-flash, with reasoning_effort defaulting to xhigh. The top-level Chat Completions request field reasoning_effort accepts none, minimal, low, medium, high, xhigh, and max. Do not set reasoning_effort and thinking_budget together: the request returns an error.
Choose low, medium, or xhigh for the thinking effort. For compatibility, minimal maps to low, high and max map to xhigh, and none disables thinking.
Add the following argument to client.chat.completions.create() in the Chat Completions quick-start example. Pass reasoning_effort directly as an SDK argument.
reasoning_effort="low",
Qwen3-Omni-Flash
This section describes hybrid thinking for Qwen3-Omni-Flash. You can use the enable_thinking parameter to enable or disable the thinking mode:
truefalse(default)
In thinking mode, audio output is not supported.
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/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)
import OpenAI from "openai";
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const completion = await openai.chat.completions.create({
model: "qwen3-omni-flash",
messages: [
{ role: "user", content: "Who are you?" }
],
// stream must be set to True, otherwise an error occurs.
stream: true,
stream_options: {
include_usage: true
},
// Enable or disable thinking mode. Audio output is not supported in thinking mode. Qwen-Omni-Turbo does not support enable_thinking.
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" }
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
console.log(chunk.choices[0].delta);
} else {
console.log(chunk.usage);
}
}
# ======= Important note =======
# API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Delete this comment before execution ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-omni-flash",
"messages": [
{
"role": "user",
"content": "Who are you?"
}
],
"stream":true,
"stream_options":{
"include_usage":true
},
"modalities":["text"],
"enable_thinking": true
}'
Response
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
For Qwen3.8-Omni-Flash multi-turn conversations, preserve_thinking is enabled by default. Put the previous answer and reasoning in the historical assistant message's content and reasoning_content fields, respectively, and include that message in messages for the next request. When supplied and enabled, historical reasoning counts toward input tokens and billing. For a complete multi-turn example, see Pass the thinking process.
The following multi-turn example uses Qwen3.8-Omni-Flash with reasoning_effort="none" to disable thinking. It passes text responses in historical assistant messages and text plus one modality in each user message. For combined input, see Combined multimodal input:
-
Assistant Message
Assistant messages in the messages array can contain only text data.
-
User Message
In this example, each user message contains text and one other modality. In multi-turn conversations, you can input different modalities in different user messages.
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/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.8-omni-flash",
reasoning_effort="none",
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."}],
},
],
modalities=["text"],
stream=True,
stream_options={"include_usage": True},
)
for chunk in completion:
if chunk.choices:
print(chunk.choices[0].delta)
else:
print(chunk.usage)
import OpenAI from "openai";
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const completion = await openai.chat.completions.create({
model: "qwen3.8-omni-flash",
reasoning_effort: "none",
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." }]
}],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text"]
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
console.log(chunk.choices[0].delta);
} else {
console.log(chunk.usage);
}
}
# ======= Important note =======
# API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Delete this comment before execution ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.8-omni-flash",
"reasoning_effort": "none",
"messages": [
{
"role": "user",
"content": [
{
"type": "input_audio",
"input_audio": {
"data": "https://dashscope.oss-cn-beijing.aliyuncs.com/audios/welcome.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."
}
]
}
],
"stream": true,
"stream_options": {
"include_usage": true
},
"modalities": ["text"]
}'
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/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()
// Before running:
// For Windows/Mac/Linux:
// 1. Ensure Node.js version >= 14 is installed.
// 2. Run the following command to install necessary dependencies:
// npm install openai wav
//
// To use the real-time playback feature (Method 2), you also need:
// Windows:
// npm install speaker
// Mac:
// brew install portaudio
// npm install speaker
// Linux (Ubuntu/Debian):
// sudo apt-get install libasound2-dev
// npm install speaker
import OpenAI from "openai";
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const completion = await openai.chat.completions.create({
model: "qwen3.5-omni-plus", // For Qwen3-Omni-Flash, run in non-thinking mode.
messages: [
{
"role": "user",
"content": "Who are you?"
}],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text", "audio"],
audio: { voice: "Tina", format: "wav" }
});
// Method 1: Decode after generation is complete
// Requires installation: npm install wav
import { createWriteStream } from 'node:fs'; // node:fs is a built-in Node.js module, no installation required
import { Writer } from 'wav';
async function convertAudio(audioString, audioPath) {
try {
// Decode the Base64 string into a Buffer
const wavBuffer = Buffer.from(audioString, 'base64');
// Create a WAV file write stream
const writer = new Writer({
sampleRate: 24000, // Sample rate
channels: 1, // Mono
bitDepth: 16 // 16-bit depth
});
// Create an output file stream and establish a pipe connection
const outputStream = createWriteStream(audioPath);
writer.pipe(outputStream);
// Write PCM data and end writing
writer.write(wavBuffer);
writer.end();
// Use a Promise to wait for the file to finish writing
await new Promise((resolve, reject) => {
outputStream.on('finish', resolve);
outputStream.on('error', reject);
});
// Add extra wait time to ensure audio integrity
await new Promise(resolve => setTimeout(resolve, 800));
console.log(`Audio file successfully saved as ${audioPath}`);
} catch (error) {
console.error('An error occurred during processing:', error);
}
}
let audioString = "";
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
if (chunk.choices[0].delta.audio) {
if (chunk.choices[0].delta.audio["data"]) {
audioString += chunk.choices[0].delta.audio["data"];
}
}
} else {
console.log(chunk.usage);
}
}
// Execute the conversion
convertAudio(audioString, "audio_assistant_mjs.wav");
// Method 2: Generate and play in real time
// Install necessary components according to your system's instructions above.
// import Speaker from 'speaker'; // Import the audio playback library
// // Create a speaker instance (configuration matches WAV file parameters)
// const speaker = new Speaker({
// sampleRate: 24000, // Sample rate
// channels: 1, // Number of sound channels
// bitDepth: 16, // Bit depth
// signed: true // Signed PCM
// });
// for await (const chunk of completion) {
// if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
// if (chunk.choices[0].delta.audio) {
// if (chunk.choices[0].delta.audio["data"]) {
// const pcmBuffer = Buffer.from(chunk.choices[0].delta.audio.data, 'base64');
// // Write directly to the speaker for playback
// speaker.write(pcmBuffer);
// }
// }
// } else {
// console.log(chunk.usage);
// }
// }
// speaker.on('finish', () => console.log('Playback complete'));
// speaker.end(); // Call based on the actual end of the API stream
Input Base64-encoded local file
The following examples use Qwen3.8-Omni-Flash to analyze Base64-encoded local files and return text. Qwen3.5-Omni, Qwen3-Omni-Flash, and Qwen-Omni-Turbo require the encoded Base64 string to be smaller than 10 MB.
Images
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/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.8-omni-flash",
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?"},
],
},
],
modalities=["text"],
stream=True,
stream_options={"include_usage": True},
)
for chunk in completion:
if chunk.choices:
print(chunk.choices[0].delta)
else:
print(chunk.usage)
import OpenAI from "openai";
import { readFileSync } from 'fs';
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const encodeImage = (imagePath) => {
const imageFile = readFileSync(imagePath);
return imageFile.toString('base64');
};
const base64Image = encodeImage("eagle.png")
const completion = await openai.chat.completions.create({
model: "qwen3.8-omni-flash",
messages: [
{
"role": "user",
"content": [{
"type": "image_url",
"image_url": { "url": `data:image/png;base64,${base64Image}` },
},
{ "type": "text", "text": "What scene is depicted in the image?" }]
}],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text"],
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
console.log(chunk.choices[0].delta);
} else {
console.log(chunk.usage);
}
}
Audio
This example uses the locally saved file welcome.mp3.
import os
from openai import OpenAI
import base64
import numpy as np
import soundfile as sf
import requests
client = OpenAI(
# API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/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",
)
def encode_audio(audio_path):
with open(audio_path, "rb") as audio_file:
return base64.b64encode(audio_file.read()).decode("utf-8")
base64_audio = encode_audio("welcome.mp3")
completion = client.chat.completions.create(
model="qwen3.8-omni-flash",
messages=[
{
"role": "user",
"content": [
{
"type": "input_audio",
"input_audio": {
"data": f"data:;base64,{base64_audio}",
"format": "mp3",
},
},
{"type": "text", "text": "What is this audio about"},
],
},
],
modalities=["text"],
stream=True,
stream_options={"include_usage": True},
)
for chunk in completion:
if chunk.choices:
print(chunk.choices[0].delta)
else:
print(chunk.usage)
import OpenAI from "openai";
import { readFileSync } from 'fs';
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const encodeAudio = (audioPath) => {
const audioFile = readFileSync(audioPath);
return audioFile.toString('base64');
};
const base64Audio = encodeAudio("welcome.mp3")
const completion = await openai.chat.completions.create({
model: "qwen3.8-omni-flash",
messages: [
{
"role": "user",
"content": [{
"type": "input_audio",
"input_audio": { "data": `data:;base64,${base64Audio}`, "format": "mp3" },
},
{ "type": "text", "text": "What is this audio about" }]
}],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text"],
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
console.log(chunk.choices[0].delta);
} else {
console.log(chunk.usage);
}
}
Video
Video file
This example uses the locally saved file spring_mountain.mp4.
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/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_video(video_path):
with open(video_path, "rb") as video_file:
return base64.b64encode(video_file.read()).decode("utf-8")
base64_video = encode_video("spring_mountain.mp4")
completion = client.chat.completions.create(
model="qwen3.8-omni-flash",
messages=[
{
"role": "user",
"content": [
{
"type": "video_url",
"video_url": {"url": f"data:;base64,{base64_video}"},
},
{"type": "text", "text": "What is she singing?"},
],
},
],
modalities=["text"],
stream=True,
stream_options={"include_usage": True},
)
for chunk in completion:
if chunk.choices:
print(chunk.choices[0].delta)
else:
print(chunk.usage)
import OpenAI from "openai";
import { readFileSync } from 'fs';
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const encodeVideo = (videoPath) => {
const videoFile = readFileSync(videoPath);
return videoFile.toString('base64');
};
const base64Video = encodeVideo("spring_mountain.mp4")
const completion = await openai.chat.completions.create({
model: "qwen3.8-omni-flash",
messages: [
{
"role": "user",
"content": [{
"type": "video_url",
"video_url": { "url": `data:;base64,${base64Video}` },
},
{ "type": "text", "text": "What is she singing?" }]
}],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text"],
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
console.log(chunk.choices[0].delta);
} else {
console.log(chunk.usage);
}
}
Image list
For example, consider the locally saved files football1.jpg, football2.jpg, football3.jpg, and football4.jpg.
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/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.
)
# 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_1 = encode_image("football1.jpg")
base64_image_2 = encode_image("football2.jpg")
base64_image_3 = encode_image("football3.jpg")
base64_image_4 = encode_image("football4.jpg")
completion = client.chat.completions.create(
model="qwen3.8-omni-flash",
messages=[
{
"role": "user",
"content": [
{
"type": "video",
"video": [
f"data:image/jpeg;base64,{base64_image_1}",
f"data:image/jpeg;base64,{base64_image_2}",
f"data:image/jpeg;base64,{base64_image_3}",
f"data:image/jpeg;base64,{base64_image_4}",
],
},
{"type": "text", "text": "Describe the process shown in this video"},
],
}
],
modalities=["text"],
stream=True,
stream_options={"include_usage": True},
)
for chunk in completion:
if chunk.choices:
print(chunk.choices[0].delta)
else:
print(chunk.usage)
import OpenAI from "openai";
import { readFileSync } from 'fs';
const openai = new OpenAI(
{
// API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const encodeImage = (imagePath) => {
const imageFile = readFileSync(imagePath);
return imageFile.toString('base64');
};
const base64Image1 = encodeImage("football1.jpg")
const base64Image2 = encodeImage("football2.jpg")
const base64Image3 = encodeImage("football3.jpg")
const base64Image4 = encodeImage("football4.jpg")
const completion = await openai.chat.completions.create({
model: "qwen3.8-omni-flash",
messages: [{
role: "user",
content: [
{
type: "video",
video: [
`data:image/jpeg;base64,${base64Image1}`,
`data:image/jpeg;base64,${base64Image2}`,
`data:image/jpeg;base64,${base64Image3}`,
`data:image/jpeg;base64,${base64Image4}`
]
},
{
type: "text",
text: "Describe the process shown in this video"
}
]
}],
stream: true,
stream_options: {
include_usage: true
},
modalities: ["text"],
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
console.log(chunk.choices[0].delta);
} else {
console.log(chunk.usage);
}
}
API reference
- Chat Completions: Input and output parameters for the models on this page.
- Responses: Input and output parameters for Qwen3.8-Omni-Flash.
Billing and rate limits
Qwen3.8-Omni-Flash supports automatic implicit caching. qwen3.8-omni-flash supports Responses Session caching. For configuration, see Session cache.
Qwen-Omni is billed based on tokens consumed across modalities (audio, image, and video). Check billing details in the console.
Token conversion rules for audio, images, and videos
The following conversion rules apply to Qwen3.5-Omni, Qwen3-Omni-Flash, and Qwen-Omni-Turbo.
Audio
-
Qwen3.5-Omni series:- Input audio formula:
Total tokens = Audio duration (seconds) * 7 - Output audio formula:
Total tokens = Audio duration (seconds) * 12.5
- Input audio formula:
-
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.
Images
Qwen3.5-Omni seriesandQwen3-Omni-Flash1 token per32x32pixelsQwen-Omni-Turbomodel: 1 token per28x28pixels
For the Qwen3.5-Omni series, each image requires a minimum of 24 tokens; for Qwen3-Omni-Flash and Qwen-Omni-Turbo, the minimum is 4 tokens. The default maximum is 1280 tokens. The Qwen3.5-Omni series supports the vl_high_resolution_images parameter to increase the maximum to 16384 tokens (Qwen-Omni-Turbo and Qwen3-Omni-Flash do not support this parameter). Use the following code to estimate the token count for a single image:
import math
from PIL import Image # pip install Pillow
# ============ Model configuration (modify as needed) ============
# Image factor: 32 for Qwen3.5-Omni series and Qwen3-Omni-Flash; 28 for Qwen-Omni-Turbo
IMAGE_FACTOR = 32
# Min tokens: 24 for Qwen3.5-Omni series; 4 for Qwen-Omni-Turbo and Qwen3-Omni-Flash
MIN_TOKENS = 24
# High-resolution mode (Qwen3.5-Omni series only; not supported by Qwen-Omni-Turbo or Qwen3-Omni-Flash)
# True → max tokens = 16384
# False → max tokens = 1280 (default)
VL_HIGH_RESOLUTION_IMAGES = False
# ============ Pixel range (auto-calculated from above) ============
MIN_PIXELS = MIN_TOKENS * IMAGE_FACTOR * IMAGE_FACTOR
MAX_PIXELS = (16384 if VL_HIGH_RESOLUTION_IMAGES else 1280) * IMAGE_FACTOR * IMAGE_FACTOR
def smart_resize(height, width, factor=IMAGE_FACTOR,
min_pixels=MIN_PIXELS, max_pixels=MAX_PIXELS):
"""Align image dimensions to multiples of factor and scale to [min_pixels, max_pixels]."""
h_bar = max(factor, round(height / factor) * factor)
w_bar = max(factor, round(width / factor) * factor)
if h_bar * w_bar > max_pixels:
beta = math.sqrt((height * width) / max_pixels)
h_bar = math.floor(height / beta / factor) * factor
w_bar = math.floor(width / beta / factor) * factor
elif h_bar * w_bar < min_pixels:
beta = math.sqrt(min_pixels / (height * width))
h_bar = math.ceil(height * beta / factor) * factor
w_bar = math.ceil(width * beta / factor) * factor
return h_bar, w_bar
if __name__ == "__main__":
image = Image.open("xxx/test.jpg")
print(f"Original size: {image.width}x{image.height}")
resized_h, resized_w = smart_resize(image.height, image.width)
token = int(resized_h * resized_w / (IMAGE_FACTOR * IMAGE_FACTOR)) + 2
print(f"Resized: {resized_w}x{resized_h}, tokens: {token}")
Video
Tokens for video files are divided into video_tokens and audio_tokens.
-
video_tokensThe calculation is complex. See the following code:
# pip install opencv-python
import math
import cv2
# ============ Model configuration (modify as needed) ============
# Image factor: 32 for Qwen3.5-Omni series and Qwen3-Omni-Flash; 28 for Qwen-Omni-Turbo
IMAGE_FACTOR = 32
FRAME_FACTOR = 2
FPS = 2
MAX_RATIO = 200
# Min pixels per video frame
VIDEO_MIN_PIXELS = 64 * IMAGE_FACTOR * IMAGE_FACTOR
# Max pixels per video frame
# Qwen3.5-Omni series: 640 * 32 * 32
# Qwen3-Omni-Flash: 768 * 32 * 32
# Qwen-Omni-Turbo: 768 * 28 * 28
VIDEO_MAX_PIXELS = 640 * IMAGE_FACTOR * IMAGE_FACTOR
# Min extracted frames: 2 for Qwen3.5-Omni series and Qwen3-Omni-Flash; 4 for Qwen-Omni-Turbo
FPS_MIN_FRAMES = 2
# Max extracted frames: 2048 for Qwen3.5-Omni series; 128 for Qwen3-Omni-Flash; 80 for Qwen-Omni-Turbo
FPS_MAX_FRAMES = 2048
# Max total pixels for video input
# Qwen3.5-Omni series: 180224 * 32 * 32
# Qwen3-Omni-Flash: 16384 * 32 * 32
# Qwen-Omni-Turbo: 16384 * 28 * 28
VIDEO_TOTAL_PIXELS = 180224 * IMAGE_FACTOR * IMAGE_FACTOR
# ============ Core functions ============
def get_video_info(video_path):
"""Read basic video info: height, width, total frames, fps."""
cap = cv2.VideoCapture(video_path)
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
fps = cap.get(cv2.CAP_PROP_FPS)
cap.release()
return height, width, total_frames, fps
def smart_nframes(total_frames, video_fps):
"""Calculate the number of frames to extract based on video duration and fps."""
min_frames = math.ceil(FPS_MIN_FRAMES / FRAME_FACTOR) * FRAME_FACTOR
max_frames = min(FPS_MAX_FRAMES, total_frames) // FRAME_FACTOR * FRAME_FACTOR
duration = total_frames / video_fps if video_fps else 0
if duration - int(duration) > (1 / FPS):
total_frames = math.ceil(duration * video_fps)
else:
total_frames = math.ceil(int(duration) * video_fps)
nframes = total_frames / video_fps * FPS
nframes = int(min(max(nframes, min_frames), max_frames, total_frames))
if not (FRAME_FACTOR <= nframes <= total_frames):
raise ValueError(f"nframes should in [{FRAME_FACTOR}, {total_frames}], got {nframes}")
return nframes
def smart_resize(height, width, nframes, factor=IMAGE_FACTOR):
"""Scale video frames to a reasonable pixel range, aligning to multiples of factor."""
max_pixels = max(
min(VIDEO_MAX_PIXELS, VIDEO_TOTAL_PIXELS / nframes * FRAME_FACTOR),
int(VIDEO_MIN_PIXELS * 1.05)
)
if max(height, width) / min(height, width) > MAX_RATIO:
raise ValueError(f"aspect ratio exceeds {MAX_RATIO}")
h_bar = max(factor, round(height / factor) * factor)
w_bar = max(factor, round(width / factor) * factor)
if h_bar * w_bar > max_pixels:
beta = math.sqrt((height * width) / max_pixels)
h_bar = math.floor(height / beta / factor) * factor
w_bar = math.floor(width / beta / factor) * factor
elif h_bar * w_bar < VIDEO_MIN_PIXELS:
beta = math.sqrt(VIDEO_MIN_PIXELS / (height * width))
h_bar = math.ceil(height * beta / factor) * factor
w_bar = math.ceil(width * beta / factor) * factor
return h_bar, w_bar
# ============ Calculate tokens ============
if __name__ == "__main__":
video_path = "spring_mountain.mp4"
height, width, total_frames, video_fps = get_video_info(video_path)
print(f"Video info: {width}x{height}, {total_frames} frames, {video_fps:.1f} fps")
nframes = smart_nframes(total_frames, video_fps)
resized_h, resized_w = smart_resize(height, width, nframes)
video_tokens = int(
math.ceil(nframes / FPS) * resized_h / IMAGE_FACTOR * resized_w / IMAGE_FACTOR
) + 2
print(f"Extracted frames: {nframes}, resized: {resized_w}x{resized_h}, video_tokens: {video_tokens}")
-
audio_tokens-
Qwen3.5-Omni series:- Input audio:
Total tokens = Audio duration (seconds) * 7 - Output audio:
Total tokens = Audio duration (seconds) * 12.5
- Input audio:
-
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
Audio with a duration of less than 1 second is calculated as 1 second.
-
To claim, query, or use your free quota, see Free quota for new users.
Rate limitsFor 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 voices available to Qwen-Omni models that support audio output, see Voice list.