Architecture

TTS natif par instructions

Compilez le SDK natif depuis les sources de main. Homebrew et les autres distributions CLI précompilées peuvent ne pas encore inclure ces moteurs.

Implémentation (PR #541): main

Bundles MLX publiés: aufklarer/FireRedTTS3-Instruct-MLX-fp32 · aufklarer/MOSS-VoiceGenerator-MLX-bf16

FireRedTTS3-Instruct — FireRedTTS3TTS: FireRedTTS3-Instruct conserve les poids Float32 du modèle et du décodeur. Il renvoie l’audio complet en mémoire : omettez --stream. --language accepte les alias anglais et chinois. Une limite de génération produit une erreur plutôt qu’un succès tronqué.

MOSS-VoiceGenerator — MossVoiceGeneratorTTS: MOSS-VoiceGenerator conserve les poids de langage BF16 et le codec de synthèse FP32. Utilisez --stream pour le PCM progressif. Omettez --language et précisez la langue dans --instruct. La fin vide les seize livres de codes.

Les champs texte et instruction sont limités chacun à 32 768 octets UTF-8. Le prompt d’entrée complet, modèle inclus, doit tenir dans 4 096 tokens après rendu. Les entrées dépassant une limite sont rejetées.

Le suivi des instructions n’a pas encore été noté. Les mesures sur textes courts décrivent la configuration testée ; la certification de régression de latence reste non concluante.

Breeze TTS 2 · BreezeTTS

Synthèse vocale en anglais et chinois avec création de voix, clonage et direction à partir d’un enregistrement de référence, et audio en streaming (MLX BF16/8-bit, 24 kHz ; recherche et usage non commercial).

BreezeTTS · CLI · Swift API

speech speak "The quick brown fox jumps over the lazy dog." --engine breeze \
  --instruct "A clear, calm English narrator." --stream -o design.wav
  • --breeze-model-id: aufklarer/Breeze-TTS-2-MLX-8bit
  • --breeze-bundle-dir
  • --breeze-cache-limit-mib
  • --breeze-reference-text
  • --breeze-temperature: 0.9
  • --breeze-top-k: 50
  • --breeze-top-p: 1
  • --breeze-cfg-scale: 4
  • --breeze-max-frames: 750
  • --breeze-seed: 42
  • --first-chunk-frames: 3
  • --chunk-frames: 25

Moteur natif pour Apple · PocketTTS

PocketTTS ajoute la synthèse native CoreML à speech-swift. Toutes les étapes utilisent uniquement le CPU par défaut. La voix anglaise Alba diffuse 1 920 échantillons à 24 kHz par bloc, soit 80 ms.

Utilisation Swift et CLI

speech-swift est organisé comme un package Swift modulaire avec des protocoles partagés, des modules de modèles indépendants et une CLI unifiée. Toute l'inférence s'exécute sur l'appareil en utilisant MLX (GPU Metal) ou CoreML (Neural Engine).

Graphe de dépendances des modules

                    ┌──────────┐
                    │ AudioCLI │  (point d'entrée)
                    └────┬─────┘
                         │
                  ┌──────┴──────┐
                  │ AudioCLILib │  (commandes)
                  └──────┬──────┘
                         │
       ┌─────────┬───────┼───────┬──────────┬──────────────┐
       │         │       │       │          │              │
  ┌────┴───┐ ┌──┴──┐ ┌──┴──┐ ┌─┴────┐ ┌───┴────┐ ┌──────┴───────┐
  │Qwen3ASR│ │Qwen3│ │Cosy │ │Perso-│ │Speech- │ │  Speech-     │
  │Parakeet│ │ TTS │ │Voice│ │naPlex│ │  VAD   │ │Enhancement   │
  └────┬───┘ └──┬──┘ └──┬──┘ └──┬───┘ └───┬───┘ └──────┬───────┘
       │        │       │       │         │             │
       └────────┴───────┼───────┴─────────┘             │
                        │                               │
                 ┌──────┴──────┐                        │
                 │ Qwen3Common │  (couches partagées)   │
                 └──────┬──────┘                        │
                        │                               │
                 ┌──────┴──────┐                        │
                 │ AudioCommon │ ◄──────────────────────┘
                 └─────────────┘  (protocoles, E/S audio)

Budget du cache de tampons MLX

Les modèles MLX partagent un plafond par défaut de tampons réutilisables de min(2 GiB, physical RAM / 4), du chargement des poids à la fin de leur durée de vie. Les budgets inférieurs de l’appelant, y compris MLX.Memory.cacheLimit = 0, et les budgets propres aux modèles existants sont préservés. Ce plafond concerne les tampons inactifs ; les poids actifs, les caches KV et la mémoire totale du processus peuvent le dépasser. MLX réduit le cache lors des allocations ; le dernier tampon libéré peut donc le faire dépasser temporairement le budget jusqu’à l’allocation suivante.

unload() libère l’enregistrement du modèle ; les modèles sans cette méthode le libèrent à leur destruction. Le dernier propriétaire restaure le budget de l’appelant ; les déchargements précédents préservent les plafonds des modèles restants. Les chemins utilisant uniquement CoreML n’enregistrent aucun budget MLX.

MOSS Transcribe Diarize

MossTranscribe renvoie des segments horodatés attribués aux locuteurs via des backends natifs CoreML et MLX. CoreML utilise un état fixe de 1 024 tokens pour les enregistrements courts. MLX emploie un contexte dynamique de 131 072 tokens, des poids de décodeur affine INT5/INT8 et des caches KV FP16/INT8 optionnels. Les deux runtimes sont hors ligne et autorégressifs, sans streaming.

VoiceChat 11B

Tâche et référence : speech-to-speech duplex ; SALM-Duplex: Efficient and Direct Duplex Modeling for Speech-to-Speech Language Model (Interspeech 2025), cité par la fiche VoiceChat amont de NVIDIA.

Runtime complet, M5 Pro 48 Go, Release, cadence live de 80 ms : l'INT5 avec têtes protégées atteint environ 8.69 Go de RSS maximal ; trois RTF contrôlés du pipeline complet ont donné 0.96, 0.96 et 0.99. Les performances INT8 optimisées n'ont pas encore été remesurées.

VoiceChat implémente le chemin audio-à-audio MLX natif complet : perception FastConformer causale, canaux duplex texte/fonction Nemotron-H, décodeur EAR-TTS autonome conditionné par le texte avec huit itérations MaskGIT et codec neuronal à 22,05 kHz. Le streaming conserve des caches bornés d'attention et de convolution causale par couche, tandis que la fenêtre live stable de huit trames du codec utilise un graphe compilé. Chaque trame d'entrée de 80 ms produit une décision de langage, 31 codes RVQ et exactement 1 764 échantillons de sortie. Le chargeur exige un bundle complet encoder/ + llm/ + tts/ et refuse les anciens exports limités à la compréhension. INT5 maintient désormais un RTF global sous 1 sur le M5 Pro testé, bien que la marge p95 par trame reste faible.

Backends d'inférence

BackendMatérielModèles
MLX GPU Metal Qwen3-ASR, Qwen3-TTS, Breeze TTS 2, 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, Nemotron 3 Diarization, FireRedTTS3-Instruct, MOSS-VoiceGenerator
CoreML CPU / GPU / Neural Engine (ANE) Encodeur Qwen3-ASR (hybride), Parakeet TDT, Parakeet EOU streaming, Omnilingual ASR 300M, Kokoro-82M, Qwen3.5-Chat (optionnel), diarisation Sortformer, DeepFilterNet3, Silero VAD (optionnel), WeSpeaker (optionnel), MOSS Transcribe Diarize, SpeechBrain ECAPA LID, Nemotron 3 Diarization
Accelerate CPU (SIMD) Prétraitement audio (STFT, mel, FFT), traitement du signal

Format des poids de modèles

Les modèles MLX utilisent le format safetensors avec une quantification 4 bits ou 8 bits (taille de groupe 64). Les modèles CoreML utilisent le format compilé .mlmodelc. Les scripts de conversion dans scripts/ convertissent depuis des checkpoints PyTorch.

Cohere et Voxtral proposent aussi des bundles MLX INT5 affines. MLX ne prend pas en charge INT7 affine ; INT8 est l’option de meilleure qualité prise en charge.

ModèleParamètresQuantificationTaille sur disque
Qwen3-ASR 0.6B (MLX)~600M4 bits / 8 bits680 Mo / 1,0 Go
Qwen3-ASR 0.6B (CoreML)~186M (encodeur)INT8~180 Mo
Qwen3-ASR 1.7B (MLX)~1,7B4 bits / 8 bits2,1 Go / 3,2 Go
Parakeet-TDT 0.6B (CoreML)~600MINT8500 Mo
Whisper Large-v3 Turbo (CoreML)809MFP161.6 GB
MOSS Transcribe Diarize 0.9B (MLX)908.5MFP16 audio + INT5 / INT8 decoder987.0 MiB / 1,200.1 MiB
MOSS Transcribe Diarize 0.9B (CoreML)~900MFP16 / INT8 block-321.7 GB / 1.2 GB
Parakeet-EOU 120M (CoreML)~120MINT8~120 Mo
Omnilingual-ASR-CTC 300M (CoreML)326MINT8312 Mo
Omnilingual-ASR-CTC 300M (MLX)326M4 bits / 8 bits193 Mo / 342 Mo
Omnilingual-ASR-CTC 1B (MLX)1,01B4 bits / 8 bits549 Mo / 1006 Mo
Omnilingual-ASR-CTC 3B (MLX)~3B4 bits / 8 bits1,71 Go / 3,16 Go
Omnilingual-ASR-CTC 7B (MLX)~7B4 bits / 8 bits3,55 Go / 6,63 Go
Cohere Transcribe 2B (MLX)2BFP16 / INT5 / INT83.85 / 1.62 / 2.25 GiB
Voxtral Mini 3B 2507 (MLX)3BFP16 / INT5 / INT88.71 / 3.77 / 5.18 GiB
Qwen3-ForcedAligner 0.6B (MLX)~600M4 bits / 8 bits979 Mo / 1,4 Go
Qwen3-ForcedAligner 0.6B (CoreML)~600MINT4 / INT8630 Mo / 1,0 Go
Qwen3-TTS 0.6B (MLX)~600M4 bits / 8 bits1,7 Go / 2,4 Go
Qwen3-TTS 1.7B (MLX)~1,7B4 bits / 8 bits3,2 Go / 4,8 Go
CosyVoice3 0.5B (MLX)~500MLLM 4 bits~1,2 Go
IndexTTS2 expanded bundle (MLX)1.5B-classFP16 + auxiliary models~4.8 GB
Kokoro-82M (CoreML)82MINT8 (1 bucket)~89 Mo
Qwen3.5-Chat 0.8B (MLX)~800MINT4418 Mo
Qwen3.5-Chat 0.8B (CoreML)~800MINT8981 Mo
PersonaPlex 7B (MLX)~7B4 bits / 8 bits4,9 Go / 9,1 Go
VoiceChat 11B (MLX)~11BINT5 / INT88.56 GB / 12.11 GB
Pyannote VAD (MLX)~1,49Mfloat32~5,7 Mo
Silero VAD v5~309Kfloat32~1,2 Mo (MLX et CoreML)
p99 turn-1-mini5.3MFloat3222 MB (CoreML)
VAP (otoSpeech)5.8MFloat3239 MB (CoreML) / 40 MB (ONNX)
WeSpeaker ResNet34~6,6Mfloat32~25 Mo (MLX et CoreML)
SpeechBrain ECAPA VoxLingua10721.25MFP16~40.6 MiB (MLX) / ~40.8 MiB (CoreML)
ReDimNet2-B612,3Mfloat16~25 Mio (CoreML)
Pyannote Community-1 (CoreML)8.35Mfloat32 + native VBx~32 MB
Nemotron 3 Diarization (CoreML / MLX)100MINT8~100 MB per backend
Sortformer (CoreML)—float16~50 Mo
DeepFilterNet3 (CoreML)~2,1MFP16~4,2 Mo
LocalVQE v1.4-AEC (CoreML + C++)200K + 2 742FP16 + FP32~732 Ko

Initialisation des modèles MLX

QuantizedLinear.preQuantized crée des tableaux provisoires de zéros pour les couches linéaires quantifiées chargées depuis un checkpoint, évitant les poids aléatoires et leurs graphes temporaires de quantification. withThrowawayRandomState sépare l’initialisation en virgule flottante destinée à être supprimée de la chaîne de clés aléatoires de l’appelant. Les chargeurs de modèles composites isolent chaque composant : T5 et EnCodec de MAGNeT, T5Gemma et SAME-L de Stable Audio 3, et le codec Mimi de CSM. Les embeddings quantifiés de CSM utilisent toujours l’initialiseur amont et conservent sa limitation connue concernant la durée de vie du graphe d’initialisation.

Optimisations de performance

Traitement audio

Toutes les E/S audio utilisent du PCM Float32. Le rééchantillonnage interne gère la conversion de format :

ModèleTaux attenduFormat
Qwen3-ASR16 kHzMono Float32
Cohere Transcribe 2B16 kHzMono Float32
Voxtral Mini 3B16 kHzMono Float32
Qwen3-TTS24 kHz en sortieMono Float32
CosyVoice324 kHz en sortieMono Float32
Kokoro-82M24 kHz en sortieMono Float32
PersonaPlex24 kHz E/SMono Float32
Pyannote VAD16 kHzMono Float32
Silero VAD16 kHzMono Float32
WeSpeaker16 kHzMono Float32
SpeechBrain ECAPA LID16 kHzMono Float32
ReDimNet2-B616 kHzMono Float32
DeepFilterNet348 kHzMono Float32

Structure des sources

Sources/
  AudioCommon/            Protocoles partagés, E/S audio, capture de la
                          sortie système (SystemAudioTap), téléchargeur
                          HuggingFace, SentencePieceModel (lecteur protobuf)
  MLXCommon/              Utilitaires MLX : chargement des poids, aides QuantizedLinear,
                          aide d'attention multi-tête SDPA, budget Metal
  Qwen3Common/            Composants de modèle partagés (cache KV, RoPE, quantification)
  Qwen3ASR/               Qwen3-ASR parole vers texte
  ParakeetASR/            Parakeet TDT parole vers texte (CoreML)
  ParakeetStreamingASR/   Dictée streaming Parakeet EOU 120M (CoreML)
  OmnilingualASR/         Meta wav2vec2 + CTC, 1 672 langues
                          (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 texte vers parole
  FireRedTTS3TTS/         FireRedTTS3-Instruct (MLX, Float32)
  MossVoiceGeneratorTTS/  MOSS-VoiceGenerator (MLX, BF16 + FP32)
  CosyVoiceTTS/           CosyVoice3 texte vers parole
  KokoroTTS/              Kokoro-82M texte vers parole (CoreML)
  Qwen3Chat/              Chat LLM embarqué Qwen3.5-0.8B (MLX + CoreML)
  PersonaPlex/            PersonaPlex parole-à-parole
  SpeechVAD/              VAD (Silero + Pyannote), diarisation, empreintes de locuteur
  SpeechLanguageID/       Identification de la langue parlée (SpeechBrain ECAPA, MLX + CoreML, 107 étiquettes)
  SpeechEnhancement/      Suppression de bruit DeepFilterNet3 (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)
  GLiNER/                 GLiNER2.5-Decide classification + entity spans (MLX, INT8/FP16/FP32)
  AudioCLILib/            Implémentations des commandes CLI
  AudioCLI/               Point d'entrée CLI

scripts/              Conversion de modèles (PyTorch → MLX/CoreML), benchmarking
Tests/                Tests unitaires et d'intégration
Examples/             Applications de démonstration (PersonaPlexDemo, SpeechDemo)

GLiNER2.5-Decide : classification et segments d’entités natifs en MLX (poids INT8, FP16 ou FP32) ; pas de Python à l’inférence.

⚠ Translation out of date — English guide. The new Clef section below awaits translation.

Clef-flash: development preview of local text decisions (9B, affine 4-bit MLX), with a joint schema head and a separate output-embedding prior.

MOSS-TTS-Nano

Synthèse vocale en streaming et clonage avec CoreML, audio stéréo 48 kHz et blocs de 80 ms.

MossTTSNanoModel sérialise les requêtes et crée un état CoreML neuf par énoncé. synthesize et synthesizeStream conservent la stéréo ; SpeechGenerationModel renvoie un mixage mono. Passez language: nil. Le flux se termine par un marqueur final vide.

macOS 15+ / iOS 18+ ; quatre modèles compilés totalisant 367,6 Mo. Le prompt, la référence et les trames demandées partagent 1 024 lignes de contexte. Le dépassement du contexte ou de maxFrames avant la fin naturelle provoque une erreur. CPU par défaut ; gpu autorise CPU+GPU. Les graines PCG64 sont compatibles avec NumPy ; les écarts numériques entre backends peuvent modifier la sortie.

MOSS-TTS-Nano

Gestion facultative des modèles

SpeechRuntime fournit un chargement partagé, une admission FIFO annulable et une exécution sérialisée. Qwen3ASRRuntime sélectionne MLX ou CoreML complet par descripteurs explicites ; les API natives et options CLI restent disponibles.

Le serveur conserve un permis pendant toute la requête, y compris la sortie en streaming, avec jusqu’à 32 requêtes en attente. Les échecs ASR produisent des erreurs HTTP ou des événements d’erreur WebSocket ; les transcriptions vides valides restent des succès. La lecture conserve les échantillons excédentaires. Les modèles en cache et l’audio en attente occupent toujours de la mémoire.

Voxtral TTS

Voxtral 4B TTS 2603 fonctionne localement sur Apple Silicon via le module VoxtralTTS : 20 voix prédéfinies, neuf langues et une sortie mono à 24 kHz.

VoxtralTTS → 26-layer LM → 3-layer acoustic transformer → 24 kHz PCM

Voix prédéfinies uniquement ; le clonage à partir d’un audio de référence est indisponible. Le SDK, la CLI, WebSocket et HTTP PCM émettent l’audio pendant la génération. Le texte complet doit être fourni au départ. Les poids sont sous licence CC BY-NC 4.0.

Lire le guide Voxtral TTS

Fish Audio Drama 3

La prise en charge native expérimentale de Drama 3 en MLX est disponible via FishAudioDrama3Model. Un modèle MoE de 35 milliards de paramètres à attention hybride, un décodeur audio temporel et le codec Fish DAC produisent un son mono à 44,1 kHz. Le modèle 4 bits a réussi les tests audio et de reconnaissance indépendante pour la génération à partir de texte, le clonage avec référence et la sortie CLI sur Apple M5 Pro. Les variantes 8 bits et BF16 restent à valider.

Le mode par défaut balanced libère les tampons MLX inactifs au-delà de 512 MiB entre les étapes. Le plafond partagé s’applique aussi pendant la durée de vie du modèle et préserve les budgets inférieurs de l’appelant ; aucun de ces contrôles ne limite la mémoire totale du processus. --fish-drama3-memory-mode unrestricted ou memoryOptions: .unrestricted charge les poids à l’avance et ignore le nettoyage entre étapes, mais conserve le plafond de durée de vie.

La génération de texte seul diffère le chargement de 794.4 MiB de poids de l’encodeur de référence. Le premier encodage les charge et les conserve ; gardez codec.safetensors disponible jusque-là. Les codes de référence précalculés n’ont pas besoin de l’encodeur.

FishAudioTTS: FishAudioDrama3Model · backbone.model.* · semantic_head.* · tower.* · codec.safetensors

Créé avec Fish Audio. Les paquets conservent la Community License et NOTICE.

Mesures en 4 bits

Le streaming PCM est disponible via generateStreaming, generateStream et --stream. Un bloc contient par défaut 3 trames du codec, soit environ 139 ms d’audio. Le découpage automatique des textes longs et l’entrée progressive de texte restent indisponibles.

Chaque dictionnaire de codes de la tour utilise 4 096 valeurs de jeton. Le décodage Fish DAC en mémoire comme en flux ramène les codes résiduels dans la plage des dictionnaires résiduels de 1 024 entrées du codec. Les dictionnaires de codes renvoyés conservent les valeurs originales de la tour.

Les dimensions rotatives non valides sont rejetées avant le chargement des poids du modèle.