Architektur
speech-swift ist als modulares Swift-Paket organisiert mit gemeinsamen Protokollen, unabhängigen Modellmodulen und einer einheitlichen CLI. Die gesamte Inferenz läuft auf dem Gerät über MLX (Metal-GPU) oder CoreML (Neural Engine).
Modul-Abhängigkeitsgraph
┌──────────┐
│ AudioCLI │ (Einstiegspunkt)
└────┬─────┘
│
┌──────┴──────┐
│ AudioCLILib │ (Befehle)
└──────┬──────┘
│
┌─────────┬───────┼───────┬──────────┬──────────────┐
│ │ │ │ │ │
┌────┴───┐ ┌──┴──┐ ┌──┴──┐ ┌─┴────┐ ┌───┴────┐ ┌──────┴───────┐
│Qwen3ASR│ │Qwen3│ │Cosy │ │Perso-│ │Speech- │ │ Speech- │
│Parakeet│ │ TTS │ │Voice│ │naPlex│ │ VAD │ │Enhancement │
└────┬───┘ └──┬──┘ └──┬──┘ └──┬───┘ └───┬───┘ └──────┬───────┘
│ │ │ │ │ │
└────────┴───────┼───────┴─────────┘ │
│ │
┌──────┴──────┐ │
│ Qwen3Common │ (gemeinsame Schichten)│
└──────┬──────┘ │
│ │
┌──────┴──────┐ │
│ AudioCommon │ ◄──────────────────────┘
└─────────────┘ (Protokolle, Audio-I/O)MOSS Transcribe Diarize
MossTranscribe liefert Segmente mit Sprecherzuordnung und Zeitstempeln über native CoreML- und MLX-Backends. CoreML nutzt für kurze Aufnahmen einen festen Zustand mit 1.024 Tokens. MLX verwendet einen dynamischen Kontext mit 131.072 Tokens, affine INT5/INT8-Decodergewichte und optionale FP16/INT8-KV-Caches. Beide Laufzeiten arbeiten offline und autoregressiv, nicht als Streaming-Modell.
VoiceChat 11B
Aufgabe und Referenz: Duplex-Speech-to-Speech; SALM-Duplex: Efficient and Direct Duplex Modeling for Speech-to-Speech Language Model (Interspeech 2025), zitiert in NVIDIAs Upstream-VoiceChat-Modellkarte.
Vollständige Laufzeit, M5 Pro 48 GB, Release, 80-ms-Live-Takt: INT5 mit geschützten Heads erreicht etwa 8.69 GB Peak-RSS; drei kontrollierte Gesamtpfad-RTF-Ergebnisse waren 0.96, 0.96 und 0.99. Die optimierte INT8-Leistung wurde noch nicht neu gemessen.
VoiceChat implementiert den vollständigen nativen MLX-Audio-zu-Audio-Pfad: kausale FastConformer-Wahrnehmung, Nemotron-H-Duplex-Text-/Funktionskanäle, einen eigenständigen textkonditionierten EAR-TTS-Decoder mit acht MaskGIT-Iterationen und einen neuronalen 22,05-kHz-Codec. Das Streaming hält begrenzte Attention- und kausale Faltungs-Caches pro Schicht; das stabile Acht-Frame-Live-Codec-Fenster nutzt einen kompilierten Graphen. Jeder 80-ms-Eingangsframe erzeugt eine Sprachentscheidung, 31 RVQ-Codes und genau 1.764 Ausgabesamples. Der Loader verlangt ein vollständiges encoder/ + llm/ + tts/-Bundle und lehnt ältere reine Verständnis-Exporte ab. INT5 hält auf dem getesteten M5 Pro nun den durchschnittlichen RTF unter 1, obwohl der p95-Spielraum pro Frame knapp bleibt.
Inferenz-Backends
| Backend | Hardware | Modelle |
|---|---|---|
| MLX | Metal-GPU | Qwen3-ASR, Qwen3-TTS, CosyVoice3, IndexTTS2, Qwen3.5-Chat, PersonaPlex, VoiceChat 11B, Omnilingual ASR (300M / 1B / 3B / 7B), Cohere Transcribe 2B, Voxtral Mini 3B, Pyannote, Silero VAD, WeSpeaker, MOSS Transcribe Diarize, SpeechBrain ECAPA LID |
| CoreML | Neural Engine | Qwen3-ASR-Encoder (Hybrid), Parakeet TDT, Parakeet EOU Streaming, Omnilingual ASR 300M, Kokoro-82M, Qwen3.5-Chat (optional), Sortformer-Diarisierung, DeepFilterNet3, Silero VAD (optional), WeSpeaker (optional), MOSS Transcribe Diarize, SpeechBrain ECAPA LID |
| Accelerate | CPU (SIMD) | Audio-Vorverarbeitung (STFT, Mel, FFT), Signalverarbeitung |
Modell-Gewichtsformat
MLX-Modelle verwenden das Format safetensors mit 4-Bit- oder 8-Bit-Quantisierung (Gruppengröße 64). CoreML-Modelle verwenden das kompilierte Format .mlmodelc. Konvertierungsskripte in scripts/ konvertieren aus PyTorch-Checkpoints.
Cohere und Voxtral bieten zusätzlich affine MLX-INT5-Pakete. MLX unterstützt kein affines INT7; INT8 ist die unterstützte Option mit höherer Qualität.
| Modell | Parameter | Quantisierung | Größe auf Disk |
|---|---|---|---|
| Qwen3-ASR 0.6B (MLX) | ~600M | 4-Bit / 8-Bit | 680 MB / 1,0 GB |
| Qwen3-ASR 0.6B (CoreML) | ~186M (Encoder) | INT8 | ~180 MB |
| Qwen3-ASR 1.7B (MLX) | ~1,7B | 4-Bit / 8-Bit | 2,1 GB / 3,2 GB |
| Parakeet-TDT 0.6B (CoreML) | ~600M | INT8 | 500 MB |
| Whisper Large-v3 Turbo (CoreML) | 809M | FP16 | 1.6 GB |
| MOSS Transcribe Diarize 0.9B (MLX) | 908.5M | FP16 audio + INT5 / INT8 decoder | 987.0 MiB / 1,200.1 MiB |
| MOSS Transcribe Diarize 0.9B (CoreML) | ~900M | FP16 / INT8 block-32 | 1.7 GB / 1.2 GB |
| Parakeet-EOU 120M (CoreML) | ~120M | INT8 | ~120 MB |
| Omnilingual-ASR-CTC 300M (CoreML) | 326M | INT8 | 312 MB |
| Omnilingual-ASR-CTC 300M (MLX) | 326M | 4-Bit / 8-Bit | 193 MB / 342 MB |
| Omnilingual-ASR-CTC 1B (MLX) | 1,01B | 4-Bit / 8-Bit | 549 MB / 1006 MB |
| Omnilingual-ASR-CTC 3B (MLX) | ~3B | 4-Bit / 8-Bit | 1,71 GB / 3,16 GB |
| Omnilingual-ASR-CTC 7B (MLX) | ~7B | 4-Bit / 8-Bit | 3,55 GB / 6,63 GB |
| Cohere Transcribe 2B (MLX) | 2B | FP16 / INT5 / INT8 | 3.85 / 1.62 / 2.25 GiB |
| Voxtral Mini 3B 2507 (MLX) | 3B | FP16 / INT5 / INT8 | 8.71 / 3.77 / 5.18 GiB |
| Qwen3-ForcedAligner 0.6B (MLX) | ~600M | 4-Bit / 8-Bit | 979 MB / 1,4 GB |
| Qwen3-ForcedAligner 0.6B (CoreML) | ~600M | INT4 / INT8 | 630 MB / 1,0 GB |
| Qwen3-TTS 0.6B (MLX) | ~600M | 4-Bit / 8-Bit | 1,7 GB / 2,4 GB |
| Qwen3-TTS 1.7B (MLX) | ~1,7B | 4-Bit / 8-Bit | 3,2 GB / 4,8 GB |
| CosyVoice3 0.5B (MLX) | ~500M | 4-Bit-LLM | ~1,2 GB |
| IndexTTS2 expanded bundle (MLX) | 1.5B-class | FP16 + auxiliary models | ~4.8 GB |
| Kokoro-82M (CoreML) | 82M | INT8 (1 Bucket) | ~89 MB |
| Qwen3.5-Chat 0.8B (MLX) | ~800M | INT4 | 418 MB |
| Qwen3.5-Chat 0.8B (CoreML) | ~800M | INT8 | 981 MB |
| PersonaPlex 7B (MLX) | ~7B | 4-Bit / 8-Bit | 4,9 GB / 9,1 GB |
| VoiceChat 11B (MLX) | ~11B | INT5 / INT8 | 8.56 GB / 12.11 GB |
| Pyannote VAD (MLX) | ~1,49M | float32 | ~5,7 MB |
| Silero VAD v5 | ~309K | float32 | ~1,2 MB (MLX & CoreML) |
| WeSpeaker ResNet34 | ~6,6M | float32 | ~25 MB (MLX & CoreML) |
| SpeechBrain ECAPA VoxLingua107 | 21.25M | FP16 | ~40.6 MiB (MLX) / ~40.8 MiB (CoreML) |
| ReDimNet2-B6 | 12,3M | float16 | ~25 MiB (CoreML) |
| Pyannote Community-1 (CoreML) | 8.35M | float32 + native VBx | ~32 MB |
| Sortformer (CoreML) | — | float16 | ~50 MB |
| DeepFilterNet3 (CoreML) | ~2,1M | FP16 | ~4,2 MB |
| LocalVQE v1.4-AEC (CoreML + C++) | 200K + 2.742 | FP16 + FP32 | ~732 KB |
Leistungsoptimierungen
- MLX compile() — Kernel-Fusion für autoregressive Schleifen. Talker verwendet
compile(shapeless: true), Code-Predictor verwendetcompile(shapeless: false)mit festen Cache-Größen. - Metal-Shader-Bibliothek — Vorab kompilierte metallib vermeidet ~5-fachen JIT-Kompilierungsoverhead. Erstellt über
scripts/build_mlx_metallib.sh. - Chunked Codec Decode — Der TTS-Decoder verarbeitet Audio in 25-Frame-Chunks mit 10-Frame-Kontextüberlappung, um GPU-Timeouts zu vermeiden.
- Batch-doppeltes CFG — CosyVoice3 DiT halbiert Flow-Matching-Durchläufe, indem es bedingte + unbedingte zusammen batcht.
- Fused RoPE — Verwendet
MLXNN.RoPEauf Basis eines Metal-Kernels statt manueller Rotation. - BN-Fusion — WeSpeaker-Batch-Normalisierung wird zur Konvertierungszeit in Conv2d-Gewichte fusioniert.
Audio-Verarbeitung
Alle Audio-I/O verwenden Float32-PCM. Internes Resampling übernimmt die Formatkonvertierung:
| Modell | Erwartete Rate | Format |
|---|---|---|
| Qwen3-ASR | 16 kHz | Mono Float32 |
| Cohere Transcribe 2B | 16 kHz | Mono Float32 |
| Voxtral Mini 3B | 16 kHz | Mono Float32 |
| Qwen3-TTS | 24 kHz Ausgabe | Mono Float32 |
| CosyVoice3 | 24 kHz Ausgabe | Mono Float32 |
| Kokoro-82M | 24 kHz Ausgabe | Mono Float32 |
| PersonaPlex | 24 kHz I/O | Mono Float32 |
| Pyannote VAD | 16 kHz | Mono Float32 |
| Silero VAD | 16 kHz | Mono Float32 |
| WeSpeaker | 16 kHz | Mono Float32 |
| SpeechBrain ECAPA LID | 16 kHz | Mono Float32 |
| ReDimNet2-B6 | 16 kHz | Mono Float32 |
| DeepFilterNet3 | 48 kHz | Mono Float32 |
Quellstruktur
Sources/
AudioCommon/ Gemeinsame Protokolle, Audio-I/O, Systemausgabe-
Erfassung (SystemAudioTap), HuggingFace-
Downloader, SentencePieceModel (Protobuf-Reader)
MLXCommon/ MLX-Hilfsprogramme: Gewichtsladen, QuantizedLinear-Helfer,
SDPA-Multi-Head-Attention-Helfer, Metal-Budget
Qwen3Common/ Gemeinsame Modellkomponenten (KV-Cache, RoPE, Quantisierung)
Qwen3ASR/ Qwen3-ASR Sprache-zu-Text
ParakeetASR/ Parakeet TDT Sprache-zu-Text (CoreML)
ParakeetStreamingASR/ Parakeet EOU 120M Streaming-Diktat (CoreML)
OmnilingualASR/ Meta wav2vec2 + CTC, 1.672 Sprachen
(CoreML 300M + MLX 300M / 1B / 3B / 7B)
CohereTranscribeASR/ Cohere Transcribe 2B speech-to-text (MLX)
VoxtralASR/ Voxtral Mini 3B speech-to-text (MLX)
Qwen3TTS/ Qwen3-TTS Text-zu-Sprache
CosyVoiceTTS/ CosyVoice3 Text-zu-Sprache
KokoroTTS/ Kokoro-82M Text-zu-Sprache (CoreML)
Qwen3Chat/ Qwen3.5-0.8B LLM-Chat auf dem Gerät (MLX + CoreML)
PersonaPlex/ PersonaPlex Sprache-zu-Sprache
SpeechVAD/ VAD (Silero + Pyannote), Diarisierung, Sprechereinbettungen
SpeechLanguageID/ Identifikation der gesprochenen Sprache (SpeechBrain ECAPA, MLX + CoreML, 107 Labels)
SpeechEnhancement/ DeepFilterNet3 Rauschunterdrückung (CoreML)
SourceSeparation/ Open-Unmix HQ / UMX-L + HTDemucs (Demucs v4) music source separation (MLX, 4 stems)
MAGNeTMusicGen/ MAGNeT text-to-music generation (MLX, 30 s @ 32 kHz, INT4/INT8)
VoxCPM2TTS/ VoxCPM2 text-to-speech (MLX, 48 kHz, voice cloning + voice design)
IndexTTS2TTS/ IndexTTS2 voice cloning (MLX, semantic GPT + emotion/tempo/pause control + S2Mel + BigVGAN)
VibeVoiceTTS/ VibeVoice long-form / multi-speaker TTS (MLX, EN/ZH)
MADLADTranslation/ MADLAD-400 many-to-many translation (MLX, 400+ languages)
AudioCLILib/ CLI-Befehlsimplementierungen
AudioCLI/ CLI-Einstiegspunkt
scripts/ Modellkonvertierung (PyTorch → MLX/CoreML), Benchmarking
Tests/ Unit- und Integrationstests
Examples/ Demo-Apps (PersonaPlexDemo, SpeechDemo)