# Voz conversacional ChatTTS

ChatTTS es un modelo generativo de voz de 300 millones de parámetros optimizado para escenarios de diálogo como asistentes LLM, chatbots y aplicaciones de voz interactivas. Produce una voz de sonido natural con pausas realistas, risas, muletillas e entonación — características que la mayoría de los sistemas TTS tienen dificultades para reproducir. El modelo admite inglés y chino y genera audio a 24 kHz.

**GitHub:** [2noise/ChatTTS](https://github.com/2noise/ChatTTS) (30K+ estrellas) **Licencia:** AGPLv3+ (código), CC BY-NC 4.0 (pesos del modelo — no comercial)

## Características clave

* **Prosodia conversacional** — pausas naturales, muletillas y entonación afinadas para diálogo
* **Etiquetas de control de grano fino** — `[oral_0-9]`, `[laugh_0-2]`, `[break_0-7]`, `[uv_break]`, `[lbreak]`
* **Multivoz** — muestrea hablantes aleatorios o reutiliza embeddings de hablante para consistencia
* **Temperatura / top-P / top-K** — controlar la diversidad de la generación
* **Inferencia por lotes** — sintetiza múltiples textos en una sola llamada
* **Ligero** — \~300M de parámetros, funciona con 4 GB de VRAM

## Requisitos

| Componente | Mínimo                 | Recomendado         |
| ---------- | ---------------------- | ------------------- |
| GPU        | RTX 3060 (4 GB libres) | RTX 3090 / RTX 4090 |
| VRAM       | 4 GB                   | 8 GB+               |
| RAM        | 8 GB                   | 16 GB               |
| Disco      | 5 GB                   | 10 GB               |
| Python     | 3.9+                   | 3.11                |
| CUDA       | 11.8+                  | 12.1+               |

**Recomendación de Clore.ai:** Una RTX 3060 (~~$0.15–0.30/día) maneja ChatTTS con comodidad. Para producción por lotes o menor latencia, elige una RTX 3090 (~~$0.30–1.00/día).

## Instalación

```bash
# Instalar desde PyPI
pip install ChatTTS torch torchaudio

# O instala desde la fuente para las últimas funciones
git clone https://github.com/2noise/ChatTTS.git
cd ChatTTS
pip install -r requirements.txt

# Verificar GPU
python -c "import torch; print(torch.cuda.get_device_name(0))"
```

## Inicio rápido

```python
import ChatTTS
import torch
import torchaudio

# Inicializa y carga el modelo (descarga los pesos en la primera ejecución)
chat = ChatTTS.Chat()
chat.load(compile=False)  # Establece compile=True para inferencia más rápida después del calentamiento

texts = [
    "¡Hola! ¿Cómo va tu día hasta ahora?",
    "He estado trabajando en este proyecto toda la mañana. Va muy bien.",
]

wavs = chat.infer(texts)

for i, wav in enumerate(wavs):
    audio_tensor = torch.from_numpy(wav)
    if audio_tensor.dim() == 1:
        audio_tensor = audio_tensor.unsqueeze(0)
    torchaudio.save(f"output_{i}.wav", audio_tensor, 24000)
    print(f"Guardado output_{i}.wav")
```

## Ejemplos de uso

### Voz de hablante consistente

Muestra un embedding de hablante aleatorio y reutilízalo en múltiples generaciones para una voz consistente:

```python
import ChatTTS
import torch
import torchaudio

chat = ChatTTS.Chat()
chat.load(compile=False)

# Muestra un hablante — guarda esta cadena para reutilizarla más tarde
rand_spk = chat.sample_random_speaker()

params_infer_code = ChatTTS.Chat.InferCodeParams(
    spk_emb=rand_spk,
    temperature=0.3,
    top_P=0.7,
    top_K=20,
)

params_refine_text = ChatTTS.Chat.RefineTextParams(
    prompt='[oral_2][laugh_0][break_4]',
)

texts = ["Bienvenidos al episodio de hoy. Permítanme contarles algo emocionante."]

wavs = chat.infer(
    texts,
    params_refine_text=params_refine_text,
    params_infer_code=params_infer_code,
)

audio = torch.from_numpy(wavs[0])
if audio.dim() == 1:
    audio = audio.unsqueeze(0)
torchaudio.save("consistent_speaker.wav", audio, 24000)
```

### Etiquetas de control a nivel de palabra

Inserta etiquetas de control directamente en el texto para una prosodia precisa:

```python
import ChatTTS
import torch
import torchaudio

chat = ChatTTS.Chat()
chat.load(compile=False)

# Etiquetas: [uv_break] = pausa corta, [laugh] = risa, [lbreak] = pausa larga
text = '¿Cuál es [uv_break]tu comida favorita?[laugh][lbreak]'

rand_spk = chat.sample_random_speaker()
params = ChatTTS.Chat.InferCodeParams(spk_emb=rand_spk, temperature=0.3)

# skip_refine_text=True preserva tus etiquetas de control manuales
wavs = chat.infer(text, skip_refine_text=True, params_infer_code=params)

audio = torch.from_numpy(wavs[0])
if audio.dim() == 1:
    audio = audio.unsqueeze(0)
torchaudio.save("controlled_output.wav", audio, 24000)
```

### Procesamiento por lotes con WebUI

ChatTTS incluye una interfaz web Gradio para uso interactivo:

```bash
cd ChatTTS
python examples/web/webui.py --server_name 0.0.0.0 --server_port 7860
```

Abre el `http_pub` URL desde el panel de pedidos de Clore.ai para acceder a la interfaz.

## Consejos para usuarios de Clore.ai

* **Usa `compile=True`** después de las pruebas iniciales — la compilación de PyTorch añade tiempo de inicio pero acelera significativamente la inferencia repetida
* **Mapeo de puertos** — exponer puerto `7860/http` al desplegar con la WebUI
* **Imagen Docker** — usar `pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime` como base
* **Persistencia de hablante** — guardar `rand_spk` cadenas en un archivo para que puedas reutilizar voces entre sesiones sin volver a muestrear
* **Agrupa tus solicitudes** — `chat.infer()` acepta una lista de textos y los procesa juntos, lo cual es más eficiente que llamadas una por una
* **Licencia no comercial** — los pesos del modelo son CC BY-NC 4.0; verifica los requisitos de licencia para tu caso de uso

## Solución de problemas

| Problema                             | Solución                                                                                                                       |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `CUDA fuera de memoria`              | Reduce el tamaño del lote o usa una GPU con ≥ 6 GB de VRAM                                                                     |
| El modelo se descarga lentamente     | Pre-descarga desde HuggingFace: `huggingface-cli download 2Noise/ChatTTS`                                                      |
| El audio tiene estática/ruido        | Esto es intencional en el modelo de código abierto (medida anti-abuso); usa `compile=True` para una salida más limpia          |
| `torchaudio.save` error de dimensión | Asegúrate de que el tensor sea 2D: `audio.unsqueeze(0)` si es necesario                                                        |
| Salida en chino distorsionada        | Asegúrate de que el texto de entrada esté codificado en UTF-8; instala `WeTextProcessing` para una mejor normalización         |
| Primera inferencia lenta             | Normal — la compilación del modelo y la carga de pesos ocurren en la primera llamada; las llamadas posteriores son más rápidas |
