DEV Community

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

Posted on • Originally published at apidog.com

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

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. Utilisez-le via l'API Alibaba Cloud DashScope ou exécutez-le localement avec HuggingFace Transformers. Ce guide détaille la configuration de l'API, fournit des exemples de code pour chaque modalité, explique le clonage de voix, et montre comment tester vos requêtes avec Apidog.

Essayez Apidog dès aujourd'hui

Ce avec quoi vous travaillez

Qwen3.5-Omni est un modèle conçu pour traiter simultanément quatre types d'entrée : texte, image, audio et vidéo. Il peut générer du texte ou de la parole naturelle selon votre configuration.

Qwen3.5-Omni Architecture

Lancé le 30 mars 2026, il s'appuie sur une architecture Thinker-Talker avec un cœur MoE. Le Thinker traite l'entrée multimodale, le Talker convertit la sortie en parole via un système multi-dictionnaires, diffusant l'audio avant la fin du texte.

Trois variantes sont disponibles :

  • Plus : Qualité maximale, idéal pour le raisonnement et le clonage de voix
  • Flash : Bon équilibre vitesse/qualité, conseillé pour la production
  • Light : Latence minimale, adapté aux usages mobiles et embarqués

Ce guide utilise Flash par défaut. Préférez Plus pour une qualité optimale.

Accès à l'API via DashScope

L'API DashScope d'Alibaba Cloud est la méthode recommandée pour utiliser Qwen3.5-Omni en production. Prérequis : un compte DashScope et une clé API.

Étape 1 : Créer un compte DashScope

Rendez-vous sur dashscope.aliyuncs.com et inscrivez-vous. Si vous avez déjà un compte Alibaba Cloud, connectez-vous.

É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
  3. Cliquez sur Créer une clé API
  4. Copiez la clé générée (sk-...)

Étape 3 : Installer le SDK

pip install dashscope
Enter fullscreen mode Exit fullscreen mode

Ou utilisez le SDK OpenAI compatible :

pip install openai
Enter fullscreen mode Exit fullscreen mode

DashScope expose une API compatible OpenAI à https://dashscope.aliyuncs.com/compatible-mode/v1. Remplacez simplement le base_url pour réutiliser vos scripts OpenAI.

Entrée et sortie de texte

Cas d'usage de base : 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": "Explique la différence entre les API REST et GraphQL en termes simples."
        }
    ],
)

print(response.choices[0].message.content)
Enter fullscreen mode Exit fullscreen mode

Utilisez qwen3.5-omni-plus pour les tâches de raisonnement complexes ou qwen3.5-omni-light si la latence est critique.


Entrée audio : transcription et compréhension

Transmettez une URL audio ou un fichier encodé en base64. Le modèle transcrit et comprend directement l'audio, sans étape ASR séparée.

import base64
from openai import OpenAI

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

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": "Résume les décisions clés prises lors de cette réunion et liste les tâches à faire."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)
Enter fullscreen mode Exit fullscreen mode
  • 113 langues reconnues automatiquement
  • Formats audio : WAV, MP3, M4A, OGG, FLAC

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

Obtenez une réponse vocale en configurant le paramètre de 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": "Décris les étapes pour authentifier une API REST avec OAuth 2.0."
        }
    ],
)

text_content = response.choices[0].message.content
audio_data = response.choices[0].message.audio.data

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

print(f"Texte : {text_content}")
print("Audio enregistré dans response.wav")
Enter fullscreen mode Exit fullscreen mode
  • Voix disponibles : Chelsie (femme), Ethan (homme)
  • Synthèse vocale dans 36 langues

Entrée image : compréhension visuelle

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

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": "Décris ce diagramme d'architecture API et identifie les goulets d'étranglement potentiels."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)
Enter fullscreen mode Exit fullscreen mode

Pour une image locale :

import base64

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

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": "Quelle erreur s'affiche sur cette capture d'écran ?"
                }
            ]
        }
    ],
)
Enter fullscreen mode Exit fullscreen mode

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

Le modèle peut raisonner sur la vidéo et l'audio en simultané.

from openai import OpenAI
import base64

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

# Vidéo hébergée
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": "Décris ce que le développeur construit dans cette démo et écris le code équivalent."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)
Enter fullscreen mode Exit fullscreen mode

Codage d'ambiance Audio-Visuel

Pour générer du code à partir d'un enregistrement d'écran :

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",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "video_url",
                    "video_url": {
                        "url": f"data:video/mp4;base64,{video_data}"
                    }
                },
                {
                    "type": "text",
                    "text": "Observe cet enregistrement et écris le code complet qui reproduit ce qui est construit. Inclue tous les composants UI et leurs interactions."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)
Enter fullscreen mode Exit fullscreen mode
  • Fenêtre contextuelle : 256K tokens ≈ 400s de vidéo 720p avec audio.

Clonage de voix

Permet au modèle de répondre avec une voix cible (Plus/Flash uniquement) :

import base64
from openai import OpenAI

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

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": "Bienvenue sur le portail développeur Apidog. Comment puis-je vous aider ?"
        }
    ],
)

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

Conseils :

  • Utilisez un enregistrement propre sans bruit
  • 15-30 secondes d'échantillon donnent de meilleurs résultats
  • Format WAV, 16 kHz ou supérieur
  • Parole naturelle (pas de texte lu)

Diffusion des réponses

Pour les applications interactives, activez la diffusion audio/text en temps réel :

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": "Explique la différence entre une connexion WebSocket et le polling HTTP."
        }
    ],
    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()

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)
Enter fullscreen mode Exit fullscreen mode
  • PCM16 : idéal pour la diffusion audio en temps réel

Conversation multi-tours avec des modalités mixtes

Gérez l'historique de conversation, y compris texte, image, audio :

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

# Tour 1 : texte
print(send_message([{"type": "text", "text": "Mon API retourne sans cesse des erreurs 503."}]))

# Tour 2 : capture d'écran (image)
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": "Voici la capture du log d'erreur. Quelle en est la cause ?"}
]))

# Tour 3 : suivi texte
print(send_message([{"type": "text", "text": "Comment corriger l'épuisement du pool de connexions mentionné ?"}]))
Enter fullscreen mode Exit fullscreen mode

Fenêtre contextuelle 256K : conversations longues, multimodales, sans troncature.

Déploiement local avec HuggingFace

Pour exécuter le modèle en local :

pip install transformers==4.57.3
pip install accelerate
pip install qwen-omni-utils -U
pip install -U flash-attn --no-build-isolation
Enter fullscreen mode Exit fullscreen mode
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": "Vous êtes Qwen, un humain virtuel développé par l'équipe Qwen d'Alibaba Group, capable de percevoir l'audio, la vidéo, et de générer du texte et de la parole."}
        ],
    },
    {
        "role": "user",
        "content": [
            {"type": "audio", "audio": "path/to/your/audio.wav"},
            {"type": "text", "text": "De quoi parle cet 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)
Enter fullscreen mode Exit fullscreen mode

Besoins GPU pour le local :

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

Préférez vLLM à HuggingFace Transformers pour l'inférence locale en production (plus rapide pour les modèles MoE).

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

Les requêtes multimodales (audio, vidéo en base64, contenus imbriqués) sont difficiles à tester en pur JSON/terminal.

Apidog multimodal

Apidog simplifie la gestion multimodale. Ajoutez votre point de terminaison DashScope dans une collection, stockez la clé API comme variable d'environnement, créez des modèles de requête pour chaque modalité.

Dupliquez les requêtes pour tester les variantes (Plus, Flash, Light), comparez qualité, latence et réponses dans une seule interface.

Ajoutez des assertions de test dans Apidog :

  • Vérifiez que choices[0].message.content n'est pas vide (texte)
  • Vérifiez que choices[0].message.audio.data existe (audio)
  • Contrôlez que la latence de Flash est sous le seuil cible

Idéal pour sélectionner la variante la plus adaptée à votre prod.

Gestion des erreurs et logique de nouvelle tentative

Attendez-vous à des limites de débit/délais sur les gros inputs, surtout vidéo. Gérez les retries 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,
)

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. Attente {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"Erreur réseau : {e}. Nouvelle tentative dans {wait:.1f}s...")
            time.sleep(wait)
    raise RuntimeError(f"Échec après {max_retries} tentatives")
Enter fullscreen mode Exit fullscreen mode

Pour les vidéos >100 Mo :

  • Rognez la partie utile avant l'envoi
  • Abaissez la résolution à 480p si possible
  • Découpez en segments, agrégerez côté client

Problèmes courants et solutions

Sortie audio déformée sur nombres / termes techniques

Utilisez Qwen3.5-Omni (pas une version antérieure). Avec du self-hosting, prenez les derniers poids sur HuggingFace.

Le modèle continue de parler malgré une interruption audio

L'interruption sémantique nécessite Flash ou Plus et la diffusion (pas batch).

Mauvaise qualité du clonage de voix

Échantillon propre, sans bruit, minimum 15s, format WAV 16/44,1 kHz, parole naturelle.

Erreur de limite de tokens sur vidéo

256K tokens ≈ 400s de 720p. Découpez à <6min pour éviter l'erreur.

Déploiement local très lent

Utilisez vLLM pour le routing MoE, pas HuggingFace Transformers en prod.

FAQ

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

qwen3.5-omni-plus, qwen3.5-omni-flash, ou qwen3.5-omni-light. Flash est le point de départ recommandé.

Puis-je utiliser le SDK Python OpenAI avec DashScope ?

Oui, en définissant base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" et votre clé DashScope comme api_key. Le format est identique à celui de l’API OpenAI.

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

Placez-les dans le tableau content comme objets typés distincts, avec l’invite texte. Les 4 modalités sont supportées dans le même message.

Limites de taille pour les fichiers audio/vidéo ?

DashScope limite la taille par requête. Pour les gros fichiers, fournissez une URL accessible plutôt que l'encodage base64.

Désactiver la sortie audio et n’obtenir que du texte ?

Définissez modalities=["text"] ou omettez ce paramètre. C’est plus rapide et économique.

Prise en charge de l’appel de fonctions/outils ?

Oui, via le paramètre tools comme dans l’API OpenAI. Le modèle renvoie des objets structurés à exécuter côté application.

Meilleures pratiques pour de longs enregistrements audio ?

Jusqu’à 10h : une requête. Plus long : découpez par pauses naturelles, traitez chaque segment, puis agrégez.

Tester ses requêtes multimodales avant l’app complète ?

Utilisez Apidog pour créer des modèles de requête et assertions, explorer les réponses, et comparer facilement les variantes sans écrire de code d’intégration.

Top comments (0)