Alucinaciones de Whisper: Por Qué Repite Líneas e Inventa Texto
Alucinaciones de Whisper: por qué escribe «Thank you for watching» sobre un silencio o repite una línea, qué cuesta cada solución y cómo detectarlas en un SRT.
Las alucinaciones de Whisper (Whisper hallucinations, en inglés) son texto que el modelo escribe aunque nadie lo haya dicho: «Thank you for watching» sobre un silencio, un crédito de subtítulos o una misma línea repetida durante un minuto. Dos ajustes evitan la mayoría de ellas —filtrar el audio sin voz y evitar que el modelo use su propia salida anterior como contexto—, y las herramientas estándar de Whisper no traen ninguno activado de serie.
A continuación: los dos tipos lado a lado, por qué ocurre cada uno, qué medimos cuando uno de ellos afectó a nuestra propia aplicación, lo que cuesta cada solución, los ajustes de openai-whisper, faster-whisper y whisper.cpp, y cómo encontrar las que sobreviven en un archivo de subtítulos terminado.
Alucinaciones de Whisper, lado a lado
| Frase fantasma | Bucle de repetición | Habla omitida | |
|---|---|---|---|
| Lo que ves | «Thank you for watching», «Thanks for watching», un crédito de subtítulos | Una misma línea escrita una y otra vez, a menudo sin puntuación | Una frase que falta en la transcripción |
| Dónde aparece | Silencio, música, aplausos, ruido de sala | En cualquier sitio; una vez que empieza, continúa | Inicios en voz baja, interjecciones cortas |
| Qué lo causa | Audio sin voz que llega al decodificador | Cada ventana se decodifica con la salida anterior como prompt | Cómo trata ese audio un modelo concreto |
| Primera solución | Un filtro de detección de actividad de voz (VAD) | Desactivar el contexto del texto anterior | Probar un segundo modelo con el mismo clip |
| Cómo se ve en los subtítulos | Un subtítulo de más sobre una pausa | Un subtítulo atascado en una sola línea, o subtítulos sin cortes de frase | Un hueco donde debería haber una línea |
La tercera columna es el fallo contrario: habla que se saltó en lugar de texto que se inventó. Tiene otras causas y otras soluciones, que se tratan en la comparativa de modelos de Whisper. Todo lo que sigue trata de las dos primeras.
¿Por qué Whisper escribe texto que nadie dijo?
Whisper recorre el audio en ventanas de 30 segundos, y su decodificador escribe texto para cada una. Existe una comprobación de no-habla, pero es un umbral sobre una probabilidad, y las ventanas de música, aplausos o sonido ambiente la superan con regularidad y acaban convertidas en palabras. Las palabras que elige delatan la causa. Whisper se entrenó con 680.000 horas de audio de la web emparejado con transcripciones, y las despedidas y los créditos de subtítulos, frecuentes en esos textos, son la explicación habitual de lo que escribe cuando no hay nada que transcribir.
Las cifras no son pequeñas. En un estudio de 2025, investigadores de la AGH University of Kraków ejecutaron large-v3 sobre audio sin voz —ruido, música, sonido ambiental— 301.317 veces. Produjo texto el 40,3 por ciento de las veces, y el 9,1 por ciento de esas alucinaciones eran bucles. Las salidas más frecuentes fueron «thank you», con el 24,76 por ciento de las alucinaciones, y «thanks for watching», con el 10,32 por ciento.
Con habla real la tasa es mucho menor y el daño es peor. El estudio de 2024 Careless Whisper encontró que alrededor del 1 por ciento de las transcripciones contenía frases u oraciones completas que no existían en el audio, que el 38 por ciento de ellas incluía daños explícitos, como perpetuar la violencia, inventar asociaciones o dar a entender una autoridad falsa, y que se daban de forma desproporcionada en hablantes con pausas largas.
Para los subtítulos, el coste es concreto. Una frase alucinada llega como un subtítulo perfectamente formateado sobre una pausa, y el espectador la lee como diálogo.
Por qué una línea mala se convierte en cuarenta
El bucle tiene otra causa. Por defecto, Whisper decodifica cada ventana con su propia salida anterior como prompt, así que el contexto pasa de una ventana a otra: los nombres se siguen escribiendo igual y las frases continúan. Esa misma característica deja que una ventana mala envenene la siguiente. En cuanto el decodificador escribe una línea dos veces, la siguiente ventana arranca con esa línea y la vuelve a escribir. La documentación de faster-whisper sobre condition_on_previous_text lo dice sin rodeos: con la opción desactivada, el modelo «se vuelve menos propenso a quedarse atascado en un bucle de fallo, como un bucle de repeticiones o marcas de tiempo que se desincronizan».
Nos topamos con esto en nuestra propia aplicación antes del lanzamiento, así que lo medimos: el mismo clip en turco de 101 segundos que usamos en nuestra comparativa de modelos, en una RTX 3060 Ti con float16, sin cambiar nada salvo esa opción.
large-v3, con texto anterior | large-v3, sin texto anterior | medium, con texto anterior | medium, sin texto anterior | |
|---|---|---|---|---|
| Signos de fin de frase en la transcripción | 0 | 30 | 47 | 30 |
| Frases repetidas (6-gramas) | 9 | 0 | 0 | 0 |
El valor por defecto destrozó large-v3 y no le hizo nada a medium. Con el texto anterior como contexto, el modelo más grande no escribió ni un signo de puntuación de fin de frase y produjo nueve frases repetidas; el más pequeño, con el mismo audio y los mismos ajustes, funcionó bien. En una ejecución, un solo subtítulo contenía esto, sobre 0,12 segundos de audio:
[58.26 -> 58.38] bir level oldu bir level oldu bir level oldu bir level oldu
bir level oldu bir level oldu bir level oldu bir level oldu
La puntuación que falta importa tanto como las repeticiones. Las herramientas de subtítulos cortan una transcripción en subtítulos por los límites de las frases, y una transcripción sin puntos no les da nada por donde cortar: salen subtítulos gigantes o, con un divisor de líneas descuidado, subtítulos de una sola palabra. Desactivar el contexto del texto anterior devolvió la puntuación sin cambiar de modelo.
Un solo clip no es un benchmark. Sí demuestra dos cosas: el tamaño del modelo no protege, y la solución más barata es un ajuste.
¿Cuesta algo desactivar el contexto del texto anterior?
Sí. Cada solución contra las alucinaciones tiene su coste, y conviene conocerlo antes de aplicarla:
- Coherencia entre ventanas. Sin el texto anterior como contexto, la ortografía y el estilo de puntuación pueden variar de una ventana a otra; la documentación advierte de que desactivarlo «puede hacer que el texto sea inconsistente entre ventanas». En la práctica: un nombre escrito de dos maneras en un archivo largo.
- Tu initial prompt no pasa de la primera ventana. Las herramientas le pasan a Whisper una lista de vocabulario —nombres, marcas, jerga— como initial prompt (el texto inicial con el que se orienta al modelo); con el contexto del texto anterior desactivado, solo influye en la primera ventana.
--carry_initial_prompt Trueen openai-whisper y--carry-initial-prompten whisper.cpp lo reenvían en cada ventana; en faster-whisper, esa tarea la hace la opciónhotwords. - Las penalizaciones por repetición borran repeticiones reales.
repetition_penaltyyno_repeat_ngram_sizesuprimirían un bucle, pero no saben distinguir un bucle de un hablante que se repite. Nuestro clip de prueba tiene justo eso: una frase dicha dos veces seguidas, a propósito. Una penalización que la elimina está borrando diálogo. - Un filtro de detección de actividad de voz puede recortar habla en voz baja. El VAD decide qué cuenta como habla antes de que Whisper la oiga, y los inicios en voz baja y el audio de banda limitada, como las llamadas telefónicas, son donde se le escapan palabras. AutoSubs añadió en septiembre de 2026 un interruptor para desactivar su omisión de silencios precisamente para ese caso.
hallucination_silence_thresholdnecesita marcas de tiempo por palabra, y no es una cura. Se salta los silencios largos que rodean a una posible alucinación. En nuestro clip no supuso ninguna diferencia medible: la línea que sospechábamos inventada resultó ser habla real.
Ninguno de estos costes se acerca al de un bucle. Un nombre mal escrito se arregla con un buscar y reemplazar; un bucle de repetición es un pasaje que hay que transcribir otra vez.
Cómo evitar que Whisper alucine, herramienta por herramienta
| openai-whisper | faster-whisper | whisper.cpp | Sablate | |
|---|---|---|---|---|
| Filtro de detección de actividad de voz | Ninguno integrado | vad_filter=True, activado por defecto solo en el pipeline por lotes | --vad con un modelo Silero | Siempre activado |
| Desactivar el contexto del texto anterior | --condition_on_previous_text False | condition_on_previous_text=False | -mc 0 | Siempre desactivado |
| Saltar el silencio tras una posible alucinación | --hallucination_silence_threshold | hallucination_silence_threshold | Sin equivalente | No |
| Reenviar el prompt en cada ventana | --carry_initial_prompt True | hotwords | --carry-initial-prompt | No |
| Puedes cambiar estos ajustes | Sí | Sí | Sí | No |
Las tres últimas filas son el punto débil de Sablate, dicho con franqueza: las dos soluciones están siempre activadas y ninguno de estos ajustes se puede tocar. Si quieres afinar el filtro o llevar un prompt de una ventana a otra, las herramientas de código abierto te lo permiten.
Para openai-whisper, con un archivo de entrevista:
whisper talk.mp4 --model turbo --output_format srt --condition_on_previous_text False
openai-whisper no tiene filtro de detección de actividad de voz propio, así que este comando arregla el bucle, pero no las frases fantasma; --hallucination_silence_threshold junto con --word_timestamps True es su respuesta parcial a estas. whisper.cpp incluye las dos soluciones, y su herramienta de línea de comandos espera un WAV de 16 bits:
ffmpeg -i talk.mp4 -ar 16000 -ac 1 -c:a pcm_s16le talk.wav
./build/bin/whisper-cli -m models/ggml-large-v3-turbo.bin -f talk.wav -osrt -mc 0 --vad -vm models/ggml-silero-v6.2.0.bin
-mc 0 no mantiene ningún contexto de texto entre ventanas, y el modelo Silero sale del script download-vad-model.sh del repositorio. En Python, faster-whisper recibe las dos cosas como argumentos:
from faster_whisper import WhisperModel
model = WhisperModel("large-v3-turbo")
segments, info = model.transcribe("talk.mp4", vad_filter=True, condition_on_previous_text=False)
¿Cómo se encuentran las alucinaciones en un SRT terminado?
Ningún ajuste elimina todas las alucinaciones, así que revisa el archivo. Tres comandos detectan la mayoría de las que sobreviven, en macOS y Linux o en Git Bash y WSL en Windows:
grep -n -i -E "thank(s| you) for watching|amara\.org|subtitles by" talk.srt
awk '{ sub(/\r$/, "") } NF && !/-->/ && !/^[0-9]+$/ { if ($0 == prev) print NR": "$0; prev = $0 }' talk.srt
perl -ne 'print "$.: $_" if /(\S+(?: \S+){1,4}) \1 \1/' talk.srt
El primero encuentra despedidas típicas y créditos de subtítulos. El segundo imprime cualquier línea de subtítulo idéntica a la anterior, que es el aspecto habitual de un bucle una vez cortado en subtítulos. El tercero detecta una frase de dos a cinco palabras repetida tres veces dentro de una misma línea.
Trata cada coincidencia como una pregunta, no como un veredicto. La gente sí dice «thank you», y sí se repite. Reproduce el subtítulo junto al audio y decide si lo conservas o lo borras. Las frases fantasma que aparecen sobre pausas largas y música no coinciden con ningún patrón; la única comprobación es leer los subtítulos que caen sobre los tramos sin habla.
Qué solución usar en cada caso
«Subtitulo charlas, entrevistas o clases». Activa el filtro de detección de actividad de voz y desactiva el contexto del texto anterior. Esa combinación es el ajuste por defecto sensato para cualquier habla que vayas a subtitular.
«La grabación tiene silencios largos o música de fondo». Aquí el filtro es lo que más importa. Lee de todos modos los subtítulos que caen sobre la música.
«Es una llamada telefónica o una grabación baja y de banda limitada». Pásala una vez con el filtro y otra sin él, y compara qué falta. Un filtro que se come las palabras en voz baja es peor que un «thank you» suelto.
«Dependo de un initial prompt para los nombres». Desactiva el contexto del texto anterior y reenvía el prompt en cada ventana con las opciones de arriba, o corrige los nombres después con buscar y reemplazar.
«Las líneas siguen repitiéndose después de las dos soluciones». Prueba otro modelo con el mismo archivo antes de recurrir a una penalización por repetición; nuestro clip entró en bucle con large-v3 y no con medium. Si aun así necesitas no_repeat_ngram_size, escucha el audio entero por si ha eliminado alguna línea.
Cómo lo gestiona Sablate
En Sablate las dos soluciones están siempre activadas: un filtro de detección de actividad de voz delante del modelo y ningún uso del texto anterior como contexto. Sablate ejecuta Whisper en tu propio equipo, y dejamos de usar el texto anterior como contexto tras la medición de arriba. También arreglamos el divisor de líneas que convertía una transcripción sin puntuación en subtítulos de una sola palabra.
Hay dos consecuencias que conviene conocer. El vocabulario personalizado de Defaults → Custom vocabulary llega a Whisper como su initial prompt, así que, con el contexto del texto anterior desactivado, solo influye en la primera ventana, más o menos los primeros 30 segundos de habla; los nombres que aparecen más adelante en una grabación larga son trabajo para Find & replace en el editor, que actúa sobre un idioma cada vez. Y como los ajustes son fijos, no hay nada que afinar. Si una grabación necesita el filtro desactivado, usa una de las herramientas de código abierto de más arriba.
En el editor puedes recorrer los subtítulos con el vídeo en reproducción, que es la forma más rápida de juzgar las coincidencias de los comandos de arriba, y la exportación escribe los subtítulos corregidos como .srt, .vtt o un vídeo con los subtítulos incrustados. Fast y Balanced funcionan en el plan Gratis; Accurate y Best forman parte de Pro. Descarga Sablate para Windows o Mac y pruébalo con tu propio material.
En resumen
Whisper alucina de dos maneras: escribe frases típicas sobre audio sin voz y entra en bucle cuando una ventana mala alimenta a la siguiente. Un filtro de detección de actividad de voz arregla lo primero, desactivar condition_on_previous_text arregla lo segundo, y las herramientas estándar no traen ninguno activado. Las dos soluciones cuestan poco al lado de un bucle. Un modelo más grande no es un modelo más seguro. Y cambies lo que cambies, lee el archivo de subtítulos terminado antes que nadie: la guía para crear archivos SRT trae las comprobaciones del formato en sí.