Files
Aletheia/tools/tts/train_piper.sh
T

66 lines
1.9 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 3 ]]; then
echo "Usage: $0 DATASET_DIR OUTPUT_DIR PIPER_REPO [EPOCHS]" >&2
exit 2
fi
dataset_dir="$(realpath "$1")"
output_dir="$(mkdir -p "$2" && realpath "$2")"
piper_repo="$(realpath "$3")"
epochs="${4:-2000}"
metadata="$dataset_dir/metadata.csv"
audio_dir="$dataset_dir/wav"
if [[ ! -f "$metadata" || ! -d "$audio_dir" ]]; then
echo "Dataset must contain metadata.csv and wav/" >&2
exit 2
fi
if [[ ! -f "$piper_repo/src/piper/train/__main__.py" ]]; then
echo "Piper training sources not found at $piper_repo" >&2
exit 2
fi
python3 -m piper.train fit \
--data.voice_name aletheia_ru \
--data.csv_path "$metadata" \
--data.audio_dir "$audio_dir" \
--data.espeak_voice ru \
--data.cache_dir "$output_dir/cache" \
--data.config_path "$output_dir/aletheia_ru.onnx.json" \
--data.batch_size 16 \
--data.num_workers 4 \
--model.sample_rate 22050 \
--trainer.accelerator gpu \
--trainer.devices 1 \
--trainer.precision 16-mixed \
--trainer.max_epochs "$epochs" \
--trainer.default_root_dir "$output_dir/checkpoints"
checkpoint="$(find "$output_dir/checkpoints" -type f -name '*.ckpt' -printf '%T@ %p\n' | sort -nr | head -n 1 | cut -d' ' -f2-)"
if [[ -z "$checkpoint" ]]; then
echo "Training finished without a checkpoint" >&2
exit 1
fi
python3 -m piper.train.export_onnx \
--checkpoint "$checkpoint" \
--output-file "$output_dir/aletheia_ru.onnx"
python3 - "$output_dir" <<'PY'
import hashlib
import json
import pathlib
import sys
root = pathlib.Path(sys.argv[1])
artifacts = {}
for name in ("aletheia_ru.onnx", "aletheia_ru.onnx.json"):
path = root / name
digest = hashlib.sha256(path.read_bytes()).hexdigest()
artifacts[name] = {"bytes": path.stat().st_size, "sha256": digest}
(root / "artifacts.json").write_text(json.dumps(artifacts, indent=2), encoding="utf-8")
print(json.dumps(artifacts, indent=2))
PY