Skip to content
anecho.ai

Null Test v0.1: diez mejoradores de voz, dieciocho condiciones, y nada superó al audio sin procesar en la media agregada

El arnés, el dataset, las configuraciones y ahora los resultados. Diez motores de mejora puntuados contra un control sin procesar en WER, descomposición de errores, VAD y coste. El audio sin procesar ganó en la WER agregada — pero al menos un motor lo superó en 11 de las 18 condiciones individuales, y las inserciones subieron en lugar de bajar.

Anecho Engineering13 ago 202616 min de lectura
nulltestbenchmarkmethodologyopen-sourcerelease

Actualización del 20 de octubre de 2026: un experimento aparte compara ahora nuestro v8_2 con ai-coustics Quail VF 2.2 S en conversaciones en vivo construidas: empate con faster-whisper base.en, ventaja de v8_2 con la transcripción de entrada de Gemini Live, y la condición decidiendo quién va delante. Ver conversaciones en vivo. Nada de este post cambia.

Actualizado el 14 de agosto de 2026: la matriz se regeneró con cinco condiciones adicionales de transporte de telefonía, pasando de trece a dieciocho. Los números absolutos se movieron; el orden no. Cada cifra de abajo está citada del benchmark.json publicado.

Hoy publicamos Null Test v0.1 — el arnés, el manifiesto del dataset, las configuraciones, las reglas y el primer conjunto completo de resultados. Mide lo que le pasa a la precisión del speech-to-text cuando pones un motor de mejora de voz (speech enhancement) delante de un reconocedor, en dieciocho condiciones acústicas, contra un control de hipótesis nula al que se le permite ganar.

En los números agregados, ganó — y el desglose por condición que hay debajo es donde vive la ingeniería de verdad.

Un null test es la medición canónica de la ingeniería de audio: resta la señal procesada de la referencia y lo que queda es exactamente lo que hizo el procesador — incluido el daño. Esa es toda la ambición de este proyecto, y por eso es el nombre.

Por qué existe esto

Las afirmaciones públicas son irreconciliables. Krisp comercializa una reducción de la tasa de error de palabras (WER) de aproximadamente 46%. ai-coustics comercializa aproximadamente 43%. Un estudio independiente (arXiv:2512.17562) encontró que el audio mejorado puntuó peor que el audio sin procesar en las 40 configuraciones que probó — aunque solo con MetricGAN+, sobre habla médica, en WER semántica. AssemblyAI, citándolo, informó por separado de que la salida de Krisp aproximadamente duplicaba la WER cuando se pasaba a su STT mientras recortaba los disparos falsos de la detección de actividad de voz (VAD) alrededor de 3.5x. Deepgram ha publicado la posición de que la mejora perjudica la precisión, y no hemos encontrado datos que la acompañen. Nadie comparte un corpus, un conjunto de condiciones, una configuración ni un control. La versión larga de ese desacuerdo está en ¿La supresión de ruido ayuda de verdad al speech-to-text?.

Qué se ejecutó

Reconocedorfaster-whisper base.en, CTranslate2 int8 CPU, decodificación greedy
VADSilero VAD, umbral 0.5, bloques de 512 muestras
Conjunto de prueba10 hablantes, 180 clips, aproximadamente 1406 segundos de audio, semilla 20260101
Palabras de referenciaunas 190 por condición, 3420 en total por backend
Condiciones18
Backends12 (sin procesar, control passthrough y diez mejoradores)
HostApple M1 Max, onnxruntime 1.28.0, fijado a 1 hilo intra-op

Las dieciocho condiciones: clean; ruido de banda ancha a -5, 0, 5, 10 y 20 dB SNR; babble_snr5; hablante que compite a 0 y 5 dB; reverb y reverb_snr10; y siete condiciones de telefonía — telephony (una ida y vuelta G.711 µ-law), telephony_snr10, más A-law, G.722, Opus a 12 kbps, y pérdida de paquetes a ráfagas de 3% y 10%.

Los diez mejoradores: GTCRN (MIT), cinco variantes de FastEnhancer T/S/B/M/L (MIT), DeepFilterNet3 en dos configuraciones (MIT o Apache-2.0), y dos modelos de ai-coustics, Quail L y Quail VF 2.2 L, ejecutados a través del SDK con licencia como línea base propietaria de referencia.

Nuestros propios modelos no están en esta matriz. Chamber y Clearline serán filas en ella, bajo las mismas reglas, contra el mismo control que acaba de ganarles a todos. Publicar al árbitro antes que al concursante era el sentido de ese orden.

Los resultados

Agregado sobre las dieciocho condiciones:

BackendWERInsercionesEliminacionesRTFLatencia
Sin procesar (raw)14.77%10160—0 ms
ai-coustics Quail L15.56%126570.12430 ms
ai-coustics Quail VF 2.2 L18.10%161750.07630 ms
GTCRN (MIT)20.26%210400.05016 ms
FastEnhancer-L (MIT)20.44%1591070.37625.8 ms
FastEnhancer-M (MIT)22.40%217830.11022 ms
FastEnhancer-T (MIT)22.46%1451090.01316 ms
DeepFilterNet335.18%3801970.133100 ms

Ningún mejorador superó al audio sin procesar en la WER agregada. El mejor fue ai-coustics Quail L con 15.56% contra el 14.77% del audio sin procesar — unas ocho décimas de punto peor, lo que con este tamaño de muestra llamaríamos un empate más que una derrota. Todo lo que hay por debajo perdió por cinco puntos o más, y eso no es un empate.

El agregado responde a «¿debería la mejora estar activada por defecto?» y a casi nada más; las secciones por condición de abajo son las que sirven para actuar, y dicen algo distinto.

Las inserciones subieron, no bajaron. El audio sin procesar produjo 101. GTCRN produjo 210. DeepFilterNet3 produjo 380. Esto es exactamente lo contrario de la afirmación de los proveedores de que la mejora elimina palabras alucinadas, y vale la pena detenerse en ello: una inserción no es una palabra deformada, es el reconocedor emitiendo una palabra que nadie dijo. Nuestra lectura es que lo que deja atrás un supresor — ruido musical, silencio de compuerta, transitorios emborronados — es más decodificable-como-habla que el ruido que eliminó.

La descomposición de GTCRN remacha el punto: 210 inserciones contra solo 40 eliminaciones, donde el audio sin procesar tenía 101 y 60. No se está comiendo tus palabras funcionales, está añadiendo palabras que nadie pronunció. Modos de fallo opuestos, y un solo número de WER esconde cuál de los dos compraste. Por eso cada celda publica S, D e I por separado.

Dónde sí se sostiene la afirmación de los proveedores

Detenernos en el número agregado sería hacer exactamente lo que criticamos a los proveedores. La mejora gana márgenes reales en condiciones específicas — en 11 de nuestras 18, al menos un motor superó al audio sin procesar — y son las condiciones que predecirías: donde el ruido o una voz que compite está destruyendo de verdad las pistas fonéticas.

El caso más claro es el aislamiento del hablante (speaker isolation). ai-coustics Quail VF es un modelo Voice Focus: su trabajo es aislar al hablante principal y rechazar otras voces. Con un hablante que compite a 5 dB recortó las inserciones de 19 a 10 y la WER de 26.3% a 20.5%. Con murmullo a 5 dB, de 24.7% a 20.5% con las inserciones bajando de 10 a 7. Esos son los resultados más fuertes que publicó aquí cualquier mejorador. El ruido de banda ancha a SNR baja muestra la misma forma — a 0 dB, ocho de los diez motores superaron al audio sin procesar, el mejor por 4.7 puntos.

Las siete condiciones donde nada superó al audio sin procesar son igual de informativas: las dos con reverberación, y las cinco condiciones de transporte de telefonía. En cuatro de esas cinco lo mejor que consigue un motor es un empate exacto con no hacer nada, lo que es una respuesta en sí misma.

Lo que nada de eso respalda es la afirmación general. Agregado, Quail VF es más de tres puntos peor que el audio sin procesar, porque también corre sobre material limpio, reverberante y de banda estrecha donde solo puede quitar información. La mejora paga donde el audio es genuinamente malo y te cuesta donde no lo es, y un único escalar — el nuestro incluido — esconde en qué lado de esa línea está tu tráfico.

VAD: la métrica que todos citan apenas se mueve, la que importa se mueve mucho

La misma ejecución puntuó Silero VAD en cada stream. F1 de VAD agregada: 0.950 sin procesar contra 0.947 para el mejor stream mejorado. Califica la mejora por la F1 de VAD y concluirás que no hace nada.

La tasa de falsas alarmas es otra historia, y una falsa alarma es lo que realmente es un barge-in espurio:

CondiciónTasa de falsas alarmas, sin procesarMejoradoMotor
Murmullo a 5 dB97.7%68.2%FastEnhancer-L
Hablante que compite a 5 dB58.1%37.2%ai-coustics Quail VF

Bajo murmullo a 5 dB el stream sin procesar da falsa alarma en esencialmente cada frame sin habla — una VAD que ha dejado de funcionar como compuerta. La mejora lleva eso a 68.2%, todavía malo y treinta puntos mejor.

Así que la misma ejecución dice que la mejora te cuesta cinco puntos de WER agregada y te compra un tercio menos de tasa de falsas alarmas. Eso no es una contradicción, es una arquitectura: audio mejorado al detector de turnos, audio sin procesar al reconocedor. Lo publicamos como el valor por defecto del SDK y el razonamiento está en El pipeline dividido.

Telefonía: ningún mejorador ayudó, y varios hicieron mucho daño

En la ida y vuelta G.711 µ-law, el audio sin procesar está en 5.8% de WER. Contra eso: ai-coustics Quail L +1.6 puntos, Quail VF +2.6, GTCRN +3.2, FastEnhancer-T +6.8, DeepFilterNet3 +9.5. En la misma ida y vuelta con ruido a 10 dB, el audio sin procesar está en 10.5% y el rango va de +0.5 a +9.5.

Ningún mejorador produjo una mejora significativa sobre audio de telefonía, y varios causaron degradaciones grandes. Dos filas salen fraccionalmente por debajo del audio sin procesar y ninguna es un resultado: FastEnhancer-S está a -0.5 en la fila limpia — con 190 palabras de referencia, a menos de una sola palabra de no hacer nada — y a +3.7 en la ruidosa; Quail VF está a -1.1 en la fila ruidosa y a +2.6 en la limpia. Empates, en ambas direcciones.

Las cinco condiciones de transporte añadidas en esta actualización dicen lo mismo con menos rodeos. En A-law, G.722, Opus a 12 kbps y pérdida a ráfagas de 3%, lo mejor que consigue cualquier motor es un empate exacto con el audio sin procesar; con 10% de pérdida nada lo alcanza. Las peores celdas son severas — FastEnhancer-M publica 49.0% en A-law contra el 7.4% del audio sin procesar, con 61 inserciones donde el audio sin procesar tiene 2. El ruido de cuantización por compansión está fuera de lo que ese modelo espera y responde alucinando.

Eso importa porque la telefonía es donde está el volumen de llamadas, y su forma no es un accidente: el DNS Challenge, la serie de benchmarks contra la que se afinan la mayoría de los supresores publicados, nunca tuvo una pista de banda estrecha. El campo optimizó para 16 y 48 kHz porque eso era lo que se puntuaba.

Importa con un gran asterisco. Una WER sin procesar de 5.8% en la condición base de telefonía significa que es una condición fácil, y no lo que rompe los despliegues telefónicos en producción — ver las salvedades. La historia completa de la banda estrecha, incluido un experimento separado de 8 kHz de extremo a extremo con motores nativos de banda estrecha y un control de ida y vuelta de remuestreo, está en 8 kHz es donde la IA de voz se rompe de verdad. Su versión corta: el 8 kHz nativo supera a remuestrear-y-cruzar-los-dedos por 0.7 puntos para el mismo proveedor, y nada en absoluto supera al audio del llamante sin tocar.

Salvedades, completas

Un resultado sin sus límites es un anuncio. Estas van pegadas a cada número de arriba.

  • Un solo reconocedor. faster-whisper base.en. Un reconocedor distinto da números absolutos distintos. El arnés soporta Deepgram y AssemblyAI, así que el orden puede volver a comprobarse, y nos gustaría que lo hiciera alguien que no se fíe de nosotros.
  • Unas 190 palabras de referencia por condición, 3420 agregadas. Suficiente para separar efectos grandes, no para resolver uno o dos puntos de WER: una palabra vale aproximadamente 0.5 puntos por condición y 0.03 agregado. Lee la diferencia entre el audio sin procesar y Quail L como un empate; las brechas de cinco a veinte puntos por debajo no lo son.
  • DeepFilterNet3 se mide a través de un adaptador block-online. Ningún export público de ONNX lleva los tensores de estado recurrente, así que el streaming por frame es imposible con los pesos publicados. Su 35.18% es una cota inferior de calidad y una cota superior de coste, y su latencia de 100 ms está muy por encima de lo que logra un runtime nativo en Rust. Nunca cites el número sin esta frase. También corre a 48 kHz sobre material de 16 kHz sobremuestreado a 48 kHz — la situación honesta de VoIP, no la condición para la que fue diseñado.
  • Las filas de ai-coustics son una línea base propietaria ejecutada a través del SDK con licencia. Un punto de referencia, nunca una ruta de código que nosotros vayamos a desplegar.
  • Las licencias restringen la reutilización. El ruido de ESC-50 es CC-BY-NC-3.0, así que esas condiciones son solo de evaluación. LibriSpeech es CC-BY-4.0, y las condiciones de murmullo y de hablante que compite se construyen solo con LibriSpeech, así que no llevan restricción NC.
  • onnxruntime fijado a 1 hilo intra-op, ejecución secuencial. La columna RTF es un stream en un núcleo, no un reparto.
  • Solo inglés, puntuación por lotes, sin panel de escucha, sin métricas a nivel de turno. La mejora se ejecuta bloque a bloque con estado transportado entre bloques, pero el reconocedor se puntúa sobre enunciados completos, y la VAD es a nivel de frame. «Menos barge-ins falsos» como métrica de producto necesita fronteras de turno etiquetadas y una definición acordada.
  • Las condiciones de telefonía son más realistas de lo que eran, y siguen sin ser una llamada telefónica. Ahora incluyen tramos A-law y G.722, Opus a 12 kbps, y pérdida de paquetes a ráfagas de dos estados a 3% y 10% con ocultación por repetición atenuada — en lugar de pérdida aleatoria independiente con relleno de silencio, que favorece a los decodificadores y exagera el daño, respectivamente. Sigue faltando: eco acústico con distorsión no lineal del altavoz, supresión en el lado del terminal, y tramos AMR-WB o EVS. El eco es la brecha que más nos importa, porque es el deterioro detrás de la parte de nuestra propia hoja de ruta que no se puede cerrar con un parche.
  • Estas dieciocho condiciones se almacenan a 16 kHz después de un tramo de transporte de 8 kHz, así que cada backend las ve a su propia frecuencia nativa. El experimento genuinamente de banda estrecha — 60 clips, 8 kHz de principio a fin, nada remuestreado, motores nativos de 8 kHz incluidos — es un artefacto aparte con su propio límite de resolución de 1,140 palabras de referencia, donde una palabra es 0.09 puntos.

Metodología, con detalle suficiente para atacarla

El streaming se simula honestamente. Cada mejorador se ejecuta bloque a bloque con su tamaño de bloque declarado, transportando estado entre bloques, sin más lookahead que su latencia algorítmica declarada. El procesamiento offline de archivos completos favorece al mejorador y no es lo que recibe un agente en vivo. La latencia se reporta como latencia algorítmica — frame más lookahead — una propiedad del modelo, no de nuestro portátil.

El RTF se mide, no se cita. Un solo núcleo fijado, pasadas de calentamiento descartadas, cadena de hardware registrada en cada fila. Un modelo que gana en WER a 4x el tiempo real no es una opción desplegable, así que el número de precisión y el número de coste viajan juntos.

El ruido se mezcla, no se obtiene premezclado. Habla limpia más ruido a una SNR objetivo calculada solo sobre las regiones de habla activa, para que el silencio inicial y final no distorsione la relación. La reverberación es convolución con respuestas al impulso de salas medidas. La telefonía es una ida y vuelta real de códec — remuestrear a 8 kHz, codificar y decodificar G.711 µ-law, remuestrear de vuelta — en lugar de un filtro paso-bajo haciendo de canal. Un tramo de códec real, y aun así no una llamada telefónica real; la salvedad de arriba lista lo que deja fuera.

La normalización de texto está fijada y publicada. La WER es (S + D + I) / N después de un normalizador aplicado de forma idéntica a cada hipótesis y referencia: paso a minúsculas, eliminación de puntuación, expansión de números, manejo de contracciones. La normalización puede mover la WER varios puntos, así que está versionada en el repositorio y registrada en cada fila.

Determinismo, y salidas por enunciado. Semillas fijas para la selección de ruido, el sorteo de SNR y la selección de RIR; el manifiesto del dataset está direccionado por contenido con SHA-256 por archivo, verificado al descargar, así que la misma configuración en el mismo commit produce las mismas filas. Cada ejecución también emite hipótesis y referencias por enunciado junto a los agregados, para que cualquiera pueda recalcular, cortar de otra manera, o encontrar los diez archivos que cargan con un resultado. Los benchmarks de solo agregados no se pueden comprobar, que es buena parte de cómo el campo llegó hasta aquí.

Las reglas que lo convierten en un árbitro

  1. El control sin procesar está siempre en la matriz y se le permite ganar. En v0.1 ganó.
  2. Nos puntuamos a nosotros mismos bajo las mismas reglas, en las mismas tablas. Chamber y Clearline serán filas, no una página de marketing aparte.
  3. Cada celda se publica, incluidas las que perdemos. Ninguna condición se elimina después de ver el resultado.
  4. Las configuraciones están en el repositorio. Si un proveedor cree que configuramos mal su motor, el arreglo es un pull request contra un archivo YAML, y nosotros reejecutamos y republicamos.
  5. Derecho de réplica. Cualquier mantenedor o proveedor puede pedir una reejecución con un ajuste distinto. Publicamos ambos.
  6. La licencia se declara por fila. Donde los términos de un proveedor prohíben publicar resultados de benchmark, decimos que la celda está bloqueada y nombramos la razón en lugar de omitirla en silencio.

El formato de salida

El documento completo está en /benchmark. El resumen de un backend:

{
  "id": "gtcrn",
  "label": "GTCRN",
  "license": "MIT",
  "wer": 0.2026,
  "werSubstitutions": 443,
  "werInsertions": 210,
  "werDeletions": 40,
  "werRefWords": 3420,
  "vadF1": 0.9472,
  "vadFalseAlarm": 0.1638,
  "rtf": 0.0498,
  "latencyMs": 16.0
}

Cada backend lleva además un objeto conditions con la misma descomposición por condición — donde viven los desacuerdos interesantes.

Ejecutarlo tú mismo

git clone https://github.com/anecho/nulltest
cd nulltest
uv sync

# fetch and verify the dataset against the content-addressed manifest
python -m nulltest.data fetch --manifest data/manifest.json

# one condition, two backends, one recogniser — a few minutes on a laptop
python -m nulltest.run \
  --condition babble_snr5 \
  --backend gtcrn --backend raw \
  --stt faster-whisper:base.en \
  --out out/

python -m nulltest.report out/ --format md

Añadir un motor es un archivo. El benchmark solo habla con esta interfaz:

class Enhancer(Protocol):
    id: str
    sample_rate: int
    block_size: int              # samples per process() call
    algorithmic_latency_ms: float

    def reset(self) -> None: ...

    def process(self, block: np.ndarray) -> np.ndarray:
        """block: float32 mono, shape (block_size,), range -1 to 1. Returns same shape."""

Si tu motor implementa reset y process, puede estar en la matriz. Nos gustaría especialmente que los proveedores cuyas afirmaciones publicadas citamos enviaran sus propios adaptadores y configuraciones.

Qué viene después, y la parte comercial

v0.2 añade métricas de endpointing a nivel de turno vía Onset, STT de streaming con latencia hasta el final, un segundo y un tercer reconocedor para que el orden pueda comprobarse en lugar de creerse, condiciones multilingües, y una condición de eco con distorsión no lineal del altavoz. Chamber y Clearline entran en la matriz cuando tengan algo que merezca puntuarse.

Sobre ese último punto, sin rodeos: una fila aquí no es una nota de prensa, y no vamos a publicar una antes de que merezca leerse. Los experimentos de arquitectura y de corpus están corriendo contra las mismas condiciones reservadas que produjeron las tablas de arriba, y Clearline entra en la matriz cuando se gane la fila — medido en condiciones de telefonía dignas de ese nombre, contra un control al que se le permite ganarle.

La parte comercial, dicha una vez y sin decoración: este benchmark no es el producto. Un benchmark no tiene comprador ni retención — nadie renueva una tabla de clasificación. Lo que pretendemos vender es Clearline, una ruta de audio para telefonía: aislamiento nativo del hablante principal a 8 kHz, supresión de eco residual, por minuto, con una clave de API instantánea y sin llamada de ventas. Fíjate exactamente en lo que v0.1 nos autoriza a decir sobre eso. Dice que nada en el estante ayuda en un canal de banda estrecha, y que nadie entrega aislamiento del hablante a 8 kHz en absoluto. Todavía no dice que el nuestro sea mejor — ese número pertenece a la tabla, no a un párrafo, y va ahí cuando se mida. Null Test es cómo descubrimos qué construir, y cómo tú compruebas si estamos mintiendo al respecto.

Arnés e issues: github.com/anecho. Matriz completa: /benchmark. Inicio rápido: /docs. Si quieres que se añada una condición, un motor o un reconocedor, abre un issue — incluso si esperas que nos deje mal.

Siguiente
  • 24 oct 2026

    Alternativas a ai-coustics para agentes de voz y centros de llamadas (2026)

    Por qué hay equipos que buscan más allá de ai-coustics Quail Voice Focus, y una lista corta con fuentes según figuraba en octubre de 2026: Krisp VIVA, AssemblyAI Voice Focus, el aislamiento de voz de LiveKit Cloud, NVIDIA Speaker Focus, Anecho y referencias de código abierto. Hemos comparado ai-coustics con nuestro propio modelo en conversaciones en vivo: empate con faster-whisper, ventaja de v8_2 con Gemini Live, menos interrupciones falsas para ai-coustics, y la condición decide quién va delante.

  • 22 oct 2026

    Alternativas a Krisp para agentes de voz y centros de llamadas (2026)

    Por qué hay equipos que buscan más allá de Krisp VIVA, y una lista corta con fuentes según figuraba en octubre de 2026: ai-coustics Quail Voice Focus, AssemblyAI Voice Focus, el aislamiento de voz de LiveKit Cloud, NVIDIA Speaker Focus, Anecho y referencias de código abierto, con dónde se ejecuta cada uno, su precio público y si lo hemos medido. No hemos medido Krisp.

  • 20 oct 2026

    Comparativa de SDK de aislamiento de hablante (2026): Krisp, ai-coustics, AssemblyAI, LiveKit y Anecho

    Una comparación con fuentes del aislamiento de hablante para agentes de voz y centros de llamadas, tal como figuraba en octubre de 2026: dónde se ejecuta cada producto, latencia declarada, frecuencias de muestreo, integración, precio público y licencias. Krisp VIVA y Anecho declaran 15 ms en CPU; ai-coustics indica menos de 30 ms; AssemblyAI y LiveKit venden el aislamiento dentro de un servicio en la nube. Los números de calidad vienen solo de nuestro propio benchmark.