Vocalizer — це нативне PHP-розширення від Akram Zerarka для локального синтезу мовлення (TTS). Воно працює без викликів API та зовнішніх залежностей у runtime. Розширення містить два рушії виведення — sherpa-onnx (ONNX Runtime) та audio.cpp (ggml) — і постачається як попередньо зібраний бінарний файл .so, тому компіляція не потрібна.
Основні можливості розширення:
- Вісім сімейств моделей, єдиний API — Chatterbox, Supertonic, Piper/VITS, Pocket, Kokoro, Kitten, Matcha та ZipVoice (автоматично визначаються в директорії моделей).
- Клонування голосу — Chatterbox клонує будь-який голос на основі 3–10 секундного WAV-файлу для 23 мов.
- Захист від «галюцинацій» — результати Chatterbox перевіряються на наявність пропущеного тексту, циклів або тиші; у разі підозрілого результату синтез повторюється з новим seed.
- Ізоляція збоїв — за замовчуванням моделі запускаються у режимі fork, тому в разі краху рушія процес повторюється або перезавантажується, не зупиняючи PHP-воркер.
- Кешування моделей — моделі завантажуються один раз на PHP-воркер (витіснення LRU, параметр
vocalizer.max_models) і залишаються готовими для наступних запитів. - Асинхронний синтез — метод
speakAsync()повертає job, на виконання якого можна очікувати черезwait()із налаштуванням таймаутів. - Вихід у WAV або PCM — можливість зберігати у файл, отримувати WAV як рядок або працювати з float32 PCM.
# Єдиний API для восьми сімейств моделей
Метод Engine::load() вказує на директорію з моделлю та автоматично визначає потрібний бекенд. Синтез виконується одним викликом speak():
use Vocalizer\Engine;
$engine = Engine::load('/opt/voices/sherpa-onnx-supertonic-3-tts-int8-2026-05-11');
$res = $engine->speak('Ваше замовлення готове.', [
'lang' => 'uk', // обов'язково для Supertonic
'voice' => 0, // пресети голосів 0–9
'speed' => 1.0,
'timeout_ms' => 30_000,
]);
$res->save('/var/www/audio/notice.wav');
echo $res->seconds, " с за ", $res->generationMs, " мс\n";
Вибір моделі залежить від ваших цілей:
| Ціль | Модель | Затримка (CPU) |
|---|---|---|
| Максимальний реалізм, клонування голосу | Chatterbox | Повільно (~20× від реального часу) |
| Швидка підтримка багатьох мов (31 мова) | Supertonic 3 | У реальному часі |
| Легке клонування для FR/EN | Pocket TTS | Швидко |
| Найшвидша робота, одна модель на локаль | Piper/VITS | Дуже швидко |
# Клонування голосу з Chatterbox
Chatterbox підтримує 23 мови за допомогою однієї моделі розміром ~7.5 ГБ і клонує голос на основі короткого референсного WAV-файлу цільовою мовою:
$engine = Engine::load('/opt/voices/chatterbox', [
'threads' => 4,
'opts' => ['weight_type' => 'f16'], // за замовчуванням: q8_0
]);
$res = $engine->speak('Bonjour, votre commande est prête.', [
'lang' => 'fr',
'reference' => '/opt/voices/refs/fr.wav',
'opts' => [
'temperature' => 0.6,
'repetition_penalty' => 1.2,
'seed' => 42,
],
'timeout_ms' => 600_000,
]);
echo $res->qualityRetries; // кількість повторних спроб синтезу (0 = успіх з першого разу)
$res->save('/tmp/out.wav');
Авторегресивні TTS-моделі іноді пропускають текст або зациклюються. Vocalizer перевіряє вихідний сигнал на відповідність довжині тексту та енергії сигналу. Якщо аудіо підозріле, система робить до двох повторних спроб (налаштовується через verify_retries). Якщо всі спроби невдалі, викидається Vocalizer\Exception, що дозволяє легко реалізувати fallback на швидшу модель:
try {
$res = $engine->speak($text, ['lang' => 'fr', 'reference' => $ref]);
} catch (\Vocalizer\Exception $e) {
$res = Engine::load('/opt/voices/sherpa-onnx-supertonic-3-tts-int8-2026-05-11')
->speak($text, ['lang' => 'fr']);
}
# Ізоляція збоїв та асинхронність
Нативні рушії можуть спричинити segfault, що зазвичай призводить до падіння всього PHP FPM воркера. Vocalizer використовує режим ізоляції fork: синтез запускається у дочірньому процесі. Крах перехоплюється, виконується повторна спроба (до vocalizer.max_retries), а модель перезавантажується. Chatterbox — виняток: його пул потоків ggml несумісний із fork, тому він завжди працює у режимі direct.
Для довгих текстів speakAsync() дозволяє винести синтез за межі основного циклу запиту:
$job = $engine->speakAsync($paragraph);
$res = $job->wait(30_000) ?? throw new RuntimeException('Синтез триває занадто довго');
Налаштування здійснюється через php.ini: vocalizer.isolation (fork або direct), vocalizer.timeout_ms, vocalizer.max_models для кешу та vocalizer.max_concurrency для асинхронного пулу. Важливо: пам'ять для моделей виділяється на кожен FPM-воркер, а один лише Chatterbox потребує кілька гігабайт RAM.
# Встановлення
Vocalizer потребує Linux x86-64 (glibc ≥ 2.28) та PHP 8.4 або 8.5 NTS. Збірки для Alpine/musl, ARM та ZTS наразі не підтримуються. Скрипт встановлення завантажує розширення (~44 МБ) та перевіряє його через SHA256:
curl -fsSL https://raw.githubusercontent.com/akramzerarka/vocalizer/main/install.sh | bash
Моделі завантажуються окремо за допомогою вбудованого скрипта:
./scripts/download-model.sh chatterbox # ~7.5 ГБ
./scripts/download-model.sh sherpa-onnx-supertonic-3-tts-int8-2026-05-11 # ~120 МБ
./scripts/download-model.sh vits-piper-en_US-amy-low # ~65 МБ
Розширення має ліцензію MIT і статично лінкує залежності: sherpa-onnx (Apache-2.0), audio.cpp/ggml (MIT), ONNX Runtime (MIT) та espeak-ng (GPL-3.0).
Повна документація API та каталог моделей доступні на GitHub.