# Clonación de voz TTS Zonos

Zonos por [Zyphra](https://www.zyphra.com/) es un modelo de texto a voz de pesos abiertos de 0,4B parámetros entrenado en más de 200K horas de habla multilingüe. Realiza clonación de voz en zero-shot con solo 2–30 segundos de audio de referencia y ofrece control fino sobre la emoción, la velocidad de habla, la variación de tono y la calidad de audio. La salida es audio de alta fidelidad a 44 kHz. Hay dos variantes de modelo disponibles: Transformer (mejor calidad) y Hybrid/Mamba (inferencia más rápida).

**GitHub:** [Zyphra/Zonos](https://github.com/Zyphra/Zonos) **HuggingFace:** [Zyphra/Zonos-v0.1-transformer](https://huggingface.co/Zyphra/Zonos-v0.1-transformer) **Licencia:** Apache 2.0

## Características clave

* **Clonación de voz desde 2–30 segundos** — no se requiere ajuste fino
* **Salida de alta fidelidad a 44 kHz** — calidad de audio de nivel de estudio
* **Control de emoción** — felicidad, tristeza, ira, miedo, sorpresa, asco mediante vector 8D
* **Velocidad de habla y tono** — control fino e independiente
* **Entradas de prefijo de audio** — permite susurros y otros comportamientos difíciles de clonar
* **Multilingüe** — Inglés, japonés, chino, francés, alemán
* **Dos arquitecturas** — Transformer (calidad) y Hybrid/Mamba (velocidad, \~2× en tiempo real en RTX 4090)
* **Apache 2.0** — gratis para uso personal y comercial

## Requisitos

| Componente | Mínimo             | Recomendado    |
| ---------- | ------------------ | -------------- |
| GPU        | RTX 3080 10 GB     | RTX 4090 24 GB |
| VRAM       | 6 GB (Transformer) | 10 GB+         |
| RAM        | 16 GB              | 32 GB          |
| Disco      | 10 GB              | 20 GB          |
| Python     | 3.10+              | 3.11           |
| CUDA       | 11.8+              | 12.4           |
| Sistema    | espeak-ng          | —              |

**Recomendación de Clore.ai:** RTX 3090 (~~$0.30–1.00/día) para margen cómodo. RTX 4090 (~~$0.50–2.00/día) para el modelo Hybrid y la inferencia más rápida.

## Instalación

```bash
# Instalar dependencia del sistema
apt-get install -y espeak-ng

# Clona e instala
git clone https://github.com/Zyphra/Zonos.git
cd Zonos
pip install -e .

# Para el modelo Hybrid (requiere GPU Ampere+, es decir, serie RTX 3000 o más reciente)
pip install -e ".[compile]"

# Verificar
python -c "from zonos.model import Zonos; print('Zonos listo')"
```

## Inicio rápido

```python
import torch
import torchaudio
from zonos.model import Zonos
from zonos.conditioning import make_cond_dict

# Cargar modelo (descarga los pesos en la primera ejecución)
model = Zonos.from_pretrained("Zyphra/Zonos-v0.1-transformer", device="cuda")

# Cargar audio de referencia para la clonación de voz
wav, sr = torchaudio.load("reference_speaker.wav")
speaker = model.make_speaker_embedding(wav, sr)

# Construir condicionamiento
cond_dict = make_cond_dict(
    text="¡Hola desde Clore.ai! Esta es una demostración de clonación de voz.",
    speaker=speaker,
    language="en-us",
)
conditioning = model.prepare_conditioning(cond_dict)

# Generar
torch.manual_seed(42)
codes = model.generate(conditioning)
wavs = model.autoencoder.decode(codes).cpu()

torchaudio.save("output.wav", wavs[0], model.autoencoder.sampling_rate)
print(f"Saved output.wav at {model.autoencoder.sampling_rate} Hz")
```

## Ejemplos de uso

### Control de emoción

Zonos acepta un vector de emoción de 8 dimensiones: `[felicidad, tristeza, asco, miedo, sorpresa, ira, otro, neutral]`.

```python
import torch
import torchaudio
from zonos.model import Zonos
from zonos.conditioning import make_cond_dict

model = Zonos.from_pretrained("Zyphra/Zonos-v0.1-transformer", device="cuda")

wav, sr = torchaudio.load("speaker_ref.wav")
speaker = model.make_speaker_embedding(wav, sr)

text = "¡No puedo creer lo que acaba de pasar hoy!"

emotions = {
    "happy":   [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    "sad":     [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    "angry":   [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
    "fearful": [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
    "neutral": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
}

for name, emo_vec in emotions.items():
    cond_dict = make_cond_dict(
        text=text,
        speaker=speaker,
        language="en-us",
        emotion=torch.tensor(emo_vec).unsqueeze(0),
    )
    conditioning = model.prepare_conditioning(cond_dict)
    codes = model.generate(conditioning)
    audio = model.autoencoder.decode(codes).cpu()
    torchaudio.save(f"emotion_{name}.wav", audio[0], model.autoencoder.sampling_rate)
    print(f"Generado: {name}")
```

### Control de velocidad de habla y tono

```python
import torch
import torchaudio
from zonos.model import Zonos
from zonos.conditioning import make_cond_dict

model = Zonos.from_pretrained("Zyphra/Zonos-v0.1-transformer", device="cuda")

wav, sr = torchaudio.load("speaker_ref.wav")
speaker = model.make_speaker_embedding(wav, sr)

# Lento y tranquilo
cond_slow = make_cond_dict(
    text="Tómate tu tiempo. No hay prisa en absoluto.",
    speaker=speaker,
    language="en-us",
    speaking_rate=torch.tensor([8.0]),   # menor = más lento
    pitch_std=torch.tensor([20.0]),      # menor = más monótono
)
codes = model.generate(model.prepare_conditioning(cond_slow))
audio = model.autoencoder.decode(codes).cpu()
torchaudio.save("slow_calm.wav", audio[0], model.autoencoder.sampling_rate)

# Rápido y enérgico
cond_fast = make_cond_dict(
    text="¡Date prisa! ¡Tenemos que irnos ahora mismo!",
    speaker=speaker,
    language="en-us",
    speaking_rate=torch.tensor([22.0]),  # mayor = más rápido
    pitch_std=torch.tensor([80.0]),      # mayor = más expresivo
)
codes = model.generate(model.prepare_conditioning(cond_fast))
audio = model.autoencoder.decode(codes).cpu()
torchaudio.save("fast_energetic.wav", audio[0], model.autoencoder.sampling_rate)
```

### Interfaz web Gradio

```bash
cd Zonos
python gradio_interface.py
# O con uv:
# uv run gradio_interface.py
```

Exponer puerto `7860/http` en tu pedido de Clore.ai y abre la `http_pub` URL para acceder a la interfaz.

## Consejos para usuarios de Clore.ai

* **Elección de modelo** — Transformer para la mejor calidad, Hybrid para \~2× inferencia más rápida (requiere GPU RTX 3000+)
* **Audio de referencia** — 10–30 segundos de habla limpia dan mejores resultados; clips más cortos (2–5s) funcionan pero con menor fidelidad
* **Configuración con Docker** — usar `pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime`, agrega `apt-get install -y espeak-ng` al inicio
* **Mapeo de puertos** — exponer `7860/http` para la interfaz Gradio, `8000/http` para el servidor API
* **Control de semilla** — establece `torch.manual_seed()` antes de la generación para salida reproducible
* **Parámetro de calidad de audio** — experimenta con el `audio_quality` campo de condicionamiento para una salida más limpia

## Solución de problemas

| Problema                     | Solución                                                                                        |
| ---------------------------- | ----------------------------------------------------------------------------------------------- |
| `espeak-ng no encontrado`    | Ejecuta `apt-get install -y espeak-ng` (requerido para la fonemización)                         |
| `CUDA fuera de memoria`      | Usa el modelo Transformer (más pequeño que Hybrid); reduce la longitud de texto por llamada     |
| El modelo Hybrid falla       | Requiere GPU Ampere+ (serie RTX 3000 o más reciente) y `pip install -e ".[compile]"`            |
| La voz clonada suena extraña | Usa un clip de referencia más largo (15–30s) con habla clara y ruido de fondo mínimo            |
| Generación lenta             | Normal para Transformer (\~0.5× en tiempo real); Hybrid alcanza \~2× en tiempo real en RTX 4090 |
| `ModuleNotFoundError: zonos` | Asegúrate de haber instalado desde la fuente: `cd Zonos && pip install -e .`                    |
