Files

188 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Enshrouded — русская озвучка записок
Русская озвучка всех **525 озвученных записок и мини-историй** (Ministory) Enshrouded. Голос — клон
английского диктора игры, текст — официальный русский перевод игры. Мод ставится через EML
(Enshrouded Mod Loader) и не трогает оригинальные файлы игры.
| | |
|---|---|
| Версия | 0.4.0 (игра 1.0, октябрь 2026) |
| Объём | 525 записок, 425 минут, 467 МБ |
| Синтез | Qwen3-TTS 1.7B, дообучение [`ru-stress-cf`](https://huggingface.co/siriusfreak/qwen3-tts-12hz-1.7b-ru-stress-cf) с ударениями, ICL-клон диктора |
| Контроль | автоматический, без прослушивания: ударения 99,9 % по всем кускам; WER 2,4 % и MOS 3,45 на выборке из 60 записок |
> Озвучка — синтез, а не запись актёра. Голос повторяет тембр английского диктора, тексты принадлежат
> Keen Games. Это любительский мод: не продавайте его и не выдавайте за официальный.
## Что в репозитории
```
mod/ru_voice_notes/ готовый мод: data/*.qoa (Git LFS), src/*.lua, mod.json
install.py установка и удаление мода (только стандартная библиотека Python)
run.py конвейер генерации по шагам (каждый шаг в своём окружении)
ensvoice/ ключевые скрипты конвейера
extract.py тексты и английский звук из файлов игры
refs.py референсы диктора, его тембр и паузы
segments.py текст для голоса: лексикон, ударения, нарезка по абзацам
lexicon.py ← главное место для правок: имена, ударения, сокращения
render.py, tts/ синтез (локальный GPU или сервер media-node)
qc.py, pick.py автоматическая проверка дублей и отбор лучшего
assemble.py, mod.py склейка записок, QOA, сборка мода
refbench.py сравнение референсов голоса по метрикам
env/ зависимости двух окружений
docs/GENERATION.md как устроена генерация и как её улучшать
config.example.toml пример настроек
```
В репозиторий не попадают данные, извлечённые из игры (`work/`), окружения (`.venv-*`), модели,
бинарники EML (`tools/`) и `config.toml`: всё это перечислено в `.gitignore`.
---
## Установка мода (для игрока)
Нужны Windows, Steam-версия Enshrouded, Python 3.11+, Git с Git LFS.
```bash
git clone https://git.shahovalov.ru/mikhail/enshrouded-ru-voice.git
cd enshrouded-ru-voice
git lfs pull
python install.py
```
В конце должна появиться строка `[ru_voice] replaced 525 notes, 0 failed`, затем `INSTALLED`.
Игру запускать как обычно, из Steam. Язык озвучки в игре оставить **английским**: мод подменяет
английскую дорожку записок, своего русского слота у озвучки в игре нет.
Удаление: `python install.py --uninstall` (или «Проверить целостность файлов» в Steam).
---
## Инструкция для агента: установка
Агент выполняет шаги по порядку. После каждого шага есть проверка: если она не прошла, агент не идёт
дальше и разбирает причину по таблице ниже. Команды даны для Git Bash или PowerShell 7 на Windows.
### A. Только поставить мод (без генерации)
1. **Проверить окружение.**
```bash
python --version
git lfs version
```
Ожидаемо: Python 3.11 или новее, git-lfs 3.x. Если Python нет, поставить `winget install Python.Python.3.12`;
если нет Git LFS, поставить `winget install GitHub.GitLFS`, затем выполнить `git lfs install`.
2. **Клонировать и скачать звук.**
```bash
git clone https://git.shahovalov.ru/mikhail/enshrouded-ru-voice.git
cd enshrouded-ru-voice
git lfs pull
```
Проверка: в `mod/ru_voice_notes/data` лежат 525 файлов `.qoa`, все больше 1 КБ, вместе около 467 МБ.
Файлы меньше 1 КБ — это LFS-указатели: снова выполнить `git lfs pull`.
3. **Спросить пользователя**, закрыта ли игра и можно ли записать в папку игры `dbghelp.dll` и
`mods/ru_voice_notes`. Без согласия дальше не идти.
4. **Установить.**
```bash
python install.py
```
Если игра стоит не в библиотеке Steam, добавить `--game "<папка с enshrouded.kfc>"`.
Ожидаемо: строки `[ru_voice] replaced 525 notes, 0 failed` и `INSTALLED`.
5. Сообщить пользователю: игру запускать из Steam, язык озвучки оставить английским, записки читаются
по-русски. Откат: `python install.py --uninstall`.
### B. Поставить конвейер генерации (чтобы дорабатывать)
Требования: NVIDIA GPU с 12 ГБ VRAM и больше (проверено на RTX 5080 16 ГБ и Tesla V100 32 ГБ),
32 ГБ RAM, около 35 ГБ на диске (модели около 10 ГБ, рабочая папка около 15 ГБ), свежий драйвер NVIDIA
(CUDA 12.8), [uv](https://docs.astral.sh/uv/). Сначала выполнить раздел A до шага 2 включительно.
1. **Проверить GPU и uv.**
```bash
nvidia-smi
uv --version
```
Если `uv` нет: `winget install astral-sh.uv`.
2. **Создать два окружения.** Их два, потому что `qwen-tts` требует transformers 4.x, а модели контроля
качества требуют 5.x.
```bash
uv venv -p 3.12 .venv-tts
uv pip install -p .venv-tts/Scripts/python.exe torch torchaudio --index-url https://download.pytorch.org/whl/cu128
uv pip install -p .venv-tts/Scripts/python.exe -r env/tts.txt
uv venv -p 3.12 .venv-qc
uv pip install -p .venv-qc/Scripts/python.exe torch torchaudio --index-url https://download.pytorch.org/whl/cu128
uv pip install -p .venv-qc/Scripts/python.exe -r env/qc.txt
```
На Linux путь к интерпретатору — `.venv-tts/bin/python`.
3. **Настроить.** Скопировать `config.example.toml` в `config.toml` и заполнить:
- `paths.game` — папка игры (её нашёл `install.py`, путь напечатан в строке `game:`);
- `paths.work` — папка на **том же диске, что и игра** (см. «Ловушки»), с 15 ГБ свободного места;
- `tts.dtype` — `bfloat16` для RTX 30xx и новее, `float16` для RTX 20xx, GTX 16xx, V100.
4. **Инструменты EML.** Если `install.py` ещё не запускался, скачать их через него, ответив пользователю
по шагу A.3, либо взять `kfc-parser.exe` и `emm.exe` вручную из релиза
[Brabb3l/kfc-parser v0.2.0](https://github.com/Brabb3l/kfc-parser/releases/tag/v0.2.0) в `tools/`.
5. **Проверить установку.**
```bash
python run.py check
```
Ожидаемо: две строки с версией torch, `cuda True` и именем GPU, затем `CHECK_OK`.
6. **Пробный прогон на трёх записках**, около 15 минут. Модели (около 10 ГБ) скачиваются с Hugging Face
при первом запуске.
```bash
export ENSVOICE_NOTES=n016,n238,n363 # PowerShell: $env:ENSVOICE_NOTES="n016,n238,n363"
python run.py extract
python run.py refs
python run.py segments
python run.py render
python run.py qc
python run.py pick
python run.py assemble
```
Ожидаемо: после `extract` — `notes 525 EN minutes 488`; после `refs` —
`configured reference ... found`; после `pick` — `'segments': 16, 'picked': 16`;
после `assemble` — `ASSEMBLED 3 notes`. Готовые WAV для проверки лежат в `<work>/wav48/`.
**Не запускать** `python run.py mod` с переменной `ENSVOICE_NOTES`: собранный мод заменит в
`mod/ru_voice_notes` все 525 записок тремя.
7. Снять переменную (`unset ENSVOICE_NOTES`) и сообщить пользователю, что конвейер работает.
Полный прогон (`python run.py all`) на RTX 5080 занимает около суток (см. docs/GENERATION.md), его
запускают по просьбе пользователя.
### Ловушки и ошибки
| Симптом | Причина и что делать |
|---|---|
| `extract`: `EN minutes` не 488, а около 425 | В игре применён мод: EML пропатчил `enshrouded.kfc`, и прочиталась русская озвучка. `extract` сам берёт исходный индекс из `enshrouded.kfc.bak` через жёсткие ссылки — для этого `paths.work` должен быть на диске игры. Иначе: `tools/emm.exe restore -g "<игра>"` и повторить `extract`. |
| `install.py`: `close Enshrouded first`, `os error 32` | Игра запущена: закрыть её. |
| `.qoa` по 130 байт, `LFS pointers` | Не скачан LFS: `git lfs install`, затем `git lfs pull`. |
| `render`: `CUDA out of memory` | Уменьшить `tts.batch` до 4. Больше 8 не ставить: на RTX 5080 16 ГБ батч 16 упирается в видеопамять и работает в разы медленнее. |
| `bf16 is not supported` / NaN | GPU старше Ampere: `tts.dtype = "float16"`. |
| `qc` убит, `Killed`, MemoryError | Каждый процесс QC берёт 8–13 ГБ RAM: запускать меньше шардов. |
| `refs`: `configured reference ... NOT FOUND` | Другая версия игры: выбрать id из `<work>/refs.json` через `refbench`. |
| `extract`: `expected 525 voiced notes` | Обновление игры изменило записки: конвейер работает, но мод из репозитория может не подойти — собрать свой. |
---
## Как дорабатывать и делиться
Порядок работы и все приёмы описаны в [docs/GENERATION.md](docs/GENERATION.md). Коротко: правки идут в
`lexicon.py` или конфиг, затем по цепочке `segments → render → qc → pick → assemble → mod` (заново
считаются только изменённые куски) и `python install.py`.
Делиться результатом: ветка с изменениями кода, лексикона и обновлённым `mod/ru_voice_notes` плюс
pull request. В описании PR привести числа из `<work>/pick_report.json` до и после (`wer`, `stress`,
`mos`, `weak`): по ним видно, что правка улучшила озвучку, а не просто изменила её. Без доступа на запись
в этот Gitea — форк или patch-файл с `git format-patch`.
## Благодарности
[Brabb3l/kfc-parser](https://github.com/Brabb3l/kfc-parser) (распаковка и EML) ·
[Qwen3-TTS](https://github.com/QwenLM/Qwen3-TTS) ·
[siriusfreak/qwen3-tts-12hz-1.7b-ru-stress-cf](https://huggingface.co/siriusfreak/qwen3-tts-12hz-1.7b-ru-stress-cf) (ударения и meter2) ·
[RUAccent](https://github.com/Den4ikAI/ruaccent) ·
[GigaAM](https://github.com/salute-developers/GigaAM) ·
[UTMOSv2](https://github.com/sarulab-speech/UTMOSv2) ·
[WavLM](https://huggingface.co/microsoft/wavlm-base-plus-sv)
Код — MIT (см. `LICENSE`). Озвучка в `mod/` — производная от материалов игры и не покрывается
лицензией кода.