Comment Utiliser Qwen3.5-Omni: Texte, Audio, Vidéo et Clonage Vocal via l'API

@apidog

@apidog

31 March 2026

Comment Utiliser Qwen3.5-Omni: Texte, Audio, Vidéo et Clonage Vocal via l'API

Apidog pour les entreprises

Déploiement sur site

SSO & RBAC

Conforme SOC 2

Explorer Apidog Enterprise

En bref

Qwen3.5-Omni accepte le texte, les images, l'audio et la vidéo en entrée et renvoie du texte ou de la parole en temps réel. Accédez-y via l'API Alibaba Cloud DashScope ou exécutez-le localement via HuggingFace Transformers. Ce guide couvre la configuration de l'API, des exemples de code fonctionnels pour chaque modalité, le clonage de voix, et comment tester vos requêtes avec Apidog.

bouton

Ce avec quoi vous travaillez

Qwen3.5-Omni est un modèle unique qui gère simultanément quatre types d'entrée : le texte, les images, l'audio et la vidéo. Il renvoie soit du texte, soit de la parole naturelle, selon la façon dont vous configurez la requête.

Lancé le 30 mars 2026, il est construit sur une architecture Thinker-Talker avec un cœur MoE. Le Thinker traite l'entrée multimodale et raisonne dessus. Le Talker convertit la sortie en parole en utilisant un système multi-dictionnaires qui commence à diffuser l'audio avant que la réponse complète ne soit terminée.

Trois variantes sont disponibles :

Ce guide utilise Flash pour la plupart des exemples, car c'est le bon point de départ pour la plupart des applications. Utilisez Plus là où vous avez besoin d'une qualité maximale.

Accès à l'API via DashScope

L'API DashScope d'Alibaba Cloud est le principal moyen d'utiliser Qwen3.5-Omni en production. Vous aurez besoin d'un compte DashScope et d'une clé API.

Étape 1 : Créer un compte DashScope

Accédez à dashscope.aliyuncs.com et inscrivez-vous. Si vous avez déjà un compte Alibaba Cloud, utilisez-le.

Étape 2 : Obtenir votre clé API

  1. Connectez-vous à la console DashScope
  2. Cliquez sur Gestion des clés API dans la barre latérale gauche
  3. Cliquez sur Créer une clé API
  4. Copiez la clé (format : sk-...)

Étape 3 : Installer le SDK

pip install dashscope

Ou utilisez directement le point de terminaison compatible OpenAI avec le SDK openai :

pip install openai

DashScope expose une API compatible OpenAI à l'adresse https://dashscope.aliyuncs.com/compatible-mode/v1, ce qui signifie que vous pouvez échanger votre base_url et utiliser le même code que vous écririez pour OpenAI.

Entrée et sortie de texte

Commencez par le cas le plus simple : texte en entrée, texte en sortie.

from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    messages=[
        {
            "role": "user",
            "content": "Explain the difference between REST and GraphQL APIs in plain terms."
        }
    ],
)

print(response.choices[0].message.content)

Passez à qwen3.5-omni-plus pour les tâches de raisonnement plus complexes ou à qwen3.5-omni-light lorsque la latence est la priorité.


Entrée audio : transcription et compréhension

Passez une URL de fichier audio ou un audio encodé en base64. Le modèle transcrit, comprend et raisonne sur le contenu nativement. Aucune étape ASR séparée n'est nécessaire.

import base64
from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

# Load a local audio file
with open("meeting_recording.wav", "rb") as f:
    audio_data = base64.b64encode(f.read()).decode("utf-8")

response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "input_audio",
                    "input_audio": {
                        "data": audio_data,
                        "format": "wav"
                    }
                },
                {
                    "type": "text",
                    "text": "Summarize the key decisions made in this meeting and list any action items."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)

Le modèle gère 113 langues pour la reconnaissance vocale. Vous n'avez pas besoin de spécifier la langue ; il la détecte automatiquement.

Formats audio pris en charge : WAV, MP3, M4A, OGG, FLAC.

Sortie audio : synthèse vocale dans la réponse

Pour obtenir de la parole au lieu de texte, définissez le paramètre modalities et configurez la sortie audio :

from openai import OpenAI
import base64

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    messages=[
        {
            "role": "user",
            "content": "Describe the steps to authenticate a REST API using OAuth 2.0."
        }
    ],
)

# The response includes both text and audio
text_content = response.choices[0].message.content
audio_data = response.choices[0].message.audio.data  # base64-encoded WAV

# Save the audio
with open("response.wav", "wb") as f:
    f.write(base64.b64decode(audio_data))

print(f"Text: {text_content}")
print("Audio saved to response.wav")

Deux voix intégrées sont disponibles : Chelsie (féminine) et Ethan (masculine). La génération de parole fonctionne dans 36 langues.

Entrée image : compréhension visuelle

Passez une URL d'image ou une image encodée en base64 avec une question textuelle :

from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://example.com/api-diagram.png"
                    }
                },
                {
                    "type": "text",
                    "text": "Describe this API architecture diagram and identify any potential bottlenecks."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)

Pour les images locales, encodez-les en base64 :

import base64

with open("screenshot.png", "rb") as f:
    image_data = base64.b64encode(f.read()).decode("utf-8")

# Use data URL format
image_url = f"data:image/png;base64,{image_data}"

response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url": image_url}
                },
                {
                    "type": "text",
                    "text": "What error is shown in this screenshot?"
                }
            ]
        }
    ],
)

Entrée vidéo : compréhension des enregistrements et des captures d'écran

L'entrée vidéo est l'endroit où Qwen3.5-Omni fait quelque chose qu'aucun modèle de texte ou d'image ne peut faire : raisonner simultanément sur les pistes visuelles et audio.

from openai import OpenAI
import base64

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

# Pass a video URL
response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "video_url",
                    "video_url": {
                        "url": "https://example.com/product-demo.mp4"
                    }
                },
                {
                    "type": "text",
                    "text": "Describe what the developer is building in this demo and write equivalent code."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)

Codage d'ambiance Audio-Visuel

Le cas d'utilisation "Vibe Coding" consiste à passer un enregistrement d'écran et à demander au modèle de générer du code à partir de ce qu'il voit :

with open("screen_recording.mp4", "rb") as f:
    video_data = base64.b64encode(f.read()).decode("utf-8")

response = client.chat.completions.create(
    model="qwen3.5-omni-plus",  # Use Plus for best code generation quality
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "video_url",
                    "video_url": {
                        "url": f"data:video/mp4;base64,{video_data}"
                    }
                },
                {
                    "type": "text",
                    "text": "Watch this screen recording and write the complete code that replicates what you see being built. Include all the UI components and their interactions."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)

La fenêtre contextuelle de 256K tokens s'adapte à environ 400 secondes de vidéo 720p avec audio. Pour les enregistrements plus longs, coupez ou divisez.

Clonage de voix

Le clonage de voix vous permet de donner au modèle une voix cible et de le faire répondre avec cette voix. Ceci est disponible sur Plus et Flash via l'API.

import base64
from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

# Load a 10-30 second voice sample for cloning
with open("voice_sample.wav", "rb") as f:
    voice_sample = base64.b64encode(f.read()).decode("utf-8")

response = client.chat.completions.create(
    model="qwen3.5-omni-plus",
    modalities=["text", "audio"],
    audio={
        "voice": "custom",
        "format": "wav",
        "voice_sample": {
            "data": voice_sample,
            "format": "wav"
        }
    },
    messages=[
        {
            "role": "user",
            "content": "Welcome to the Apidog developer portal. How can I help you today?"
        }
    ],
)

audio_data = response.choices[0].message.audio.data
with open("cloned_response.wav", "wb") as f:
    f.write(base64.b64decode(audio_data))

Conseils pour la qualité du clonage de voix :

Diffusion des réponses

Pour les conversations vocales en temps réel ou les applications interactives, utilisez la diffusion en continu. Le modèle commence à renvoyer l'audio avant que la réponse complète ne soit générée :

from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

stream = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    modalities=["text", "audio"],
    audio={"voice": "Ethan", "format": "pcm16"},
    messages=[
        {
            "role": "user",
            "content": "Explain how WebSocket connections differ from HTTP polling."
        }
    ],
    stream=True,
)

audio_chunks = []
text_chunks = []

for chunk in stream:
    delta = chunk.choices[0].delta
    if hasattr(delta, "audio") and delta.audio:
        if delta.audio.get("data"):
            audio_chunks.append(delta.audio["data"])
    if delta.content:
        text_chunks.append(delta.content)
        print(delta.content, end="", flush=True)

print()  # newline after streaming text

# Combine and save audio chunks
if audio_chunks:
    import base64
    full_audio = b"".join(base64.b64decode(chunk) for chunk in audio_chunks)
    with open("streamed_response.pcm", "wb") as f:
        f.write(full_audio)

Le format PCM16 fonctionne bien pour la diffusion en continu, car vous pouvez le transmettre directement à un tampon de sortie audio sans attendre un fichier complet.

Conversation multi-tours avec des modalités mixtes

Les conversations réelles mélangent les entrées sur plusieurs tours. Voici comment gérer l'historique des conversations avec différentes modalités :

from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

conversation = []

def send_message(content_parts):
    conversation.append({"role": "user", "content": content_parts})
    
    response = client.chat.completions.create(
        model="qwen3.5-omni-flash",
        messages=conversation,
    )
    
    reply = response.choices[0].message.content
    conversation.append({"role": "assistant", "content": reply})
    return reply

# Turn 1: text
print(send_message([{"type": "text", "text": "I have an API that keeps returning 503 errors."}]))

# Turn 2: add an image (error log screenshot)
import base64
with open("error_log.png", "rb") as f:
    img = base64.b64encode(f.read()).decode()

print(send_message([
    {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img}"}},
    {"type": "text", "text": "Here's the error log screenshot. What's causing this?"}
]))

# Turn 3: follow-up text
print(send_message([{"type": "text", "text": "How do I fix the connection pool exhaustion you mentioned?"}]))

La fenêtre contextuelle de 256K signifie que vous pouvez mener de longues conversations, y compris celles avec des images et de l'audio intégrés, sans rencontrer de problèmes de troncature.

Déploiement local avec HuggingFace

Si vous avez besoin d'exécuter Qwen3.5-Omni sur votre propre infrastructure :

pip install transformers==4.57.3
pip install accelerate
pip install qwen-omni-utils -U
pip install -U flash-attn --no-build-isolation
import soundfile as sf
from transformers import Qwen3OmniMoeForConditionalGeneration, Qwen3OmniMoeProcessor
from qwen_omni_utils import process_mm_info

model_path = "Qwen/Qwen3-Omni-30B-A3B-Instruct"

model = Qwen3OmniMoeForConditionalGeneration.from_pretrained(
    model_path,
    device_map="auto",
    attn_implementation="flash_attention_2",
)
processor = Qwen3OmniMoeProcessor.from_pretrained(model_path)

conversation = [
    {
        "role": "system",
        "content": [
            {"type": "text", "text": "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech."}
        ],
    },
    {
        "role": "user",
        "content": [
            {"type": "audio", "audio": "path/to/your/audio.wav"},
            {"type": "text", "text": "What is being discussed in this audio?"}
        ],
    },
]

text = processor.apply_chat_template(
    conversation,
    add_generation_prompt=True,
    tokenize=False,
)
audios, images, videos = process_mm_info(conversation, use_audio_in_video=True)
inputs = processor(
    text=text,
    audio=audios,
    images=images,
    videos=videos,
    return_tensors="pt",
    padding=True,
)
inputs = inputs.to(model.device).to(model.dtype)

text_ids, audio_output = model.generate(**inputs, speaker="Chelsie")

text_response = processor.batch_decode(text_ids, skip_special_tokens=True)[0]
sf.write("local_response.wav", audio_output.reshape(-1).cpu().numpy(), samplerate=24000)

print(text_response)

Exigences de mémoire GPU pour le déploiement local :

Variante Précision VRAM minimale
Plus (30B MoE) BF16 ~40GB
Flash BF16 ~20GB
Light BF16 ~10GB

Pour l'inférence locale en production, utilisez vLLM au lieu de HuggingFace Transformers. Les modèles MoE s'exécutent plus rapidement grâce aux optimisations de routage de vLLM.

Tester vos requêtes Qwen3.5-Omni avec Apidog

Les requêtes API multimodales sont plus difficiles à déboguer que le JSON simple. Vous traitez de l'audio et de la vidéo encodés en base64, des tableaux de contenu imbriqués et des réponses pouvant inclure à la fois du texte et de l'audio. Faire cela depuis un terminal devient vite fastidieux.

Apidog gère cela proprement. Configurez votre point de terminaison DashScope comme une nouvelle collection, stockez votre clé API en tant que variable d'environnement et créez des modèles de requête pour chaque modalité avec laquelle vous travaillez.

Pour chaque variante (Plus, Flash, Light), vous pouvez dupliquer la requête de base et modifier le paramètre du modèle. Exécutez les trois en séquence et comparez les réponses, la latence et la qualité de la sortie dans une seule vue.

Vous pouvez également écrire des assertions de test dans Apidog pour vérifier vos réponses multimodales :

Ceci est utile lorsque vous décidez quelle variante utiliser en production.

Gestion des erreurs et logique de nouvelle tentative

Les limites de débit et les délais d'attente sont courants avec les grands modèles multimodaux, en particulier pour les entrées vidéo. Mettez en place la gestion des nouvelles tentatives dès le début :

import time
import random
from openai import OpenAI, RateLimitError, APITimeoutError, APIConnectionError

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
    timeout=120,  # 2-minute timeout for large video inputs
)

def call_with_retry(messages, model="qwen3.5-omni-flash", max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(
                model=model,
                messages=messages,
            )
        except RateLimitError:
            wait = (2 ** attempt) + random.uniform(0, 1)
            print(f"Rate limit hit. Waiting {wait:.1f}s...")
            time.sleep(wait)
        except (APITimeoutError, APIConnectionError) as e:
            if attempt == max_retries - 1:
                raise
            wait = (2 ** attempt) + random.uniform(0, 1)
            print(f"Connection error: {e}. Retrying in {wait:.1f}s...")
            time.sleep(wait)
    raise RuntimeError(f"Failed after {max_retries} attempts")

Pour les entrées vidéo de plus de 100 Mo, considérez :


Problèmes courants et solutions

"La sortie audio est déformée sur les nombres ou les termes techniques"C'est le problème que la technologie ARIA aborde. Assurez-vous d'utiliser Qwen3.5-Omni (pas une version antérieure). Si vous hébergez vous-même, utilisez les derniers poids de modèle de HuggingFace.

"Le modèle continue de parler lorsque j'envoie une interruption audio"L'interruption sémantique nécessite la variante Flash ou Plus. Light pourrait ne pas avoir cette fonctionnalité. Vérifiez également que vous diffusez la réponse (pas en lot) pour que l'interruption fonctionne.

"La qualité du clonage de voix est mauvaise"L'échantillon vocal doit être propre. Supprimez le bruit de fond avec un outil comme Audacity avant de le télécharger. Utilisez au moins 15 secondes d'audio. Le format WAV à 16 kHz ou 44,1 kHz fonctionne le mieux.

"L'entrée vidéo renvoie une erreur concernant les limites de tokens"256K tokens couvrent environ 400 secondes de vidéo 720p. Les vidéos plus longues nécessitent un rognage ou une résolution inférieure. Vérifiez la durée de votre vidéo et réduisez-la à moins de 6 minutes par sécurité.

"Le déploiement local est très lent"Utilisez vLLM, et non HuggingFace Transformers, pour l'inférence locale en production. Les modèles MoE nécessitent les optimisations de routage de vLLM pour un débit raisonnable.

FAQ

Quel ID de modèle DashScope dois-je utiliser pour Qwen3.5-Omni ?

Utilisez qwen3.5-omni-plus, qwen3.5-omni-flash, ou qwen3.5-omni-light selon vos besoins en qualité et latence. Commencez avec Flash pour la plupart des cas d'utilisation.

Puis-je utiliser le SDK Python OpenAI avec DashScope ?

Oui. Définissez base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" et utilisez votre clé DashScope comme api_key. Le format de requête et de réponse est identique à celui de l'API OpenAI.

Comment envoyer plusieurs fichiers (audio + image) en une seule requête ?

Placez-les dans le tableau content en tant qu'objets typés séparés, à côté de votre invite de texte. Les quatre modalités peuvent apparaître dans le même message.

Y a-t-il une limite de taille pour les fichiers audio ou vidéo ?

DashScope a des limites de charge utile par requête. Pour les fichiers volumineux, utilisez une référence d'URL au lieu de l'encodage base64. Hébergez le fichier sur un stockage accessible et transmettez l'URL dans le champ audio ou video_url.

Comment désactiver la sortie audio et n'obtenir que du texte ?

Définissez modalities=["text"] ou omettez le paramètre modalities. Les réponses textuelles uniquement sont plus rapides et moins chères.

Prend-il en charge l'appel de fonctions/outils ?

Oui. Utilisez le paramètre standard tools avec les définitions de fonction, comme avec tout modèle compatible OpenAI. Le modèle renvoie des objets d'appel d'outil structurés que vous exécutez dans votre propre code.

Quelle est la meilleure façon de gérer les longs enregistrements audio ?

Pour les enregistrements de moins de 10 heures, envoyez-les en une seule requête. Pour les enregistrements plus longs, divisez-les aux points de pause naturels et traitez chaque segment séparément. Aggrégez les résultats dans votre couche d'application.

Comment tester mes requêtes multimodales avant de construire une application complète ?

Utilisez Apidog pour créer et enregistrer des modèles de requête pour chaque modalité. Vous pouvez basculer entre les variantes de modèle, inspecter la structure complète de la réponse et écrire des assertions qui vérifient la qualité de la sortie sans écrire de code d'application au préalable.

bouton

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API