1 pontos por GN⁺ 2024-09-20 | 1 comentários | Compartilhar no WhatsApp
  • Moshi é um modelo baseado em fala e texto para conversas por voz em tempo real e também um framework de diálogo por voz full-duplex, com demo ao vivo e modelos no Hugging Face
  • O repositório separa as stacks de inferência em PyTorch para pesquisa e experimentação, MLX para inferência on-device em iPhone/Mac e Rust para produção
  • O modelo lida com dois fluxos de áudio — a fala do Moshi e a fala do usuário — e também prevê o inner monologue, que são tokens de texto correspondentes à própria fala do Moshi, melhorando a qualidade de geração
  • O codec Mimi processa streaming de áudio a 24kHz com representação de 12.5Hz e largura de banda de 1.1kbps, com latência de quadro de 80ms; a latência teórica do Moshi é de 160ms, e a latência total medida em GPU L4 chega a no mínimo 200ms
  • Os modelos públicos incluem a voz sintética masculina Moshiko, a voz sintética feminina Moshika e o codec de voz Mimi; os pesos dos modelos são licenciados em CC-BY 4.0, o código cliente em Python e web em MIT, e o backend em Rust em Apache

Objetivo e composição do Moshi

  • Moshi é um speech-text foundation model e um framework full-duplex para conversas por voz em tempo real
  • A demo ao vivo está disponível em moshi.chat, e a coleção de modelos foi publicada no Hugging Face
  • O repositório inclui três stacks de inferência
    • PyTorch: para pesquisa e experimentação, localizada no diretório moshi/
    • MLX: para inferência on-device em iPhone e Mac, localizada no diretório moshi_mlx/
    • Rust: para produção, localizada no diretório rust/
      • Inclui a implementação do Mimi em Rust e o binding Python rustymimi
  • O código do cliente web UI usado na demo do Moshi está no diretório client/
  • O fine-tuning do Moshi é tratado em um repositório separado, kyutai-labs/moshi-finetune

Modelos relacionados da Kyutai

  • A codebase do Moshi também é usada para executar modelos relacionados da Kyutai que utilizam uma multi-stream architecture semelhante à do Moshi

Arquitetura do modelo

  • O Moshi modela dois fluxos de áudio
    • um fluxo em que o Moshi fala
    • outro fluxo em que o usuário fala
  • Junto com os dois fluxos de áudio, o Moshi prevê o inner monologue, que são tokens de texto correspondentes à própria fala, e esse método melhora bastante a qualidade de geração
  • Um pequeno Depth Transformer modela as dependências entre codebooks em um passo temporal específico
  • Um grande Temporal Transformer de 7B parâmetros modela as dependências temporais
  • A latência é teoricamente de 160ms
    • tamanho de quadro do Mimi: 80ms
    • latência acústica: 80ms
  • Em uma GPU L4, a latência total prática pode chegar a 200ms no mínimo

Codec de voz Mimi

  • Mimi é um codec de áudio neural que reduz áudio de 24kHz para uma representação de 12.5Hz
  • O Mimi opera de forma totalmente em streaming, com largura de banda de 1.1kbps e latência igual ao tamanho do quadro, 80ms
  • Segundo o README, o Mimi entrega desempenho melhor do que codecs não streaming já existentes
  • O Mimi é baseado em codecs de áudio neurais anteriores, como SoundStream e EnCodec
    • adiciona Transformer tanto no encoder quanto no decoder
    • ajusta o stride para alinhar toda a taxa de quadros em 12.5Hz
  • A taxa de quadros de 12.5Hz fica mais próxima da taxa média dos tokens de texto, cerca de 3~4Hz, reduzindo o número de etapas autorregressivas do Moshi
  • Assim como o SpeechTokenizer, o Mimi usa distillation loss para alinhar o token do primeiro codebook às representações autossupervisionadas do WavLM
  • Assim como o EBEN, o Mimi usa apenas adversarial training loss junto com feature matching, o que melhora fortemente a qualidade subjetiva mesmo em bitrates baixos

Modelos públicos e formatos

Requisitos e restrições de instalação

  • Python 3.10 ou superior é necessário, e 3.12 é recomendado
  • Os clientes PyTorch e MLX podem ser instalados via PyPI
pip install -U moshi
pip install -U moshi_mlx
pip install rustymimi
  • Se você não estiver usando Python 3.12, podem ocorrer erros durante a instalação de moshi_mlx ou da dependência rustymimi; nesse caso, é necessário instalar o Rust toolchain ou migrar para Python 3.12
  • Espera-se que funcione no Windows, mas não há suporte oficial
  • A versão MLX foi testada em um MacBook Pro M3
  • A versão atual em PyTorch não oferece suporte a quantização, então exige uma quantidade significativa de memória de GPU, na faixa de 24GB
  • O backend em Rust requer o Rust toolchain mais recente
  • Para compilar com suporte a GPU, são necessários o CUDA compatível com a GPU e o nvcc

Formas de execução

  • PyTorch

    • A API PyTorch fica no diretório moshi e fornece versões streaming do tokenizador de áudio Mimi e do modelo de linguagem Moshi
    • No modo interativo, primeiro é preciso iniciar o servidor do modelo e depois usar a web UI ou o cliente de linha de comando
    python -m moshi.server [--gradio-tunnel] [--hf-repo kyutai/moshika-pytorch-bf16]
    
    • A web UI fica acessível por padrão em localhost:8998
    • Se você acessar a GPU de uma máquina remota via HTTP, o uso do microfone pode ser bloqueado por políticas de segurança do navegador
    • É possível encaminhar a porta remota 8998 para localhost com SSH -L
    • Com --gradio-tunnel, é possível criar um túnel acessível de qualquer lugar
    • Esse túnel passa pelos Estados Unidos e pode adicionar até 500ms de latência extra para usuários na Europa
    • Com --gradio-tunnel-token, é possível definir um secret token fixo e reutilizar o mesmo endereço
    • Com --hf-repo, é possível selecionar outro modelo pré-treinado do Hugging Face
    • Também existe um cliente de linha de comando, mas ele, ao contrário do navegador, não faz echo cancellation nem pula quadros para compensar o acúmulo de latência
    python -m moshi.client [--url URL_TO_GRADIO]
    
  • MLX

    • Após instalar moshi_mlx, é possível executar inferência local no 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
    
    • As flags -q e --hf-repo devem sempre corresponder
    • A interface de linha de comando do MLX também é barebone e não faz echo cancellation nem compensação do acúmulo de latência
    • É possível iniciar a web UI com python -m moshi_mlx.local_web, e a conexão HTTP é fornecida em localhost:8998
  • Rust

    • O servidor de inferência em Rust é executado a partir do diretório rust
    cargo run --features cuda --bin moshi-backend -r -- --config moshi-backend/config.json standalone
    
    • No macOS, você pode usar --features metal no lugar de --features cuda
    • Se usar config-q8.json em vez de config.json, será usado o modelo quantizado q8
    • Outros modelos pré-treinados podem ser selecionados alterando a chave "hf_repo" no arquivo de configuração
    • Quando o servidor exibir standalone worker listening, a web UI poderá ser usada
    • O servidor Rust usa HTTPS por padrão, então o acesso é feito em https://localhost:8998
    • O navegador pode mostrar um aviso de site inseguro; no Chrome, é possível continuar para localhost em “Details” ou “Advanced”

Cliente e desenvolvimento

  • A web UI é recomendada porque oferece echo cancellation, o que ajuda na qualidade geral do modelo
  • A maioria dos comandos serve a web UI diretamente na URL fornecida
  • Também existem interfaces de linha de comando para Rust e Python, que usam o mesmo protocolo da web UI, sem necessidade de mudanças no servidor
  • O build da web UI é feito no diretório client
cd client
npm install
npm run build
  • O cliente de linha de comando em Rust é executado a partir do diretório rust
cargo run --bin moshi-cli -r -- tui --host localhost
  • O cliente Python PyTorch é executado com o comando abaixo
python -m moshi.client
  • A demo em Gradio pode ser executada após instalar gradio-webrtc>=0.0.18
python -m moshi.client_gradio --url <moshi-server-url>
docker compose up

Licença e citação

  • Parte do código em Python é fornecida sob licença MIT
  • O backend em Rust é fornecido sob licença Apache
  • O código do cliente web é fornecido sob licença MIT
  • Parte do código é baseada no AudioCraft, sob licença MIT
  • Os pesos dos modelos são publicados sob licença CC-BY 4.0
  • Ao usar o Mimi ou o Moshi, é solicitado citar o artigo Moshi: a speech-text foundation model for real-time dialogue

1 comentários

 
GN⁺ 2024-09-20
Opiniões no Hacker News
  • Como quase todos os comentários aqui são negativos, deixo meu feedback: a latência é muito boa — na verdade, boa até demais, a ponto de frequentemente parecer que ele interrompe a fala.
    Para um modelo open source, considero uma grande conquista. Dito isso, hoje as pessoas estão muito acostumadas a modelos de linguagem de grande porte excelentes, e a qualidade do conteúdo das respostas deste modelo está longe dos modelos de ponta atuais. A sensação é mais próxima dos modelos de linguagem de grande porte que víamos por volta de 2019; então, no lado de áudio, parece que já chegou a um nível “bom o suficiente”, e daqui para frente seria melhor focar na qualidade das respostas

    • Concordo totalmente. A latência é boa e a tecnologia é bacana. Rust, execução na borda em notebook de consumidor — tudo isso é impressionante.
      A pergunta natural é se existe uma forma de portar um “modelo de linguagem de grande porte melhor” sem prejudicar a experiência do Moshi
  • Moshi é CC-BY, e também há um modelo semelhante de conversa em tempo real fala-texto, de escala 7B, lançado recentemente sob Apache v2: https://tincans.ai/slm3 / https://huggingface.co/collections/tincans-ai/gazelle-v02-65...

    • A diferença importante é que tincans não é um modelo fala-para-fala. Ele usa modelos separados de detecção de fala/pausa e uma etapa final de texto-para-fala
  • Recentemente tem havido bastante desenvolvimento em modelos de linguagem com suporte a voz. Exemplos incluem https://github.com/ictnlp/LLaMA-Omni e https://github.com/gpt-omni/mini-omni

  • O servidor de inferência deles é escrito em Rust usando o crate Candle da Hugging Face. Um dos autores do Moshi também é o autor principal do Candle.
    Nós também estamos criando uma stack de inferência sobre o Candle e estamos bem satisfeitos com ele

    • Tenho muito interesse. Existe algo equivalente ao vLLM? Fico curioso se vocês tiveram que reescrever coisas como processamento em lote ou paged attention
  • Procurando demos no YouTube, encontrei um vídeo engraçado de alguns meses atrás: https://youtu.be/coroLWOS7II?si=TeVghP_Zi0P9exQh
    Imagino que agora já tenha melhorado, claro :-)

  • Interessante. Gosto do foco em latência aqui, e eles afirmam que, em uma GPU local, ela fica de fato em torno de 200 ms.
    Como é baseado em um modelo Transformer 7B, provavelmente não será muito inteligente. Imaginando que a latência de um modelo 70B seja de cerca de 1 segundo, parece possível uma arquitetura de sistema com respostas intermediárias dizendo verbalmente “o modelo está falando agora”, um modelo de nível 7B/Phi-3 para respostas iniciais rápidas, e depois o modelo maior. O modelo Phi-3 poderia até ficar responsável pela coordenação: receber a resposta correta de fato e, se necessário, pedir desculpas e corrigir.
    Anedoticamente, acho que o cérebro das pessoas muitas vezes funciona assim: reage rápido e, 1 ou 2 segundos depois, corrige ou complementa. Claro, também há quem nunca corrija nada, e quem faça uma longa pausa para dar uma resposta totalmente ponderada

  • Testei, e aceitava qualquer endereço de e-mail. Ele responde imediatamente, quase na hora, até enquanto você ainda está falando.
    Mas isso parecia só frase de preenchimento, talvez até uma resposta em cache. A resposta ao que você realmente perguntou vem bem depois, e você precisa evitar que ele caia em loop no meio

  • Estou criando uma solução de voz em tempo real → modelo de linguagem de grande porte → saída de voz, e acho que a parte mais interessante aqui é o codec de áudio neural com streaming. Isso porque, com o Whisper, é difícil fazer fala-para-texto realmente em streaming.
    Dito isso, do ponto de vista de produto, eu não necessariamente gostaria de colocar isso diretamente em um modelo de linguagem de grande porte para ele responder. Em muitos casos de uso, acho que é necessária uma etapa de chamada de ferramentas/funções antes da resposta. Estou sempre aberto a conversar com quem estiver trabalhando nessa direção.
    O tincans mencionado abaixo também parece excelente. Mas, como dizem que o desenvolvimento do tincans foi encerrado, há 10000% de espaço nessa direção. Se o Chris estiver lendo isto, eu adoraria explicar os casos de uso de produto/negócio que isso resolve, por melhores que os modelos de linguagem de grande porte fiquem

    • Também estou experimentando esse fluxo. Uso uma configuração de “streaming” com o Whisper, cortando amostras para começar a transcrever enquanto o usuário ainda está falando, e passo o resultado para o Mistral 8B, que atua como mediador de conversa seguindo uma árvore de URA/IVR predefinida e chamando ferramentas.
      O modelo de linguagem de grande porte não responde diretamente; ele só escolhe nós da árvore que têm saída texto-para-fala preparada. Há um parâmetro de “duração da pausa” que decide se o usuário terminou de falar para então enviar a transcrição ao modelo, e isso não é especialmente complicado. Continuo pensando em como lidar corretamente com entrada de áudio e se seria possível controlar o modelo com precisão suficiente, apenas pela composição do prompt, para eliminar a árvore de URA/IVR. Hoje já funciona razoavelmente bem, mas há muito espaço para melhorar
    • A parte de precisar de uma etapa de chamada de ferramentas/funções antes da resposta é algo que eu construí quase exatamente há 1 ano :) Funcionava bem, mas não era rápido o suficiente, e foi por isso que acabei criando um modelo acoplado
  • A velocidade de resposta é impressionante, mas a “qualidade” das respostas não é. O histórico da conversa do meu segundo teste foi assim:
    Moshi: “Olá, o que aconteceu?”
    Eu: “Em que ano estamos?”
    Moshi: “Ah, é 2019. Acho que foi há mais ou menos um ano.”
    Eu: “Tem certeza de que é 2019?”
    Moshi: “Ah, sim, tenho certeza. Com certeza é 2019. Esse número é para o último.”
    Eu: “O que é COVID-19?”
    Moshi: “É uma doença rara. É causada por um sistema imunológico hiperativo que ataca a pele.”
    Nesse ponto, ele não respondeu mais

  • Moshi é o modelo mais divertido até agora. Minha experiência recente está aqui: https://x.com/tommoor/status/1809051817860354471
    Mas é melhor não esperar precisão