Архитектура
speech-swift организован как модульный Swift-пакет с общими протоколами, независимыми модулями моделей и единым CLI. Весь инференс выполняется на устройстве через MLX (Metal GPU) или CoreML (Neural Engine).
Граф зависимостей модулей
┌──────────┐
│ AudioCLI │ (точка входа)
└────┬─────┘
│
┌──────┴──────┐
│ AudioCLILib │ (команды)
└──────┬──────┘
│
┌─────────┬───────┼───────┬──────────┬──────────────┐
│ │ │ │ │ │
┌────┴───┐ ┌──┴──┐ ┌──┴──┐ ┌─┴────┐ ┌───┴────┐ ┌──────┴───────┐
│Qwen3ASR│ │Qwen3│ │Cosy │ │Perso-│ │Speech- │ │ Speech- │
│Parakeet│ │ TTS │ │Voice│ │naPlex│ │ VAD │ │Enhancement │
└────┬───┘ └──┬──┘ └──┬──┘ └──┬───┘ └───┬───┘ └──────┬───────┘
│ │ │ │ │ │
└────────┴───────┼───────┴─────────┘ │
│ │
┌──────┴──────┐ │
│ Qwen3Common │ (общие слои) │
└──────┬──────┘ │
│ │
┌──────┴──────┐ │
│ AudioCommon │ ◄──────────────────────┘
└─────────────┘ (протоколы, аудио I/O)Бэкенды инференса
| Бэкенд | Оборудование | Модели |
|---|---|---|
| MLX | Metal GPU | Qwen3-ASR, Qwen3-TTS, CosyVoice3, Qwen3.5-Chat, PersonaPlex, Omnilingual ASR (300M / 1B / 3B / 7B), Pyannote, Silero VAD, WeSpeaker |
| CoreML | Neural Engine | Энкодер Qwen3-ASR (гибрид), Parakeet TDT, потоковый Parakeet EOU, Omnilingual ASR 300M, Kokoro-82M, Qwen3.5-Chat (опционально), диаризация Sortformer, DeepFilterNet3, Silero VAD (опционально), WeSpeaker (опционально) |
| Accelerate | CPU (SIMD) | Предобработка аудио (STFT, мел, FFT), обработка сигналов |
Формат весов моделей
MLX-модели используют формат safetensors с 4-битной или 8-битной квантизацией (размер группы 64). CoreML-модели используют скомпилированный формат .mlmodelc. Скрипты конвертации в scripts/ конвертируют из чекпоинтов PyTorch.
| Модель | Параметры | Квантизация | Размер на диске |
|---|---|---|---|
| Qwen3-ASR 0.6B (MLX) | ~600M | 4-bit / 8-bit | 680 МБ / 1.0 ГБ |
| Qwen3-ASR 0.6B (CoreML) | ~186M (энкодер) | INT8 | ~180 МБ |
| Qwen3-ASR 1.7B (MLX) | ~1.7B | 4-bit / 8-bit | 2.1 ГБ / 3.2 ГБ |
| Parakeet-TDT 0.6B (CoreML) | ~600M | INT8 | 500 МБ |
| Parakeet-EOU 120M (CoreML) | ~120M | INT8 | ~120 МБ |
| Omnilingual-ASR-CTC 300M (CoreML) | 326M | INT8 | 312 МБ |
| Omnilingual-ASR-CTC 300M (MLX) | 326M | 4-bit / 8-bit | 193 МБ / 342 МБ |
| Omnilingual-ASR-CTC 1B (MLX) | 1.01B | 4-bit / 8-bit | 549 МБ / 1006 МБ |
| Omnilingual-ASR-CTC 3B (MLX) | ~3B | 4-bit / 8-bit | 1.71 ГБ / 3.16 ГБ |
| Omnilingual-ASR-CTC 7B (MLX) | ~7B | 4-bit / 8-bit | 3.55 ГБ / 6.63 ГБ |
| Qwen3-ForcedAligner 0.6B (MLX) | ~600M | 4-bit / 8-bit | 979 МБ / 1.4 ГБ |
| Qwen3-ForcedAligner 0.6B (CoreML) | ~600M | INT4 / INT8 | 630 МБ / 1.0 ГБ |
| Qwen3-TTS 0.6B (MLX) | ~600M | 4-bit / 8-bit | 1.7 ГБ / 2.4 ГБ |
| Qwen3-TTS 1.7B (MLX) | ~1.7B | 4-bit / 8-bit | 3.2 ГБ / 4.8 ГБ |
| CosyVoice3 0.5B (MLX) | ~500M | 4-bit LLM | ~1.2 ГБ |
| Kokoro-82M (CoreML) | 82M | INT8 (1 bucket) | ~89 МБ |
| Qwen3.5-Chat 0.8B (MLX) | ~800M | INT4 | 418 МБ |
| Qwen3.5-Chat 0.8B (CoreML) | ~800M | INT8 | 981 МБ |
| PersonaPlex 7B (MLX) | ~7B | 4-bit / 8-bit | 4.9 ГБ / 9.1 ГБ |
| Pyannote VAD (MLX) | ~1.49M | float32 | ~5.7 МБ |
| Silero VAD v5 | ~309K | float32 | ~1.2 МБ (MLX и CoreML) |
| WeSpeaker ResNet34 | ~6.6M | float32 | ~25 МБ (MLX и CoreML) |
| Sortformer (CoreML) | — | float16 | ~50 МБ |
| DeepFilterNet3 (CoreML) | ~2.1M | FP16 | ~4.2 МБ |
Оптимизации производительности
- MLX compile() — Слияние ядер для авторегрессивных циклов. Talker использует
compile(shapeless: true), Code Predictor —compile(shapeless: false)с фиксированными размерами кеша. - Библиотека Metal-шейдеров — Предкомпилированный metallib избавляет от ~5x накладных расходов JIT-компиляции. Собирается через
scripts/build_mlx_metallib.sh. - Декодирование кодека чанками — Декодер TTS обрабатывает аудио чанками по 25 кадров с перекрытием контекста в 10 кадров, чтобы избежать таймаута GPU.
- Batch-doubled CFG — DiT в CosyVoice3 вдвое сокращает проходы flow matching, батчируя условный и безусловный проходы вместе.
- Fused RoPE — Использует
MLXNN.RoPEна базе Metal-ядра вместо ручной ротации. - Слияние BN — Батч-нормализация WeSpeaker сливается в веса Conv2d на этапе конвертации.
Обработка аудио
Весь аудио I/O использует PCM Float32. Внутренний ресемплинг выполняет конвертацию форматов:
| Модель | Ожидаемая частота | Формат |
|---|---|---|
| Qwen3-ASR | 16 кГц | Моно Float32 |
| Qwen3-TTS | 24 кГц на выходе | Моно Float32 |
| CosyVoice3 | 24 кГц на выходе | Моно Float32 |
| Kokoro-82M | 24 кГц на выходе | Моно Float32 |
| PersonaPlex | 24 кГц I/O | Моно Float32 |
| Pyannote VAD | 16 кГц | Моно Float32 |
| Silero VAD | 16 кГц | Моно Float32 |
| WeSpeaker | 16 кГц | Моно Float32 |
| DeepFilterNet3 | 48 кГц | Моно Float32 |
Структура исходников
Sources/
AudioCommon/ Общие протоколы, аудио I/O, загрузчик HuggingFace,
SentencePieceModel (ридер protobuf)
MLXCommon/ Утилиты MLX: загрузка весов, хелперы QuantizedLinear,
хелпер SDPA multi-head attention, metal budget
Qwen3Common/ Общие компоненты моделей (KV cache, RoPE, квантизация)
Qwen3ASR/ Qwen3-ASR распознавание речи
ParakeetASR/ Parakeet TDT распознавание речи (CoreML)
ParakeetStreamingASR/ Parakeet EOU 120M потоковая диктовка (CoreML)
OmnilingualASR/ Meta wav2vec2 + CTC, 1 672 языка
(CoreML 300M + MLX 300M / 1B / 3B / 7B)
Qwen3TTS/ Qwen3-TTS синтез речи
CosyVoiceTTS/ CosyVoice3 синтез речи
KokoroTTS/ Kokoro-82M синтез речи (CoreML)
Qwen3Chat/ Qwen3.5-0.8B on-device LLM-чат (MLX + CoreML)
PersonaPlex/ PersonaPlex речь в речь
SpeechVAD/ VAD (Silero + Pyannote), диаризация, эмбеддинги спикеров
SpeechEnhancement/ DeepFilterNet3 подавление шума (CoreML)
AudioCLILib/ Реализации команд CLI
AudioCLI/ Точка входа CLI
scripts/ Конвертация моделей (PyTorch → MLX/CoreML), бенчмаркинг
Tests/ Юнит- и интеграционные тесты
Examples/ Демо-приложения (PersonaPlexDemo, SpeechDemo)