Коротким видео для TikTok, Reels, YouTube Shorts и карточек товаров на маркетплейсах нужен закадровый голос, а записывать каждый сценарий самостоятельно долго. Онлайн-сервисы синтеза речи берут плату за каждый символ и требуют загружать к ним ваши тексты. Kokoro — модель синтеза речи с открытыми весами и естественно звучащими голосами, достаточно компактная, чтобы работать на обычном сервере без GPU. В статье: установка Kokoro, выбор голоса, превращение текстовых сценариев в озвучку WAV с синхронными субтитрами SRT, работа с английскими словами в китайской озвучке и подготовка звука к загрузке на платформы.
# Debian 12 / Ubuntu 22.04 or 24.04 (Kokoro needs Python 3.10 to 3.12)
apt install -y python3-venv espeak-ng ffmpeg
python3 -m venv /opt/tts
/opt/tts/bin/pip install --upgrade pip
/opt/tts/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu # CPU-only build, much smaller
/opt/tts/bin/pip install kokoro soundfile "misaki[zh]"
# Japanese voices additionally need:
/opt/tts/bin/pip install "misaki[ja]"
/opt/tts/bin/python -m unidic download # Japanese dictionary, about 500 MB
Если системный Python версии 3.13 или новее (например, в Debian 13), создайте окружение с Python 3.12 через uv; параметр --seed добавляет pip, поэтому все последующие команды остаются прежними:
curl -LsSf https://astral.sh/uv/install.sh | sh
~/.local/bin/uv venv --seed -p 3.12 /opt/tts
/opt/tts/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu
/opt/tts/bin/pip install kokoro soundfile "misaki[zh]"
Модель (около 330 МБ) и каждый голос скачиваются с Hugging Face при первом использовании.
| Код | Язык | Примеры голосов |
|---|---|---|
| a | Американский английский | af_heart, af_bella, am_michael, am_adam |
| b | Британский английский | bf_emma, bf_isabella, bm_george, bm_daniel |
| z | Китайский (путунхуа) | zf_xiaobei, zf_xiaoni, zm_yunxi, zm_yunjian |
| j | Японский | jf_alpha, jf_nezumi, jm_kumo |
| e | Испанский | ef_dora, em_alex |
| f | Французский | ff_siwis |
| i | Итальянский | if_sara, im_nicola |
| p | Бразильский португальский | pf_dora, pm_alex |
| h | Хинди | hf_alpha, hm_omega |
Первая буква в названии голоса обозначает язык, вторая — женский (f) или мужской (m) голос. Корейский, русский, тайский, вьетнамский и малайский языки Kokoro не поддерживает; для этих рынков используйте субтитры или другой движок синтеза речи.
cat > /opt/tts/tts.py <<'EOF2'
import os, sys
import numpy as np
import soundfile as sf
from kokoro import KPipeline
LANG = os.environ.get("TTS_LANG", "a") # a = US English, z = Mandarin Chinese, j = Japanese ...
VOICE = os.environ.get("TTS_VOICE", "af_heart")
SPEED = float(os.environ.get("TTS_SPEED", "1.0"))
PAUSE = float(os.environ.get("TTS_PAUSE", "0.3")) # seconds of silence after each line
RATE = 24000
def ts(t):
ms = int(round(t * 1000))
h, ms = divmod(ms, 3600000)
m, ms = divmod(ms, 60000)
s, ms = divmod(ms, 1000)
return f"{h:02d}:{m:02d}:{s:02d},{ms:03d}"
pipeline = KPipeline(lang_code=LANG, repo_id="hexgrad/Kokoro-82M")
for path in sys.argv[1:]:
lines = [l.strip() for l in open(path, encoding="utf-8") if l.strip()]
parts, srt, pos = [], [], 0
for i, line in enumerate(lines, 1):
show, _, say = line.partition("|") # "subtitle text|text to speak" (optional)
chunks = [np.asarray(a, dtype=np.float32) for _, _, a in pipeline(say or show, voice=VOICE, speed=SPEED)]
audio = np.concatenate(chunks) if chunks else np.zeros(RATE // 2, dtype=np.float32)
srt.append(f"{i}\n{ts(pos / RATE)} --> {ts((pos + len(audio)) / RATE)}\n{show.strip()}\n")
silence = np.zeros(int(PAUSE * RATE), dtype=np.float32)
parts += [audio, silence]
pos += len(audio) + len(silence)
base = os.path.splitext(path)[0]
sf.write(base + ".wav", np.concatenate(parts), RATE)
with open(base + ".srt", "w", encoding="utf-8") as f:
f.write("\n".join(srt))
print(f"{path}: {len(lines)} lines, {pos / RATE:.1f}s -> {base}.wav, {base}.srt", flush=True)
EOF2
Каждая строка текстового файла становится одной фразой озвучки и одним субтитром. Рядом с текстовым файлом скрипт сохраняет файл WAV и файл SRT с точно совпадающими таймингами. Язык, голос, скорость речи и пауза между строками задаются переменными окружения.
mkdir -p /data/voice && cd /data/voice
cat > demo.txt <<'EOF2'
这款竹制笔记本支架有六档高度可调。
支持 USB-C 接口和 iPhone。|支持 优艾斯比西 接口和爱疯。
折叠后可以放进背包,重量只有一点一公斤。
EOF2
TTS_LANG=z TTS_VOICE=zf_xiaobei /opt/tts/bin/python /opt/tts/tts.py demo.txt
# English: TTS_LANG=a TTS_VOICE=af_heart Japanese: TTS_LANG=j TTS_VOICE=jf_alpha
В наших тестах китайские голоса правильно читали числа вроде 39.9 или 2026, но пропускали или искажали латинские слова, такие как USB-C или iPhone. Для таких строк сначала напишите текст субтитра, затем | и текст для озвучки, как во второй строке примера выше: в субтитре будет правильное название товара, а голос прочитает фонетический вариант. Тот же приём помогает с названиями брендов в японском (запишите их катаканой после |).
# Render the same text with several voices to compare them
for v in zf_xiaobei zf_xiaoni zm_yunxi zm_yunjian; do
cp demo.txt "try-$v.txt"
TTS_LANG=z TTS_VOICE=$v /opt/tts/bin/python /opt/tts/tts.py "try-$v.txt"
done
# Slightly faster speech and shorter pauses, typical for short videos
TTS_LANG=z TTS_VOICE=zm_yunxi TTS_SPEED=1.1 TTS_PAUSE=0.2 /opt/tts/bin/python /opt/tts/tts.py demo.txt
Скачайте файлы WAV и прослушайте их на телефоне — именно так их услышит большинство зрителей. Короткие предложения с запятыми в естественных местах звучат гораздо лучше длинных и сложных.
# Normalise loudness to about -14 LUFS (common for short-video platforms) and make an MP3
ffmpeg -i demo.wav -af loudnorm=I=-14:TP=-1.5 -ar 48000 -ac 2 demo-final.wav
ffmpeg -i demo-final.wav -c:a libmp3lame -q:a 2 demo.mp3
Импортируйте звук и demo.srt в видеоредактор или поручите скрипту собрать всё видео из фотографий, голоса и субтитров, как описано в статье автоматическое создание видео товаров. Чтобы перевести готовое видео на другой язык, см. ИИ-дубляж видео на другой язык.
Kokoro — небольшая модель. На современном многоядерном сервере она обычно синтезирует речь быстрее реального времени, так что после загрузки модели минутная озвучка создаётся значительно меньше чем за минуту. Скорость зависит от процессора и длины текста.
Kokoro предлагает только встроенные голоса. Для клонирования голоса нужны другие модели, как правило с GPU. Клонируйте голос только с явного согласия его владельца и соблюдайте правила платформ в отношении синтетического контента.
На момент написания статьи код и модель Kokoro распространяются по лицензии Apache 2.0, которая разрешает коммерческое использование. Прежде чем на это полагаться, проверьте актуальную лицензию на странице проекта и соблюдайте правила платформ в отношении контента, созданного ИИ.
Для английского и ряда других языков слова, которых нет в словаре, обрабатываются через espeak-ng. Убедитесь, что пакет espeak-ng из шага 1 установлен, и запустите скрипт снова.
Если проблема не решена, создайте тикет — техническая поддержка IMIDC работает 24/7. Укажите IP сервера, версии ОС и Python, выполненную команду и полный текст ошибки, чтобы мы быстрее нашли причину.