Skip to main content

SDK de Python de Qwen-Audio-TTS

Utilice el SDK de Python de DashScope para integrar la síntesis de voz en tiempo real de Qwen-Audio-TTS en su aplicación mediante modos sin streaming, streaming unidireccional o streaming bidireccional.

Endpoint de servicio

El endpoint de servicio del SDK está determinado por los parámetros workspace/region del constructor de Client (corresponden a las direcciones siguientes, que incluyen el WorkspaceId). Para cambiar a una región diferente, modifique los parámetros del constructor de Client por los valores de la región de destino.
  • Singapore
  • China (Beijing)
wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inferenceReemplace {WorkspaceId} con su ID de espacio de trabajo real.
Alibaba Cloud Model Studio ha lanzado dominios específicos del espacio de trabajo para las regiones China (Pekín) y Singapore. Los nuevos dominios dedicados ofrecen un rendimiento superior y una mayor estabilidad para las solicitudes de inferencia. Recomendamos migrar a los nuevos dominios:
  • China (Pekín): de dashscope.aliyuncs.com a {WorkspaceId}.cn-beijing.maas.aliyuncs.com
  • Singapur: de dashscope-intl.aliyuncs.com a {WorkspaceId}.ap-southeast-1.maas.aliyuncs.com

Recurso principal (client.audio.tts)

Ruta del recurso: client.audio.tts Función: Síntesis de voz basada en WebSocket que ofrece tres modos de invocación: síntesis en una sola llamada (synthesize), síntesis por streaming (stream) y sesiones de streaming bidireccional (connect).

Puntos de entrada de invocación

# Síntesis en una sola llamada: devuelve el audio completo como bytes
audio = client.audio.tts.synthesize(
    text,                      # text es obligatorio (posicional)
    model="qwen-audio-3.0-tts-flash", # el modelo al que pertenece la voz
    voice="longanhuan_v3.6",   # la voz
    format="mp3",              # formato de codificación de audio, predeterminado "mp3"
    sample_rate=22050,         # frecuencia de muestreo, predeterminada 22050
)

# Síntesis por streaming: devuelve fragmentos de bytes de audio uno a uno (escríbalos o reprodúzcalos a medida que los recibe)
for chunk in client.audio.tts.stream(text, model=..., voice=...):
    ...

# Sesión de streaming bidireccional: envíe el texto en segmentos; la conexión se establece automáticamente al entrar en el contexto with
with client.audio.tts.connect(model=..., voice=...) as session:
    session.send_text(text)    # puede llamarse varias veces para agregar texto
    session.stop()             # notifica al servidor que la entrada ha finalizado
    for chunk in session.audio_chunks():
        ...

synthesize() - sin streaming

Firma del método:
def synthesize(self, text: str, *, model: str,
               voice: str, format: str = "mp3",
               sample_rate: int = 22050, volume: int = None,
               rate: float = None, pitch: float = None,
               language_hints: list = None, enable_ssml: bool = None,
               parameters: Dict = None, ...) -> bytes
Parámetros:
ParámetroTipoObligatorioDescripción
textstrSíEl texto completo a sintetizar. Longitud máxima: 20,000 caracteres.
Valor de retorno: bytes que contiene los datos de audio completos. Descripción: Esta llamada bloqueante espera a que la síntesis se complete y devuelve los datos de audio completos de una sola vez. Es más adecuada para textos cortos donde no se requiere transmisión en tiempo real. Cada llamada a synthesize o stream crea su propia sesión; no es necesario reutilizar instancias.

stream() - streaming

Firma del método:
def stream(self, text: str, *, model: str, voice: str,
           format: str = "mp3", sample_rate: int = 22050, ...) -> Iterator[bytes]
Parámetros:
ParámetroTipoObligatorioDescripción
textstrSíEl texto completo a sintetizar. Longitud máxima: 20,000 caracteres.
Valor de retorno: Iterator[bytes] que contiene los datos de audio devueltos fragmento a fragmento. Descripción: La síntesis por streaming envía el texto completo de una sola vez y devuelve el audio fragmento a fragmento (Iterator[bytes]). Es ideal para la síntesis de voz de texto corto que requiere baja latencia. Para enviar el texto en segmentos, utilice una sesión de streaming bidireccional (connect).

send_text() - entrada en streaming (método de sesión)

Envíe texto en segmentos dentro de una sesión de streaming bidireccional (client.audio.tts.connect(...)). Firma del método:
def send_text(self, text: str) -> None
Parámetros: text es el segmento de texto actual a sintetizar. Llame a send_text varias veces para agregar texto. Máximo por llamada: 20,000 caracteres. Máximo acumulado: 200,000 caracteres. El envío de texto y la recepción de audio deben ejecutarse de forma concurrente (utilícelo junto con audio_chunks()/events() y stop).

stop() - finalizar entrada en streaming (método de sesión)

Firma del método:
def stop(self) -> None
Descripción: Notifica al servidor que se ha enviado todo el texto. Esta llamada no bloquea el hilo actual; el hilo receptor debe seguir consumiendo audio_chunks()/events() hasta que se sintetice el texto restante y se devuelvan todos los datos de audio. Si no se llama a este método, es posible que el texto final no se convierta en voz.

cancel() - cancelar síntesis por streaming (método de sesión)

Firma del método:
def cancel(self) -> None
Descripción: Cancela el turno actual de síntesis de voz por streaming. Después de llamar a este método, el SDK finaliza inmediatamente la tarea actual. Tras la cancelación, la sesión ya no puede enviar texto; cree una nueva sesión para continuar con la síntesis.

Métricas y respuestas de la sesión (atributos de sesión)

session.first_package_delay
session.usage
session.last_response
  • first_package_delay: float, el retraso en milisegundos desde el envío del texto hasta la recepción del primer fragmento de audio. Léalo después de que se complete la síntesis.
  • usage: dict, la información de uso de la tarea de síntesis más reciente.
  • last_response: dict, el mensaje de respuesta de la tarea de síntesis más reciente (con las claves header/payload). El ID de solicitud de la solicitud más reciente se puede recuperar del header de session.last_response, lo que resulta útil para la solución de problemas y la correlación de registros.

Parámetros de solicitud

Los siguientes parámetros se configuran a través de los métodos synthesize/stream/connect de client.audio.tts para controlar el modelo, la voz, el formato y las características del audio de la síntesis (model, voice, format, sample_rate, volume, rate, pitch, language_hints y enable_ssml son parámetros con nombre; los demás parámetros se pasan a través del diccionario parameters).
ParámetroTipoObligatorioDescripción
modelstrSíEl nombre del modelo.
voicestrSíLa voz utilizada para la síntesis de habla.
  • Voces del sistema: Consulte la lista de voces de Qwen-Audio-TTS
  • Voces clonadas: Voces personalizadas creadas mediante clonación de voz
  • Voces personalizadas: Voces personalizadas creadas mediante diseño de voz
formatstrNoFormato de codificación de audio.Predeterminado: mp3.Admite mp3, wav, pcm y otros formatos; la frecuencia de muestreo se establece a través del parámetro sample_rate, con valor predeterminado de 22050.
volumeintNoEl nivel de volumen.Valor predeterminado: 50.Valores válidos: [0, 100].
ratefloatNoLa velocidad del habla.Valor predeterminado: 1.0.Valores válidos: [0.5, 2.0].
pitchfloatNoEl tono.Valor predeterminado: 1.0.Valores válidos: [0.5, 2.0].
bit_rateintNoLa tasa de bits de audio en kbps. Cuando el formato de audio es mp3 u opus, utilice bit_rate para ajustar la tasa de bits.Valor predeterminado: 32.Valores válidos: [6, 510].Configure bit_rate a través del diccionario parameters:
audio = client.audio.tts.synthesize(
    "Text to synthesize",
    model="qwen-audio-3.0-tts-flash",
    voice="longanhuan_v3.6",
    parameters={"bit_rate": 128},
)
word_timestamp_enabledboolNoEspecifica si se deben habilitar las marcas de tiempo a nivel de palabra.Valor predeterminado: false.Disponible solo en modo de salida por streaming. Se admiten voces clonadas. Para voces del sistema compatibles, consulte la lista de voces de Qwen-Audio-TTS.Configure word_timestamp_enabled a través del diccionario parameters:
audio = client.audio.tts.stream(
    "Text to synthesize",
    model="qwen-audio-3.0-tts-flash",
    voice="your_voice",  # A system or cloned voice that supports word-level timestamps
    parameters={"word_timestamp_enabled": True},
)
seedintNoUna semilla aleatoria para controlar la variación en la salida de la síntesis. Cuando la versión del modelo, el texto, la voz y otros parámetros no cambian, usar la misma semilla produce resultados idénticos.Valor predeterminado: 0.Valores válidos: [0, 65535].
language_hintslist[str]No
  • Este parámetro es una matriz, pero la versión actual solo procesa el primer elemento. Pase un único valor.
  • Este parámetro especifica el idioma de destino para la síntesis de voz. No está relacionado con el idioma de la muestra de audio utilizada en la clonación de voz. Para establecer el idioma de origen de una tarea de clonación, consulte la referencia de la API de clonación de voz.
Especifica el idioma objetivo para la síntesis de voz con el fin de mejorar la calidad de salida.Cuando la pronunciación de dígitos, la expansión de abreviaturas, la lectura de símbolos o la síntesis en idiomas minoritarios no cumpla con las expectativas, utilice este parámetro. Por ejemplo:
  • Pronunciación inesperada de dígitos: "hola, esto es 110" se lee como "hola, esto es uno cero" en lugar de la pronunciación china esperada
  • Pronunciación incorrecta de símbolos: "@" se lee como su equivalente en chino en lugar de "arroba"
  • Mala calidad de síntesis en idiomas minoritarios con resultados poco naturales
  • zh: Chino
  • en: Inglés
  • fr: Francés
  • de: Alemán
  • ja: Japonés
  • ko: Coreano
  • ru: Ruso
  • pt: Portugués
  • th: Tailandés
  • id: Indonesio
  • vi: Vietnamita
  • es: Español
  • it: Italiano
  • ms: Malayo
  • fil: Filipino
  • ar: Árabe
  • other: Otros idiomas (compatibles con qwen-audio-3.1-tts-flash) búlgaro, neerlandés, húngaro, rumano, danés, croata, griego, checo, noruego, sueco, hindi, eslovaco, finés, urdu, serbio, español de México, lituano, letón, turco, persa, hebreo, mongol, esloveno, azerbaiyano, polaco, catalán, jemer, portugués de Brasil, lao, georgiano, afrikáans, nepalí, bielorruso, malabar, luxemburgués, albanés, tamil, cingalés, telugu, estonio, cebuano, bosnio, birmano, armenio, latín, islandés, maltés, suajili, kazajo, criollo seychelense, ucraniano.
instructionstrNoControla las características de la síntesis, como el dialecto, la emoción o el estilo de habla.Para detalles de uso, consulte Control de instrucciones.
enable_aigc_tagboolNoEspecifica si se debe incrustar una marca de agua AIGC en el audio generado. Cuando se establece en true, la marca de agua se incrusta en archivos de audio de formatos compatibles (wav/mp3/opus).Valor predeterminado: false.Configure enable_aigc_tag, aigc_propagator y aigc_propagate_id a través del diccionario parameters:
audio = client.audio.tts.synthesize(
    "Text to synthesize",
    model="qwen-audio-3.0-tts-flash",
    voice="longanhuan_v3.6",
    parameters={
        "enable_aigc_tag": True,
        "aigc_propagator": "your_propagator",
        "aigc_propagate_id": "your_propagate_id"
    },
)
aigc_propagatorstrNoEstablece el campo ContentPropagator en la marca de agua AIGC, identificando al propagador del contenido. Surte efecto solo cuando enable_aigc_tag es true.Valor predeterminado: UID de Alibaba Cloud.Se configura a través del diccionario parameters. Consulte el ejemplo de enable_aigc_tag.
aigc_propagate_idstrNoEstablece el campo PropagateID en la marca de agua AIGC, identificando de manera única una acción de propagación específica. Surte efecto solo cuando enable_aigc_tag es true.Valor predeterminado: El ID de solicitud de la solicitud actual de síntesis de voz.Se configura a través del diccionario parameters. Consulte el ejemplo de enable_aigc_tag.
hot_fixdictNoConfigura correcciones de pronunciación y reemplazos de texto aplicados antes de la síntesis.Parámetros:
  • pronunciation: Pronunciación personalizada. Especifica anotaciones pinyin para palabras con el fin de corregir pronunciaciones predeterminadas inexactas.
  • replace: Reemplazo de texto. Reemplaza palabras específicas con texto de destino antes de la síntesis. El texto reemplazado se utiliza como entrada real de la síntesis.
Ejemplo:
audio = client.audio.tts.synthesize(
    "Text to synthesize",
    model="qwen-audio-3.0-tts-flash",
    voice="your_voice_id", # Voice
    parameters={
        "hot_fix": {
            "pronunciation": [{"weather": "tian1 qi4"}],
            "replace": [{"today": "gold day"}]
        }
    },
)

Sesiones e iteración de eventos

La síntesis por streaming ya no utiliza interfaces de devolución de llamada: el audio y los eventos del servidor se reciben a través de los métodos de iteración de la sesión. stream()/synthesize() no requieren gestión de sesiones. El ciclo de vida de una sesión de streaming bidireccional (client.audio.tts.connect(...)) es: al entrar en el contexto with se abre la conexión automáticamente → múltiples llamadas a send_text() → stop() → leer todos los resultados restantes → al salir del contexto se cierra la conexión automáticamente.

audio_chunks() - iterar datos de audio

Firma del método:
def audio_chunks(self) -> Iterator[bytes]
Valor de retorno: Iterator[bytes] que contiene los fragmentos de datos binarios de audio devueltos uno a uno, en el formato especificado por el parámetro format. Descripción: Itere en el hilo receptor para recibir los datos de audio fragmento a fragmento; se producen múltiples fragmentos durante la síntesis. Escriba los datos en un archivo o envíelos a un dispositivo de reproducción. Solo se permite un lector de events() o audio_chunks() por sesión.

events() - iterar eventos del servidor

Firma del método:
def events(self) -> Generator[Union[Dict, bytes], None, None]
Valor de retorno: Devuelve tanto eventos de respuesta del servidor (dict, que contienen header (información de la solicitud) y payload (información de salida)) como bytes de audio. payload.output contiene el tipo de evento, el texto original y otros detalles. Consulte campo output en eventos de events(). Descripción: Itere las respuestas del servidor en el hilo receptor. Contiene la información de salida de los eventos de síntesis (tipo de evento, texto original, información de la oración); acceda directamente a payload.output para obtener más detalles.

Manejo de errores

Cuando ocurre un error durante la síntesis, la capa WebSocket lanza una excepción DashScopeError y la conexión se cierra automáticamente después de que se lanza la excepción. Utilice try/except en el lado de envío o recepción para capturar y registrar errores para la solución de problemas:
from dashscope.v2 import DashScopeError

try:
    ...
except DashScopeError as e:
    print(e.code, e.message, e.request_id)

Ciclo de vida de la sesión

  • Al entrar en el contexto with se abre la conexión automáticamente (inicialice de antemano los flujos de salida de audio o abra los recursos de archivos).
  • Después de que todo el texto se haya sintetizado y se hayan producido todos los datos de audio, la iteración events()/audio_chunks() finaliza; a continuación se pueden leer métricas de rendimiento como first_package_delay.
  • Al salir del contexto with se cierra la conexión automáticamente (libere después los recursos, como los dispositivos de reproducción de audio).

campo output en eventos de events()

El evento dict devuelto por la iteración events() de la sesión contiene un campo payload.output con información del evento de síntesis. Utilice este campo para rastrear el progreso de la síntesis y recuperar detalles por oración. La estructura del campo output es la siguiente:
CampoTipoDescripción
typestrTipo de evento. Valores: sentence-begin (inicio de síntesis de oración), sentence-synthesis (síntesis de oración en curso) o sentence-end (finalización de síntesis de oración).
original_textstrEl texto original de la oración actual. Se devuelve en los eventos sentence-begin y sentence-end.
sentencedictInformación de la oración. Contiene index (número de secuencia de la oración) y words (lista de palabras con información de marcas de tiempo cuando word_timestamp_enabled está activado).
Ejemplo de mensaje:
{
  "header": {
    "task_id": "xxx",
    "event": "result-generated",
    "attributes": {}
  },
  "payload": {
    "output": {
      "type": "sentence-begin",
      "original_text": "How is the weather today?",
      "sentence": {
        "index": 0,
        "words": []
      }
    }
  }
}
Ejemplo de análisis:
def handle_event(event):
    output = (event.get('payload') or {}).get('output') or {}
    event_type = output.get('type', '')
    original_text = output.get('original_text', '')
    if event_type:
        print(f'Event type: {event_type}, original text: {original_text}')

Ejemplos de código

El SDK admite los siguientes modos de síntesis:
  • No streaming: Una llamada bloqueante que envía el texto completo de una sola vez y devuelve el audio completo directamente. Ideal para la síntesis de voz de texto corto.
  • Streaming unidireccional: Una llamada no bloqueante que envía el texto completo de una sola vez y recibe los datos de audio iterando los fragmentos devueltos por stream. Ideal para la síntesis de voz de texto corto que requiere baja latencia.
  • Streaming bidireccional: Una llamada no bloqueante que envía texto en múltiples segmentos y recibe el flujo de audio sintetizado incrementalmente en tiempo real iterando audio_chunks()/events() de la sesión. Ideal para la síntesis de voz de texto largo que requiere baja latencia.
  • Sin streaming
  • Streaming unidireccional
  • Streaming bidireccional
El texto enviado en una sola llamada no debe exceder los 20,000 caracteres. Superar este límite provoca un error.
Cada llamada a synthesize o stream crea su propia sesión; no es necesario reutilizar instancias.
# coding=utf-8

import os

import dashscope

# Las API Key de las regiones de Singapur y Pekín son diferentes. Obtenga su API Key: https://www.alibabacloud.com/help/model-studio/get-api-key
# Si no se ha configurado la variable de entorno, sustituya la siguiente línea por su API Key de Model Studio: api_key="sk-xxx"
# La siguiente configuración corresponde a la región de Singapur (ap-southeast-1). Sustituya "{WorkspaceId}" por el ID real de su espacio de trabajo. La configuración varía según la región.
client = dashscope.Client(
    api_key=os.environ.get('DASHSCOPE_API_KEY'),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

# Modelo
model = "qwen-audio-3.0-tts-flash"
# Voz
voice = "longanhuan_v3.6"

# Envíe el texto para sintetizar y obtenga el audio binario
audio = client.audio.tts.synthesize("How is the weather today?", model=model, voice=voice)

# Guarde el audio en un archivo local
with open('output.mp3', 'wb') as f:
    f.write(audio)
  • CLI de dashscope
Llamada a través de la línea de comandos dashscope.
export DASHSCOPE_API_KEY="your-api-key"
# Replace {WorkspaceId} with your workspace ID, ap-southeast-1 with your region (e.g., us-east-1, eu-central-1)
export DASHSCOPE_HTTP_BASE_URL="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1"
dashscope speech-synthesis create -m qwen-audio-3.0-tts-flash -t "Hello world" --voice longanhuan_v3.6
El asistente interactivo SDK Expert puede realizar las mismas tareas de desarrollo y solución de problemas mediante lenguaje natural; consulte DashScope SDK Expert.
Para la tabla completa de regiones, consulte Resumen de URL base.