架构
原生指令语音合成
请从 main 源码构建原生 SDK 支持。Homebrew 等预编译 CLI 发行版可能尚未包含这些引擎。
已发布的 MLX 模型包: aufklarer/FireRedTTS3-Instruct-MLX-fp32 · aufklarer/MOSS-VoiceGenerator-MLX-bf16
FireRedTTS3-Instruct — FireRedTTS3TTS: FireRedTTS3-Instruct 保留 Float32 模型和解码器权重。它返回完整缓冲音频,请勿使用 --stream。--language 接受英语和中文别名。达到生成上限会报错,不会将截断音频视为成功。
MOSS-VoiceGenerator — MossVoiceGeneratorTTS: MOSS-VoiceGenerator 保留 BF16 语言模型权重和 FP32 合成编解码器。使用 --stream 输出增量 PCM。请省略 --language,将语言要求写入 --instruct。结束前会排空全部十六个码本。
文本和指令两个字段各限 32,768 个 UTF-8 字节。包含模板的完整输入提示词渲染后不得超过 4,096 个令牌。超过任一限制都会被拒绝。
指令遵循质量尚未评分。短文本测量仅描述受测配置;现有模型的延迟回归认证仍无定论。
Breeze TTS 2 · BreezeTTS
英语/中文语音合成,支持声音设计、参考音频克隆与风格控制以及流式音频(MLX BF16/8-bit,24 kHz;仅限研究和非商业用途).
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
Apple 原生运行时 · PocketTTS
PocketTTS 为 speech-swift 添加原生 CoreML 语音合成。所有阶段默认仅使用 CPU。英语 Alba 预设以 24 kHz 流式输出,每帧 1,920 个采样(80 毫秒)。
speech-swift 是一个模块化的 Swift 包,由共享协议、独立的模型模块和统一的 CLI 组成。所有推理都在端侧使用 MLX(Metal GPU)或 CoreML(Neural Engine)运行。
模块依赖图
┌──────────┐
│ AudioCLI │ (entry point)
└────┬─────┘
│
┌──────┴──────┐
│ AudioCLILib │ (commands)
└──────┬──────┘
│
┌─────────┬───────┼───────┬──────────┬──────────────┐
│ │ │ │ │ │
┌────┴───┐ ┌──┴──┐ ┌──┴──┐ ┌─┴────┐ ┌───┴────┐ ┌──────┴───────┐
│Qwen3ASR│ │Qwen3│ │Cosy │ │Perso-│ │Speech- │ │ Speech- │
│Parakeet│ │ TTS │ │Voice│ │naPlex│ │ VAD │ │Enhancement │
└────┬───┘ └──┬──┘ └──┬──┘ └──┬───┘ └───┬───┘ └──────┬───────┘
│ │ │ │ │ │
└────────┴───────┼───────┴─────────┘ │
│ │
┌──────┴──────┐ │
│ Qwen3Common │ (shared layers) │
└──────┬──────┘ │
│ │
┌──────┴──────┐ │
│ AudioCommon │ ◄──────────────────────┘
└─────────────┘ (protocols, audio I/O)MLX 缓冲区缓存预算
MLX 模型运行时从加载权重开始,在模型生命周期内共享默认可复用缓冲区上限 min(2 GiB, physical RAM / 4)。调用方设置的更低预算(包括 MLX.Memory.cacheLimit = 0)及现有模型专用预算都会保留。此上限仅限制空闲缓冲区;活动权重、KV 缓存和进程总内存可能超过它。 MLX 会在分配时修剪缓存,因此最后释放的缓冲区可能使缓存暂时超出预算,直到下一次分配。
unload() 会释放模型的注册;没有此方法的运行时会在销毁时释放。最后一个持有者释放后恢复调用方预算,此前的卸载仍保留其他模型的上限。纯 CoreML 路径不会注册 MLX 预算。
MOSS Transcribe Diarize
MossTranscribe 通过原生 CoreML 和 MLX 后端返回带说话人标记的时间戳分段。CoreML 为短音频使用固定 1,024-token 状态;MLX 使用动态 131,072-token 上下文、仿射 INT5/INT8 解码器权重及可选 FP16/INT8 KV 缓存。两者均为离线自回归运行时,不支持流式输出。
VoiceChat 11B
任务与参考:双工语音到语音(speech-to-speech);SALM-Duplex: Efficient and Direct Duplex Modeling for Speech-to-Speech Language Model(Interspeech 2025),由 NVIDIA 上游 VoiceChat 模型卡引用。
完整运行时,M5 Pro 48 GB,Release,80 ms 实时节奏:保护输出头的 INT5 峰值 RSS 约 8.69 GB;三次受控的全流程 RTF 结果为 0.96、0.96 和 0.99。优化后的 INT8 性能尚未重新测量。
VoiceChat 实现完整的原生 MLX 音频到音频路径:因果 FastConformer 感知、Nemotron-H 双工文本/函数通道、采用八次 MaskGIT 迭代的独立文本条件 EAR-TTS 解码器,以及 22.05 kHz 神经音频编解码器。流式处理保留有界的逐层注意力和因果卷积缓存,稳态的八帧实时编解码器窗口则使用编译图。每个 80 ms 输入帧都会产生一次语言决策、31 个 RVQ 码和恰好 1,764 个输出采样。加载器要求完整的 encoder/ + llm/ + tts/ bundle,并拒绝旧的仅理解导出。INT5 现在可在测试的 M5 Pro 上持续保持低于 1 的总体 RTF,但每帧 p95 余量仍然很小。
推理后端
| 后端 | 硬件 | 模型 |
|---|---|---|
| MLX | Metal GPU | Qwen3-ASR、Qwen3-TTS、Breeze TTS 2、CosyVoice3、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) | Qwen3-ASR 编码器(混合)、Parakeet TDT、Parakeet EOU 流式、Omnilingual ASR 300M、Kokoro-82M、Qwen3.5-Chat(可选)、Sortformer 说话人分离、DeepFilterNet3、Silero VAD(可选)、WeSpeaker(可选), MOSS Transcribe Diarize, SpeechBrain ECAPA LID, Nemotron 3 Diarization |
| Accelerate | CPU (SIMD) | 音频预处理(STFT、mel、FFT)、信号处理 |
模型权重格式
MLX 模型采用 safetensors 格式,使用 4 位或 8 位量化(group size 64)。CoreML 模型采用 .mlmodelc 编译格式。scripts/ 中的转换脚本将 PyTorch checkpoint 转换为相应格式。
Cohere 和 Voxtral 还提供 MLX 仿射 INT5 包。MLX 不支持仿射 INT7;INT8 是受支持的更高质量选项。
| 模型 | 参数量 | 量化 | 磁盘大小 |
|---|---|---|---|
| Qwen3-ASR 0.6B (MLX) | ~600M | 4-bit / 8-bit | 680 MB / 1.0 GB |
| Qwen3-ASR 0.6B (CoreML) | ~186M(编码器) | 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) |
| p99 turn-1-mini | 5.3M | Float32 | 22 MB (CoreML) |
| VAP (otoSpeech) | 5.8M | Float32 | 39 MB (CoreML) / 40 MB (ONNX) |
| 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 |
| Nemotron 3 Diarization (CoreML / MLX) | 100M | INT8 | ~100 MB per backend |
| 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 |
MLX 模型初始化
QuantizedLinear.preQuantized 为从检查点加载的量化线性层创建零占位数组,避免生成随机权重及其临时量化计算图。withThrowawayRandomState 将会被丢弃的浮点初始化与调用方的随机密钥链隔离。组合模型的加载器为每个组件设置独立作用域,包括 MAGNeT 的 T5 和 EnCodec、Stable Audio 3 的 T5Gemma 和 SAME-L,以及 CSM 的 Mimi 编解码器。CSM 的量化嵌入仍使用上游初始化器,因此仍存在其已知的初始化计算图生命周期限制。
性能优化
- MLX compile() — 针对自回归循环的 kernel fusion。Talker 使用
compile(shapeless: true),Code Predictor 使用固定 cache 大小的compile(shapeless: false)。 - Metal shader 库 — 预编译的 metallib 避免了约 5 倍的 JIT 编译开销。通过
scripts/build_mlx_metallib.sh构建。 - 分块 codec 解码 — TTS 解码器以 25 帧为一块、10 帧上下文重叠的方式处理音频,避免 GPU 超时。
- 批量加倍 CFG — CosyVoice3 DiT 通过将 conditional 与 unconditional 一起 batch,把 flow matching 的 pass 数减半。
- 融合 RoPE — 使用基于 Metal kernel 的
MLXNN.RoPE,替代手动旋转。 - BN 融合 — WeSpeaker 的 batch normalization 在转换时融合到 Conv2d 权重中。
音频处理
所有音频 I/O 都使用 Float32 PCM。内部的重采样负责格式转换:
| 模型 | 期望采样率 | 格式 |
|---|---|---|
| Qwen3-ASR | 16 kHz | Mono Float32 |
| Cohere Transcribe 2B | 16 kHz | Mono Float32 |
| Voxtral Mini 3B | 16 kHz | Mono Float32 |
| Qwen3-TTS | 24 kHz 输出 | Mono Float32 |
| CosyVoice3 | 24 kHz 输出 | Mono Float32 |
| Kokoro-82M | 24 kHz 输出 | 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 |
源码结构
Sources/
AudioCommon/ 共享协议、音频 I/O、系统输出捕获(SystemAudioTap)、HuggingFace
下载器、SentencePieceModel(protobuf 读取器)
MLXCommon/ MLX utilities: weight loading, QuantizedLinear helpers,
SDPA multi-head attention helper, metal budget
Qwen3Common/ Shared model components (KV cache, RoPE, quantization)
Qwen3ASR/ Qwen3-ASR speech-to-text
ParakeetASR/ Parakeet TDT speech-to-text (CoreML)
ParakeetStreamingASR/ Parakeet EOU 120M streaming dictation (CoreML)
OmnilingualASR/ Meta wav2vec2 + CTC, 1,672 languages
(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-to-speech
FireRedTTS3TTS/ FireRedTTS3-Instruct (MLX, Float32)
MossVoiceGeneratorTTS/ MOSS-VoiceGenerator (MLX, BF16 + FP32)
CosyVoiceTTS/ CosyVoice3 text-to-speech
KokoroTTS/ Kokoro-82M text-to-speech (CoreML)
Qwen3Chat/ Qwen3.5-0.8B on-device LLM chat (MLX + CoreML)
PersonaPlex/ PersonaPlex speech-to-speech
SpeechVAD/ VAD (Silero + Pyannote), diarization, speaker embeddings
SpeechLanguageID/ 口语语言识别(SpeechBrain ECAPA、MLX + CoreML、107 个标签)
SpeechEnhancement/ DeepFilterNet3 noise suppression (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/ CLI command implementations
AudioCLI/ CLI entry point
scripts/ Model conversion (PyTorch → MLX/CoreML), benchmarking
Tests/ Unit and integration tests
Examples/ Demo apps (PersonaPlexDemo, SpeechDemo)GLiNER2.5-Decide:原生 MLX 分类与实体片段(INT8、FP16 或 FP32 权重);推理时不需要 Python。
⚠ 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
通过 CoreML 进行流式语音合成与语音克隆,输出 48 kHz 立体声,分块时长为 80 ms。
MossTTSNanoModel 串行处理请求,并为每次合成创建独立 CoreML 状态。synthesize 和 synthesizeStream 保留立体声;SpeechGenerationModel 返回单声道混音。请传入 language: nil。流以空的最终标记结束。
需要 macOS 15+ / iOS 18+;四个编译模型共 367.6 MB。提示、参考音频与请求的生成帧共享 1,024 行上下文。超出上下文或在自然结束前达到 maxFrames 时会报错。默认使用 CPU;gpu 允许 CPU+GPU。PCG64 采样种子与 NumPy 兼容;后端数值差异仍可能改变输出。
可选模型管理
SpeechRuntime 提供共享加载、可取消的 FIFO 准入和串行执行。Qwen3ASRRuntime 通过显式描述符选择 MLX 或完整 CoreML;原生 API 和 CLI 参数继续可用。
音频服务器在整个请求(包括流式输出)期间持有一个执行许可,最多有 32 个请求等待。ASR 失败返回 HTTP 错误或 WebSocket 错误事件;有效的空转录仍视为成功。播放会保留溢出的采样。缓存模型和待播放音频仍占用内存。
Voxtral TTS
Voxtral 4B TTS 2603 通过 VoxtralTTS 模块在 Apple Silicon 上本地运行,提供 20 种预设声音、9 种语言和 24 kHz 单声道语音。
VoxtralTTS → 26-layer LM → 3-layer acoustic transformer → 24 kHz PCM仅支持预设音色,不支持参考音频克隆。SDK、CLI、WebSocket 和 HTTP PCM 均可在生成过程中输出音频。输入文本须一次性完整提供。模型权重采用 CC BY-NC 4.0 许可。
Fish Audio Drama 3
Drama 3 的实验性原生 MLX 支持通过 FishAudioDrama3Model 提供。350 亿参数的混合注意力 MoE 主干、时序音频解码塔和 Fish DAC 编解码器输出 44.1 kHz 单声道音频。4 位检查点已在 Apple M5 Pro 上通过纯文本生成、参考语音克隆和 CLI 输出的波形及独立 ASR 验证。8 位和 BF16 版本尚未验证。
默认 balanced 模式会在阶段边界修剪超过 512 MiB 的空闲 MLX 缓冲区。模型生命周期内还应用共享缓存上限,并保留调用方的更低预算;两者都不限制进程总内存。--fish-drama3-memory-mode unrestricted 或 memoryOptions: .unrestricted 会提前加载权重并跳过阶段修剪,但仍保留生命周期上限。
纯文本生成会延迟加载 794.4 MiB 的参考音频编码器权重。首次编码参考音频时加载并保留这些权重,因此在此之前请保留 codec.safetensors。预先计算的参考编码无需编码器。
FishAudioTTS: FishAudioDrama3Model · backbone.model.* · semantic_head.* · tower.* · codec.safetensors
基于 Fish Audio 构建。模型包保留社区许可证和 NOTICE。
可通过 generateStreaming、generateStream 和 --stream 获取 PCM 流式输出。默认每块 3 个编解码帧,约 139 毫秒音频。尚不支持长文本自动分块和流式文本输入。
塔式解码器的每个码本使用 4,096 个词元值。缓冲和流式 Fish DAC 解码都会将残差码限制在编解码器的 1,024 项残差码本范围内。返回的码本保留塔式解码器的原始值。
无效的旋转位置编码维度会在加载模型权重前被拒绝。