2 puntos por kdrkdrkdr 7 시간 전 | Aún no hay comentarios. | Compartir por WhatsApp

Es un proyecto hecho por mí.

  • Biblioteca que reimplementa en C puro el runtime de FastEnhancer-Medium (modelo de mejora de voz en streaming a 48 kHz)
  • Modelo original: https://github.com/aask1357/fastenhancer (Ahn et al., 2025)
  • Usa tal cual los pesos a 48 kHz que el repositorio original publicó adicionalmente después del paper (16 kHz). Sin reentrenamiento, fine-tuning ni calibration set
  • El modelo y los pesos son de los autores originales; lo optimizado aquí es la parte del runtime

■ Rendimiento

  • En un solo núcleo de Apple M2 da un real-time factor de 0.069. En la misma máquina, ejecutar el mismo grafo con ONNX Runtime da 0.230, así que es 3.3 veces más rápido
  • En un Galaxy S23+ (Snapdragon 8 Gen 2) da 0.096
  • Casi no hay pérdida de calidad. En 824 utterances de VoiceBank-DEMAND, frente al modelo fp32, se queda en -0.006 PESQ. No es un nivel de diferencia que se pueda distinguir al oído

■ Optimizaciones aplicadas

No salió 3 veces más rápido por una sola técnica; se ajustaron varias capas por separado.

  • Cuantización: el rango de activaciones se recalcula en cada frame. Por eso no hace falta ajustar ni distribuir un calibration set, y no se rompe aunque cambie la distribución de entrada
  • Convolución: se aplica Winograd F(2,3) a conv con k=3, y hasta el epílogo que sigue (dequant + bias + SiLU + fp16 write) se pliega en el mismo pase para eliminar buffers intermedios
  • Recurrencia: el GRU se fusiona por completo en un kernel por tier. La multiplicación de matrices del lado de entrada, la del estado oculto, las tres compuertas r/z/n y la actualización del hidden se resuelven en un solo kernel, así que el acumulador int32 no se derrama a memoria
  • Atención: softmax procesa directamente puntajes int32. Como no se crea en absoluto una matriz de puntajes fp32, se elimina ese tráfico de memoria de ida y vuelta
  • Memoria: los estados cross-stage (GRU hidden, encoder skip) se guardan en fp16 para reducir a la mitad el ancho de banda entre frames
  • Kernels: se escribieron manualmente 6 kernels int8 GEMM por ISA y se seleccionan automáticamente al inicializar (ARM NEON/DOTPROD/I8MM, x86 AVX2/AVX-VNNI/AVX-512)
  • El resto de la lista de optimizaciones puede verse en el Github del proyecto

■ Estabilidad en tiempo real

  • No se dio por terminado con un solo benchmark de 37 segundos; se verificó ejecutándolo durante 30 minutos continuos con el ciclo real de callback de audio
  • El M2 se mantuvo dentro del presupuesto por frame durante los 30 minutos completos (p99 0.56)

■ Otros

  • 0 dependencias externas. Se compila con cmake + make y la biblioteca estática pesa 162 KiB
  • La API pública tiene 4 funciones (fe_init / fe_run / fe_reset / fe_free)
  • Blob de pesos de 565 KB, 511,754 parámetros
  • Licencia MIT

Aún no hay comentarios.

Aún no hay comentarios.