66 lines
1.9 KiB
Bash
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
|