canberk7 / ema-lightning
git clone https://github.com/canberk7/ema-lightning.git
v1.1.2 · 10d ago
Tiny, fast and accurate Turkish text-to-speech. 8.6M parameters, 0.92% WER on Freya-TR-Eval, first audio in ~4 ms and 1,300× real time on one GPU. Streams audio, batches many callers on one GPU, and runs offline on a GPU or CPU.
—
stars, 24h
—
stars, 7 days
+243
stars, 30 days · #1,080
243
★ total
31
forks · 4 open issues
Star history starts 2026-10-20; the chart appears after the second daily snapshot.
LanguagePython
LicenseApache-2.0
Created2026-10-05 (15d ago)
Last push10d ago
Watchers7
OwnerUser
Links
README excerpt
# ⚡ EMA Lightning **Tiny, fast and accurate Turkish text to speech.** 8.6M parameters, about 34 MB, Apache-2.0. It runs on your own GPU or CPU, offline: no text or audio leaves the machine. - **The most accurate on Freya-TR-Eval:** 0.92% word error rate, the lowest of every system measured, including ElevenLabs v4, Gemini 3.8 and the 2.38B-parameter Trendyol-TTS. - **Fast:** the first audio is ready in about 4 ms. One request runs 440× faster than real time, and batched work 1,316× (RTX 4090). - **Cheap:** about $0.0085 per million characters on a rented RTX 4090. - **Takes Turkish as people write it:** numbers, dates, times, money, units, abbreviations and symbols are read aloud. - **Streams:** audio starts while the rest of the text is still being made. - **One model serves many callers:** call it from as many threads as you like. Its built-in scheduler, Playhead, runs everyone's work together on the GPU. No server or queue system to run. | System | Size | Word error rate | Speed, RTX 4090 | |---|---|---|---| | **EMA Lightning** | **8.6M** | **0.92%** | **440× real time** | | Trendyol-TTS | 2.38B | 0.98% | 2.8× | | Gemini 3.8 Flash-Lite | cloud | 1.31% | — | | ElevenLabs v4 | cloud | 1.43% | — | | Anka TTS † | 336M | 1.73% | 6.3× | | XTTS-v2 † | 470M | 3.34% | 7.1× | | FreyaTTS † | 183M | 12.02% | 8.4× | Freya-TR-Eval, all 495 sentences, speed 1.0. † Reported on the Anka TTS model card. The full table and how it was measured are on the model card. ## Install [code] CPython 3.11 to 3.13 with PyTorch 2.1 or newer. The weights (about 34 MB) download from Hugging Face on first use. On Linux the default PyTorch build includes CUDA, which pulls in about 1.5 GB of NVIDIA packages. On a machine without an NVIDIA GPU, install the CPU-only build instead: [code] Thanks to @keyiflerolsun for spotting the 1.5 GB of unneeded NVIDIA packages on CPU machines (#4). ## Use Make one `EMA` and keep it for the whole program. There are two ways to get speech out of it: | | `say()` | `stream()` | |---|---|---| | Gives you | the whole audio, once it's ready | the audio piece by piece, as it's made | | Takes | one text, or a list of texts | one text per call | | Use it for | files, voiceovers, batch jobs | playing as you go: speakers, phone calls, live apps | ### `say()`: a whole text, back when it's ready [code] `say()` returns a `Speech`: the `audio` (a float32 NumPy array, mono, between -1 and 1), its `sample_rate`, its `duration` in seconds, and the `seed` that made it. With `path`, it also writes a WAV file. Pass the same `seed` again to get the same audio. Give it a list and every text is made in shared batches, one `Speech` per text, in order. With `path`, the list is written into that folder as `0.wav`, `1.wav`, …: [code] ### Word timings: when each word is heard Every `Speech` from `say()` carries `words`: each spoken word with its `start` and `end` in seconds. They come from the same frame plan the audio is made from, so they cost nothing extra