TL;DR
Qwen3.5-Omni aceita texto, imagens, áudio e vídeo como entrada e retorna texto ou fala em tempo real. Acesse-o através da API DashScope da Alibaba Cloud ou execute-o localmente via HuggingFace Transformers. Este guia abrange a configuração da API, exemplos de código funcionais para cada modalidade, clonagem de voz e como testar suas solicitações com o Apidog.
Experimente o Apidog hoje mesmo
Com o que você está trabalhando
Qwen3.5-Omni é um modelo que lida com texto, imagens, áudio e vídeo simultaneamente, retornando texto ou fala natural conforme sua configuração.
Arquitetura Thinker-Talker com backbone MoE. O Thinker processa a entrada multimodal; o Talker converte a saída em fala via sistema multi-codebook que transmite áudio antes da resposta completa.
Três variantes:
- Plus: Qualidade máxima, ideal para raciocínio e clonagem de voz
- Flash: Equilíbrio entre velocidade e qualidade; recomendado para produção
- Light: Latência mínima, indicado para edge/mobile
Este guia utiliza Flash como padrão. Troque para Plus para máxima qualidade.
Acesso à API via DashScope
A maneira principal de usar o Qwen3.5-Omni em produção é via API DashScope da Alibaba Cloud. Você precisará de uma conta e chave de API.
Passo 1: Crie uma conta DashScope
Acesse dashscope.aliyuncs.com e faça cadastro ou login com sua conta Alibaba Cloud.
Passo 2: Obtenha sua chave de API
- Faça login no console DashScope
- Clique em API Key Management na barra lateral
- Clique em Create API Key
- Copie a chave no formato
sk-...
Passo 3: Instale o SDK
pip install dashscope
Ou use o endpoint compatível com OpenAI:
pip install openai
O DashScope expõe uma API compatível com OpenAI em https://dashscope.aliyuncs.com/compatible-mode/v1. Basta trocar seu base_url e usar a mesma lógica dos exemplos OpenAI.
Entrada e saída de texto
Envie texto e receba texto como resposta:
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 a diferença entre APIs REST e GraphQL em termos simples."
}
],
)
print(response.choices[0].message.content)
Troque para qwen3.5-omni-plus para tarefas mais complexas ou qwen3.5-omni-light para priorizar latência.
Entrada de áudio: transcrição e compreensão
Envie um arquivo de áudio (URL ou base64) e o modelo transcreve, compreende e raciocina sobre o conteúdo.
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": "Resuma as principais decisões desta reunião e liste os itens de ação."
}
]
}
],
)
print(response.choices[0].message.content)
- Suporte a 113 idiomas (detecção automática)
- Formatos: WAV, MP3, M4A, OGG, FLAC
Saída de áudio: conversão de texto em fala
Defina modalities e configure a saída de áudio para obter resposta falada:
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": "Descreva os passos para autenticar uma API REST usando 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"Texto: {text_content}")
print("Áudio salvo em response.wav")
- Vozes:
Chelsie(feminina) eEthan(masculina) - TTS disponível em 36 idiomas
Entrada de imagem: compreensão visual
Envie uma imagem (URL ou base64) e uma pergunta:
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": "Descreva este diagrama de arquitetura de API e identifique possíveis gargalos."
}
]
}
],
)
print(response.choices[0].message.content)
Para imagens locais (base64):
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": "Qual erro aparece nesta captura de tela?"
}
]
}
],
)
Entrada de vídeo: compreensão de gravações
Qwen3.5-Omni processa vídeo (visual e áudio) simultaneamente.
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",
messages=[
{
"role": "user",
"content": [
{
"type": "video_url",
"video_url": {
"url": "https://example.com/product-demo.mp4"
}
},
{
"type": "text",
"text": "Descreva o que o desenvolvedor está construindo neste demo e escreva o código equivalente."
}
]
}
],
)
print(response.choices[0].message.content)
Vibe Coding: geração de código via gravação de tela
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": "Assista a esta gravação de tela e gere o código completo que replica o que está sendo construído, incluindo todos os componentes de UI e interações."
}
]
}
],
)
print(response.choices[0].message.content)
- Janela de contexto: 256K tokens (~400s de vídeo 720p com áudio)
- Para vídeos longos, corte ou divida em partes menores
Clonagem de voz
Disponível em Plus e Flash via API. Envie uma amostra de voz (10-30s) para clonar.
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": "Bem-vindo ao portal do desenvolvedor Apidog. Como posso ajudar?"
}
],
)
audio_data = response.choices[0].message.audio.data
with open("cloned_response.wav", "wb") as f:
f.write(base64.b64decode(audio_data))
Dicas de qualidade:
- Use gravação limpa, sem ruído
- 15-30s de áudio, formato WAV 16kHz+
- Prefira fala natural
Respostas em streaming
Para voz em tempo real ou UI interativa, utilize streaming:
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 como WebSocket difere do 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() # Quebra de linha após o texto
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)
- PCM16 é recomendado para streaming: pode ser enviado ao buffer de áudio diretamente.
Conversa multi-turno com modalidades mistas
Gerencie histórico e múltiplas modalidades na conversa:
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": "Minha API retorna erro 503 constantemente."}]))
# Turno 2: imagem
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": "Segue o log de erro. O que está causando isso?"}
]))
# Turno 3: texto
print(send_message([{"type": "text", "text": "Como corrijo a exaustão do pool de conexões mencionada?"}]))
- Contexto de 256K tokens: mantenha conversas longas, multimodais, sem truncamento.
Implantação local com HuggingFace
Execute Qwen3.5-Omni localmente:
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": "Você é Qwen, humano virtual da Alibaba, capaz de processar entrada auditiva e visual e gerar texto e fala."}
],
},
{
"role": "user",
"content": [
{"type": "audio", "audio": "path/to/your/audio.wav"},
{"type": "text", "text": "Sobre o que é este áudio?"}
],
},
]
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 mínimos de VRAM:
| Variante | Precisão | VRAM Mínima |
|---|---|---|
| Plus (30B MoE) | BF16 | ~40GB |
| Flash | BF16 | ~20GB |
| Light | BF16 | ~10GB |
Para produção local, prefira vLLM ao invés de HuggingFace Transformers para melhor desempenho com modelos MoE.
Testando suas solicitações Qwen3.5-Omni com Apidog
APIs multimodais envolvem áudio/vídeo base64, arrays de conteúdo e respostas compostas. Fazer isso manualmente é trabalhoso.
Apidog facilita o teste de endpoints DashScope. Crie uma coleção, armazene sua chave de API como variável de ambiente, e modele solicitações para cada modalidade.
- Duplique solicitações para cada variante (Plus, Flash, Light) e compare facilmente latência, qualidade e resposta.
- Adicione asserções:
- Verifique se
choices[0].message.contentnão está vazio (texto) - Verifique se
choices[0].message.audio.dataexiste (áudio) - Confirme latência da Flash abaixo do limite definido
- Verifique se
Essas práticas ajudam na escolha da variante ideal para produção.
Tratamento de erros e lógica de repetição
Implemente retry para lidar com rate limits e timeouts, comuns em entradas grandes (especialmente vídeo):
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"Limite atingido. 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"Erro de conexão: {e}. Tentando novamente em {wait:.1f}s...")
time.sleep(wait)
raise RuntimeError(f"Falha após {max_retries} tentativas")
Para arquivos de vídeo acima de 100MB:
- Corte o trecho relevante antes de enviar
- Reduza para 480p se possível
- Divida gravações longas e agregue depois
Problemas comuns e soluções
Áudio distorcido em números ou termos técnicos:
Use Qwen3.5-Omni atualizado; se auto-hospedando, baixe os pesos mais recentes.
Modelo não para após interrupção de áudio:
Interrupção semântica exige Flash ou Plus, além de streaming ativado.
Clonagem de voz ruim:
Amostra deve ser limpa, sem ruído, com pelo menos 15s. Formato WAV 16kHz+.
Erro de limite de tokens em vídeo:
256K tokens ≈ 400s de vídeo 720p. Corte para 6 minutos ou menos.
Inferência local lenta:
Use vLLM ao invés de Transformers para produção.
FAQ
Qual ID de modelo DashScope devo usar para Qwen3.5-Omni?
Use qwen3.5-omni-plus, qwen3.5-omni-flash ou qwen3.5-omni-light conforme qualidade e latência desejadas. Flash é o padrão recomendado.
Posso usar o SDK Python do OpenAI com DashScope?
Sim. Defina base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" e use sua chave DashScope como api_key. O formato é idêntico ao da OpenAI.
Como envio vários arquivos (áudio + imagem) em uma solicitação?
Inclua ambos no array content como objetos tipados distintos, junto ao prompt de texto. Todas as modalidades podem ser combinadas.
Existe limite de tamanho para áudio/vídeo?
DashScope aplica limites de payload. Para arquivos grandes, hospede externamente e envie o URL nos campos audio ou video_url.
Como desativo a saída de áudio e recebo só texto?
Defina modalities=["text"] ou omita o parâmetro. Só texto é mais rápido e barato.
Suporta chamada de função/ferramenta?
Sim. Use o parâmetro tools como na OpenAI, e o modelo retorna objetos de função para execução.
Melhor forma de processar gravações de áudio longas?
Até 10 horas: envie em uma única solicitação. Acima disso, divida em segmentos e agregue os resultados.
Como testo solicitações multimodais antes de construir o app?
Use o Apidog para construir e salvar modelos de requisição, alternar variantes, inspecionar respostas e escrever asserções sem precisar codificar a aplicação primeiro.

Top comments (0)