# Clonación de voz RVC

Clona y convierte voces usando Conversion de Voz basada en Recuperación.

{% hint style="success" %}
Todos los ejemplos pueden ejecutarse en servidores GPU alquilados a través de [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

## Alquiler en CLORE.AI

1. Visitar [CLORE.AI Marketplace](https://clore.ai/marketplace)
2. Filtrar por tipo de GPU, VRAM y precio
3. Elegir **Bajo demanda** (tarifa fija) o **Spot** (precio de oferta)
4. Configura tu pedido:
   * Selecciona la imagen de Docker
   * Configura los puertos (TCP para SSH, HTTP para interfaces web)
   * Agrega variables de entorno si es necesario
   * Introduce el comando de inicio
5. Selecciona el pago: **CLORE**, **BTC**, o **USDT/USDC**
6. Crea el pedido y espera el despliegue

### Accede a tu servidor

* Encuentra los detalles de conexión en **Mis Pedidos**
* Interfaces web: Usa la URL del puerto HTTP
* SSH: `ssh -p <port> root@<proxy-address>`

## ¿Qué es RVC?

RVC (Conversion de Voz basada en Recuperación) puede:

* Clonar cualquier voz con entrenamiento mínimo
* Convertir voces cantadas/habladas
* Conversión de voz en tiempo real
* Salida de alta calidad

## Requisitos

| Tarea         | VRAM mínima | Recomendado |
| ------------- | ----------- | ----------- |
| Inferencia    | 4GB         | RTX 3060    |
| Entrenamiento | 8GB         | RTX 3090    |
| Tiempo real   | 6GB         | RTX 3070    |

## Despliegue rápido

**Imagen de Docker:**

```
pytorch/pytorch:2.5.1-cuda12.4-cudnn9-devel
```

**Puertos:**

```
22/tcp
7865/http
```

**Comando:**

```bash
apt-get update && apt-get install -y ffmpeg git && \
cd /workspace && \
git clone https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI.git && \
cd Retrieval-based-Voice-Conversion-WebUI && \
pip install -r requirements.txt && \
python infer-web.py --host 0.0.0.0 --port 7865
```

## Accediendo a tu servicio

Después del despliegue, encuentra tu `http_pub` URL en **Mis Pedidos**:

1. Ir a **Mis Pedidos** página
2. Haz clic en tu pedido
3. Encuentra la `http_pub` URL (por ejemplo, `abc123.clorecloud.net`)

Usa `https://YOUR_HTTP_PUB_URL` en lugar de `localhost` en los ejemplos a continuación.

## Instalación

```bash

# Clonar repositorio
git clone https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI.git
cd Retrieval-based-Voice-Conversion-WebUI

# Instalar dependencias
pip install -r requirements.txt

# Descargar modelos
python tools/download_models.py
```

## Conversión de Voz (Inferencia)

### Usando la interfaz web

1. Abrir `http://<proxy>:7865`
2. Ir a la pestaña "Model Inference"
3. Subir archivo de audio
4. Seleccionar modelo de voz
5. Ajustar configuraciones
6. Hacer clic en "Convert"

### API de Python

```python
from infer_pack.models import SynthesizerTrnMs256NSFsid, SynthesizerTrnMs768NSFsid
from vc_infer_pipeline import VC
import torch
import soundfile as sf

# Cargar modelo
model_path = "./models/my_voice.pth"
index_path = "./models/my_voice.index"

vc = VC(
    model_path=model_path,
    config_path="./configs/v2/48k.json",
    device="cuda"
)

# Convertir audio
audio, sr = sf.read("input.wav")
output = vc.convert(
    audio=audio,
    f0_method="rmvpe",  # Método de extracción de tono
    index_path=index_path,
    index_rate=0.75,
    f0_up_key=0,  # Cambio de tono (semitonos)
    protect=0.33
)

sf.write("output.wav", output, sr)
```

## Entrenamiento de Voz Personalizada

### Preparar conjunto de datos

1. Recopila 10-30 minutos de audio limpio
2. Corta en clips de 5-15 segundos
3. Elimina ruido de fondo/música

```bash

# Dividir audio en clips
ffmpeg -i full_audio.mp3 -f segment -segment_time 10 -c copy clips/clip_%03d.mp3
```

### Entrenar vía interfaz web

1. Ir a la pestaña "Train"
2. Introduce el nombre del experimento
3. Configura la ruta de la carpeta de entrenamiento
4. Haz clic en "Process data"
5. Haz clic en "Feature extraction"
6. Haz clic en "Train"

### Entrenar vía línea de comandos

```bash

# Paso 1: Procesar audio
python trainset_preprocess_pipeline_print.py \
    "./dataset" \
    48000 \
    8 \
    "./logs/experiment" \
    False

# Paso 2: Extraer características
python extract_f0_print.py \
    "./logs/experiment" \
    8 \
    "rmvpe"

python extract_feature_print.py \
    "cuda:0" \
    "1" \
    "0" \
    "0" \
    "./logs/experiment" \
    "v2"

# Paso 3: Entrenar
python train_nsf_sim_cache_sid_load_pretrain.py \
    -e "experiment" \
    -sr "48k" \
    -f0 1 \
    -bs 8 \
    -g 0 \
    -te 200 \
    -se 20 \
    -pg "./pretrained/f0G48k.pth" \
    -pd "./pretrained/f0D48k.pth" \
    -l 0 \
    -c 1 \
    -sw 0 \
    -v "v2"
```

## Parámetros de Entrenamiento

| Parámetro              | Descripción                  | Recomendado |
| ---------------------- | ---------------------------- | ----------- |
| Frecuencia de muestreo | Calidad de audio             | 48000       |
| Tamaño de lote         | Lote de entrenamiento        | 8-16        |
| Épocas                 | Iteraciones de entrenamiento | 200-500     |
| Guardar cada           | Frecuencia de checkpoints    | 20-50       |
| Método f0              | Extracción de tono           | rmvpe       |

## Métodos F0

| Método  | Calidad | Velocidad | Mejor para |
| ------- | ------- | --------- | ---------- |
| pm      | OK      | Rápido    | Pruebas    |
| harvest | Bueno   | Lento     | General    |
| crepe   | Genial  | Medio     | Canto      |
| rmvpe   | Mejor   | Medio     | Todo       |

## Conversión en tiempo real

### Configuración

```python
import pyaudio
import numpy as np
from infer_pack.models import SynthesizerTrnMs256NSFsid
from vc_infer_pipeline import VC

# Inicializar
vc = VC(model_path="./models/voice.pth", device="cuda")

# Configuración de audio
CHUNK = 1024
FORMAT = pyaudio.paFloat32
CHANNELS = 1
RATE = 48000

p = pyaudio.PyAudio()
stream_in = p.open(format=FORMAT, channels=CHANNELS, rate=RATE,
                   input=True, frames_per_buffer=CHUNK)
stream_out = p.open(format=FORMAT, channels=CHANNELS, rate=RATE,
                    output=True, frames_per_buffer=CHUNK)

# Bucle en tiempo real
while True:
    audio_in = np.frombuffer(stream_in.read(CHUNK), dtype=np.float32)
    audio_out = vc.convert(audio_in)
    stream_out.write(audio_out.tobytes())
```

## Formatos de modelo

### Convertir a ONNX

```python
import torch

# Cargar modelo de PyTorch
model = torch.load("model.pth")

# Exportar a ONNX
torch.onnx.export(
    model,
    dummy_input,
    "model.onnx",
    input_names=["audio"],
    output_names=["converted"],
    dynamic_axes={"audio": {0: "length"}}
)
```

## Preprocesamiento de audio

### Eliminar ruido

```python
import noisereduce as nr
import soundfile as sf

audio, sr = sf.read("noisy.wav")
reduced_noise = nr.reduce_noise(y=audio, sr=sr)
sf.write("clean.wav", reduced_noise, sr)
```

### Normalizar volumen

```python
from pydub import AudioSegment

audio = AudioSegment.from_wav("input.wav")
normalized = audio.normalize()
normalized.export("normalized.wav", format="wav")
```

### Eliminar silencio

```python
from pydub import AudioSegment
from pydub.silence import split_on_silence

audio = AudioSegment.from_wav("input.wav")
chunks = split_on_silence(audio, min_silence_len=500, silence_thresh=-40)
combined = sum(chunks)
combined.export("no_silence.wav", format="wav")
```

## Procesamiento por lotes

```python
import os
from vc_infer_pipeline import VC
import soundfile as sf

vc = VC(model_path="./models/voice.pth", device="cuda")

input_dir = "./inputs"
output_dir = "./outputs"
os.makedirs(output_dir, exist_ok=True)

for filename in os.listdir(input_dir):
    if filename.endswith(('.wav', '.mp3', '.flac')):
        input_path = os.path.join(input_dir, filename)
        output_path = os.path.join(output_dir, f"converted_{filename}")

        audio, sr = sf.read(input_path)
        converted = vc.convert(audio)
        sf.write(output_path, converted, sr)

        print(f"Converted: {filename}")
```

## Conversión de voz para canto

Para canciones, usa configuraciones apropiadas:

```python
output = vc.convert(
    audio=audio,
    f0_method="rmvpe",  # Mejor para canto
    index_rate=0.5,     # Más bajo para canto
    f0_up_key=-2,       # Ajustar el tono para que coincida
    protect=0.5         # Proteger consonantes
)
```

## Problemas comunes

### La voz suena robótica

* Usa audio fuente de mayor calidad
* Aumenta el valor de protect (0.4-0.5)
* Prueba un método f0 diferente

### Problemas de tono

* Ajusta f0\_up\_key
* Usa el método f0 rmvpe
* Asegura un tono consistente en los datos de entrenamiento

### Calidad de audio

* Usa frecuencia de muestreo de 48 kHz
* Elimina ruido de fondo de los datos de entrenamiento
* Entrena por más épocas

## Servidor API

```python
from fastapi import FastAPI, UploadFile
from fastapi.responses import FileResponse
from vc_infer_pipeline import VC
import soundfile as sf
import tempfile

app = FastAPI()
vc = VC(model_path="./models/voice.pth", device="cuda")

@app.post("/convert")
async def convert_voice(file: UploadFile, pitch: int = 0):
    with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp_in:
        content = await file.read()
        tmp_in.write(content)
        tmp_in_path = tmp_in.name

    audio, sr = sf.read(tmp_in_path)
    converted = vc.convert(audio, f0_up_key=pitch)

    with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp_out:
        sf.write(tmp_out.name, converted, sr)
        return FileResponse(tmp_out.name, media_type="audio/wav")
```

## Consejos de entrenamiento

### Para mejor calidad

* Usa más de 20 minutos de audio limpio
* Elimina todo el ruido de fondo
* Configuración de micrófono/grabación consistente
* Incluye expresiones/emociones variadas

### Para entrenamiento más rápido

* Usa tamaño de lote 8-16
* Habilita precisión mixta
* Usa SSD NVMe para el conjunto de datos

## Rendimiento

| Tarea                              | GPU      | Tiempo         |
| ---------------------------------- | -------- | -------------- |
| Inferencia (1 min de audio)        | RTX 3090 | \~5s           |
| Entrenamiento (conjunto de 30 min) | RTX 3090 | \~2 horas      |
| Conversión en tiempo real          | RTX 3070 | latencia <50ms |

## Solución de problemas

## Estimación de costos

Tarifas típicas del marketplace de CLORE.AI (a fecha de 2024):

| GPU       | Tarifa por hora | Tarifa diaria | Sesión de 4 horas |
| --------- | --------------- | ------------- | ----------------- |
| RTX 3060  | \~$0.03         | \~$0.70       | \~$0.12           |
| RTX 3090  | \~$0.06         | \~$1.50       | \~$0.25           |
| RTX 4090  | \~$0.10         | \~$2.30       | \~$0.40           |
| A100 40GB | \~$0.17         | \~$4.00       | \~$0.70           |
| A100 80GB | \~$0.25         | \~$6.00       | \~$1.00           |

*Los precios varían según el proveedor y la demanda. Consulta* [*CLORE.AI Marketplace*](https://clore.ai/marketplace) *para tarifas actuales.*

**Ahorra dinero:**

* Usa **Spot** mercado para cargas de trabajo flexibles (a menudo 30-50% más barato)
* Paga con **CLORE** tokens
* Compara precios entre distintos proveedores

## Próximos pasos

* [Bark TTS](https://docs.clore.ai/guides/guides_v2-es/audio-y-voz/bark-tts) - Texto a voz
* [AudioCraft Music](https://docs.clore.ai/guides/guides_v2-es/audio-y-voz/audiocraft-music) - Generación de música
* [Whisper Transcription](https://docs.clore.ai/guides/guides_v2-es/audio-y-voz/whisper-transcription) - Voz a texto
