- Flag
- Default
- --data-dir
- (required)
- --shuffle-data
- off
- --max-src-len
- 256
Specs
- FlagDefault
- --data-dir(required)
- --shuffle-dataoff
- --max-src-len256
- --max-tgt-len200
- --d-model256
- --nhead8
- --num-layers3
- --dim-ff1024
- --dropout0.1
- --batch-size64
- --epochs10
- --lr1e-4
- --out-dircheckpoints
- --resume—
- --dict-tsv<data-dir>/dict.tsv
- --no-lexiconoff
- --unknown-context-chars48
- --lexicon-train-full-sentenceoff
README
G2P Transformer (English text → IPA)
Train a small Transformer that maps English text to IPA phonemes. Training data is a folder of tab-separated files (text<TAB>ipa). You can build TSVs with WikiText → espeak-ng (build_corpus_tsv.py), HF word list → espeak-ng (build_dictionary_tsv.py), librig2p-nostress (build_librig2p_nostress_tsv.py), or CMUdict (build_cmudict_tsv.py); the last three use ARPAbet → Unicode IPA in arpabet_ipa.py (no espeak-ng).
Requirements
-
Python 3.10+
-
espeak-ng must be installed on your system and available in
PATHwhen running the dataset build scripts (the Python package is a wrapper around the binary).- macOS:
brew install espeak-ng - Ubuntu/Debian:
sudo apt install espeak-ng
- macOS:
Install
pip install -r requirements.txt
Building training TSVs
Corpus (WikiText lines + IPA):
python build_corpus_tsv.py -o data/corpus.tsv --max-sentences 20000
Dictionary words + IPA (example HF dataset):
python build_dictionary_tsv.py -o data/dictionary.tsv --max-words 10000
LibriG2P (no stress) lexicon or sentence splits (downloads dataset/<split>.json via huggingface_hub):
python build_librig2p_nostress_tsv.py -o data/librig2p_lex.tsv --split lexicon_train
# optional: --json-path /path/to/lexicon_train.json --max-rows 50000 --skip-unknown-phonemes
CMU Pronouncing Dictionary (cmudict.dict from GitHub by default):
python build_cmudict_tsv.py -o data/dict.tsv
# optional: --cmudict-path ./cmudict.dict --lowercase --download-cache ~/.cache/cmudict.dict
# default TSV has a third column ``ambiguous`` (true/false); training still uses only text+ipa
# use --no-ambiguous-column for a two-column file
Phoneme tokens (phn) are treated as stress-free ARPAbet (trailing 0/1/2 stripped if present), mapped to IPA, and concatenated into one string per example so the target side stays character-level like the other TSV builders. IPA symbols and conventions can differ from espeak-ng; mixing this TSV with espeak-built TSVs in one --data-dir is allowed but may widen the target alphabet. CMUdict and LibriG2P exports share the same mapping in arpabet_ipa.py.
Put one or more *.tsv files in a directory (e.g. data/) and point training at that folder. Files are read in sorted path order and concatenated. The lexicon file dict.tsv in that folder (if present) is not loaded as training rows; it is used only for hybrid encoder input (see --dict-tsv).
Training
python train_g2p.py --data-dir data
Options:
| Flag | Default | Description |
|---|---|---|
--data-dir |
(required) | Directory containing one or more *.tsv files (text<TAB>ipa after optional # comment lines) |
--shuffle-data |
off | Shuffle all pairs after loading (loader still shuffles batches) |
--max-src-len |
256 | Max grapheme sequence length |
--max-tgt-len |
200 | Max IPA sequence length |
--d-model |
256 | Transformer dimension |
--nhead |
8 | Number of attention heads |
--num-layers |
3 | Encoder and decoder layers |
--dim-ff |
1024 | Feedforward hidden size |
--dropout |
0.1 | Dropout |
--batch-size |
64 | Batch size |
--epochs |
10 | Training epochs |
--lr |
1e-4 | Learning rate |
--out-dir |
checkpoints | Where to save model and vocabs |
--resume |
— | Resume from checkpoint in DIR; use the same --data-dir as the original run |
--dict-tsv |
<data-dir>/dict.tsv |
Pronouncing-dictionary TSV for <k>…</k> / <u>…</u> hybrid sources |
--no-lexicon |
off | Disable hybrid source; raw text only (older checkpoints) |
--unknown-context-chars |
48 | Context radius for lexicon window training (tag-aligned) and default for inference |
--lexicon-train-full-sentence |
off | With lexicon: train on full hybrid per row instead of one example per <u>…</u> |
Example (smaller/faster run):
python train_g2p.py --data-dir data --epochs 5 --batch-size 32 --out-dir out
Continue training from an existing checkpoint:
python train_g2p.py --data-dir data --resume checkpoints --epochs 5
Outputs in --out-dir:
g2p_transformer.pt– model state dictsrc_vocab.json– source (grapheme) character vocabularytgt_vocab.json– target (IPA) character vocabularyconfig.json– hyperparameters anddata_dir(absolute path) for reference
Model
- Encoder–decoder Transformer (PyTorch
nn.Transformer). - Character-level input and output: no subword tokenizer; both text and IPA are encoded as sequences of Unicode characters.
- Training is teacher-forced with cross-entropy on the decoder output.
Data format
Each TSV may start with # comment lines, then a header row whose first two columns are text and ipa (additional columns are ignored by training):
text ipa
Then one training pair per row. The loader in g2p_tsv_io.py merges every *.tsv in --data-dir. CMUdict exports may add ambiguous (see above).
Inference
After training, run:
python infer.py "Hello world"
# or
echo "Hello world" | python infer.py
Use --checkpoint-dir if you saved to a different directory (e.g. python infer.py --checkpoint-dir out "Hello world").
Lexicon-trained checkpoints run windowed inference by default: each <u>…</u> span is predicted in a separate forward pass with --unknown-context-chars of hybrid text on each side (default 48, tag-aligned expansion so tags are not cut; also stored in config.json as unknown_context_chars). Training uses the same windowing by default (one loss example per unknown, teacher-forced gold for earlier unknowns). Use --lexicon-train-full-sentence to train on full hybrid sequences, and --lexicon-full-sentence at inference for a single pass on the whole hybrid. eval_g2p.py accepts the same inference flags.