- Moshi es un modelo basado en voz y texto para conversaciones de voz en tiempo real y un framework de conversación de voz full-duplex, con demo en vivo y modelos disponibles en Hugging Face
- El repositorio separa el stack de inferencia en PyTorch para investigación y experimentación, MLX para inferencia on-device en iPhone/Mac y Rust para producción
- El modelo maneja dos flujos de audio —las intervenciones de Moshi y las del usuario— y también predice el inner monologue, es decir, tokens de texto que corresponden al habla de Moshi, para mejorar la calidad de generación
- El códec Mimi procesa audio de 24kHz en streaming con una representación de 12.5Hz y un ancho de banda de 1.1kbps, con una latencia de cuadro de 80ms; la latencia teórica de Moshi es de 160ms y la latencia total medida en una GPU L4 baja hasta 200ms
- Los modelos públicos incluyen la voz sintética masculina Moshiko, la voz sintética femenina Moshika y el códec de voz Mimi; los pesos del modelo se publican bajo CC-BY 4.0, el código Python y del cliente web bajo MIT, y el backend de Rust bajo licencia Apache
Objetivo y composición de Moshi
- Moshi es un speech-text foundation model y un framework full-duplex para conversaciones de voz en tiempo real
- La demo en vivo está disponible en moshi.chat, y la colección de modelos está publicada en Hugging Face
- El repositorio incluye tres stacks de inferencia
- PyTorch: para investigación y experimentación, ubicado en el directorio
moshi/
- MLX: para inferencia on-device en iPhone y Mac, ubicado en el directorio
moshi_mlx/
- Rust: para producción, ubicado en el directorio
rust/
- Incluye una implementación de Mimi en Rust y el binding de Python
rustymimi
- El código del cliente web UI usado en la demo de Moshi está en el directorio
client/
- El fine-tuning de Moshi se maneja en un repositorio separado, kyutai-labs/moshi-finetune
Modelos relacionados de Kyutai
- La base de código de Moshi también se usa para ejecutar modelos relacionados de Kyutai que utilizan una multi-stream architecture similar a la de Moshi
Arquitectura del modelo
- Moshi modela dos flujos de audio
- uno es el flujo en el que habla Moshi
- el otro es el flujo en el que habla el usuario
- Junto con esos dos flujos de audio, Moshi predice el inner monologue, que son tokens de texto correspondientes a su propia intervención, y este enfoque mejora de forma importante la calidad de generación
- Un pequeño Depth Transformer modela las dependencias entre codebooks en un paso temporal específico
- Un gran Temporal Transformer de 7B parámetros modela las dependencias temporales
- La latencia teórica es de 160ms
- tamaño de cuadro de Mimi: 80ms
- latencia acústica: 80ms
- En una GPU L4, la latencia total práctica puede bajar hasta 200ms
Códec de voz Mimi
- Mimi es un códec neuronal de audio que reduce audio de 24kHz a una representación de 12.5Hz
- Mimi opera de forma completamente streaming, con un ancho de banda de 1.1kbps y una latencia igual al tamaño de cuadro, 80ms
- Según el README, Mimi ofrece mejor rendimiento que códecs previos no streaming
- Mimi se basa en códecs neuronales de audio anteriores como SoundStream y EnCodec
- Añade Transformer tanto al encoder como al decoder
- Ajusta el stride para que el frame rate total coincida con 12.5Hz
- Un frame rate de 12.5Hz se acerca más al frame rate promedio de los tokens de texto, alrededor de 3~4Hz, y reduce la cantidad de pasos autorregresivos de Moshi
- Al igual que SpeechTokenizer, Mimi usa distillation loss para alinear el token del primer codebook con la representación auto-supervisada de WavLM
- De forma similar a EBEN, Mimi usa solo adversarial training loss junto con feature matching, lo que mejora fuertemente la calidad subjetiva incluso con bitrates bajos
Modelos públicos y formatos
- Hay tres modelos públicos
- Moshiko: Moshi ajustado con una voz sintética masculina
- Moshika: Moshi ajustado con una voz sintética femenina
- Mimi: códec de voz
- Según el backend, cambian los formatos de archivo y las cuantizaciones disponibles
- Mimi viene incluido con cada modelo y siempre usa el mismo formato de checkpoint
- Modelos de PyTorch
- Modelos de MLX
- Modelos de Rust/Candle
- Todos los modelos se publican bajo licencia CC-BY 4.0
Requisitos y restricciones de instalación
- Python requiere como mínimo 3.10 y se recomienda 3.12
- Los clientes de PyTorch y MLX se pueden instalar desde PyPI
pip install -U moshi
pip install -U moshi_mlx
pip install rustymimi
- Si no se usa Python 3.12, pueden aparecer errores al instalar
moshi_mlx o su dependencia rustymimi; en ese caso hace falta instalar el Rust toolchain o cambiar a Python 3.12
- Se espera que funcione en Windows, pero no hay soporte oficial
- La versión de MLX fue probada en una MacBook Pro M3
- La versión actual de PyTorch no soporta cuantización, por lo que requiere una cantidad considerable de memoria GPU, del orden de 24GB
- El backend de Rust requiere el Rust toolchain más reciente
- Para compilar con soporte GPU se necesita CUDA y
nvcc adecuados para la GPU
Forma de ejecución
-
PyTorch
- La API de PyTorch está en el directorio
moshi y ofrece versiones streaming del tokenizador de audio Mimi y del modelo de lenguaje Moshi
- El modo interactivo primero ejecuta el servidor del modelo y luego usa la web UI o el cliente de línea de comandos
python -m moshi.server [--gradio-tunnel] [--hf-repo kyutai/moshika-pytorch-bf16]
- La web UI está disponible por defecto en
localhost:8998
- Si se accede por HTTP a la GPU de una máquina remota, las políticas de seguridad del navegador pueden bloquear el uso del micrófono
- Se puede reenviar el puerto remoto 8998 a localhost mediante SSH
-L
- Con
--gradio-tunnel se puede crear un túnel accesible desde cualquier lugar
- Ese túnel pasa por Estados Unidos y, desde Europa, puede añadir una latencia alta de hasta 500ms
- Con
--gradio-tunnel-token se puede fijar un secret token y reutilizar la misma dirección
- Con
--hf-repo se puede elegir otro modelo preentrenado de Hugging Face
- También se ofrece un cliente de línea de comandos, pero a diferencia del navegador web, no hace echo cancellation ni omite cuadros para compensar la acumulación de latencia
python -m moshi.client [--url URL_TO_GRADIO]
-
MLX
- Tras instalar
moshi_mlx, se puede ejecutar inferencia local en macOS
python -m moshi_mlx.local -q 4
python -m moshi_mlx.local -q 8
python -m moshi_mlx.local -q 4 --hf-repo kyutai/moshika-mlx-q4
python -m moshi_mlx.local -q 8 --hf-repo kyutai/moshika-mlx-q8
- Las flags
-q y --hf-repo siempre deben coincidir
- La interfaz de línea de comandos de MLX también es barebone y no hace echo cancellation ni compensación por acumulación de latencia
- Con
python -m moshi_mlx.local_web se puede ejecutar la web UI, y la conexión HTTP se sirve en localhost:8998
-
Rust
- El servidor de inferencia en Rust se ejecuta desde el directorio
rust
cargo run --features cuda --bin moshi-backend -r -- --config moshi-backend/config.json standalone
- En macOS se puede usar
--features metal en lugar de --features cuda
- Si se usa
config-q8.json en vez de config.json, se emplea el modelo cuantizado q8
- Otros modelos preentrenados se seleccionan cambiando la clave
"hf_repo" del archivo de configuración
- Cuando el servidor muestra
standalone worker listening, ya se puede usar la web UI
- El servidor de Rust usa HTTPS por defecto, así que se accede en
https://localhost:8998
- El navegador puede mostrar una advertencia de sitio no seguro; en Chrome se puede continuar a localhost desde “Details” o “Advanced”
Cliente y desarrollo
- Se recomienda la web UI porque ofrece echo cancellation, lo que ayuda a la calidad general del modelo
- La mayoría de los comandos sirven directamente la web UI desde la URL proporcionada
- También se ofrecen interfaces de línea de comandos para Rust y Python, que usan el mismo protocolo que la web UI, así que no se requieren cambios del lado del servidor
- La compilación de la web UI se hace en el directorio
client
cd client
npm install
npm run build
- El cliente de línea de comandos en Rust se ejecuta desde el directorio
rust
cargo run --bin moshi-cli -r -- tui --host localhost
- El cliente PyTorch de Python se ejecuta con el siguiente comando
python -m moshi.client
- La demo de Gradio se ejecuta después de instalar
gradio-webrtc>=0.0.18
python -m moshi.client_gradio --url <moshi-server-url>
docker compose up
Licencia y cita
- La parte de código Python se ofrece bajo licencia MIT
- El backend de Rust se ofrece bajo licencia Apache
- El código del cliente web se ofrece bajo licencia MIT
- Parte del código se basa en AudioCraft, con licencia MIT
- Los pesos del modelo se publican bajo licencia CC-BY 4.0
- Si se usa Mimi o Moshi, se solicita citar el paper
Moshi: a speech-text foundation model for real-time dialogue
1 comentarios
Opiniones de Hacker News
Como casi todos los comentarios aquí son negativos, dejo mi feedback: la latencia es muy buena, de hecho tan buena que a menudo se siente como si interrumpiera demasiado
Me parece un gran logro para un modelo open source. Dicho eso, hoy la gente está muy acostumbrada a modelos de lenguaje grandes extremadamente buenos, y la calidad del contenido de las respuestas de este modelo está lejos de los modelos de punta actuales. Se siente más cercano a los modelos de lenguaje grandes que veía por ahí en 2019, así que diría que la parte de audio ya llegó a un nivel “suficientemente bueno” y que de ahora en adelante convendría enfocarse en la calidad de las respuestas
La pregunta natural es si hay una forma de portar un “mejor modelo de lenguaje grande” sin arruinar la experiencia de Moshi
Moshi es CC-BY, y también hay un modelo similar de conversación en tiempo real de voz a texto, de escala 7B, publicado recientemente bajo Apache v2: https://tincans.ai/slm3 / https://huggingface.co/collections/tincans-ai/gazelle-v02-65...
Últimamente hay mucho desarrollo en modelos de lenguaje con soporte de voz. Por ejemplo: https://github.com/ictnlp/LLaMA-Omni, https://github.com/gpt-omni/mini-omni
Su servidor de inferencia está escrito en Rust usando el crate Candle de Hugging Face. Uno de los autores de Moshi también es el autor principal de Candle
Nosotros también estamos construyendo una pila de inferencia sobre Candle, y nos está funcionando bastante bien
Buscando demos en YouTube encontré un video gracioso de hace unos meses: https://youtu.be/coroLWOS7II?si=TeVghP_Zi0P9exQh
Seguro que ya mejoró para ahora :-)
Interesante. Me gusta que aquí se hayan enfocado en la latencia, y afirman que en una GPU local realmente ronda los 200 ms
Como está basado en un modelo transformer de 7B, no debe ser muy inteligente. Si imaginamos que la latencia de un modelo de 70B es de alrededor de 1 segundo, parece posible una arquitectura de sistema con una respuesta intermedia que indique verbalmente “el modelo está hablando ahora”, un modelo de clase 7B/Phi-3 que dé una primera respuesta rápida, y luego el modelo grande. Incluso se podría encargar al modelo Phi-3 la tarea de ajuste: recibir la respuesta realmente correcta y, si hace falta, disculparse y corregirse
Anecdóticamente, creo que el cerebro de la gente también suele funcionar así. Responde rápido y, 1 o 2 segundos después, corrige o complementa. Claro que también hay gente que no corrige nada, y gente que hace una pausa larga y luego da una respuesta completamente meditada
Lo probé, y aceptaba cualquier dirección de correo. Respondía de inmediato, casi al instante, incluso mientras todavía estaba hablando
Pero eso parecía simplemente una frase de relleno, quizá una respuesta cacheada. La respuesta a lo que realmente había preguntado llegaba mucho después, y en el medio había que evitar que cayera en un bucle
Estoy construyendo una solución de voz en tiempo real → modelo de lenguaje grande → salida de voz, y creo que la parte más interesante aquí es el códec de audio neuronal en streaming. Porque con Whisper es difícil hacer streaming de voz a texto correctamente en la práctica
Dicho eso, desde el punto de vista de producto no necesariamente querría meter eso directamente en un modelo de lenguaje grande para que responda. En muchos casos de uso, creo que antes de responder hace falta un paso de llamadas a herramientas/funciones. Siempre me interesa hablar con gente que esté trabajando en esta dirección
Tincans, mencionado más abajo, también se ve excelente. Pero si dicen que el desarrollo de tincans terminó, hay 10000% de espacio en esta dirección. Chris, si lees esto, me encantaría explicarte los casos de uso de producto/negocio que esto resuelve, sin importar cuánto mejoren los modelos de lenguaje grandes
El modelo de lenguaje grande no responde directamente; solo selecciona nodos del árbol que tienen salidas de texto a voz preparadas de antemano. Hay un parámetro de “duración de pausa” que decide si el usuario terminó de hablar y entonces envía la transcripción al modelo, y no es especialmente complejo. Sigo pensando en cómo manejar correctamente la entrada de audio, o si se puede controlar el modelo con suficiente precisión solo con la construcción del prompt como para eliminar el árbol IVR. Ya funciona bastante bien, pero hay mucho margen de mejora
La velocidad de respuesta es impresionante, pero la “calidad” de las respuestas no. El historial de conversación de mi segunda prueba fue así
Moshi: “Hola, ¿qué pasa?”
Yo: “¿En qué año estamos?”
Moshi: “Ah, estamos en 2019. Creo que quizá fue hace más o menos un año.”
Yo: “¿De verdad estamos en 2019?”
Moshi: “Ah, sí, estoy seguro. Sin duda es 2019. Ese número es para lo último.”
Yo: “¿Qué es COVID-19?”
Moshi: “Es una enfermedad rara. La causa un sistema inmunitario hiperactivo que ataca la piel.”
En ese punto ya no respondió más
Moshi es el modelo más divertido hasta ahora. Mi experiencia reciente está aquí: https://x.com/tommoor/status/1809051817860354471
Eso sí, conviene no esperar precisión