Configuration Parsing Warning:Invalid JSON for config file config.json

Khmer TTS β€” Female (VITS, ONNX)

A single-speaker female Khmer text-to-speech voice. VITS (end-to-end), grapheme-based (no phonemizer), exported to ONNX so it runs fully offline on-device β€” in the browser via onnxruntime-web and on mobile via onnxruntime-react-native. Built for iAny, where it reads Khmer news aloud in the Radio feature.

Files

File What
khmer_tts_v3.onnx The voice to use. Tuned export: length_scale 1.15 (a touch slower/clearer), noise_scale 0.5, noise_scale_w 0.6 (less timing jitter). These are baked into the graph.
tts_meta.json Grapheme vocabulary + inference metadata (see below).
config.json Coqui-TTS training/model config.
best_model.pth PyTorch checkpoint (for re-export / continued training).
khmer_tts*.onnx (others) Earlier / alternate-speed exports, kept for comparison.

tts_meta.json fields:

{
  "vocab": ["…"],        // grapheme -> id is the index into this array
  "add_blank": true,     // interleave the blank token between graphemes
  "blank": "@",          // the blank symbol
  "sample_rate": 22050
}

Inference (ONNX Runtime)

The graph takes token ids and returns float PCM:

  • Inputs: x = int64[1, T] (grapheme ids), x_lengths = int64[1] (= T)
  • Output: y = float32 waveform, mono, 22050 Hz

Tokenize by mapping each character to its index in vocab; if add_blank is true, start with the blank id and put a blank id between every grapheme.

import json, numpy as np, onnxruntime as ort, soundfile as sf

meta = json.load(open("tts_meta.json"))
id_of = {c: i for i, c in enumerate(meta["vocab"])}
blank = id_of[meta["blank"]]

def to_ids(text):
    ids = [id_of[c] for c in text if c in id_of]
    if meta["add_blank"]:
        out = [blank]
        for i in ids: out += [i, blank]
        return out
    return ids

sess = ort.InferenceSession("khmer_tts_v3.onnx")
ids = np.array([to_ids("αžŸαž½αžŸαŸ’αžŠαžΈ αž–αž·αž—αž–αž›αŸ„αž€")], dtype=np.int64)
xlen = np.array([ids.shape[1]], dtype=np.int64)
y = sess.run(None, {"x": ids, "x_lengths": xlen})[0]
sf.write("out.wav", np.asarray(y).squeeze(), meta["sample_rate"])

The same tokenize β†’ run β†’ play flow is used in the browser (Web Audio) and in React Native (expo-av); see the iAny source for reference implementations.

Training

VITS trained from scratch on a single female Khmer speaker (~727 h DDD-Cambodia read-speech corpus), then continued training for more steps/data (the "v2" line). The v3 ONNX is the same model with tuned inference constants.

License & attribution

CC-BY-SA-4.0. This voice is trained on the DDD-Cambodia speech corpus, which is licensed CC-BY-SA-4.0. ShareAlike carries over, so the voice β€” and any derivative of it β€” must:

  • credit the DDD-Cambodia corpus, and
  • be shared under CC-BY-SA-4.0 as well.

Model architecture: VITS (Kim et al., 2021), trained with the Coqui TTS toolkit.

Downloads last month
665
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Space using sengtha/khmer-tts-female-v2 1