- Reconocimiento de voz en streaming con una implementación basada en Rust que puede ejecutarse tanto en entornos nativos como en el navegador, usando el framework ML Burn
- El modelo se basa en Voxtral Mini 4B Realtime de Mistral y realiza inferencia completamente del lado del cliente en una pestaña del navegador mediante WASM + WebGPU
- El modelo cuantizado Q4 GGUF (2.5 GB) puede ejecutarse en el navegador, mientras que el modelo F32 basado en SafeTensors (9 GB) funciona en entornos nativos
- Para resolver las limitaciones del navegador (asignación de 2 GB, espacio de direcciones de 4 GB, restricciones de lectura de GPU, etc.), aplica técnicas como sharding, carga en dos etapas y procesamiento asíncrono de tensores
- Está publicado bajo licencia Apache-2.0 y se puede probar una demo en tiempo real en HuggingFace Spaces
Resumen de Voxtral Mini 4B Realtime (Rust)
- Implementación completa en Rust y el framework ML Burn del modelo Voxtral Mini 4B Realtime de Mistral
- Permite ejecutar reconocimiento de voz en streaming en entornos locales y de navegador
- La versión para navegador usa WASM (WebAssembly) y WebGPU para funcionar del lado del cliente
- El modelo cuantizado Q4 GGUF (aprox. 2.5 GB) se ejecuta en el navegador, y el modelo F32 SafeTensors (aprox. 9 GB) se usa en entornos nativos
- Ofrece una demo en tiempo real en HuggingFace Spaces
Arquitectura
- El audio de entrada (16 kHz mono) se convierte en un espectrograma Mel y luego pasa por un encoder (32 capas) y un decoder (26 capas) para transformarse en texto
- Etapas principales del procesamiento
- Espectrograma Mel → encoder (32 capas, 1280 dimensiones) → Conv con downsampling 4x → adaptador (3072 dimensiones) → decoder (GQA 32Q/8KV)
- Se ofrecen dos rutas de inferencia
- F32 (native): basado en SafeTensors, usa operaciones de tensores de Burn
- Q4 GGUF (native + browser): cuantización GGUF Q4_0, usa shaders WGSL personalizados
Soluciones técnicas para ejecutarlo en el navegador
- Para ejecutar un modelo 4B dentro del navegador, se resolvieron 5 restricciones
- Límite de asignación de 2 GB → lectura de múltiples buffers con
ShardedCursor
- Límite de espacio de direcciones de 4 GB → carga en 2 etapas (parseo, liberación del reader y finalización posterior)
- Tabla de embeddings de 1.5 GiB → embeddings Q4 en GPU + búsqueda de filas en CPU
- Lectura síncrona de GPU no permitida → uso de
into_data_async().await
- Límite de 256 workgroups → restricción del tamaño del kernel mediante un parche a cubecl-wgpu
Corrección del padding Q4
- El mistral-common base rellena el audio con 32 tokens de silencio, pero eso solo cubre la mitad de los 38 prefijos del decoder
- En el modelo cuantizado Q4_0, esto provoca errores cuando la entrada comienza con voz de inmediato
- Para resolverlo, el padding se amplió a 76 tokens (= 38 tokens del decoder) para llenar todo el prefijo con silencio
Compilación y pruebas
- Opciones de compilación
- Predeterminado:
cargo build --release (wgpu + native-tokenizer)
- Para navegador:
wasm-pack build --target web --features wasm
- Pruebas
- Soporta pruebas unitarias y de integración basadas en GPU
- Las pruebas E2E en navegador se ejecutan con Playwright + un entorno real con GPU
- En CI, como no hay GPU, esas pruebas se omiten
Preparación del modelo y sharding
Licencia y recursos
1 comentarios
Comentarios en Hacker News
Si a la gente le interesa, @antirez publicó una implementación en C de Voxtral Mini 4B
Se puede ver en antirez/voxtral.c
Yo hice mi fork y estoy agregando una implementación con CUDA y algunas mejoras
Funciona bastante bien, pero todavía no alcanza la velocidad del endpoint API de Mistral AI
Siento que antes de ponerme a escribir código tendría que leer y aprender del tema, así que estaría bueno tener alguna guía de referencia
No tengo muy clara la diferencia, pero parece que la reacción de la comunidad es mejor con esa
Probé la demo y hay que presionar el botón Mic, grabar y luego hacer clic en “Stop and transcribe” para ver el resultado
Me pregunto si se podría hacer un modo realmente en tiempo real, donde los subtítulos aparezcan apenas 1 o 2 segundos después de que el usuario habla
La demo server-side de Hugging Face lo hace con un modelo de 8.5 GB basado en GPU
Pero con una UI basada en ring buffer se puede hacer algo parecido
Yo uso Whisper así en Flutter, y también corro inferencia GGUF de llama.cpp desde Dart
Incluso en una M4 Max no es tiempo real, y Whisper en dispositivos de 2022 en adelante va casi en tiempo real con ONNX
Creo que en hardware de consumo la velocidad de inferencia importa más que mejorar la precisión (WER)
Este tipo de modelos abiertos on-premise es justo la dirección que de verdad se necesita
Tanto usuarios como empresas prefieren algo así. Parece que Mistral entendió bien eso
La era de los modelos abiertos se va a poner todavía más interesante
Muy buen trabajo. Estaría bueno integrarlo con handy.computer, y me pregunto si hay planes de soporte para streaming
La primera versión probablemente no va a tener soporte de streaming
Gracias a eso conocí una buena herramienta, y ahora siento que de verdad hace falta soporte para Voxtral
No conozco mucho el modelo, pero probé Nvidia Parakeet y funciona muy bien
Me pregunto si un modelo de 9 GB como este hay que mantenerlo siempre cargado en la memoria de la GPU para usarlo en tiempo real, o si se puede cargar cada vez
Las frases cortas se convierten casi al instante, y las largas en 1 a 3 segundos
Una pequeña pérdida de precisión no importa para usos de conversación con IA
En la app open source Handy (link) usan Parakeet V3, pero la implementación en C era mucho más lenta
En STT la velocidad es la clave de la UX
La latencia aparece cuando se trae un modelo nuevo o se cambia un contexto grande
La mayor parte del tiempo el modelo ya está cargado, así que la variable principal son los tokens por segundo
En arquitecturas complejas con varios agentes se vuelve más lento por el cambio de contexto
El prompt caching de ik_llama ayuda a acelerar estas situaciones
En resumen, mientras no cambies de modelo o de contexto con frecuencia, la latencia de carga de pesos no es un gran problema
Me pregunto si es eficiente que una pestaña del navegador descargue un modelo de 2.5 GB para luego borrarlo poco después
Aunque la velocidad de internet y el almacenamiento se hayan abaratado, este enfoque se siente desperdiciador
Me gusta el cómputo del lado del cliente, pero para modelos de este tamaño parece más lógico correrlos en el servidor
Pero eso podría cambiar si aparece un estándar de API web para LLM
Si el navegador se comunica con el modelo preferido del usuario y abstrae la inferencia local/remota, los sitios podrían compartir modelos entre sí
Si en 2026 el problema es un modelo local de 2.5 GB, ya no sé qué consideraríamos inseguro
La evolución fue imposible → centralizado → local, y si el costo de eso es 2.5 GB, me parece totalmente aceptable
Está genial que corra en el navegador, pero no quiero un mundo donde los sitios web descarguen 2.5 GB en segundo plano
Nano se guarda en almacenamiento local y se comparte entre sitios, así que se descarga una sola vez
Mistral no parece funcionar así
Las estadísticas relacionadas están resumidas en esta entrada de blog
creo que el entorno sandbox del navegador es más seguro que instalar un paquete o descargar un ejecutable
Pronto también nos acostumbraremos a esto :-)
En mi entorno (Firefox, Asahi Linux, M1 Pro) no funciona bien
Dije “hello” y como un minuto después empezó a imprimir palabras raras repetidas
Pregunta simple: me gustaría saber qué tan buenos son los modelos abiertos como Mistral comparados con OpenAI o Anthropic
Si ya alcanzan para usar funciones de LLM de forma privada en una máquina personal,
o si todavía están bastante lejos de los modelos comerciales
Proyecto interesante, y también da gusto ver que usa el framework burn
Pero lo corrí en la última versión de Chromium, el sistema se congeló y el OS se apagó a la fuerza
Justo después de descargar el modelo también se cortó la conexión VPN, y no sé por qué porque no había límite de ancho de banda