CoolFace
Modelpublic

TilLabs/kokoro-tts-kazakh

sourceHugging Faceapache-2.0updated 2d agoView on Hugging Face
4likes234downloads
Model Card

Kokoro TTS Kazakh (km_m1)

Nuraidar Mambetaly · Anuar Sultanbekov · Altair Balakhazy

A single-speaker Kazakh text-to-speech voice, built by fine-tuning Kokoro-82M on the ISSAI KazakhTTS2 corpus with a StyleTTS2-based training pipeline (kikiri-tts).

Kokoro is an 82M-parameter architecture, which keeps this checkpoint lightweight and fast — synthesis runs comfortably in real time on a regular CPU, with no GPU required for inference.

Samples

<audio controls src="https://huggingface.co/TilLabs/kokoro-tts-kazakh/resolve/main/samples/demo_1.wav"></audio>

<audio controls src="https://huggingface.co/TilLabs/kokoro-tts-kazakh/resolve/main/samples/demo_2.wav"></audio>

<audio controls src="https://huggingface.co/TilLabs/kokoro-tts-kazakh/resolve/main/samples/demo_3.wav"></audio>

All three were synthesized from held-out validation text not seen during training (see Why This Checkpoint).

Model Details

Base modelhexgrad/Kokoro-82M (82M params, 24 kHz)
LanguageKazakh (kk)
Speakerkm_m1 — male, single speaker
Training frameworkkikiri-tts (StyleTTS2 Stage 1 + Stage 2)
Phonemizationespeak-ng via misaki, IPA
Training audio (km_m1)102.8 h across 48,154 clips
Full multi-speaker corpusISSAI KazakhTTS2 — 5 speakers, 269.9 h total
LicenseApache 2.0 (inherited from Kokoro-82M / kikiri-tts)

Training Configuration

Value
Batch size12
OptimizerAdamW (betas=0.0/0.99, eps=1e-9, weight_decay=1e-4)
Learning rate (acoustic / PL-BERT)1e-4 / 1e-5
Epochs (Stage 1 / Stage 2)5 / 5
joint_epoch2 (adversarial/SLM loss starts here — required to avoid style-encoder collapse)
Sample rate24,000 Hz, 80 mel bands
Training time≈ 52 hours (13h Stage 1 + 38.6h Stage 2)

Why This Checkpoint

StyleTTS2/GAN-style training can silently collapse the style encoder partway through a run, so checkpoints are not reliable to pick by filename or epoch number alone. Several km_m1 candidates produced during training were instead synthesized on 20 held-out validation sentences (not seen during training) and scored for word error rate (WER) using a Kazakh-fine-tuned Whisper ASR model with jiwer:

VoicepackWER on held-out setVerdict
final (this release)16.4%Clean, intelligible speech
epoch4_good131.3%Garbled / repetitive looping — stale, incompatible with the current decoder despite the filename
epoch9_collapsed217.4%Confirmed style-encoder collapse

final matches the exact decoder weights shipped here (kokoro_kazakh.pth) — both were exported from the same training checkpoint, so there is no decoder/voicepack mismatch. Stage 2 validation loss also decreased monotonically across all 5 epochs of this run (0.402 → 0.385), with no sign of the divergence seen in the collapsed run.

Installation & Usage

Runs on CPU — no GPU needed.

bash
pip install torch kokoro "misaki[kk]"

misaki[kk] pulls in espeak-ng bindings for Kazakh phonemization; see kikiri-tts for a ready-made inference script (inference_kazakh.py).

Note: kokoro_kazakh.pth is stored using the legacy weight_norm key format (weight_g / weight_v) so it loads cleanly with current torch/kokoro releases. If you re-export this checkpoint yourself from a different PyTorch version, double-check the resulting key names match what your installed kokoro expects — a silent weight_g/weight_v vs. parametrizations.weight.original0/original1 mismatch will make load_state_dict skip the decoder/predictor weights without raising an error, producing noise instead of speech.
python
import torch
from kokoro import KModel
from misaki import espeak

g2p = espeak.EspeakG2P(language="kk")
model = KModel(repo_id="hexgrad/Kokoro-82M", config="config.json", model="kokoro_kazakh.pth").eval()
voicepack = torch.load("km_m1.pt", map_location="cpu", weights_only=True)

text = "Сәлем! Бұл қазақ тіліндегі сөйлеу синтезі."
phonemes, _ = g2p(text)
ref_s = voicepack[min(len(phonemes) - 1, voicepack.shape[0] - 1)]

audio = model(phonemes, ref_s, speed=1.0)

Download the checkpoint files directly with huggingface_hub:

python
from huggingface_hub import snapshot_download
snapshot_download("TilLabs/kokoro-tts-kazakh", local_dir="kokoro-tts-kazakh")

CPU Benchmarks

Measured on an AMD Ryzen 5 5500U (6 physical cores / 12 threads via SMT, up to 4.06 GHz, no GPU), synthesizing a 3-sentence, 22.45s-audio test set:

CPU threadsSynthesis timeReal-time factor (RTF)Speed vs. real timePeak RAM
120.9 s0.93×1.1×1.46 GB
213.1 s0.58×1.7×1.46 GB
311.0 s0.49×2.0×1.39 GB
49.5 s0.42×2.4×1.41 GB
59.1 s0.41×2.5×1.41 GB
68.7 s0.39×2.6× (peak)1.41 GB
89.7 s0.43×2.3×1.42 GB
109.7 s0.43×2.3×1.42 GB
1210.1 s0.45×2.2×1.39 GB

Throughput scales with core count up to the number of physical cores (6 here); beyond that, additional SMT threads add scheduling overhead without extra real compute, so speed slightly regresses. Even single-threaded, this model already runs faster than real time. Peak memory stays flat at ~1.4 GB regardless of thread count.

The table above measures single-request latency: how many threads to give one synthesis call so it finishes faster. That's a different question from throughput: how many simultaneous requests from different users the machine can serve. For that, each request should run single-threaded, with concurrency handled by running multiple worker processes in parallel instead of parallelizing one request across threads — this avoids the synchronization overhead that caps the table above at ~2.6×.

Concurrent single-threaded workers, same CPU:

Concurrent workersAggregate speed vs. real timeRequests/sec
11.1×0.14
21.9×0.26
32.4×0.32
42.7×0.44
63.1×0.50
83.1×0.53
102.6×0.52
122.8×0.63

With process-level concurrency, aggregate throughput exceeds the single-request ceiling (~3.1× real time vs. 2.6×), and keeps benefiting from SMT threads past the physical core count — the opposite pattern from the latency table above. In practice, on this 6-core/12-thread CPU, running around 6-8 concurrent single-threaded workers is a reasonable default for serving multiple users at once.

Files

  • —kokoro_kazakh.pth — fine-tuned Kokoro decoder / text-encoder / predictor weights
  • —km_m1.pt — km_m1 speaker voicepack (style reference vectors)
  • —config.json — Kokoro model config
  • —samples/ — demo clips synthesized from held-out validation text during evaluation

Acknowledgements