Resumen
Qwen3.5-Omni acepta texto, imágenes, audio y vídeo como entrada y devuelve texto o voz en tiempo real. Acceda a él a través de la API DashScope de Alibaba Cloud o ejecútelo localmente a través de HuggingFace Transformers. Esta guía cubre la configuración de la API, ejemplos de código funcionales para cada modalidad, la clonación de voz y cómo probar sus solicitudes con Apidog.
Lo que está utilizando
Qwen3.5-Omni es un modelo único que maneja cuatro tipos de entrada simultáneamente: texto, imágenes, audio y vídeo. Devuelve texto o voz natural, según cómo configure la solicitud.

Lanzado el 30 de marzo de 2026, está construido sobre una arquitectura Thinker-Talker con una base MoE. El Thinker procesa la entrada multimodal y razona sobre ella. El Talker convierte la salida en voz utilizando un sistema de múltiples libros de códigos que comienza a transmitir audio antes de que la respuesta completa esté terminada.
Hay tres variantes disponibles:
- Plus: La más alta calidad, la mejor para el razonamiento y la clonación de voz
- Flash: Velocidad y calidad equilibradas, recomendada para la mayoría de usos en producción
- Light: La latencia más baja, para escenarios móviles y de borde
Esta guía utiliza Flash para la mayoría de los ejemplos, ya que es el punto de partida adecuado para la mayoría de las aplicaciones. Sustituya por Plus donde necesite la máxima calidad.
Acceso a la API a través de DashScope
La API DashScope de Alibaba Cloud es la forma principal de usar Qwen3.5-Omni en producción. Necesitará una cuenta DashScope y una clave API.
Paso 1: Crear una cuenta DashScope
Vaya a dashscope.aliyuncs.com y regístrese. Si ya tiene una cuenta de Alibaba Cloud, úsela.
Paso 2: Obtener su clave API
- Inicie sesión en la consola de DashScope
- Haga clic en Gestión de claves API en la barra lateral izquierda
- Haga clic en Crear clave API
- Copie la clave (formato:
sk-...)
Paso 3: Instalar el SDK
pip install dashscope
O use el punto final compatible con OpenAI directamente con el SDK de openai:
pip install openai
DashScope expone una API compatible con OpenAI en https://dashscope.aliyuncs.com/compatible-mode/v1, lo que significa que puede intercambiar su base_url y usar el mismo código que escribiría para OpenAI.
Entrada y salida de texto
Comience con el caso más simple: entrada de texto, salida de texto.
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)
Cambie a qwen3.5-omni-plus para tareas de razonamiento más difíciles o a qwen3.5-omni-light cuando la latencia sea la prioridad.
Entrada de audio: transcripción y comprensión
Pase una URL de archivo de audio o audio codificado en base64. El modelo transcribe, comprende y razona sobre el contenido de forma nativa. No se necesita un paso ASR separado.
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)
El modelo maneja 113 idiomas para el reconocimiento de voz. No necesita especificar el idioma; lo detecta automáticamente.
Formatos de audio compatibles: WAV, MP3, M4A, OGG, FLAC.
Salida de audio: texto a voz en la respuesta
Para obtener voz en lugar de texto, configure el parámetro modalities y la salida de 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."
}
],
)
# La respuesta incluye tanto texto como audio
text_content = response.choices[0].message.content
audio_data = response.choices[0].message.audio.data # WAV codificado en base64
# Guarde el audio
with open("response.wav", "wb") as f:
f.write(base64.b64decode(audio_data))
print(f"Texto: {text_content}")
print("Audio guardado en response.wav")
Hay dos voces integradas disponibles: Chelsie (femenina) y Ethan (masculina). La generación de voz funciona en 36 idiomas.
Entrada de imagen: comprensión visual
Pase una URL de imagen o una imagen codificada en base64 junto con una pregunta de texto:
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)
Para imágenes locales, codifíquelas en base64:
import base64
with open("screenshot.png", "rb") as f:
image_data = base64.b64encode(f.read()).decode("utf-8")
# Usar formato de URL de datos
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?"
}
]
}
],
)
Entrada de vídeo: comprensión de grabaciones y capturas de pantalla
La entrada de vídeo es donde Qwen3.5-Omni hace algo que ningún modelo de texto o imagen puede hacer: razonar simultáneamente sobre las pistas visuales y de audio.
from openai import OpenAI
import base64
client = OpenAI(
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="sk-YOUR_DASHSCOPE_KEY",
)
# Pasar una URL de vídeo
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)
Programación "Vibe Coding" Audiovisual
El caso de uso de "Vibe Coding" consiste en pasar una grabación de pantalla y pedirle al modelo que genere código a partir de lo que ve:
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 ventana de contexto de 256K tokens se ajusta aproximadamente a 400 segundos de vídeo 720p con audio. Para grabaciones más largas, recorte o divida.
Clonación de voz
La clonación de voz le permite dar al modelo una voz objetivo y hacer que responda con esa voz. Esto está disponible en Plus y Flash a través de la API.
import base64
from openai import OpenAI
client = OpenAI(
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="sk-YOUR_DASHSCOPE_KEY",
)
# Cargue una muestra de voz de 10-30 segundos para la clonación
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))
Consejos para la calidad de la clonación de voz:
- Utilice una grabación limpia sin ruido de fondo
- 15-30 segundos funciona mejor que clips muy cortos
- Formato WAV a 16kHz o superior
- La muestra de voz debe tener un habla natural, no texto leído en voz alta, para una mejor coincidencia de prosodia
Respuestas en streaming
Para chat de voz en tiempo real o aplicaciones interactivas, utilice streaming. El modelo comienza a devolver audio antes de que se genere la respuesta completa:
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() # nueva línea después del texto en streaming
# Combine y guarde los fragmentos de audio
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)
El formato PCM16 funciona bien para el streaming, ya que puede canalizarlo directamente a un búfer de salida de audio sin esperar un archivo completo.
Conversación multiturno con modalidades mixtas
Las conversaciones reales mezclan entradas a lo largo de los turnos. Así es como se gestiona el historial de conversaciones con diferentes modalidades:
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
# Turno 1: texto
print(send_message([{"type": "text", "text": "I have an API that keeps returning 503 errors."}]))
# Turno 2: añadir una imagen (captura de pantalla del registro de errores)
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?"}
]))
# Turno 3: texto de seguimiento
print(send_message([{"type": "text", "text": "How do I fix the connection pool exhaustion you mentioned?"}]))
La ventana de contexto de 256K tokens significa que puede mantener conversaciones largas, incluidas aquellas con imágenes y audio incrustados, sin problemas de truncamiento.
Despliegue local con HuggingFace
Si necesita ejecutar Qwen3.5-Omni en su propia infraestructura:
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": "Usted es Qwen, un humano virtual desarrollado por el Equipo Qwen, Alibaba Group, capaz de percibir entradas auditivas y visuales, así como de generar texto y voz."}
],
},
{
"role": "user",
"content": [
{"type": "audio", "audio": "path/to/your/audio.wav"},
{"type": "text", "text": "¿Qué se está discutiendo en este 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)
Requisitos de memoria de GPU para el despliegue local:
| Variante | Precisión | VRAM Mínima |
|---|---|---|
| Plus (30B MoE) | BF16 | ~40GB |
| Flash | BF16 | ~20GB |
| Light | BF16 | ~10GB |
Para la inferencia local en producción, use vLLM en lugar de HuggingFace Transformers. Los modelos MoE se ejecutan más rápido con las optimizaciones de enrutamiento de vLLM.
Probando sus solicitudes Qwen3.5-Omni con Apidog
Las solicitudes API multimodales son más difíciles de depurar que el JSON simple. Está lidiando con audio y vídeo codificados en base64, arrays de contenido anidados y respuestas que pueden incluir tanto texto como audio. Hacer esto desde una terminal se vuelve tedioso rápidamente.

Apidog lo maneja de forma limpia. Configure su endpoint DashScope como una nueva colección, guarde su clave API como una variable de entorno y construya plantillas de solicitud para cada modalidad con la que esté trabajando.
Para cada variante (Plus, Flash, Light), puede duplicar la solicitud base y cambiar el parámetro del modelo. Ejecute las tres en secuencia y compare las respuestas, la latencia y la calidad de salida en una sola vista.
También puede escribir aserciones de prueba en Apidog para verificar sus respuestas multimodales:
- Verifique que
choices[0].message.contentno esté vacío para las respuestas de texto - Verifique que
choices[0].message.audio.dataesté presente cuando se solicite la salida de audio - Asegure que la latencia de respuesta para Flash esté por debajo de su umbral objetivo
Esto es útil cuando está decidiendo qué variante usar en producción.
Manejo de errores y lógica de reintentos
Los límites de velocidad y los tiempos de espera son comunes con modelos multimodales grandes, especialmente para entradas de vídeo. Construya el manejo de reintentos desde el principio:
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, # Tiempo de espera de 2 minutos para grandes entradas de vídeo
)
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"Límite de tasa alcanzado. Esperando {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"Error de conexión: {e}. Reintentando en {wait:.1f}s...")
time.sleep(wait)
raise RuntimeError(f"Falló después de {max_retries} intentos")
Para entradas de vídeo de más de 100MB, considere:
- Recortar a la porción relevante antes de enviar
- Reducir la resolución a 480p si el contenido visual no requiere alta resolución
- Dividir grabaciones largas en segmentos y agregar los resultados
Problemas comunes y soluciones
“La salida de audio es ininteligible en números o términos técnicos”Este es el problema que aborda la tecnología ARIA. Asegúrese de estar usando Qwen3.5-Omni (no una versión anterior). Si está autoalojando, use los pesos del modelo más recientes de HuggingFace.
“El modelo sigue hablando cuando envío una interrupción de audio”La interrupción semántica requiere la variante Flash o Plus. Light puede no tener esta característica. También verifique que esté transmitiendo la respuesta (no por lotes) para que la interrupción funcione.
“La calidad de la clonación de voz es deficiente”La muestra de voz debe ser limpia. Elimine el ruido de fondo con una herramienta como Audacity antes de subirla. Use al menos 15 segundos de audio. WAV a 16kHz o 44.1kHz funciona mejor.
“La entrada de vídeo devuelve un error sobre los límites de tokens”256K tokens cubren aproximadamente 400 segundos de vídeo 720p. Los vídeos más largos necesitan ser recortados o tener una resolución más baja. Verifique la duración de su vídeo y redúzcala a menos de 6 minutos por seguridad.
“El despliegue local es muy lento”Use vLLM, no HuggingFace Transformers, para la inferencia local en producción. Los modelos MoE necesitan las optimizaciones de enrutamiento de vLLM para un rendimiento razonable.
Preguntas frecuentes
¿Qué ID de modelo de DashScope uso para Qwen3.5-Omni?
Use qwen3.5-omni-plus, qwen3.5-omni-flash o qwen3.5-omni-light según sus necesidades de calidad y latencia. Comience con Flash para la mayoría de los casos de uso.
¿Puedo usar el SDK de Python de OpenAI con DashScope?
Sí. Establezca base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" y use su clave DashScope como api_key. El formato de solicitud y respuesta es idéntico al de la API de OpenAI.
¿Cómo envío múltiples archivos (audio + imagen) en una sola solicitud?
Colóquelos en el array content como objetos tipados separados junto con su prompt de texto. Las cuatro modalidades pueden aparecer en el mismo mensaje.
¿Hay un límite de tamaño para los archivos de audio o vídeo?
DashScope tiene límites de carga útil por solicitud. Para archivos grandes, use una referencia de URL en lugar de codificación base64. Aloje el archivo en un almacenamiento accesible y pase la URL en el campo audio o video_url.
¿Cómo desactivo la salida de audio y obtengo solo texto?
Establezca modalities=["text"] u omita el parámetro modalities. Las respuestas solo de texto son más rápidas y económicas.
¿Admite la llamada a funciones/herramientas?
Sí. Use el parámetro estándar tools con definiciones de funciones, igual que con cualquier modelo compatible con OpenAI. El modelo devuelve objetos de llamada a herramientas estructurados que usted ejecuta en su propio código.
¿Cuál es la mejor manera de manejar grabaciones de audio largas?
Para grabaciones de menos de 10 horas, envíelas como una sola solicitud. Para grabaciones más largas, divida en puntos de pausa naturales y procese cada segmento por separado. Agregue los resultados en su capa de aplicación.
¿Cómo pruebo mis solicitudes multimodales antes de construir una aplicación completa?
Use Apidog para construir y guardar plantillas de solicitud para cada modalidad. Puede alternar entre variantes de modelo, inspeccionar la estructura completa de la respuesta y escribir aserciones que verifiquen la calidad de la salida sin escribir código de aplicación primero.
