Metadata-Version: 2.4
Name: eist
Version: 0.1.0
Summary: Scottish Gaelic speech-to-subtitles pipeline — transcribe, align, punctuate, translate
Author-email: Christoph Minixhofer <christoph.minixhofer@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/eist-edinburgh/eist
Project-URL: Documentation, https://eist-edinburgh.github.io/eist/
Project-URL: Demo, https://huggingface.co/spaces/eist-edinburgh/demo
Keywords: scottish-gaelic,asr,subtitles,speech,whisper,alignment,translation
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.24
Requires-Dist: click>=8.0
Provides-Extra: transcribe
Requires-Dist: faster-whisper>=1.0; extra == "transcribe"
Requires-Dist: torch>=2.0; extra == "transcribe"
Provides-Extra: align
Requires-Dist: sk-align[accel,hub]>=0.3.1; extra == "align"
Provides-Extra: punctuate
Requires-Dist: onnxruntime>=1.17; extra == "punctuate"
Requires-Dist: tokenizers>=0.15; extra == "punctuate"
Requires-Dist: huggingface_hub>=0.20; extra == "punctuate"
Provides-Extra: translate
Provides-Extra: all
Requires-Dist: eist[align,punctuate,transcribe]; extra == "all"
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.0; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
Provides-Extra: dev
Requires-Dist: eist[all,docs,test]; extra == "dev"
Requires-Dist: ruff; extra == "dev"

# eist

<p>
  <img src="docs/img/badge-version.svg" alt="version v0.1.0">
  <img src="docs/img/badge-python.svg" alt="python ≥3.10">
  <img src="docs/img/badge-license.svg" alt="license MIT">
  <img src="docs/img/badge-tests.svg" alt="tests passing">
</p>

**Scottish Gaelic speech-to-subtitles pipeline** — transcribe, align, punctuate, translate.

`eist` (Scottish Gaelic for *"listen"*) is a Python library that packages all features of the [ÈIST demo](https://huggingface.co/spaces/eist-edinburgh/demo) into a pip-installable local package following PyTorch / Hugging Face conventions.

**[Documentation](https://eist-edinburgh.github.io/eist/)** · **[Models](https://huggingface.co/eist-edinburgh)** · **[Demo](https://huggingface.co/spaces/eist-edinburgh/demo)**

## Quick start

```bash
pip install eist[all]
```

### End-to-end pipeline

```python
from eist import GaelicASRPipeline

pipe = GaelicASRPipeline.from_pretrained()
result = pipe("audio.wav")

for sub in result:
    print(f"[{sub.start:.1f}–{sub.end:.1f}] {sub.text}")

# Export as SRT
with open("output.srt", "w") as f:
    f.write(result.to_srt())
```

### Component-level usage

```python
from eist import Transcriber, PunctuationModel, SubtitleFormatter
from sk_align import Aligner

# Load individual components
transcriber = Transcriber.from_pretrained()
aligner = Aligner.from_pretrained()
punct = PunctuationModel.from_pretrained()
formatter = SubtitleFormatter(max_words=10, min_words=3)

# Run step-by-step
segments = transcriber.transcribe("audio.wav")
# ... align, punctuate, format as needed
```

### Translation

```python
from eist import Translator

translator = Translator(api_key="sk-...")  # or set OPENAI_KEY env var
translator.translate(result.subtitles)

# Export translated SRT
print(result.to_srt(translated=True))
```

## Installation

Install only the components you need:

```bash
pip install eist                    # core types + subtitle formatter (no heavy deps)
pip install eist[transcribe]        # + Whisper (faster-whisper, torch)
pip install eist[align]             # + forced alignment (sk-align)
pip install eist[punctuate]         # + punctuation model (onnxruntime)
pip install eist[all]               # everything
```

## Command line

After installing, the `eist` command is available:

```bash
# Transcribe to SRT (default)
eist transcribe audio.wav -o output.srt

# WebVTT format
eist transcribe audio.wav -f vtt -o output.vtt

# Plain text transcript
eist transcribe audio.wav -f txt

# JSON output (includes word-level timestamps)
eist transcribe audio.wav -f json -o output.json

# Skip alignment or punctuation for faster processing
eist transcribe audio.wav --no-align --no-punctuate

# Translate to English (requires OpenAI API key)
eist transcribe audio.wav --translate --api-key sk-...

# Use a specific device / compute type
eist transcribe audio.wav --device cpu --compute-type float32

# Suppress progress messages
eist transcribe audio.wav -q -o output.srt
```

Run `eist transcribe --help` for all options. You can also use `python -m eist`.

## Components

| Class | Purpose | Extra |
|---|---|---|
| `Transcriber` | Whisper-based Scottish Gaelic ASR | `[transcribe]` |
| `Aligner` | Forced alignment → word timestamps (via sk-align) | `[align]` |
| `PunctuationModel` | Restore `.!?,;:` and capitalisation | `[punctuate]` |
| `SubtitleFormatter` | Regroup words into readable subtitle segments | (core) |
| `Translator` | LLM-based Gaelic → English translation | (core) |
| `GaelicASRPipeline` | End-to-end: audio → subtitles | `[all]` |

## Data types

All components use typed dataclasses:

- **`Word`** — `text`, `start`, `end`
- **`Subtitle`** — `text`, `start`, `end`, `words`, `paragraph_break`, `translation`
- **`TranscriptionResult`** — `subtitles`, `language`, `duration`, `timing`
  - `.to_srt()`, `.to_vtt()` for export
  - `.text` for plain-text transcript
  - Iterable: `for sub in result: ...`

## Models

All models are hosted on the [eist-edinburgh](https://huggingface.co/eist-edinburgh) Hugging Face organisation.

### ASR (Speech Recognition)

| Model | Description | WER* | RTF (CPU) |
|---|---|---|---|
| [whisper-large-v3-turbo-gaelic-ct2-v2](https://huggingface.co/eist-edinburgh/whisper-large-v3-turbo-gaelic-ct2-v2) | CTranslate2 v2 | 11.6% | 0.83× |
| [whisper-large-v3-turbo-gaelic-ct2-v3](https://huggingface.co/eist-edinburgh/whisper-large-v3-turbo-gaelic-ct2-v3) | CTranslate2 v3 **(default)** | 12.8% | 1.05× |
| [whisper-large-v3-turbo-gaelic](https://huggingface.co/eist-edinburgh/whisper-large-v3-turbo-gaelic) | Original Safetensors (0.8 B params) | — | — |

\*WER measured on 30 s of a BBC Radio nan Gàidheal broadcast, compared against a word-count-matched manual transcript.
RTF = real-time factor (lower is faster); measured on CPU (Intel® Core™ i7, single-thread CTranslate2).

### Forced Alignment

| Model | RTF (CPU, 60 s) | Words aligned |
|---|---|---|
| [nnet3_alignment_model](https://huggingface.co/eist-edinburgh/nnet3_alignment_model) | 0.07× | 187 / 187 |

Alignment uses [sk-align](https://pypi.org/project/sk-align/) with a Kaldi nnet3 chain model.

### Punctuation Restoration

| Model | Punct F1 | Comma F1 | Period F1 | Question F1 | Case F1 |
|---|---|---|---|---|---|
| [gaelic-punctuation-model-v2](https://huggingface.co/eist-edinburgh/gaelic-punctuation-model-v2) | 0.63 | 0.61 | 0.67 | 0.57 | 0.83 |

Punctuation F1 scores averaged over two ~30 min BBC Radio nan Gàidheal broadcasts (~9 300 words total).

### Benchmark details

All benchmarks run on an Intel® Core™ i7 CPU with `float32` precision, no GPU.
Audio from BBC Radio nan Gàidheal broadcasts, ~30 min each.
ASR evaluation capped to 30 s due to CPU speed; alignment capped to 60 s.
Full results in [`benchmarks/`](benchmarks/).

## License

MIT
