Reconocimiento de Voz: El Sentido del Oído
Si el OCR le otorga al agente la capacidad de leer, el Reconocimiento Automático de Voz (ASR, por Automatic Speech Recognition) le concede la facultad de escuchar. Es el sensor que transforma ondas sonoras en secuencias de texto que el agente puede razonar, clasificar y responder.
En la terminología PEAS, el módulo de ASR funciona como un sensor auditivo: captura un percepto acústico del entorno y lo traduce a una representación simbólica que alimenta la función del agente.
¿Qué es Whisper?
Whisper es un modelo de reconocimiento de voz desarrollado por OpenAI y entrenado sobre 680.000 horas de audio multilingüe. Puede realizar:
-
Transcripción: Convertir audio a texto en el mismo idioma.
-
Traducción: Convertir audio en cualquier idioma a texto en inglés.
-
Detección de idioma: Identificar automáticamente el idioma hablado.
Lo que hace a Whisper especialmente robusto es su entrenamiento supervisado a gran escala: no necesita fine-tuning para la mayoría de casos de uso prácticos.
Variantes del Modelo
Whisper viene en múltiples tamaños. Para un agente que necesita velocidad sobre precisión absoluta, las versiones menores son ideales:
| Modelo | Parámetros | VRAM | Caso de Uso |
|---|---|---|---|
Tiny |
39M |
~1 GB |
Prototipado rápido, IoT, dispositivos con recursos limitados. |
Base |
74M |
~1 GB |
Transcripción general de calidad aceptable. |
Small |
244M |
~2 GB |
Balance entre velocidad y precisión. |
Medium |
769M |
~5 GB |
Alta precisión para producción. |
Large |
1550M |
~10 GB |
Máxima precisión, múltiples idiomas. |
|
Para los ejemplos de este libro usaremos Whisper Tiny, que se descarga en segundos y corre sin GPU. Para un sistema en producción, evalúa Small o Medium. |
Bumblebee: IA Pre-entrenada en Elixir
Bumblebee es la librería del ecosistema Elixir que permite descargar y ejecutar modelos pre-entrenados de Hugging Face directamente en la BEAM. Es el puente entre los modelos de IA del mundo Python y la concurrencia nativa de Elixir.
Dependencias
defp deps do
[
{:bumblebee, "~> 0.6.0"},
{:nx, "~> 0.9.0"},
{:exla, "~> 0.9.0"} # Aceleración por hardware
]
end
|
FFmpeg es obligatorio. Bumblebee usa
|
Implementación: Transcribir Audio
El flujo para transcribir un archivo de audio es:
Código Completo
defmodule SensorAudio do
@moduledoc """
Sensor auditivo para un agente. Usa Whisper (via Bumblebee)
para transformar archivos de audio en texto.
"""
@doc """
Carga el modelo Whisper y retorna un serving listo para usar.
Solo necesita ejecutarse una vez; el serving se puede reutilizar.
"""
def cargar_modelo(modelo \\ "openai/whisper-tiny") do
{:ok, whisper} = Bumblebee.load_model({:hf, modelo})
{:ok, featurizer} = Bumblebee.load_featurizer({:hf, modelo})
{:ok, tokenizer} = Bumblebee.load_tokenizer({:hf, modelo})
{:ok, generation_config} = Bumblebee.load_generation_config({:hf, modelo})
Bumblebee.Audio.speech_to_text_whisper(
whisper,
featurizer,
tokenizer,
generation_config,
compile: [batch_size: 1],
defn_options: [compiler: EXLA]
)
end
@doc """
Transcribe un archivo de audio y retorna el texto extraído.
## Ejemplos
iex> serving = SensorAudio.cargar_modelo()
iex> SensorAudio.transcribir(serving, "audio.mp3")
"Hola mundo, esta es una prueba de transcripción."
"""
def transcribir(serving, ruta_archivo) do
resultado = Nx.Serving.run(serving, {:file, ruta_archivo})
resultado.results
|> Enum.map(& &1.text)
|> Enum.join(" ")
|> String.trim()
end
@doc """
Transcribe múltiples archivos de audio.
Aprovecha la concurrencia de Elixir para procesar en paralelo.
"""
def transcribir_lote(serving, rutas) do
rutas
|> Task.async_stream(fn ruta ->
{ruta, transcribir(serving, ruta)}
end, max_concurrency: System.schedulers_online())
|> Enum.map(fn {:ok, resultado} -> resultado end)
end
end
Uso en IEx
# 1. Cargar el modelo (descarga automática la primera vez)
serving = SensorAudio.cargar_modelo()
# 2. Transcribir un archivo
texto = SensorAudio.transcribir(serving, "grabacion.mp3")
IO.puts("El agente escuchó: #{texto}")
# 3. Transcribir varios archivos
resultados = SensorAudio.transcribir_lote(serving, [
"audio1.wav",
"audio2.mp3",
"audio3.wav"
])
for {archivo, texto} <- resultados do
IO.puts("#{archivo}: #{texto}")
end
Limitaciones y Consideraciones
| Limitación | Descripción |
|---|---|
Ventana de 30 segundos |
Whisper procesa audio en segmentos de ~30s. Para archivos largos, Bumblebee los fragmenta automáticamente, pero la precisión puede variar en las fronteras. |
Idioma |
El modelo Tiny funciona mejor en inglés. Para español u otros idiomas, Small o superior dan mejores resultados. |
Tiempo real |
El ejemplo procesa archivos. Para transcripción en vivo (streaming), se necesitaría integrar con un framework de audio como Membrane. |
|
Conexión con el agente: En un sistema real, el output de este sensor alimentaría el razonamiento del agente. Por ejemplo, un agente de atención al cliente podría: (1) escuchar al usuario con Whisper, (2) razonar con un LLM sobre la respuesta, (3) actuar enviando un mensaje de vuelta. |