MOSS-TTS-Nano

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

Apache-2.0 · aufklarer/MOSS-TTS-Nano-100M-CoreML

CLI

speech speak "Hello world." --engine moss-nano -o hello.wav
speech speak "The weather is nice today." --engine moss-nano \
  --voice-sample reference.wav --moss-nano-seed 1 -o cloned.wav
speech speak "Hello world." --engine moss-nano --stream --play -o streamed.wav

Utilisez --voice-sample pour cloner une voix sans transcription de référence. Les références mono sont dupliquées en stéréo, rééchantillonnées à 48 kHz puis complétées à un multiple de 80 ms. Encodez la référence une fois et réutilisez ses codes.

--moss-nano-modelaufklarer/MOSS-TTS-Nano-100M-CoreMLDépôt du modèle ou répertoire local
--moss-nano-compute-unitscpucpu ou gpu
--moss-nano-max-frames300Maximum de trames de 80 ms ; fin naturelle requise
--moss-nano-seed0Graine reproductible du tirage Swift

API Swift

import AudioCommon
import MossTTSNano

let model = try await MossTTSNanoModel.fromPretrained()
let reference = try await model.encodeReference(url: referenceURL)
let result = try await model.synthesize(
    text: "The weather is nice today.", reference: reference,
    options: MossTTSNanoOptions(maxFrames: 300, seed: 1))
try WAVWriter.writeStereo(left: result.left, right: result.right,
    sampleRate: 48000, to: outputURL)

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.

Limites et mesures

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.

Python/CoreML sur M5 Pro, 48 Go, macOS 26.6.2 ; processus distincts et cinq requêtes chaudes par cas. Référence de 2,72 s. Les valeurs initiales/chaudes incluent lecture, chargement de l’encodeur et encodage ; le cache réutilise les codes. Le chargement des modèles de synthèse est exclu. RSS couvre tout le processus Python sans PyTorch ni ASR. Il ne s’agit pas de mesures Swift/iPhone ni de similarité du locuteur.

BackendRSS maximalPremier token : initial / chaud / cachePremier audio : initial / chaud / cache
CPU779 MiB542 / 203 / 52 ms563 / 216 / 65 ms
CPU+GPU731 MiB649 / 225 / 24 ms741 / 245 / 48 ms

Swift · Release

CLI native Swift release sur le même M5 Pro : une requête par nouveau processus avec les mêmes référence, texte et graine. Préparation de référence incluse, chargement des modèles de synthèse exclu. RSS couvre toute la CLI sans poids ASR. Les tirets indiquent les cas chauds/en cache non mesurés. Les deux sorties ont restitué exactement la phrase demandée via une ASR indépendante.

BackendRSS maximalPremier token : initial / chaud / cachePremier audio : initial / chaud / cache
CPU670.7 MiB537 / — / — ms560 / — / — ms
CPU+GPU602.5 MiB570 / — / — ms645 / — / — ms

MossTTSNano · OpenMOSS