Fangjun Kuang
Committed by GitHub

Add scripts for exporting Piper TTS models to sherpa-onnx (#2299)

name: export-piper
on:
push:
branches:
- export-piper
workflow_dispatch:
concurrency:
group: export-piper-${{ github.ref }}
cancel-in-progress: true
jobs:
export-piper:
if: github.repository_owner == 'k2-fsa' || github.repository_owner == 'csukuangfj'
name: ${{ matrix.index }}/${{ matrix.total }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.10"]
total: ["20"]
index: [
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
]
# total: ["1"]
# index: ["0"]
steps:
- uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Python dependencies
shell: bash
run: |
python3 -m pip install --upgrade pip jinja2 iso639-lang onnx==1.17.0 onnxruntime==1.17.1 sherpa-onnx onnxmltools==1.13.0
python3 -m pip install "numpy<2" soundfile
- name: Generate script
env:
HF_TOKEN: ${{ secrets.HF_TOKEN }}
shell: bash
run: |
cd scripts/piper
total=${{ matrix.total }}
index=${{ matrix.index }}
git config --global user.email "csukuangfj@gmail.com"
git config --global user.name "Fangjun Kuang"
git clone https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/sherpa-onnx-tts-samples hf
python3 ./generate.py --total $total --index $index
chmod +x ./generate.sh
ls -lh
- name: Show script
shell: bash
run: |
cd scripts/piper
cat ./generate.sh
- name: Run script
shell: bash
run: |
cd scripts/piper
./generate.sh
- name: Show generated mp3 files
shell: bash
run: |
cd scripts/piper
ls -lh hf/piper/mp3/*
echo "----"
ls -lh hf/piper/mp3/*/*
- name: Push generated mp3 files
env:
HF_TOKEN: ${{ secrets.HF_TOKEN }}
uses: nick-fields/retry@v3
with:
max_attempts: 20
timeout_seconds: 200
shell: bash
command: |
cd scripts/piper/hf
git pull --rebase
git lfs track "*.mp3"
git status .
git add .
git commit -m 'Add mp3 files'
git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/sherpa-onnx-tts-samples main
- name: Show generated model files
shell: bash
run: |
cd scripts/piper
ls -lh *.tar.bz2
- name: Show generated model files(2)
shell: bash
run: |
cd scripts/piper
ls -lh release/
- name: Publish to huggingface
env:
HF_TOKEN: ${{ secrets.HF_TOKEN }}
uses: nick-fields/retry@v3
with:
max_attempts: 20
timeout_seconds: 200
shell: bash
command: |
git config --global user.email "csukuangfj@gmail.com"
git config --global user.name "Fangjun Kuang"
export GIT_LFS_SKIP_SMUDGE=1
export GIT_CLONE_PROTECTION_ACTIVE=false
dirs=(
vits-piper-de_DE-glados-high
vits-piper-de_DE-glados-low
vits-piper-de_DE-glados-medium
vits-piper-de_DE-glados_turret-high
vits-piper-de_DE-glados_turret-low
vits-piper-de_DE-glados_turret-medium
vits-piper-en_US-glados-high
)
for d in ${dirs[@]}; do
src=scripts/piper/release/$d
if [ ! -d $src ]; then
continue;
fi
rm -rf huggingface
git clone https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/$d huggingface
cp -a $src/* ./huggingface
pushd huggingface
git lfs track "*.onnx"
git lfs track af_dict
git lfs track ar_dict
git lfs track cmn_dict
git lfs track da_dict en_dict fa_dict hu_dict ia_dict it_dict lb_dict phondata ru_dict ta_dict
git lfs track ur_dict yue_dict
git status
git add .
git status
git commit -m "add models"
git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/$d main
popd
done
- name: Release
if: github.repository_owner == 'csukuangfj'
uses: svenstaro/upload-release-action@v2
with:
file_glob: true
file: ./scripts/piper/vits-piper-*.tar.bz2
overwrite: true
repo_name: k2-fsa/sherpa-onnx
repo_token: ${{ secrets.UPLOAD_GH_SHERPA_ONNX_TOKEN }}
tag: tts-models
- name: Release
if: github.repository_owner == 'k2-fsa'
uses: svenstaro/upload-release-action@v2
with:
file_glob: true
file: ./scripts/piper/vits-piper-*.tar.bz2
overwrite: true
tag: tts-models
... ...
*.sh
*.onnx
*.json
MODEL_CARD
generate_samples-vits-piper*.py
... ...
#!/usr/bin/env python3
# Copyright 2025 Xiaomi Corp. (authors: Fangjun Kuang)
import argparse
import json
from typing import Any, Dict
import onnx
from iso639 import Lang
def get_args():
# For en_GB-semaine-medium
# --name semaine
# --kind medium
# --lang en_GB
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument(
"--name",
type=str,
required=True,
)
parser.add_argument(
"--kind",
type=str,
required=True,
)
parser.add_argument(
"--lang",
type=str,
required=True,
)
return parser.parse_args()
def add_meta_data(filename: str, meta_data: Dict[str, Any]):
"""Add meta data to an ONNX model. It is changed in-place.
Args:
filename:
Filename of the ONNX model to be changed.
meta_data:
Key-value pairs.
"""
model = onnx.load(filename)
while len(model.metadata_props):
model.metadata_props.pop()
for key, value in meta_data.items():
meta = model.metadata_props.add()
meta.key = key
meta.value = str(value)
onnx.save(model, filename)
def load_config(filename):
with open(filename, "r") as file:
config = json.load(file)
return config
def generate_tokens(config):
id_map = config["phoneme_id_map"]
with open("tokens.txt", "w", encoding="utf-8") as f:
for s, i in id_map.items():
f.write(f"{s} {i[0]}\n")
print("Generated tokens.txt")
# for en_US-lessac-medium.onnx
# export LANG=en_US
# export TYPE=lessac
# export NAME=medium
def main():
args = get_args()
print(args)
lang = args.lang
lang_iso = Lang(lang.split("_")[0])
print(lang, lang_iso)
kind = args.kind
name = args.name
# en_GB-alan-low.onnx.json
config = load_config(f"{lang}-{name}-{kind}.onnx.json")
print("generate tokens")
generate_tokens(config)
sample_rate = config["audio"]["sample_rate"]
if sample_rate == 22500:
print("Change sample rate from 22500 to 22050")
sample_rate = 22050
print("add model metadata")
meta_data = {
"model_type": "vits",
"comment": "piper", # must be piper for models from piper
"language": lang_iso.name,
"voice": config["espeak"]["voice"], # e.g., en-us
"has_espeak": 1,
"n_speakers": config["num_speakers"],
"sample_rate": sample_rate,
}
print(meta_data)
add_meta_data(f"{lang}-{name}-{kind}.onnx", meta_data)
main()
... ...
#!/usr/bin/env python3
# Copyright 2025 Xiaomi Corp. (authors: Fangjun Kuang)
import argparse
import onnxmltools
from onnxmltools.utils.float16_converter import convert_float_to_float16
from onnxruntime.quantization import QuantType, quantize_dynamic
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument(
"--input",
type=str,
required=True,
)
parser.add_argument(
"--output-fp16",
type=str,
required=True,
)
parser.add_argument(
"--output-int8",
type=str,
required=True,
)
return parser.parse_args()
# for op_block_list, see also
# https://github.com/microsoft/onnxruntime/blob/089c52e4522491312e6839af146a276f2351972e/onnxruntime/python/tools/transformers/float16.py#L115
#
# libc++abi: terminating with uncaught exception of type Ort::Exception:
# Type Error: Type (tensor(float16)) of output arg (/dp/RandomNormalLike_output_0)
# of node (/dp/RandomNormalLike) does not match expected type (tensor(float)).
#
# libc++abi: terminating with uncaught exception of type Ort::Exception:
# This is an invalid model. Type Error: Type 'tensor(float16)' of input
# parameter (/enc_p/encoder/attn_layers.0/Constant_84_output_0) of
# operator (Range) in node (/Range_1) is invalid.
def export_onnx_fp16(onnx_fp32_path, onnx_fp16_path):
onnx_fp32_model = onnxmltools.utils.load_model(onnx_fp32_path)
onnx_fp16_model = convert_float_to_float16(
onnx_fp32_model,
keep_io_types=True,
op_block_list=[
"RandomNormalLike",
"Range",
],
)
onnxmltools.utils.save_model(onnx_fp16_model, onnx_fp16_path)
def main():
args = get_args()
print(args)
in_filename = args.input
output_fp16 = args.output_fp16
output_int8 = args.output_int8
quantize_dynamic(
model_input=in_filename,
model_output=output_int8,
weight_type=QuantType.QUInt8,
)
export_onnx_fp16(in_filename, output_fp16)
if __name__ == "__main__":
main()
... ...
#!/usr/bin/env python3
# Copyright 2025 Xiaomi Corp. (authors: Fangjun Kuang)
import argparse
from dataclasses import dataclass
from pathlib import Path
import jinja2
"""
TODO:
- add https://huggingface.co/csukuangfj/vits-piper-en_US-glados
"""
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument(
"--total",
type=int,
default=1,
help="Number of runners",
)
parser.add_argument(
"--index",
type=int,
default=0,
help="Index of the current runner",
)
return parser.parse_args()
@dataclass
class PiperModel:
# For en_GB-semaine-medium
name: str # semaine
kind: str # e.g. medium
sr: int # sample rate
ns: int # number of speakers
lang: str = "" # e.g., en_GB
cmd: str = ""
model_name: str = ""
text: str = ""
index: int = 0
url: str = ""
# arabic
def get_ar_models():
ar_jo = [
PiperModel(name="kareem", kind="low", sr=16000, ns=1),
PiperModel(name="kareem", kind="medium", sr=22050, ns=1),
]
for m in ar_jo:
m.lang = "ar_JO"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = ar_jo
for m in ans:
m.text = "كيف حالك اليوم؟"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# catlan
def get_ca_models():
ca_es = [
PiperModel(name="upc_ona", kind="medium", sr=22050, ns=1),
PiperModel(name="upc_ona", kind="x_low", sr=16000, ns=1),
PiperModel(name="upc_pau", kind="x_low", sr=16000, ns=1),
]
for m in ca_es:
m.lang = "ca_ES"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = ca_es
for m in ans:
m.text = "Si vols estar ben servit, fes-te tu mateix el llit"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# czech
def get_cs_models():
cs_cz = [
PiperModel(name="jirka", kind="low", sr=16000, ns=1),
PiperModel(name="jirka", kind="medium", sr=22050, ns=1),
]
for m in cs_cz:
m.lang = "cs_CZ"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = cs_cz
for m in ans:
m.text = "Co můžeš udělat dnes, neodkládej na zítřek. "
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# welsh
def get_cy_models():
cy_gb = [
PiperModel(name="bu_tts", kind="medium", sr=22050, ns=7),
PiperModel(name="gwryw_gogleddol", kind="medium", sr=22050, ns=1),
]
for m in cy_gb:
m.lang = "cy_GB"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = cy_gb
for m in ans:
m.text = "Ni all y gwynt ei hunan ei ddilyn, ac felly mae’n rhaid i’r gŵyr ddod i’r gorwel i weld y llwybr yn gyfarwydd"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# danish
def get_da_models():
da_dk = [
PiperModel(name="talesyntese", kind="medium", sr=22050, ns=1),
]
for m in da_dk:
m.lang = "da_DK"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = da_dk
for m in ans:
m.text = (
"Hvis du går langsomt, men aldrig stopper, når du ender frem til dit mål."
)
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# greek
def get_el_models():
el_gr = [
PiperModel(name="rapunzelina", kind="low", sr=16000, ns=1),
]
for m in el_gr:
m.lang = "el_GR"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = el_gr
for m in ans:
m.text = (
"Όταν το δέντρο είναι μικρό, το στρέβλεις· όταν είναι μεγάλο, το λυγίζεις."
)
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# spanish
def get_es_models():
es_ES = [
PiperModel(name="carlfm", kind="x_low", sr=16000, ns=1),
PiperModel(name="davefx", kind="medium", sr=22050, ns=1),
PiperModel(name="sharvard", kind="medium", sr=22050, ns=2),
]
es_MX = [
PiperModel(name="ald", kind="medium", sr=22050, ns=1),
PiperModel(name="claude", kind="high", sr=22050, ns=1),
]
for m in es_ES:
m.lang = "es_ES"
for m in es_MX:
m.lang = "es_MX"
ans = es_ES + es_MX
for m in ans:
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
m.text = "Cuando te encuentres ante una puerta cerrada, no olvides que a veces el destino cierra una puerta para que te desvíes hacia un camino que lleva a una ventana que nunca habrías encontrado por tu cuenta."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# persian
def get_fa_models():
fa_IR = [
PiperModel(name="amir", kind="medium", sr=22050, ns=1),
PiperModel(name="ganji", kind="medium", sr=22050, ns=1),
PiperModel(name="ganji_adabi", kind="medium", sr=22050, ns=1),
PiperModel(name="gyro", kind="medium", sr=22050, ns=1),
PiperModel(name="reza_ibrahim", kind="medium", sr=22050, ns=1),
]
for m in fa_IR:
m.lang = "fa_IR"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = fa_IR
for m in ans:
m.text = "همانطور که کوه ها در برابر باد و باران پایدارند، اما به مرور زمان خرد و پخش می شوند، انسان نیز باید در برابر مشکلات قوی باشد، اما با خرد و خویشتن داری در زندگی به پیش برود."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# finnish
def get_fi_models():
fi_FI = [
PiperModel(name="harri", kind="low", sr=16000, ns=1),
PiperModel(name="harri", kind="medium", sr=22050, ns=1),
]
for m in fi_FI:
m.lang = "fi_FI"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = fi_FI
for m in ans:
m.text = "Sateenkaaren päässä on kultaa, mutta vain ne, jotka siihen uskovat, voivat sen löytää."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# french
def get_fr_models():
fr_FR = [
PiperModel(name="gilles", kind="low", sr=16000, ns=1),
PiperModel(name="siwis", kind="low", sr=16000, ns=1),
PiperModel(name="siwis", kind="medium", sr=22050, ns=1),
PiperModel(name="tom", kind="medium", sr=44100, ns=1),
PiperModel(name="upmc", kind="medium", sr=22050, ns=2),
]
for m in fr_FR:
m.lang = "fr_FR"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = fr_FR
for m in ans:
m.text = "Pas de nouvelles, bonnes nouvelles."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# hungarian
def get_hu_models():
hu_HU = [
PiperModel(name="anna", kind="medium", sr=22050, ns=1),
PiperModel(name="berta", kind="medium", sr=22050, ns=1),
PiperModel(name="imre", kind="medium", sr=22050, ns=1),
]
for m in hu_HU:
m.lang = "hu_HU"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = hu_HU
for m in ans:
m.text = "Ha északról fúj a szél, a lányok nem lógnak együtt."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# icelandic
def get_is_models():
is_IS = [
PiperModel(name="bui", kind="medium", sr=22050, ns=1),
PiperModel(name="salka", kind="medium", sr=22050, ns=1),
PiperModel(name="steinn", kind="medium", sr=22050, ns=1),
PiperModel(name="ugla", kind="medium", sr=22050, ns=1),
]
for m in is_IS:
m.lang = "is_IS"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = is_IS
for m in ans:
m.text = "Farðu með allt, eða farðu ekki."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# italian
def get_it_models():
it_IT = [
PiperModel(name="paola", kind="medium", sr=22050, ns=1),
PiperModel(name="riccardo", kind="x_low", sr=16000, ns=1),
]
for m in it_IT:
m.lang = "it_IT"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = it_IT
for m in ans:
m.text = (
"Se vuoi andare veloce, vai da solo; se vuoi andare lontano, vai insieme."
)
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# georgian
def get_ka_models():
ka_GE = [
PiperModel(name="natia", kind="medium", sr=22050, ns=1),
]
for m in ka_GE:
m.lang = "ka_GE"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = ka_GE
for m in ans:
m.text = "ღვინო თბილისში, საქართველო სამტრედში"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# kazakh
def get_kk_models():
kk_KZ = [
PiperModel(name="iseke", kind="x_low", sr=16000, ns=1),
PiperModel(name="issai", kind="high", sr=22050, ns=6),
PiperModel(name="raya", kind="x_low", sr=16000, ns=1),
]
for m in kk_KZ:
m.lang = "kk_KZ"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = kk_KZ
for m in ans:
m.text = "Әлемнің жұлдыздары сенің көзің, жаным."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# luxembourgish
def get_lb_models():
lb_LU = [
PiperModel(name="marylux", kind="medium", sr=22050, ns=1),
]
for m in lb_LU:
m.lang = "lb_LU"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = lb_LU
for m in ans:
m.text = "Op der Haaptstrooss sinn all Stroossen Brécken, awer d'Dier kann iwwerall erreecht ginn."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# latvian
def get_lv_models():
lv_LV = [
PiperModel(name="aivars", kind="medium", sr=22050, ns=1),
]
for m in lv_LV:
m.lang = "lv_LV"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = lv_LV
for m in ans:
m.text = "Zeme nenes augļus, ja tēvs sēj, bet māte auž."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# malayalam
def get_ml_models():
ml_IN = [
PiperModel(name="arjun", kind="medium", sr=22050, ns=1),
PiperModel(name="meera", kind="medium", sr=22050, ns=1),
]
for m in ml_IN:
m.lang = "ml_IN"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = ml_IN
for m in ans:
m.text = "മണ്ണ് മരിക്കുമ്പോൾ കാട്ടിലെ വെള്ളവും മരിക്കുന്നു."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Nepali
def get_ne_models():
ne_NP = [
PiperModel(name="chitwan", kind="medium", sr=22050, ns=1),
PiperModel(name="google", kind="medium", sr=22050, ns=18),
PiperModel(name="google", kind="x_low", sr=16000, ns=18),
]
for m in ne_NP:
m.lang = "ne_NP"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = ne_NP
for m in ans:
m.text = "घाँसको पातले पहाडलाई अभिवादन गर्दै झुक्छ।"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# dutch
def get_nl_models():
nl_BE = [
PiperModel(name="nathalie", kind="medium", sr=22050, ns=1),
PiperModel(name="nathalie", kind="x_low", sr=16000, ns=1),
]
nl_NL = [
PiperModel(name="pim", kind="medium", sr=22050, ns=1),
PiperModel(name="ronnie", kind="medium", sr=22050, ns=1),
]
for m in nl_BE:
m.lang = "nl_BE"
for m in nl_NL:
m.lang = "nl_NL"
ans = nl_BE + nl_NL
for m in ans:
m.text = "God schiep het water, maar de Nederlander schiep de dijk"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# norwegian
def get_no_models():
no_NO = [
PiperModel(name="talesyntese", kind="medium", sr=22050, ns=1),
]
for m in no_NO:
m.lang = "no_NO"
ans = no_NO
for m in ans:
m.text = "Uskyldig kan stormen veroorzaken"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# polish
def get_pl_models():
pl_PL = [
PiperModel(name="darkman", kind="medium", sr=22050, ns=1),
PiperModel(name="gosia", kind="medium", sr=22050, ns=1),
PiperModel(name="mc_speech", kind="medium", sr=22050, ns=1),
]
for m in pl_PL:
m.lang = "pl_PL"
ans = pl_PL
for m in ans:
m.text = "Nieważne, za kogo walczysz, i tak popełnisz błąd"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Portuguese
def get_pt_models():
pt_BR = [
PiperModel(name="cadu", kind="medium", sr=22050, ns=1),
PiperModel(name="edresson", kind="low", sr=16000, ns=1),
PiperModel(name="faber", kind="medium", sr=22050, ns=1),
PiperModel(name="jeff", kind="medium", sr=22050, ns=1),
]
pt_PT = [
PiperModel(name="tugão", kind="medium", sr=22050, ns=1),
]
for m in pt_BR:
m.lang = "pt_BR"
for m in pt_PT:
m.lang = "pt_PT"
ans = pt_BR + pt_PT
for m in ans:
m.text = "Marinha sem vento, não chega a porto"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Romanian
def get_ro_models():
ro_RO = [
PiperModel(name="mihai", kind="medium", sr=22050, ns=1),
]
for m in ro_RO:
m.lang = "ro_RO"
ans = ro_RO
for m in ans:
m.text = "Un foc fără lemne se stinge, o lume fără poveste moare."
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Russian
def get_ru_models():
ru_RU = [
PiperModel(name="denis", kind="medium", sr=22050, ns=1),
PiperModel(name="dmitri", kind="medium", sr=22050, ns=1),
PiperModel(name="irina", kind="medium", sr=22050, ns=1),
PiperModel(name="ruslan", kind="medium", sr=22050, ns=1),
]
for m in ru_RU:
m.lang = "ru_RU"
ans = ru_RU
for m in ans:
m.text = "Если курица укусит, ей отрубят голову."
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Slovak
def get_sk_models():
sk_SK = [
PiperModel(name="lili", kind="medium", sr=22050, ns=1),
]
for m in sk_SK:
m.lang = "sk_SK"
ans = sk_SK
for m in ans:
m.text = "Kto nepozná strach, nepozná vôľu."
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Slovenian
def get_sl_models():
sl_SI = [
PiperModel(name="artur", kind="medium", sr=22050, ns=1),
]
for m in sl_SI:
m.lang = "sl_SI"
ans = sl_SI
for m in ans:
m.text = "Kto sa nebojí, nie je hlúpy."
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Serbian
def get_sr_models():
sr_RS = [
PiperModel(name="serbski_institut", kind="medium", sr=22050, ns=2),
]
for m in sr_RS:
m.lang = "sr_RS"
ans = sr_RS
for m in ans:
m.text = "Круг не може постојати без свог центра, а нација не може постојати без својих хероја."
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Swedish
def get_sv_models():
sv_SE = [
PiperModel(name="lisa", kind="medium", sr=22050, ns=1),
PiperModel(name="nst", kind="medium", sr=22050, ns=1),
]
for m in sv_SE:
m.lang = "sv_SE"
ans = sv_SE
for m in ans:
m.text = "Liten skog, med många träd"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Swahili
def get_sw_models():
sw_CD = [
PiperModel(name="lanfrica", kind="medium", sr=22050, ns=1),
]
for m in sw_CD:
m.lang = "sw_CD"
ans = sw_CD
for m in ans:
m.text = "Mtu mmoja hawezi kuiba mazingira."
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Turkish
def get_tr_models():
tr_TR = [
PiperModel(name="dfki", kind="medium", sr=22050, ns=1),
PiperModel(name="fahrettin", kind="medium", sr=22050, ns=1),
PiperModel(name="fettah", kind="medium", sr=22050, ns=1),
]
for m in tr_TR:
m.lang = "tr_TR"
ans = tr_TR
for m in ans:
m.text = "Bir evin duvarları, bir adamın sözü, bir kadının gülü kırılmaz"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Ukrainian
def get_uk_models():
uk_UA = [
PiperModel(name="lada", kind="x_low", sr=16000, ns=1),
PiperModel(name="ukrainian_tts", kind="medium", sr=22050, ns=3),
]
for m in uk_UA:
m.lang = "uk_UA"
ans = uk_UA
for m in ans:
m.text = "Ви не можете навчити коня, якщо не відвикнете від годівлі."
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
# Vietnamese
def get_vi_models():
vi_VN = [
PiperModel(name="25hours_single", kind="low", sr=16000, ns=1),
PiperModel(name="vais1000", kind="medium", sr=22050, ns=1),
PiperModel(name="vivos", kind="x_low", sr=16000, ns=65),
]
for m in vi_VN:
m.lang = "vi_VN"
ans = vi_VN
for m in ans:
m.text = "Nước cũ đào gỗ mới, sông cũ chảy nước mới"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
def get_en_models():
en_gb = [
PiperModel(name="alan", kind="low", sr=16000, ns=1),
PiperModel(name="alan", kind="medium", sr=22050, ns=1),
PiperModel(name="alba", kind="medium", sr=22050, ns=1),
PiperModel(name="aru", kind="medium", sr=22050, ns=12),
PiperModel(name="cori", kind="high", sr=22050, ns=1),
PiperModel(name="cori", kind="medium", sr=22050, ns=1),
PiperModel(name="jenny_dioco", kind="medium", sr=22050, ns=1),
PiperModel(name="northern_english_male", kind="medium", sr=22050, ns=1),
PiperModel(name="semaine", kind="medium", sr=22050, ns=4),
PiperModel(name="southern_english_female", kind="low", sr=16000, ns=1),
PiperModel(name="vctk", kind="medium", sr=22050, ns=109),
]
en_us = [
PiperModel(name="amy", kind="low", sr=16000, ns=1),
PiperModel(name="amy", kind="medium", sr=22050, ns=1),
PiperModel(name="arctic", kind="medium", sr=22050, ns=18),
PiperModel(name="bryce", kind="medium", sr=22050, ns=1),
PiperModel(name="danny", kind="low", sr=16000, ns=1),
PiperModel(name="hfc_female", kind="medium", sr=22050, ns=1),
PiperModel(name="hfc_male", kind="medium", sr=22050, ns=1),
PiperModel(name="joe", kind="medium", sr=22050, ns=1),
PiperModel(name="john", kind="medium", sr=22050, ns=1),
PiperModel(name="kathleen", kind="low", sr=16000, ns=1),
PiperModel(name="kristin", kind="medium", sr=22050, ns=1),
PiperModel(name="kusal", kind="medium", sr=22050, ns=1),
PiperModel(name="l2arctic", kind="medium", sr=22050, ns=24),
PiperModel(name="lessac", kind="high", sr=22050, ns=1),
PiperModel(name="lessac", kind="low", sr=16000, ns=1),
PiperModel(name="lessac", kind="medium", sr=22050, ns=1),
PiperModel(name="libritts", kind="high", sr=22050, ns=904),
PiperModel(name="libritts_r", kind="medium", sr=22050, ns=904),
PiperModel(name="ljspeech", kind="high", sr=22050, ns=1),
PiperModel(name="ljspeech", kind="medium", sr=22050, ns=1),
PiperModel(name="norman", kind="medium", sr=22050, ns=1),
PiperModel(name="reza_ibrahim", kind="medium", sr=22050, ns=1),
PiperModel(name="ryan", kind="high", sr=22050, ns=1),
PiperModel(name="ryan", kind="low", sr=16000, ns=1),
PiperModel(name="ryan", kind="medium", sr=22050, ns=1),
PiperModel(name="sam", kind="medium", sr=22050, ns=1),
]
en_gb.extend(
[
PiperModel(
name="southern_english_female",
kind="medium",
sr=22050,
ns=6,
cmd="""
wget -qq https://huggingface.co/csukuangfj/vits-piper-en_GB-southern_english_female-medium/resolve/main/en_GB-southern_english_female-medium.onnx
wget -qq https://huggingface.co/csukuangfj/vits-piper-en_GB-southern_english_female-medium/resolve/main/en_GB-southern_english_female-medium.onnx.json
""",
url="https://huggingface.co/csukuangfj/vits-piper-en_GB-southern_english_female-medium",
),
PiperModel(
name="southern_english_male",
kind="medium",
sr=22050,
ns=8,
cmd="""
wget -qq https://huggingface.co/csukuangfj/vits-piper-en_GB-southern_english_male-medium/resolve/main/en_GB-southern_english_male-medium.onnx
wget -qq https://huggingface.co/csukuangfj/vits-piper-en_GB-southern_english_male-medium/resolve/main/en_GB-southern_english_male-medium.onnx.json
""",
url="https://huggingface.co/csukuangfj/vits-piper-en_GB-southern_english_male-medium",
),
]
)
en_us.extend(
[
# https://github.com/rhasspy/piper/issues/187#issuecomment-1805709037
# https://drive.google.com/file/d/1t2D7zP-e2flduS5duHm__UMB9RjuGqWK/view
PiperModel(
name="glados",
kind="high",
sr=22050,
ns=1,
cmd="""
wget -qq https://huggingface.co/csukuangfj/en_US-glados-high/resolve/main/en_US-glados-high.onnx
wget -qq https://huggingface.co/csukuangfj/en_US-glados-high/resolve/main/en_US-glados-high.onnx.json
wget -qq https://huggingface.co/csukuangfj/en_US-glados-high/resolve/main/README.md
wget -qq https://huggingface.co/csukuangfj/en_US-glados-high/resolve/main/MODEL_CARD
""",
url="https://github.com/rhasspy/piper/issues/187#issuecomment-1805709037",
),
]
)
for m in en_gb:
m.lang = "en_GB"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
for m in en_us:
m.lang = "en_US"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = en_gb + en_us
for m in ans:
m.text = "Friends fell out often because life was changing so fast. The easiest thing in the world was to lose touch with someone."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
def get_de_models():
de_de = [
PiperModel(name="eva_k", kind="x_low", sr=16000, ns=1),
PiperModel(name="karlsson", kind="low", sr=16000, ns=1),
PiperModel(name="kerstin", kind="low", sr=16000, ns=1),
PiperModel(name="pavoque", kind="low", sr=16000, ns=1),
PiperModel(name="ramona", kind="low", sr=16000, ns=1),
PiperModel(name="thorsten", kind="high", sr=22050, ns=1),
PiperModel(name="thorsten", kind="low", sr=16000, ns=1),
PiperModel(name="thorsten", kind="medium", sr=22050, ns=1),
PiperModel(name="thorsten_emotional", kind="medium", sr=22050, ns=8),
# https://github.com/rhasspy/piper/issues/187#issuecomment-2691653607
PiperModel(
name="glados",
kind="high",
sr=22050,
ns=1,
cmd="""
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados/high/de_DE-glados-high.onnx
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados/high/de_DE-glados-high.onnx.json
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados/high/MODEL_CARD
wget -qq https://huggingface.co/csukuangfj/vits-piper-de_DE-glados-high/resolve/main/README.md
""",
url="https://huggingface.co/systemofapwne/piper-de-glados",
),
PiperModel(
name="glados",
kind="low",
sr=16000,
ns=1,
cmd="""
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados/low/de_DE-glados-low.onnx
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados/low/de_DE-glados-low.onnx.json
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados/low/MODEL_CARD
wget -qq https://huggingface.co/csukuangfj/vits-piper-de_DE-glados-low/resolve/main/README.md
""",
url="https://huggingface.co/systemofapwne/piper-de-glados",
),
PiperModel(
name="glados",
kind="medium",
sr=22050,
ns=1,
cmd="""
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados/medium/de_DE-glados-medium.onnx
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados/medium/de_DE-glados-medium.onnx.json
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados/medium/MODEL_CARD
wget -qq https://huggingface.co/csukuangfj/vits-piper-de_DE-glados-medium/resolve/main/README.md
""",
url="https://huggingface.co/systemofapwne/piper-de-glados",
),
PiperModel(
name="glados_turret",
kind="high",
sr=22050,
ns=1,
cmd="""
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados-turret/high/de_DE-glados-turret-high.onnx
mv de_DE-glados-turret-high.onnx de_DE-glados_turret-high.onnx
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados-turret/high/de_DE-glados-turret-high.onnx.json
mv de_DE-glados-turret-high.onnx.json de_DE-glados_turret-high.onnx.json
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados-turret/high/MODEL_CARD
wget https://huggingface.co/csukuangfj/vits-piper-de_DE-glados_turret-high/resolve/main/README.md
""",
url="https://huggingface.co/systemofapwne/piper-de-glados",
),
PiperModel(
name="glados_turret",
kind="low",
sr=16000,
ns=1,
cmd="""
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados-turret/low/de_DE-glados-turret-low.onnx
mv de_DE-glados-turret-low.onnx de_DE-glados_turret-low.onnx
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados-turret/low/de_DE-glados-turret-low.onnx.json
mv de_DE-glados-turret-low.onnx.json de_DE-glados_turret-low.onnx.json
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados-turret/low/MODEL_CARD
wget https://huggingface.co/csukuangfj/vits-piper-de_DE-glados_turret-low/resolve/main/README.md
""",
url="https://huggingface.co/systemofapwne/piper-de-glados",
),
PiperModel(
name="glados_turret",
kind="medium",
sr=22050,
ns=1,
cmd="""
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados-turret/medium/de_DE-glados-turret-medium.onnx
mv de_DE-glados-turret-medium.onnx de_DE-glados_turret-medium.onnx
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados-turret/medium/de_DE-glados-turret-medium.onnx.json
mv de_DE-glados-turret-medium.onnx.json de_DE-glados_turret-medium.onnx.json
wget -qq https://huggingface.co/systemofapwne/piper-de-glados/resolve/main/de/de_DE/glados-turret/medium/MODEL_CARD
wget https://huggingface.co/csukuangfj/vits-piper-de_DE-glados_turret-medium/resolve/main/README.md
""",
url="https://huggingface.co/systemofapwne/piper-de-glados",
),
]
for m in de_de:
m.lang = "de_DE"
if m.model_name == "":
m.model_name = f"{m.lang}-{m.name}-{m.kind}.onnx"
ans = de_de
for m in ans:
m.text = "Alles hat ein Ende, nur die Wurst hat zwei."
code = m.lang[:2]
if m.cmd == "":
m.cmd = f"""
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/{m.model_name}.json
wget -qq https://huggingface.co/rhasspy/piper-voices/resolve/main/{code}/{m.lang}/{m.name}/{m.kind}/MODEL_CARD
"""
if m.url == "":
m.url = f"https://huggingface.co/rhasspy/piper-voices/tree/main/{code}/{m.lang}/{m.name}/{m.kind}"
return ans
def get_all_models():
ans = []
ans += get_ar_models()
ans += get_ca_models()
ans += get_cs_models()
ans += get_cy_models()
ans += get_da_models()
ans += get_de_models()
ans += get_el_models()
ans += get_en_models()
ans += get_es_models()
ans += get_fa_models()
ans += get_fi_models()
ans += get_fr_models()
ans += get_hu_models()
ans += get_is_models()
ans += get_it_models()
ans += get_ka_models()
ans += get_kk_models()
ans += get_lb_models()
ans += get_lv_models()
ans += get_ml_models()
ans += get_ne_models()
ans += get_nl_models()
ans += get_no_models()
ans += get_pl_models()
ans += get_pt_models()
ans += get_ro_models()
ans += get_ru_models()
ans += get_sk_models()
ans += get_sl_models()
ans += get_sr_models()
ans += get_sv_models()
ans += get_sw_models()
ans += get_tr_models()
ans += get_uk_models()
ans += get_vi_models()
for i, m in enumerate(ans):
m.index = i
return ans
def main():
args = get_args()
index = args.index
total = args.total
assert 0 <= index < total, (index, total)
all_model_list = get_all_models()
print(all_model_list)
num_models = len(all_model_list)
num_per_runner = num_models // total
if num_per_runner <= 0:
raise ValueError(f"num_models: {num_models}, num_runners: {total}")
start = index * num_per_runner
end = start + num_per_runner
remaining = num_models - args.total * num_per_runner
print(f"{index}/{total}: {start}-{end}/{num_models}")
d = dict()
d["model_list"] = all_model_list[start:end]
if index < remaining:
s = args.total * num_per_runner + index
d["model_list"].append(all_model_list[s])
print(f"{s}/{num_models}")
filename_list = [
"./generate.sh",
]
for filename in filename_list:
environment = jinja2.Environment()
if not Path(f"{filename}.in").is_file():
print(f"skip {filename}")
continue
with open(f"{filename}.in") as f:
s = f.read()
template = environment.from_string(s)
s = template.render(**d)
with open(filename, "w") as f:
print(s, file=f)
print(f"There are {len(all_model_list)} models")
for m in all_model_list:
print(m.index, m.model_name)
if Path("hf").is_dir():
with open("./generate_samples.py.in") as f:
s = f.read()
template = environment.from_string(s)
for m in all_model_list:
model_dir = f"vits-piper-{m.lang}-{m.name}-{m.kind}"
d = {
"model": f"{model_dir}/{m.model_name}",
"data_dir": f"{model_dir}/espeak-ng-data",
"tokens": f"{model_dir}/tokens.txt",
"text": m.text,
}
for i in range(m.ns):
s = template.render(
**d,
sid=i,
output_filename=f"hf/piper/mp3/{m.lang}/{model_dir}/{i}.mp3",
)
with open(f"generate_samples-{model_dir}-{i}.py", "w") as f:
print(s, file=f)
if __name__ == "__main__":
main()
... ...
#!/usr/bin/env bash
# Copyright 2025 Xiaomi Corp. (authors: Fangjun Kuang)
#
# Auto generated! Do NOT edit!
set -ex
log() {
# This function is from espnet
local fname=${BASH_SOURCE[1]##*/}
echo -e "$(date '+%Y-%m-%d %H:%M:%S') (${fname}:${BASH_LINENO[0]}:${FUNCNAME[1]}) $*"
}
wget -qq https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/espeak-ng-data.tar.bz2
tar xf espeak-ng-data.tar.bz2
rm espeak-ng-data.tar.bz2
mkdir -p release
{% for model in model_list %}
name={{ model.name }}
kind={{ model.kind }}
lang={{ model.lang }}
model_name={{ model.model_name }}
text="{{ model.text }}"
num_speakers={{ model.ns }}
sample_rate={{ model.sr }}
{{ model.cmd }}
python3 ./add_meta_data.py \
--name $name \
--kind $kind \
--lang $lang
dst=vits-piper-$lang-$name-$kind
dst_int8=vits-piper-$lang-$name-$kind-int8
dst_fp16=vits-piper-$lang-$name-$kind-fp16
mkdir -p $dst
mv -v tokens.txt $dst/
mv -v MODEL_CARD $dst/ || true
mv -v README $dst/ || true
mv -v *.json $dst/
cp -a ./espeak-ng-data $dst/
cp -a $dst $dst_int8
cp -a $dst $dst_fp16
mv -v *.onnx $dst/
python3 ./dynamic_quantization.py \
--input $dst/$model_name \
--output-int8 $dst_int8/$model_name \
--output-fp16 $dst_fp16/$model_name >/dev/null 2>&1
echo "---fp32---"
ls -lh $dst
echo "---int8---"
ls -lh $dst_int8
echo "---fp16---"
ls -lh $dst_fp16
tar cjf ${dst}.tar.bz2 $dst
tar cjf ${dst_int8}.tar.bz2 $dst_int8
tar cjf ${dst_fp16}.tar.bz2 $dst_fp16
if [ -d hf ]; then
mkdir -p hf/piper/mp3/$lang/vits-piper-$lang-$name-$kind
for i in $(seq $num_speakers); do
i=$((i-1))
python3 ./generate_samples-$dst-$i.py
done
ls -lh hf/piper/mp3/$lang/vits-piper-$lang-$name-$kind
fi
mv $dst release
mv $dst_int8 release
mv $dst_fp16 release
ls -lh release/*
{% endfor %}
... ...
import sherpa_onnx
import soundfile as sf
config = sherpa_onnx.OfflineTtsConfig(
model=sherpa_onnx.OfflineTtsModelConfig(
vits=sherpa_onnx.OfflineTtsVitsModelConfig(
model="{{ model }}",
lexicon="",
data_dir="{{ data_dir }}",
tokens="{{ tokens }}",
),
num_threads=1,
),
)
if not config.validate():
raise ValueError("Please check your config")
tts = sherpa_onnx.OfflineTts(config)
audio = tts.generate(text="{{text}}", sid={{sid}}, speed=1.0)
sf.write("{{ output_filename }}", audio.samples, samplerate=audio.sample_rate)
... ...
... ... @@ -18,7 +18,7 @@ void PybindOfflineTtsVitsModelConfig(py::module *m) {
.def(py::init<const std::string &, const std::string &,
const std::string &, const std::string &,
const std::string &, float, float, float>(),
py::arg("model"), py::arg("lexicon"), py::arg("tokens"),
py::arg("model"), py::arg("lexicon") = "", py::arg("tokens"),
py::arg("data_dir") = "", py::arg("dict_dir") = "",
py::arg("noise_scale") = 0.667, py::arg("noise_scale_w") = 0.8,
py::arg("length_scale") = 1.0)
... ...