Qwen3-TTS CustomVoice: озвучка текста готовыми голосами на Windows 11
В этом гайде мы настроите локальную озвучку текста из TXT на Windows 11 с помощью Qwen3-TTS CustomVoice. Используем предустановленные голоса (speaker). На выходе получите файл WAV с озвучкой.
Подходит, если нужно быстро запустить TTS без подготовки референсного аудио.
Ориентировано на конфигурацию:
- Windows 11
- NVIDIA RTX 3060 Ti, 8 GB VRAM
- 32 GB RAM
- Python 3.12
- venv
- PyTorch CUDA 12.4
- SoX установлен и доступен системе
Важно про качество русской речи
В нашей версии CustomVoice доступны спикеры: aiden, dylan, eric, ono_anna, ryan, serena, sohee, uncle_fu, vivian. Это англоязычные голоса. Русский текст они озвучивают, но возможен акцент.
Если нужна озвучка вашим голосом или максимально естественная русская речь, используйте сценарий voice cloning с референсом. Отдельный гайд: https://aisferaic.ru/blog/tutorials/152/.
Структура папки проекта - шаг 1
Создайте папку проекта, например D:\voice, и положите туда входной текст.
Структура:
\voice\
├── .venv\
├── tts_ru_preset.py
├── article_ru.txt
Где:
- article_ru.txt: текст для озвучки в UTF-8
- tts_ru_preset.py: скрипт озвучки
Результат:
- out_ru.wav: итоговый файл WAV
Установка окружения (venv, PyTorch, зависимости) - шаг 2
Откройте PowerShell и выполните последовательно команды в папке вашего проекта:
python -m venv .venv
.\.venv\Scripts\activate
python -m pip install -U pip
Установите PyTorch под CUDA 12.4:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
Установите зависимости для Qwen3-TTS:
pip install -U qwen-tts soundfile numpy "huggingface_hub[hf_xet]" hf_xet
Проверьте, что PyTorch видит GPU:
python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else None)"
SoX и PATH - шаг 3
Qwen3-TTS пайплайн для аудио на Windows часто ожидает наличие sox.exe. Без него вы получите ошибку SoX could not be found.
SoX можно скачать со страницы проекта на SourceForge (https://sourceforge.net/projects/sox/) и установить как обычную программу.
Добавить SoX в PATH
У вас SoX может лежать здесь: C:\Program Files (x86)\sox-14-4-2\sox.exe
Добавляем в PATH именно папку:
C:\Program Files (x86)\sox-14-4-2
Шаги:
- Нажмите Win и введите: Изменение переменных среды (environment variables)
- Откройте: Изменение переменных среды для вашей учетной записи (Edit environment variables for your account)
- В блоке Переменные пользователя (User variables) найдите Path и нажмите Изменить (Edit)

- Нажмите Создать (New)
- Вставьте: C:\Program Files (x86)\sox-14-4-2 или ваш путь

- Нажмите ОК во всех окнах (OK)
- Закройте все окна PowerShell и откройте новый PowerShell
2.3 Проверка в PowerShell
where.exe sox
sox --version
Если команда sox --version выводит версию, все готово.
Код: озвучка текста с помощью CustomVoice и speaker - шаг 4
Создайте файл tts_ru_preset.py рядом с article_ru.txt.
import os
import re
import time
import subprocess
from pathlib import Path
import numpy as np
import soundfile as sf
import torch
from qwen_tts import Qwen3TTSModel
# ---- CONFIG ----
SOX_DIR = r"C:\Program Files (x86)\sox-14-4-2"
ARTICLE_PATH = Path("article_ru.txt")
OUT_PATH = Path("out_ru.wav")
# Модель для предустановленных голосов
MODEL_ID = "Qwen/Qwen3-TTS-12Hz-0.6B-CustomVoice"
# Поддерживаемые значения в вашей версии:
# aiden, dylan, eric, ono_anna, ryan, serena, sohee, uncle_fu, vivian
SPEAKER = "serena"
MAX_CHARS = 600
SILENCE_MS = 120
HF_DOWNLOAD_TIMEOUT = "600"
HF_ETAG_TIMEOUT = "120"
HF_DISABLE_XET = "" # если будут таймауты на xethub, поставьте "1"
# ---------------
def _ts() -> str:
return time.strftime("%H:%M:%S")
def _log(msg: str) -> None:
print(f"[{_ts()}] {msg}", flush=True)
def _ensure_env():
# На случай, если скрипт запускается из IDE с другим PATH
os.environ["PATH"] = SOX_DIR + ";" + os.environ.get("PATH", "")
os.environ.setdefault("HF_HUB_DOWNLOAD_TIMEOUT", HF_DOWNLOAD_TIMEOUT)
os.environ.setdefault("HF_HUB_ETAG_TIMEOUT", HF_ETAG_TIMEOUT)
os.environ.setdefault("HF_HUB_DISABLE_SYMLINKS_WARNING", "1")
if HF_DISABLE_XET.strip():
os.environ["HF_HUB_DISABLE_XET"] = HF_DISABLE_XET.strip()
def _check_sox():
out = subprocess.check_output(["sox", "--version"], text=True).strip()
_log(f"SoX OK: {out}")
def split_text_ru(text: str, max_chars: int) -> list[str]:
text = re.sub(r"\s+", " ", text).strip()
if not text:
return []
parts = re.split(r"(?<=[\.\!\?…])\s+", text)
chunks, buf = [], ""
for p in parts:
p = p.strip()
if not p:
continue
if not buf:
buf = p
continue
if len(buf) + 1 + len(p) <= max_chars:
buf = buf + " " + p
else:
chunks.append(buf)
buf = p
if buf:
chunks.append(buf)
return chunks
def concat_wavs(wavs: list[np.ndarray], sr: int, silence_ms: int) -> np.ndarray:
silence = np.zeros(int(sr * (silence_ms / 1000.0)), dtype=np.float32)
out = []
for w in wavs:
out.append(np.asarray(w, dtype=np.float32).reshape(-1))
out.append(silence)
return np.concatenate(out, axis=0) if out else np.zeros((0,), dtype=np.float32)
def main():
t_start = time.time()
_log("Start")
_ensure_env()
_log("Step 0: проверка SoX")
_check_sox()
# На Windows FP32 обычно надежнее, FP16 иногда падает с CUDA assert
torch.backends.cuda.matmul.allow_tf32 = True
torch.set_float32_matmul_precision("high")
_log("Step 1: чтение входного текста")
if not ARTICLE_PATH.exists():
raise FileNotFoundError(f"Не найден файл: {ARTICLE_PATH.resolve()}")
text = ARTICLE_PATH.read_text(encoding="utf-8")
chunks = split_text_ru(text, MAX_CHARS)
if not chunks:
raise SystemExit("Пустой article_ru.txt")
_log(f"Текст разбит на чанки: {len(chunks)} (MAX_CHARS={MAX_CHARS})")
_log(f"Speaker: {SPEAKER}")
_log(f"Model: {MODEL_ID}")
_log("Step 2: загрузка модели (первый запуск может включать скачивание)")
_log("Если видите прогресс Fetching files, идет скачивание с Hugging Face")
t0 = time.time()
model = Qwen3TTSModel.from_pretrained(
MODEL_ID,
device_map="cuda:0",
dtype=torch.float32,
)
_log(f"Step 2: модель готова за {time.time() - t0:.1f}s")
_log(f"Step 3: генерация аудио ({len(chunks)} чанков)")
all_wavs = []
sr_final = None
for i, chunk in enumerate(chunks, 1):
_log(f"Chunk {i}/{len(chunks)}: start")
tg0 = time.time()
wavs, sr = model.generate_custom_voice(
text=chunk,
speaker=SPEAKER,
language="Russian",
)
wav = wavs[0]
all_wavs.append(wav)
sr_final = sr
dur = len(wav) / sr
_log(f"Chunk {i}/{len(chunks)}: ok, audio={dur:.2f}s, gen_time={time.time() - tg0:.1f}s")
_log("Step 4: склейка и сохранение WAV")
audio = concat_wavs(all_wavs, sr_final, SILENCE_MS)
sf.write(str(OUT_PATH), audio, sr_final)
_log(f"Done. Saved: {OUT_PATH.resolve()}")
_log(f"Total time: {time.time() - t_start:.1f}s")
if __name__ == "__main__":
main()
Запуск скрипта для озвучки - шаг 5
Убедитесь, что venv активирован. Запустите скрипт:
python tts_ru_preset.py
Результат: out_ru.wav.
Первый запуск может быть долгим. При первом запуске модель скачивается и загружается. Это нормально. Следующие запуски обычно заметно быстрее.
Как выбрать голос (speaker)
Поддерживаемые значения в нашей версии:
- aiden
- dylan
- eric
- ono_anna
- ryan
- serena
- sohee
- uncle_fu
- vivian
Поменяйте переменную SPEAKER в коде и запустите снова. Это самый простой способ перебора.
Частые проблемы и решения
SoX could not be found
Симптом: ошибка SoX could not be found.
Проверка:
where.exe sox
sox --version
Решение:
- Добавьте папку SoX в PATH пользователя: C:\Program Files (x86)\sox-14-4-2
- Убедитесь, что в коде SOX_DIR указывает на ту же папку
- Если запускаете из IDE, попробуйте запуск из PowerShell или оставьте принудительное добавление PATH в _ensure_env
Таймауты при скачивании модели
Симптом: ReadTimeoutError на xethub или cas-bridge.
Решение в PowerShell:
$env:HF_HUB_DOWNLOAD_TIMEOUT="600"
$env:HF_HUB_ETAG_TIMEOUT="120"
python tts_ru_preset.py
Если не помогло, отключите Xet:
$env:HF_HUB_DISABLE_XET="1"
python tts_ru_preset.py
Warning про symlinks
Симптом: предупреждение про symlinks в кэше Hugging Face.
Это не ошибка. Можно игнорировать.
Чтобы убрать:
$env:HF_HUB_DISABLE_SYMLINKS_WARNING="1"
python tts_ru_preset.py
CUDA device-side assert triggered
Симптом: падение CUDA на генерации.
Решение:
- Используйте FP32. В коде уже стоит dtype=torch.float32
Unsupported speakers
Симптом: ValueError Unsupported speakers.
Решение:
- Укажите SPEAKER строго одной из строк из списка поддерживаемых
Что дальше
Если вы хотите качественную русскую озвучку без акцента, обычно есть два пути:
- Озвучка вашим голосом через voice cloning с референсом, ссылка на отдельный гайд
- Поиск набора preset, где есть русские спикеры, в рамках другой модели или другого набора голосов
Авторизуйтесь, чтобы оставить комментарий.
Нет комментариев.