Resumen
Checkpoint de inferencia float32 del modelo más reciente del proyecto training-asr: fine-tuning de openai/whisper-medium sobre Common Voice 26 español (es) con la encoder congelada (decoder + proj_out entrenables, ~457 M / 764 M params). Entrenado en FP32 nativo sobre una NVIDIA Tesla P40 (Pascal sm_61, 24 GB, sin Tensor Cores / sin BF16).
Este checkpoint corresponde a step 10800 del run asr-rolling_step-0000700 (W&B, proyecto auden-asr-es), el checkpoint rolling más reciente exportado al corte de esta publicación:
Table with columns: Métrica, Valor| Métrica | Valor |
|---|
| Step | 10800 |
| WER (1000 muestras de validación) | 0.2970 |
| val_loss | 0.2188 |
| Checkpoint fuente | checkpoints/rolling_step-0010800.pt |
Tamaño model.safetensors | ~3.0 GB (fp32) |
Nota: el WER de este checkpoint (0.2970) es peor que el del mejor checkpoint histórico (0.1053 @ step 500, publicado como erickfmm/whisper-medium-ft-cv_es-best-hf-fp32). Ver §Estado para el contexto del problema abierto.
Estado: versión de desarrollo (debug)
⚠️ No usar en producción. Este modelo se publica como debug/dev para inspección y reproducción de experimentos. El entrenamiento sigue en curso (step 10850/20000 al corte) y hay un problema abierto de divergencia val_loss vs. WER (ver Experimentos.md §8.3):
la cross-entropy de validación bajó ~8× de forma casi monótona (1.58 → 0.20) pero el WER se estancó en ~0.20 con picos de alucinación (WER 31 y 33 en steps 1100/2200) y degradación tardía (0.9–10 entre steps 7600–9000). El mínimo WER del run largo fue 0.1986 @ step 3200; el de este checkpoint (0.2970 @ step 10800) refleja esa degradación tardía. WER>1 corresponde a loops de repetición en la decodificación greedy (generate()).
Descripción técnica
- Base:
openai/whisper-medium (encoder-decoder seq2seq, 764 M params).
- Encoder congelado siguiendo Vividh-ASR (arXiv:2605.13087) y Gumbel-BEARD (arXiv:2606.11429): adaptar el decoder preserva la geometría acústica del encoder e iguala/supera el full fine-tune en Common Voice. Sólo se entrenan decoder +
proj_out (~457 M, 60 %).
- Features:
WhisperFeatureExtractor (log-mel 80 bins, ventana 30 s, hop 160, 16 kHz).
- Pérdida: cross-entropy media sobre tokens no-padding (
pad_token_id enmascarado con -100).
- dtype de entrenamiento: FP32 (P40 sm_61, sin BF16 nativo, FP16 a 1/64 de velocidad → inviable).
- Optimizador: Turbo-Muon híbrido (Muon sobre params 2D, AdamW sobre params 1D) + schedule warmup lineal + coseno.
Métricas (trayectoria del run largo)
Table with columns: Step, val_loss, WER, Nota| Step | val_loss | WER | Nota |
|---|
| 500 | 1.5826 | 0.1053 | mejor WER histórico (run 7, playful-glade-7) |
| 800 | 0.2881 | 1.797 | inicio run 9, alucinación |
| 1100 | 0.2647 | 31.11 | alucinación |
| 2200 | 0.240 | 32.78 |
Fuente: exp/es-whisper-medium/val_log.csv (104 validaciones, steps 500–10800).
Uso
import torchfrom transformers import WhisperForConditionalGeneration, WhisperProcessor model = WhisperForConditionalGeneration.from_pretrained( "erickfmm/whisper-medium-ft-cv_es-latest-hf-fp32", torch_dtype=torch.float32,)model.eval() processor = WhisperProcessor.from_pretrained("erickfmm/whisper-medium-ft-cv_es-latest-hf-fp32") # Forzar idioma/tarea (igual que en entrenamiento)forced_decoder_ids = processor.get_decoder_prompt_ids(language="es", task="transcribe")
O con pipeline:
from transformers import pipelineasr = pipeline( "automatic-speech-recognition", model="erickfmm/whisper-medium-ft-cv_es-latest-hf-fp32", device=0, # GPU con soporte fp32 (P40, CPUs, etc.) torch_dtype=torch.float32,)out = asr("audio.wav", generate_kwargs={"language": "es", "task": "transcribe"})print(out["text"])
Cuándo usar fp32: GPUs Pascal (Tesla P40) o anteriores, CPUs, o cuando necesites máxima fidelidad numérica. Tamaño ~3 GB. Si tu GPU soporta fp16/bf16 (Ampere+, sm≥80), considera las variantes ...-hf-fp16 o ...-hf-bf16 (~1.5 GB).
Entrenamiento (config del run 9, asr-rolling_step-0000700)
./start.sh --model whisper-medium --wandb \ --batch-seconds 60 --max-duration 10 \ --grad-accum-steps 8 --lr-muon 2e-3 --lr-adamw 1e-4 \ --warmup-steps 1000 --max-steps 20000 --max-rollbacks 500 \ --num-workers 16 --snapshot-every 10 \ --rolling-every 50 --val-every 100 \ --resume exp/es-whisper-medium/checkpoints/rolling_step-0000700.pt
- Runtime al corte: ~6 días (step 10850/20000, 54 %).
- 458 rollbacks absorbidos, 0
nan_failures. lr_temp_scale=0.5 casi permanente (el run vive en cooldown).
- ~31 s/step + ~50 min de validación cada 100 steps → ciclo ~100 min/100 steps.
- Véase
Experimentos.md §8 para el detalle completo del run.
Reproducibilidad
git clone https://github.com/erickfmm/training-asr.gitcd training-asr./setup_env.sh./start.sh --model whisper-medium --wandb
Repo: https://github.com/erickfmm/training-asr.git
Documentación: README.md, Experimentos.md, investigacion.md.
Limitaciones y sesgos
- Hardware: entrenado en FP32 sobre Tesla P40; el peso exportado es fp32 válido para inferencia en cualquier backend, pero el entrenamiento en bf16/fp16 no fue posible en esta GPU.
- Dataset: Common Voice 26
es es mezcla dialectal; no tiene locale chileno (es_cl) ni hablantes infantiles. WER medido sobre 1000 muestras de validación (no el test set completo).
- Divergencia val_loss/WER: este checkpoint (step 10800) tiene WER peor que el mejor histórico (step 500). El WER del run largo se degradó tras ~step 7500 pese a val_loss descendente. Re-evaluar con beam search /
repetition_penalty antes de cualquier uso.
- Decodificación greedy: el WER se midió con
model.generate() greedy (sin beam_search ni repetition_penalty); los picos de WER > 1 se atribuyen a loops de repetición, no necesariamente a pesos malos.
Citations
@misc{radford2022whisper, title = {Robust Speech Recognition via Large-Scale Weak Supervision}, author = {Radford, Alec and others}, year = 2022, howpublished = {arXiv:2212.04356},}@misc{boissin2025turboMuon, title = {Turbo-Muon}, author = {Boissin, Théo and others}, year = 2025, note = {arXiv:2512.04632},}@misc{zclip2025, title = {ZClip: Adaptive Gradient Clipping for Stable LLM Training}, year = 2025, note = {arXiv:2504.02507},}@misc{vividh2026, title = {Vividh-ASR}, year = 2026, note = {arXiv:2605.13087},}@misc{gumbelbeard2026, title = {Gumbel-BEARD}, year = 2026, note = {arXiv:2606.11429},}@dataset{commonvoice26, title = {Common Voice 26.0}, author = {Mozilla Foundation}, url = {https://huggingface.co/datasets/mozilla-foundation/common_voice_26_0},}