1 Punkte von GN⁺ 2024-09-20 | 1 Kommentare | Auf WhatsApp teilen
  • Moshi ist ein Speech-Text-basiertes Modell für Sprachdialoge in Echtzeit und ein Full-Duplex-Framework für Sprachdialoge; es bietet eine Live-Demo und Hugging-Face-Modelle
  • Das Repository trennt die Inferenz-Stacks in PyTorch für Forschung und Experimente, MLX für On-Device-Inferenz auf iPhone/Mac und Rust für den Produktionseinsatz
  • Das Modell verarbeitet zwei Audio-Streams – Moshis Äußerungen und die Äußerungen des Nutzers – und sagt außerdem einen inner monologue voraus, also Text-Token, die Moshis eigenen Äußerungen entsprechen, um die Generierungsqualität zu verbessern
  • Der Mimi-Codec streamt 24-kHz-Audio als 12,5-Hz-Repräsentation mit 1,1 kbps Bandbreite, hat eine Frame-Latenz von 80 ms; Moshis theoretische Latenz beträgt 160 ms, die gemessene End-to-End-Latenz auf einer L4-GPU liegt im Bestfall bei 200 ms
  • Die veröffentlichten Modelle sind die männliche synthetische Stimme Moshiko, die weibliche synthetische Stimme Moshika und der Sprachcodec Mimi; Modellgewichte stehen unter CC-BY 4.0, Python- und Web-Client-Code unter MIT und das Rust-Backend unter der Apache-Lizenz

Zweck und Aufbau von Moshi

  • Moshi ist ein speech-text foundation model und ein Full-Duplex-Framework für Sprachdialoge in Echtzeit
  • Eine Live-Demo gibt es unter moshi.chat, die Modellsammlung ist auf Hugging Face veröffentlicht
  • Das Repository enthält drei Inferenz-Stacks
    • PyTorch: für Forschung und Experimente, im Verzeichnis moshi/
    • MLX: für On-Device-Inferenz auf iPhone und Mac, im Verzeichnis moshi_mlx/
    • Rust: für den Produktionseinsatz, im Verzeichnis rust/
      • Enthält eine Rust-basierte Mimi-Implementierung und die Python-Bindings rustymimi
  • Der Code des Web-UI-Clients, der für die Moshi-Demo verwendet wird, befindet sich im Verzeichnis client/
  • Moshi-Finetuning wird in einem separaten Repository behandelt: kyutai-labs/moshi-finetune

Verwandte Kyutai-Modelle

  • Die Moshi-Codebasis wird auch zum Ausführen verwandter Kyutai-Modelle verwendet, die eine Moshi-ähnliche Multi-Stream-Architecture nutzen

Modellarchitektur

  • Moshi modelliert zwei Audio-Streams
    • einen Stream, in dem Moshi spricht
    • einen weiteren Stream, in dem der Nutzer spricht
  • Zusammen mit den beiden Audio-Streams sagt Moshi den inner monologue voraus, also Text-Token, die den eigenen Äußerungen entsprechen; dieser Ansatz verbessert die Generierungsqualität deutlich
  • Ein kleiner Depth Transformer modelliert Abhängigkeiten zwischen Codebooks in einem bestimmten Zeitschritt
  • Ein großer Temporal Transformer mit 7B Parametern modelliert zeitliche Abhängigkeiten
  • Die Latenz beträgt theoretisch 160 ms
    • Mimi-Framegröße 80 ms
    • akustische Latenz 80 ms
  • Die praktische End-to-End-Latenz auf einer L4-GPU liegt im Bestfall bei 200 ms

Mimi-Sprachcodec

  • Mimi ist ein neuronaler Audiocodec, der 24-kHz-Audio auf eine 12,5-Hz-Repräsentation reduziert
  • Mimi arbeitet vollständig streamingbasiert; die Bandbreite beträgt 1,1 kbps, die Latenz entspricht der Framegröße von 80 ms
  • Laut README liefert Mimi bessere Leistung als bestehende nicht-streamingfähige Codecs
  • Mimi basiert auf früheren neuronalen Audiocodecs wie SoundStream und EnCodec
    • Fügt sowohl dem Encoder als auch dem Decoder einen Transformer hinzu
    • Passt den Stride so an, dass die gesamte Framerate auf 12,5 Hz kommt
  • Die Framerate von 12,5 Hz liegt näher an der durchschnittlichen Framerate von Text-Token von etwa 3–4 Hz und reduziert die Zahl der autoregressiven Schritte von Moshi
  • Ähnlich wie SpeechTokenizer nutzt Mimi einen Distillation Loss, damit das erste Codebook-Token mit der selbstüberwachten Repräsentation von WavLM übereinstimmt
  • Ähnlich wie EBEN verwendet Mimi neben Feature Matching ausschließlich adversarial training loss, wodurch sich die subjektive Qualität auch bei niedriger Bitrate stark verbessert

Veröffentlichte Modelle und Formate

Anforderungen und Installationsbeschränkungen

  • Python erfordert mindestens 3.10, empfohlen wird 3.12
  • PyTorch- und MLX-Clients können über PyPI installiert werden
pip install -U moshi
pip install -U moshi_mlx
pip install rustymimi
  • Wenn nicht Python 3.12 verwendet wird, können bei der Installation von moshi_mlx oder der Abhängigkeit rustymimi Fehler auftreten; in diesem Fall ist die Installation der Rust toolchain oder der Wechsel auf Python 3.12 erforderlich
  • Es wird erwartet, dass es unter Windows funktioniert, offizieller Support wird jedoch nicht angeboten
  • Die MLX-Version wurde auf einem MacBook Pro M3 getestet
  • Die aktuelle PyTorch-Version unterstützt keine Quantisierung und benötigt daher erheblichen GPU-Speicher in der Größenordnung von 24 GB
  • Das Rust-Backend benötigt eine aktuelle Rust toolchain
  • Zum Kompilieren der GPU-Unterstützung werden ein zur GPU passendes CUDA und nvcc benötigt

Ausführung

  • PyTorch

    • Die PyTorch-API befindet sich im Verzeichnis moshi und bietet Streaming-Versionen des Mimi-Audio-Tokenizers und des Moshi-Sprachmodells
    • Für den interaktiven Modus startet man zuerst den Modellserver und nutzt anschließend das Web-UI oder den Kommandozeilen-Client
    python -m moshi.server [--gradio-tunnel] [--hf-repo kyutai/moshika-pytorch-bf16]
    
    • Das Web-UI ist standardmäßig unter localhost:8998 erreichbar
    • Wenn auf die GPU einer entfernten Maschine per HTTP zugegriffen wird, kann die Nutzung des Mikrofons durch Browser-Sicherheitsrichtlinien blockiert werden
    • Mit SSH -L kann der entfernte Port 8998 auf localhost weitergeleitet werden
    • Mit --gradio-tunnel lässt sich ein von überall erreichbarer Tunnel erstellen
    • Dieser Tunnel läuft über die USA und kann aus europäischer Sicht eine hohe zusätzliche Latenz von bis zu 500 ms verursachen
    • Mit --gradio-tunnel-token kann ein festes secret token gesetzt und dieselbe Adresse wiederverwendet werden
    • Mit --hf-repo lässt sich ein anderes vortrainiertes Hugging-Face-Modell auswählen
    • Ein Kommandozeilen-Client wird ebenfalls bereitgestellt, führt jedoch im Gegensatz zum Webbrowser keine echo cancellation durch und überspringt auch keine Frames, um kumulierte Latenz auszugleichen
    python -m moshi.client [--url URL_TO_GRADIO]
    
  • MLX

    • Nach der Installation von moshi_mlx kann lokale Inferenz unter macOS ausgeführt werden
    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
    
    • Die Flags -q und --hf-repo müssen immer zueinander passen
    • Auch das MLX-Kommandozeileninterface ist barebone und führt weder echo cancellation noch einen Ausgleich kumulierter Latenz durch
    • Mit python -m moshi_mlx.local_web kann das Web-UI gestartet werden; die HTTP-Verbindung wird unter localhost:8998 bereitgestellt
  • Rust

    • Der Rust-Inferenzserver wird im Verzeichnis rust ausgeführt
    cargo run --features cuda --bin moshi-backend -r -- --config moshi-backend/config.json standalone
    
    • Unter macOS kann statt --features cuda auch --features metal verwendet werden
    • Wird statt config.json die Datei config-q8.json verwendet, kann das q8-quantisierte Modell genutzt werden
    • Andere vortrainierte Modelle wählt man, indem man den Schlüssel "hf_repo" in der Konfigurationsdatei ändert
    • Sobald der Server standalone worker listening ausgibt, kann das Web-UI verwendet werden
    • Der Rust-Server verwendet standardmäßig HTTPS und ist daher unter https://localhost:8998 erreichbar
    • Im Browser kann eine Warnung vor einer unsicheren Website erscheinen; in Chrome kann man über „Details“ oder „Advanced“ mit dem Zugriff auf localhost fortfahren

Clients und Entwicklung

  • Das Web-UI bietet echo cancellation und wird empfohlen, da dies der Gesamtqualität des Modells hilft
  • Die meisten Befehle stellen das Web-UI direkt unter der angegebenen URL bereit
  • Es gibt auch Kommandozeileninterfaces für Rust und Python; sie verwenden dasselbe Protokoll wie das Web-UI, sodass serverseitig keine Änderungen nötig sind
  • Das Web-UI wird im Verzeichnis client gebaut
cd client
npm install
npm run build
  • Der Rust-Kommandozeilenclient wird im Verzeichnis rust ausgeführt
cargo run --bin moshi-cli -r -- tui --host localhost
  • Der Python-PyTorch-Client wird mit folgendem Befehl ausgeführt
python -m moshi.client
  • Die Gradio-Demo wird nach Installation von gradio-webrtc>=0.0.18 ausgeführt
python -m moshi.client_gradio --url <moshi-server-url>
docker compose up

Lizenz und Zitierung

  • Der Code der Python-Teile steht unter der MIT-Lizenz
  • Das Rust-Backend steht unter der Apache-Lizenz
  • Der Code des Web-Clients steht unter der MIT-Lizenz
  • Teile des Codes basieren auf dem MIT-lizenzierten AudioCraft
  • Die Modellgewichte werden unter der CC-BY 4.0-Lizenz veröffentlicht
  • Bei Nutzung von Mimi oder Moshi wird darum gebeten, das Paper Moshi: a speech-text foundation model for real-time dialogue zu zitieren

1 Kommentare

 
GN⁺ 2024-09-20
Hacker-News-Kommentare
  • Da hier fast alle Kommentare ziemlich negativ sind, hier mein Feedback: Die Latenz ist sehr gut, eigentlich sogar zu gut, sodass es sich oft anfühlt, als würde das Modell einem ins Wort fallen
    Als Open-Source-Modell ist das eine große Leistung. Allerdings sind die Leute inzwischen an extrem gute große Sprachmodelle gewöhnt, und die inhaltliche Qualität der Antworten dieses Modells ist vom aktuellen Spitzenniveau noch weit entfernt. Es fühlt sich eher wie ein großes Sprachmodell aus etwa 2019 an; audioseitig ist man also bei „gut genug“ angekommen, und ab jetzt sollte man sich besser auf die Antwortqualität konzentrieren

    • Stimme voll zu. Die Latenz ist gut und die Technik ist cool. Rust, Edge-Ausführung sogar auf Consumer-Laptops, das ist beeindruckend
      Die naheliegende Frage ist, ob es eine Möglichkeit gibt, ein „besseres großes Sprachmodell“ zu portieren, ohne das Moshi-Erlebnis zu verschlechtern
  • Moshi steht unter CC-BY, und es gibt auch ein ähnliches Echtzeit-Konversationsmodell im Sprach-Text-Bereich mit etwa 7B Parametern, das kürzlich unter Apache v2 veröffentlicht wurde: https://tincans.ai/slm3 / https://huggingface.co/collections/tincans-ai/gazelle-v02-65...

    • Der wichtige Unterschied ist, dass tincans kein Speech-to-Speech-Modell ist. Es verwendet ein separates Modell zur Erkennung von Sprechen/Stoppen sowie einen abschließenden Text-to-Speech-Verarbeitungsschritt
  • In letzter Zeit gibt es viele Entwicklungen rund um sprachfähige Sprachmodelle. Beispiele sind https://github.com/ictnlp/LLaMA-Omni, https://github.com/gpt-omni/mini-omni

  • Ihr Inferenzserver ist in Rust geschrieben und nutzt das Candle-Crate von huggingface. Einer der Moshi-Autoren ist auch Hauptautor von Candle
    Wir bauen ebenfalls einen Inferenz-Stack auf Candle auf und sind ziemlich zufrieden damit

    • Sehr interessant. Gibt es ein Pendant zu vLLM? Ich frage mich, ob ihr Dinge wie Batching oder Paged Attention neu schreiben musstet
  • Beim Suchen nach Demos auf YouTube bin ich auf ein lustiges Video von vor ein paar Monaten gestoßen: https://youtu.be/coroLWOS7II?si=TeVghP_Zi0P9exQh
    Inzwischen ist es sicher besser geworden :-)

  • Interessant. Mir gefällt, dass man sich hier auf Latenz konzentriert, und es wird behauptet, auf einer lokalen GPU tatsächlich etwa 200 ms zu erreichen
    Da es auf einem 7B-Transformer-Modell basiert, wird es wohl nicht besonders schlau sein. Wenn man sich vorstellt, dass die Latenz eines 70B-Modells bei etwa 1 Sekunde liegt, scheint eine Systemarchitektur möglich zu sein mit einer Zwischenreaktion wie „das Modell spricht gerade“, einem schnellen initialen Antwortmodell in der 7B/Phi-3-Klasse und danach dem großen Modell. Dem Phi-3-Modell könnte man auch die Nachsteuerung überlassen, um die tatsächlich richtige Antwort zu liefern und sich bei Bedarf zu entschuldigen und zu korrigieren
    Anekdotisch betrachtet funktionieren die Gehirne vieler Menschen oft ähnlich: schnelle Reaktion und 1–2 Sekunden später eine Korrektur oder Ergänzung. Natürlich gibt es auch Leute, die nie korrigieren, oder andere, die lange pausieren und dann eine vollständig durchdachte Antwort geben

  • Ich habe es ausprobiert, und man konnte einfach irgendeine E-Mail-Adresse eingeben. Es antwortete sofort, fast augenblicklich, sogar noch während ich sprach
    Aber das wirkte eher wie Füllsätze, fast wie gecachte Antworten. Eine tatsächliche Antwort auf das, was man gefragt hat, kommt viel später — sofern es vorher nicht in einer Schleife hängen bleibt

    • Ich habe diese Demo beim ersten Erscheinen ausprobiert und heute noch einmal. Ich will das nicht so hochjazzen wie damals Reflection 70B, aber es scheint nicht so, als wären dieselben Gewichte hochgeladen worden wie in der ursprünglichen Demo vom Juli: https://the-decoder.com/french-ai-lab-kyutai-unveils-convers...
  • Ich baue gerade eine Echtzeit-Lösung für Sprache → großes Sprachmodell → Sprachausgabe, und der spannendste Teil hier ist meiner Meinung nach der streamingfähige neuronale Audio-Codec. Mit Whisper ist richtiges Streaming von Speech-to-Text nämlich in der Praxis schwierig
    Aus Produktsicht würde ich das aber nicht unbedingt direkt in ein großes Sprachmodell einspeisen und sofort antworten lassen. Für viele Anwendungsfälle braucht man vor der Antwort einen Schritt für Tool-/Funktionsaufrufe. Ich würde jederzeit gern mit Leuten sprechen, die in diese Richtung arbeiten
    Auch tincans, das weiter unten erwähnt wurde, sieht großartig aus. Aber wenn die Entwicklung von tincans beendet ist, gibt es hier noch zu 10000 % Spielraum. Falls Chris das liest: Ich würde unbedingt gern verstehen, welche Produkt-/Business-Anwendungsfälle das löst, egal wie gut große Sprachmodelle noch werden

    • Ich experimentiere ebenfalls mit diesem Ansatz. Ich nutze eine „Streaming“-Konfiguration, bei der ich mit Whisper Samples abschneide und schon mit der Transkription beginne, während der Nutzer noch spricht, und speise das Ergebnis in Mistral 8B ein, das als Gesprächs-Orchestrator entlang eines vordefinierten IVR-Baums Tool-Aufrufe ausführt
      Das große Sprachmodell antwortet nicht direkt, sondern wählt nur einen Baumknoten mit vorbereiteter Text-to-Speech-Ausgabe aus. Es gibt einen Parameter für die „Stopp-Länge“, der festlegt, ob der Nutzer aufgehört hat zu sprechen und das Transkript an das Modell übergeben werden kann; besonders kompliziert ist das nicht. Ich überlege aber weiterhin, wie man Audioeingaben sauber verarbeiten kann und ob sich das Modell allein durch Prompt-Gestaltung präzise genug steuern ließe, um den IVR-Baum ganz abzuschaffen. Es funktioniert schon ziemlich gut, hat aber noch viel Verbesserungspotenzial
    • Den Teil mit dem nötigen Tool-/Funktionsaufruf vor der Antwort habe ich fast genau vor einem Jahr schon einmal gebaut :) Das funktionierte ganz ordentlich, war aber nicht schnell genug, und deshalb habe ich schließlich ein gekoppeltes Modell gebaut
  • Die Antwortgeschwindigkeit ist beeindruckend, aber die „Qualität“ der Antworten nicht. Das Transkript meines zweiten Tests sah so aus
    Moshi: „Hallo, was ist los?“
    Ich: „Welches Jahr haben wir gerade?“
    Moshi: „Ah, es ist 2019. Ich glaube, das war ungefähr vor einem Jahr.“
    Ich: „Bist du sicher, dass es wirklich 2019 ist?“
    Moshi: „Ah, ja, ganz sicher. Es ist definitiv 2019. Diese Zahl ist für das Letzte.“
    Ich: „Was ist COVID-19?“
    Moshi: „Das ist eine seltene Krankheit. Sie entsteht durch ein überaktives Immunsystem, das die Haut angreift.“
    Ab da antwortete es nicht mehr

  • Moshi ist das unterhaltsamste Modell bisher. Meine jüngste Erfahrung damit ist hier: https://x.com/tommoor/status/1809051817860354471
    Auf Genauigkeit sollte man aber besser nicht setzen