Phase 06 - Lesson 05

Whisper — Arquitectura y Fine-Tuning

Whisper es un encoder-decoder transformer con ventana de 30 segundos, entrenado con 680 mil horas de pares audio-texto multilingües con supervisión débil. Una sola arquitectura, múltiples tareas, robusto en 99 idiomas. El ASR de referencia en 2026.

Tipo: Build Lenguajes: Python Prerrequisitos: Fase 6 · 04 (ASR), Fase 5 · 10 (Atención), Fase 7 · 05 (Transformer Completo) Tiempo: ~75 minutos

El Problema

Whisper, lanzado por OpenAI en septiembre de 2022, fue el primer modelo de ASR en llegar como un commodity: pega el audio, obtén el texto, 99 idiomas, robusto al ruido, corre en una laptop. Para 2024 OpenAI ya había lanzado las variantes Large-v3 y Turbo; para 2026, Whisper es el baseline por defecto para todo, desde la transcripción de podcasts hasta los asistentes de voz y los subtítulos de YouTube.

Pero Whisper no es un pipeline que puedas tratar como una caja negra para siempre. El domain shift lo destruye — jerga técnica, acentos de los hablantes, nombres propios, clips cortos, silencio. Necesitas saber:

  1. Qué es realmente por dentro.
  2. Cómo entregarle audio en chunks, en streaming o de formato largo de la manera correcta.
  3. Cuándo hacer fine-tune y cómo.

El Concepto

Encoder-decoder de Whisper, tareas, inferencia en chunks, fine-tune

Arquitectura. Encoder-decoder transformer estándar.

  • Entrada: espectrograma log-mel de 30 segundos, 80 mels, hop de 10 ms → 3000 frames. Los clips más cortos reciben zero-padding, los clips más largos se dividen en chunks.
  • Encoder: conv-downsample (stride 2) + N bloques transformer. Para Large-v3: 32 capas, 1280 dimensiones, 20 cabezas.
  • Decoder: N bloques transformer con self-attn causal + cross-attn a la salida del encoder. Del mismo tamaño que el encoder.
  • Salida: tokens BPE sobre un vocabulario de 51.865 tokens.

Large-v3 tiene 1,55 mil millones de parámetros. Turbo usa un decoder de 4 capas (en vez de 32), reduciendo la latencia en 8× con una pérdida de WER inferior al 1%.

El formato del prompt. Whisper es un modelo multitarea guiado por tokens especiales en el prompt del decoder:

<|startoftranscript|><|en|><|transcribe|><|notimestamps|> Hello world.<|endoftext|>
  • <|en|> — etiqueta de idioma; fuerza el comportamiento de traducción vs. transcripción.
  • <|transcribe|> o <|translate|> — traducir la salida al inglés a partir de una entrada en cualquier idioma, o transcribir textualmente.
  • <|notimestamps|> — omitir los timestamps a nivel de palabra (más rápido).

El prompt es lo que permite a un solo modelo realizar muchas tareas. Cambia <|en|> por <|fr|> y transcribe francés.

Ventana de 30 segundos. Todo está fijado a 30 segundos. Los clips más largos necesitan chunking; los clips más cortos reciben padding. Las ventanas no se procesan en streaming de forma nativa — por eso existen WhisperX, Whisper-Streaming y faster-whisper.

Normalización log-mel. (log_mel - mean) / std, donde las estadísticas provienen del propio corpus de entrenamiento de Whisper. Debes usar el preprocesamiento de Whisper (whisper.audio.log_mel_spectrogram), no librosa.feature.melspectrogram.

Variantes en 2026

Variante Parámetros Latencia (A100) WER (LibriSpeech-clean)
Tiny 39M 1× tiempo real 5,4%
Base 74M 4,1%
Small 244M 3,0%
Medium 769M 2,7%
Large-v3 1,55B 1,8%
Large-v3-turbo 809M 1,58%
Whisper-Streaming (2024) 1,55B streaming 2,0%

Fine-tuning

Flujo de trabajo canónico en 2026:

  1. Recolecta de 10 a 100 horas de audio del dominio objetivo con transcripciones alineadas.
  2. Ejecuta transformers.Seq2SeqTrainer con el callback generate_with_loss.
  3. Eficiente en parámetros: LoRA en q_proj, k_proj, v_proj de las capas de atención reduce la memoria de GPU en 4× con un costo de WER inferior a 0,3.
  4. Congela el encoder si tienes menos de 10 horas. Ajusta solo el decoder.
  5. Usa el propio tokenizer y formato de prompt de Whisper; nunca cambies el tokenizer.

Resultados de la comunidad: hacer fine-tune de Medium con 20 horas de dictado médico reduce el WER del 12% al 4,5% en vocabulario médico. Hacer fine-tune de Turbo con 4 horas de islandés reduce el WER del 18% al 6%.

Constrúyelo

Paso 1: ejecuta Whisper sin ajustes

import whisper
model = whisper.load_model("large-v3-turbo")
result = model.transcribe(
    "clip.wav",
    language="en",
    task="transcribe",
    temperature=0.0,
    condition_on_previous_text=False,  # prevents runaway repetition
)
print(result["text"])
for seg in result["segments"]:
    print(f"[{seg['start']:.2f}–{seg['end']:.2f}] {seg['text']}")

Valores por defecto importantes que siempre debes sobrescribir: temperature=0.0 (el muestreo usa por defecto la cadena de fallback 0.0 → 0.2 → 0.4 …), condition_on_previous_text=False (previene el problema de alucinación en cascada) y no_speech_threshold=0.6 (detección de silencio).

Paso 2: formato largo en chunks

# whisperx is the 2026 reference for long-form with word-level timestamps
import whisperx
model = whisperx.load_model("large-v3-turbo", device="cuda", compute_type="float16")
segments = model.transcribe("1hour.mp3", batch_size=16, chunk_size=30)

WhisperX agrega (1) gating mediante VAD Silero, (2) alineación a nivel de palabra vía wav2vec 2.0, (3) diarización vía pyannote.audio. El caballo de batalla de 2026 para transcripción en producción.

Paso 3: fine-tune con LoRA

from transformers import WhisperForConditionalGeneration, WhisperProcessor
from peft import LoraConfig, get_peft_model

model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-large-v3-turbo")
lora = LoraConfig(
    r=16, lora_alpha=32, target_modules=["q_proj", "v_proj"],
    lora_dropout=0.1, bias="none", task_type="SEQ_2_SEQ_LM",
)
model = get_peft_model(model, lora)
# model.print_trainable_parameters()  -> ~3M trainable / 809M total

Luego el loop estándar del Trainer. Haz checkpoint cada 1000 pasos. Evalúa con WER en un conjunto de validación separado.

Paso 4: inspecciona lo que aprende cada capa

# Grab cross-attention weights during decode to see what the decoder attends to.
with torch.inference_mode():
    out = model.generate(
        input_features=features,
        return_dict_in_generate=True,
        output_attentions=True,
    )
# out.cross_attentions: layer × head × step × src_len

Visualiza con un heatmap — verás la alineación diagonal a medida que los pasos del decoder recorren los frames del encoder. Esa diagonal es la noción de timestamps de palabras de Whisper.

Úsalo

El stack de 2026:

Situación Elección
Inglés general, offline Large-v3-turbo vía whisperx
Mobile / edge Whisper-Tiny cuantizado (int8) o Moonshine
Formato largo multilingüe Large-v3 vía whisperx + diarización
Idioma de pocos recursos Fine-tune de Medium o Turbo con LoRA
Streaming (2 s de latencia) Whisper-Streaming o Parakeet-TDT
Timestamps a nivel de palabra WhisperX (alineación forzada vía wav2vec 2.0)

faster-whisper (backend CTranslate2) es el runtime de inferencia CPU+GPU más rápido en 2026 — 4× más rápido que el original con salida idéntica.

Trampas que todavía aparecen en 2026

  • Texto alucinado en el silencio. Whisper se entrenó con subtítulos que incluyen "Thanks for watching!", "Subscribe!", letras de canciones. Aplica siempre gating por VAD antes de llamar.
  • Cascada de condition_on_previous_text. Una alucinación contamina las ventanas siguientes. Configúralo en False a menos que necesites fluidez entre los chunks.
  • Padding de clip corto. Un clip de 2 segundos rellenado hasta 30 segundos puede alucinar en el silencio final. Usa pad=False o gating por VAD.
  • Estadísticas de mel incorrectas. Usar los mels de librosa en vez de los de Whisper produce una salida casi aleatoria. Usa whisper.audio.log_mel_spectrogram.

Entrégalo

Guárdalo como outputs/skill-whisper-tuner.md. Diseña un pipeline de fine-tune o de inferencia de Whisper para un dominio específico.

Ejercicios

  1. Fácil. Ejecuta code/main.py. Tokeniza un prompt al estilo Whisper, calcula los presupuestos de shape decodificado e imprime el cronograma de chunks para un clip de 10 minutos.
  2. Medio. Instala faster-whisper, transcribe un podcast de 10 minutos y compara el WER con una transcripción humana. Prueba language="auto" vs. language="en" forzado.
  3. Difícil. Usando datasets de HF, elige un idioma en el que Whisper tiene dificultades (por ejemplo, urdu), haz fine-tune de Medium con LoRA durante 2 epochs con 2 horas y reporta el delta de WER.

Términos Clave

Término Lo que dice la gente Lo que realmente significa
Ventana de 30 s El límite de Whisper Tope rígido de entrada; divide el audio más largo en chunks.
SOT Start-of-transcript `<
Token de timestamps Alineación temporal Cada offset de 0,02 s es un token especial en el vocabulario de 51k.
Turbo La variante rápida Decoder de 4 capas, 8× más rápido, regresión de WER <1%.
WhisperX El wrapper para formato largo VAD + Whisper + alineación wav2vec + diarización.
Fine-tune con LoRA Ajuste eficiente Agrega adaptadores de bajo rango a la atención; entrena ~0,3% de los parámetros.
Alucinación La falla silenciosa Whisper produce inglés fluido a partir de ruido/silencio.

Lecturas Adicionales

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).