# Transcripción con Whisper

Transcribe archivos de audio y video usando Whisper de OpenAI en GPUs de CLORE.AI.

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

## Requisitos del servidor

| Parámetro        | Mínimo        | Recomendado      |
| ---------------- | ------------- | ---------------- |
| RAM              | 8GB           | 16GB+            |
| VRAM             | 4GB (pequeño) | 10GB+ (large-v3) |
| Red              | 200Mbps       | 500Mbps+         |
| Tiempo de inicio | \~1-2 minutos | -                |

## ¿Qué es Whisper?

OpenAI Whisper es un modelo de reconocimiento de voz que puede:

* Transcribir audio en 99 idiomas
* Traducir al inglés
* Generar marcas de tiempo
* Manejar audio con ruido

## Tamaños de modelos

| Modelo             | VRAM    | Velocidad            | Calidad   | Notas                                           |
| ------------------ | ------- | -------------------- | --------- | ----------------------------------------------- |
| tiny               | 1GB     | \~32x tiempo real    | Básico    | Más rápido, menor precisión                     |
| base               | 1GB     | \~16x tiempo real    | Bueno     | Buen equilibrio para tareas rápidas             |
| small              | 2GB     | \~6x tiempo real     | Mejor     | Recomendado para la mayoría de los casos de uso |
| medium             | 5GB     | \~2x tiempo real     | Genial    | Alta precisión, velocidad moderada              |
| large-v3           | 10GB    | \~1x tiempo real     | Mejor     | Mayor precisión                                 |
| **large-v3-turbo** | **6GB** | **\~8x tiempo real** | **Mejor** | **8x más rápido que large-v3, calidad similar** |

> **💡 Recomendación:** Usa `large-v3-turbo` para la mejor relación velocidad/calidad. Ofrece una precisión comparable a `large-v3` a 8x la velocidad con requisitos de VRAM más bajos.

### Usando large-v3-turbo

```python
import whisper

# Cargar large-v3-turbo (8x más rápido que large-v3, calidad similar)
model = whisper.load_model("large-v3-turbo", device="cuda")

result = model.transcribe("audio.mp3")
print(result["text"])
```

Con Faster-Whisper:

```python
from faster_whisper import WhisperModel

# large-v3-turbo vía faster-whisper
model = WhisperModel("deepdml/faster-whisper-large-v3-turbo-ct2", device="cuda", compute_type="float16")
segments, info = model.transcribe("audio.mp3")

for segment in segments:
    print(f"[{segment.start:.2f}s -> {segment.end:.2f}s] {segment.text}")
```

***

## WhisperX: Alternativa mejorada

Para **marcas de tiempo a nivel de palabra**, **diarización de hablantes**, y **hasta 70x más rápido** procesamiento, considera [WhisperX](https://docs.clore.ai/guides/guides_v2-es/audio-y-voz/whisperx):

```bash
pip install whisperx
```

```python
import whisperx

model = whisperx.load_model("large-v3-turbo", device="cuda", compute_type="float16")
audio = whisperx.load_audio("audio.mp3")
result = model.transcribe(audio, batch_size=16)

# Alineación a nivel de palabra
model_a, metadata = whisperx.load_align_model(language_code=result["language"], device="cuda")
result = whisperx.align(result["segments"], model_a, metadata, audio, device="cuda")

# result["word_segments"] contiene marcas de tiempo a nivel de palabra
```

➡️ Ver la guía completa [de WhisperX](https://docs.clore.ai/guides/guides_v2-es/audio-y-voz/whisperx) para diarización de hablantes y funciones avanzadas.

## Despliegue rápido (Recomendado)

Usa el servidor Faster-Whisper preconstruido para despliegue instantáneo:

**Imagen Docker:**

```
fedirz/faster-whisper-server:latest-cuda
```

**Puertos:**

```
22/tcp
8000/http
```

**No se necesita comando** - el servidor se inicia automáticamente.

### Verificar que funciona

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

```bash
curl https://your-http-pub.clorecloud.net/

# Esperado: respuesta JSON con info del servidor
```

{% hint style="warning" %}
Si obtienes HTTP 502, espera 1-2 minutos: el servicio aún se está iniciando.
{% endhint %}

### Transcribir vía API

```bash
# Transcribir archivo de audio
curl -X POST https://your-http-pub.clorecloud.net/v1/audio/transcriptions \
  -F "file=@audio.mp3" \
  -F "model=Systran/faster-whisper-large-v3" \
  -F "response_format=json"

# Con marcas de tiempo
curl -X POST https://your-http-pub.clorecloud.net/v1/audio/transcriptions \
  -F "file=@audio.mp3" \
  -F "model=Systran/faster-whisper-large-v3" \
  -F "response_format=verbose_json" \
  -F "timestamp_granularities[]=word"
```

## Referencia completa de la API (Faster-Whisper-Server)

### Endpoints

| Endpoint                   | Método | Descripción                                    |
| -------------------------- | ------ | ---------------------------------------------- |
| `/v1/audio/transcriptions` | POST   | Transcribir audio (compatible con OpenAI)      |
| `/v1/audio/translations`   | POST   | Traducir audio al inglés                       |
| `/v1/models`               | GET    | Listar todos los modelos disponibles           |
| `/v1/models/{model_name}`  | GET    | Obtener información de un modelo específico    |
| `/api/ps`                  | GET    | Listar modelos actualmente cargados            |
| `/api/ps/{model_name}`     | GET    | Verificar si un modelo específico está cargado |
| `/api/pull/{model_name}`   | POST   | Descargar y cargar un modelo                   |
| `/health`                  | GET    | Endpoint de verificación de estado             |
| `/docs`                    | GET    | Documentación Swagger UI                       |
| `/openapi.json`            | GET    | Especificación OpenAPI                         |

#### Listar modelos disponibles

```bash
curl https://your-http-pub.clorecloud.net/v1/models
```

Respuesta:

```json
{
  "data": [
    {"id": "Systran/faster-whisper-large-v3", "object": "model"},
    {"id": "Systran/faster-whisper-medium", "object": "model"}
  ]
}
```

#### Documentación Swagger

Abrir en el navegador para pruebas interactivas de la API:

```
https://your-http-pub.clorecloud.net/docs
```

### Opciones de transcripción

| Parámetro                   | Tipo    | Descripción                                                       |
| --------------------------- | ------- | ----------------------------------------------------------------- |
| `file`                      | Archivo | Archivo de audio para transcribir                                 |
| `model`                     | Cadena  | Modelo a usar (predeterminado: `Systran/faster-whisper-large-v3`) |
| `language`                  | Cadena  | Forzar un idioma específico (p. ej., `en`, `ja`, `ru`)            |
| `response_format`           | Cadena  | `json`, `text`, `srt`, `vtt`, `verbose_json`                      |
| `temperature`               | Float   | Temperatura de muestreo (0.0-1.0)                                 |
| `timestamp_granularities[]` | Array   | `word` o `segment` para marcas de tiempo                          |

#### Formatos de respuesta

**JSON (predeterminado):**

```json
{"text": "Texto transcrito aquí..."}
```

**JSON detallado:**

```json
{
  "text": "Transcripción completa...",
  "segments": [
    {"start": 0.0, "end": 2.5, "text": "Primer segmento"},
    {"start": 2.5, "end": 5.0, "text": "Segundo segmento"}
  ],
  "language": "en"
}
```

**SRT:**

```
1
00:00:00,000 --> 00:00:02,500
Primer segmento

2
00:00:02,500 --> 00:00:05,000
Segundo segmento
```

## Alternativa: Instalación manual

Si necesitas más control, despliega con instalación manual:

**Imagen Docker:**

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

**Puertos:**

```
22/tcp
```

**Comando:**

```bash
pip install openai-whisper faster-whisper
```

{% hint style="info" %}
La instalación manual toma 3-5 minutos. La imagen preconstruida anterior es recomendada para un inicio más rápido.
{% endhint %}

## Uso básico (SSH)

```bash
ssh -p <port> root@<proxy>

# Transcribir archivo de audio
whisper audio.mp3 --model large-v3 --device cuda

# Salida a un formato específico
whisper audio.mp3 --model large-v3 --output_format txt

# Especificar idioma
whisper audio.mp3 --model large-v3 --language Japanese
```

### Transcribir con marcas de tiempo

```bash
whisper audio.mp3 --model large-v3 --word_timestamps True
```

## Subir archivos de audio

```bash
# Subir un archivo único
scp -P <port> interview.mp3 root@<proxy>:/workspace/

# Subir carpeta
scp -P <port> -r ./audio_files/ root@<proxy>:/workspace/
```

## API de Python

```python
import whisper

# Cargar modelo (se descarga en el primer uso)
model = whisper.load_model("large-v3", device="cuda")

# Transcribir
result = model.transcribe("audio.mp3")

# Imprimir texto
print(result["text"])

# Imprimir con marcas de tiempo
for segment in result["segments"]:
    print(f"[{segment['start']:.2f}s -> {segment['end']:.2f}s] {segment['text']}")
```

## Faster-Whisper (Recomendado)

Faster-Whisper es 4x más rápido con menor uso de VRAM:

```bash
pip install faster-whisper
```

```python
from faster_whisper import WhisperModel

# Cargar modelo con optimizaciones
model = WhisperModel("large-v3", device="cuda", compute_type="float16")

# Transcribir
segments, info = model.transcribe("audio.mp3")

print(f"Idioma detectado: {info.language}")
for segment in segments:
    print(f"[{segment.start:.2f}s -> {segment.end:.2f}s] {segment.text}")
```

## Opciones de idioma

```python
from faster_whisper import WhisperModel

model = WhisperModel("large-v3", device="cuda")

# Detección automática de idioma
segments, info = model.transcribe("audio.mp3")
print(f"Idioma: {info.language} ({info.language_probability:.0%})")

# Forzar un idioma específico
segments, _ = model.transcribe("audio.mp3", language="ja")
```

## Traducción al inglés

```python
from faster_whisper import WhisperModel

model = WhisperModel("large-v3", device="cuda")
segments, _ = model.transcribe("japanese.mp3", task="translate")

for segment in segments:
    print(segment.text)
```

CLI:

```bash
whisper japanese.mp3 --model large-v3 --task translate
```

## Generación de subtítulos

### Formato SRT

```python
from faster_whisper import WhisperModel

def format_timestamp(seconds):
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    secs = int(seconds % 60)
    millis = int((seconds - int(seconds)) * 1000)
    return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"

model = WhisperModel("large-v3", device="cuda")
segments, _ = model.transcribe("video.mp4")

with open("subtitles.srt", "w") as f:
    for i, segment in enumerate(segments, 1):
        f.write(f"{i}\n")
        f.write(f"{format_timestamp(segment.start)} --> {format_timestamp(segment.end)}\n")
        f.write(f"{segment.text.strip()}\n\n")
```

### Formato VTT

```bash
whisper video.mp4 --model large-v3 --output_format vtt
```

## Marcas de tiempo a nivel de palabra

```python
from faster_whisper import WhisperModel

model = WhisperModel("large-v3", device="cuda")

segments, _ = model.transcribe("audio.mp3", word_timestamps=True)

for segment in segments:
    for word in segment.words:
        print(f"[{word.start:.2f}s] {word.word}")
```

## Diarización de hablantes

Quién dijo qué (requiere pyannote):

```bash
pip install pyannote.audio
```

```python
from faster_whisper import WhisperModel
from pyannote.audio import Pipeline

# Diarización
diarization = Pipeline.from_pretrained(
    "pyannote/speaker-diarization-3.1",
    use_auth_token="YOUR_HF_TOKEN"
)
diarization_result = diarization("audio.mp3")

# Transcripción
whisper = WhisperModel("large-v3", device="cuda")
segments, _ = whisper.transcribe("audio.mp3")

# Combinar
for segment in segments:
    # Encontrar hablante en el tiempo del segmento
    speaker = None
    for turn, _, spk in diarization_result.itertracks(yield_label=True):
        if turn.start <= segment.start <= turn.end:
            speaker = spk
            break
    print(f"[{speaker}] {segment.text}")
```

## Servidor REST API

Crear una API de transcripción:

```python
from fastapi import FastAPI, UploadFile
from faster_whisper import WhisperModel
import tempfile

app = FastAPI()
model = WhisperModel("large-v3", device="cuda", compute_type="float16")

@app.post("/transcribe")
async def transcribe(file: UploadFile):
    with tempfile.NamedTemporaryFile(delete=False) as tmp:
        tmp.write(await file.read())
        tmp_path = tmp.name

    segments, info = model.transcribe(tmp_path)

    return {
        "language": info.language,
        "text": " ".join([s.text for s in segments]),
        "segments": [
            {"start": s.start, "end": s.end, "text": s.text}
            for s in segments
        ]
    }

# Ejecutar: uvicorn server:app --host 0.0.0.0 --port 8000
```

## Benchmarks de rendimiento

| Modelo   | GPU      | Audio de 1 hora |
| -------- | -------- | --------------- |
| large-v3 | RTX 3090 | \~5 min         |
| large-v3 | RTX 4090 | \~3 min         |
| large-v3 | A100     | \~2 min         |
| medium   | RTX 3090 | \~2 min         |

## Procesamiento eficiente en memoria

Para audio muy largo:

```python
from faster_whisper import WhisperModel

model = WhisperModel("large-v3", device="cuda", compute_type="int8")

# Procesar en fragmentos
segments, _ = model.transcribe(
    "long_audio.mp3",
    vad_filter=True,  # Omitir silencio
    vad_parameters=dict(min_silence_duration_ms=500)
)
```

## Descargar resultados

```bash
# Descargar transcripciones
scp -P <port> -r root@<proxy>:/workspace/transcripts/ ./

# Descargar subtítulos
scp -P <port> root@<proxy>:/workspace/subtitles.srt ./
```

## Solución de problemas

{% hint style="danger" %}
**CUDA fuera de memoria**
{% endhint %}

* Usar un modelo más pequeño (medium en lugar de large)
* Usa `compute_type="int8"` para faster-whisper
* Procesar segmentos de audio más cortos

### HTTP 502 en la URL http\_pub

El servicio todavía se está iniciando. Espera 1-2 minutos y reintenta:

```bash
curl https://your-http-pub.clorecloud.net/
```

### Precisión baja

* Usa un modelo más grande
* Especifica el idioma: `--language English`
* Aumenta beam\_size para faster-whisper

### Procesamiento lento

* Asegúrate de que se use la GPU: `nvidia-smi`
* Usa faster-whisper en lugar del original
* Habilita VAD para omitir silencios

## Estimación de costos

Tarifas típicas del mercado de CLORE.AI:

| GPU      | VRAM | Precio/día | Bueno para              |
| -------- | ---- | ---------- | ----------------------- |
| RTX 3060 | 12GB | $0.15–0.30 | modelos small/medium    |
| RTX 3090 | 24GB | $0.30–1.00 | large-v3                |
| RTX 4090 | 24GB | $0.50–2.00 | large-v3, rápido        |
| A100     | 40GB | $1.50–3.00 | procesamiento por lotes |

*Precios en USD/día. Las tarifas varían según el proveedor: consulte* [*CLORE.AI Marketplace*](https://clore.ai/marketplace) *para las tarifas actuales.*
