cy_en_GB-bu_tts-bangor — Welsh/English Bilingual Neural TTS

A bilingual Welsh (Cymraeg) + English neural text-to-speech model (VITS / Piper architecture) with three studio voices.

It pronounces English natively (not Welsh-accented) and handles code-switched cy/en text within a sentence, because it is phonemized with the permissive Bangor Welsh G2P rather than eSpeak.

Developed by: Uned Technolegau Iaith (Language Technologies Unit), Bangor University Model type: Multi-speaker neural TTS (VITS), 3 voices · Languages: Welsh (cy) + English (en) · Format: ONNX

Model details

  • Architecture: Piper VITS, medium quality
  • Speakers: 3 (speaker ids 0, 1, 2)
  • Sample rate: 22,050 Hz · Symbols: 256 · Size: ~77 MB (ONNX)
  • Phonemizer: permissive Bangor Welsh G2Pbackend: bangor, english_mode: native, data_version: b1edc63e35bb7a6f
  • Punctuation-aware pauses for natural phrasing; no eSpeak/GPL at inference.

⚠️ Important: phonemization

This model was trained with the Bangor G2P, so it will not produce correct pronunciation through the default eSpeak-based piper command. You must phonemize with the matching front-end:

  • Python reference: piper-cy-local core/phonemizeBangorG2P(english_mode="native")
  • C runtime: libcy_phonemize (same repo)

Both emit the exact phoneme-id sequence the model expects; the runtime asserts data_version == b1edc63e35bb7a6f.

Usage (Python + ONNX Runtime + Bangor G2P)

import numpy as np, onnxruntime as ort, wave, sys
sys.path.insert(0, "piper-cy-local/core/phonemize")
from bangor_g2p import BangorG2P

g2p = BangorG2P(english_mode="native")
sess = ort.InferenceSession("cy_en_GB-bu_tts-bangor-medium.onnx")
scales = np.array([0.667, 1.0, 0.8], dtype=np.float32)   # noise, length, noise_w

def synth(text, sid=0, path="out.wav"):
    ids = g2p.text_to_ids(text)
    audio = sess.run(None, {
        "input": np.array([ids], dtype=np.int64),
        "input_lengths": np.array([len(ids)], dtype=np.int64),
        "scales": scales,
        "sid": np.array([sid], dtype=np.int64),
    })[0].squeeze()
    audio = (audio * (32767 / max(0.01, np.max(np.abs(audio))))).astype("<i2")  # peak-normalize
    with wave.open(path, "wb") as w:
        w.setnchannels(1); w.setsampwidth(2); w.setframerate(22050); w.writeframes(audio.tobytes())

synth("Bore da. Sut wyt ti'n teimlo heddiw?", sid=0)          # Welsh
synth("Good morning. How are you feeling today?", sid=1)      # English
synth("Nes i fwcio'r tickets ar-lein, so we're all set.", 2)  # code-switched

Model files

  • cy_en_GB-bu_tts-bangor-medium.onnx — the TTS model (ONNX)
  • cy_en_GB-bu_tts-bangor-medium.onnx.json — config (phoneme id-map, speaker map, phonemizer block)
  • cy_en_GB-bu_tts-bangor-medium.safetensors — pickle-free share of the training checkpoint

Intended use & limitations

Screen readers and assistive technology, Welsh/bilingual language-learning apps, and local/offline TTS. Best on general conversational Welsh, English, and mixed cy/en text. Medium quality (assistive-grade, not studio mastering); OOV/technical terms, rare place names and unusual spellings may mispronounce; neutral tone with limited emotional range.

Licence

Released under CC0-1.0 (public domain) — free to use, modify, and distribute for any purpose without restriction. Model-code (Piper/VITS) is MIT. Built on Piper / the Rhasspy community; the acoustic model is warm-started from the VCTK Piper checkpoint (en_GB-vctk-medium), VCTK corpus © University of Edinburgh, CC BY 4.0.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support