ghana-english-g2p
Ghanaian English text to IPA. A 104,623-word Ghanaian pronunciation lexicon is
consulted first; espeak-english handles
whatever is left over.
pip install ghana-english-g2p
from ghana_english_g2p import GhanaEnglishG2P
g2p = GhanaEnglishG2P()
g2p.ipa("Kwabena went to Achimota")
# 'kwabɪna wɛnt tuː atʃimota'
g2p.ipa("Kwabena went to Achimota", sep=" ")
# 'k w a b ɪ n a w ɛ n t t uː a tʃ i m o t a'
ghana-english-g2p "The Bank of Ghana raised the policy rate."
Why this exists
espeak reads Ghanaian names as if they were English spelling. It does not fail loudly — it returns a confident, fluent, wrong pronunciation:
| word | espeak alone | this lexicon |
|---|---|---|
| Kwabena | k w e ɪ b n ə |
k w a b ɪ n a |
| Achimota | ɐ tʃ ɪ m o ʊ ɾ ə |
a tʃ i m o t a |
| Okuapenhene | o ʊ k j uː e ɪ p ə n h iː n |
o k w a p ɛ n h ɛ n ɛ |
| Bawumia | b æ w uː m i ə |
b a w u m i a |
| Twumasi | t w uː m ɑː s i |
t w u m a s i |
| Nyantakyi | n a ɪ ɐ n t æ k ɪ i |
ɲ a n t a tɕ i |
Every one of these is a name a Ghanaian TTS or ASR system will meet on its first day. The lexicon is what makes the output Ghanaian; espeak is the general-purpose fallback behind it, not the other way round.
Rule-based conversion is not an option for this language pair, and that is measurable.
Running ghana-g2p's Twi rules over 4,000 words
of this lexicon gives 7.6% exact-match and 50.1% phoneme error — Ghanaian names come
out roughly right, English words are destroyed (concerts → tʃ o n tʃ e ɾ t s). Twi has
a shallow orthography and rules suit it; English does not, which is the reason
pronunciation dictionaries exist at all.
One notation, both paths
espeak emits stress marks and a run-together transcription; the lexicon stores spaced phones. Both go through the same segmenter, so you cannot tell from the symbols which path produced a word:
from ghana_english_g2p import segment
segment("ɐdmˈɪkstʃɚ") # espeak -> ['ɐ','d','m','ɪ','k','s','tʃ','ɚ']
segment("ɡ ɑː n ə") # lexicon -> ['ɡ','ɑː','n','ə']
segment("ɡɑːnə") # either -> ['ɡ','ɑː','n','ə']
The conventions, applied to both sources:
stress marks ˈ ˌ |
removed |
tie bars d͡ʒ |
removed — dʒ |
affricates tʃ dʒ ts dz kp ɡb |
one phone |
diphthongs aɪ oʊ eɪ |
two phones — a ɪ |
length uː |
stays on its vowel |
The inventory is 63 phones, derived from the data rather than declared up front.
Provenance
Which words the lexicon actually covered is part of the output, not something to guess at:
r = g2p.convert("Kwabena discussed decarbonisation")
r.ipa # 'kwabɪna dɪskʌst dᵻkɑːɹbənəzeɪʃən'
r.words # ['Kwabena', 'discussed', 'decarbonisation']
r.sources # ['lexicon', 'lexicon', 'espeak']
r.oov # ['decarbonisation']
r.coverage # 0.667
To measure true lexicon coverage with no fallback masking it:
GhanaEnglishG2P(use_espeak=False) # unknown words return [], source 'unknown'
ghana-english-g2p --show-source "Kwabena discussed cryptocurrency"
Measured coverage
Against the twi-health-asr transcripts, which contributed nothing to the lexicon: 77.9% of 127,846 tokens are covered by lookup alone.
Read that as a lower bound. That corpus is Twi-heavy spontaneous speech, so much of the
remainder is Twi vocabulary (yareɛ, ɛneɛ, sɛdeɛ) and single letters, which a
Ghanaian English lexicon is not meant to hold. For Twi proper use
ghana-g2p, whose rules cover 42 Ghanaian
languages.
Extending the lexicon
g2p = GhanaEnglishG2P(lexicon={"Nkrumah": "ŋ k r u m a"})
Entries are merged over the packaged lexicon, so this overrides as well as extends. IPA may be written spaced or run-together — it goes through the same segmenter.
Where the lexicon came from
Headwords are the unique vocabulary of three Ghanaian sources:
| source | contributes |
|---|---|
| ghana-named-entities | people, places, organisations |
| GhanaNouns | Ghanaian English nouns, incl. health and agriculture |
| Ghana English-Twi code-switching speech | transcript vocabulary |
Deduplication is case-insensitive and prefers the capitalised form, so named entities keep
their casing on the way in. Pronunciations were generated with Gemini 3.6 Flash, prompted
for the pronunciation used in Ghana and told explicitly not to anglicise Ghanaian names.
Accent variants are collapsed to the Ghanaian form; only genuine homographs (read, lead)
keep two entries.
These transcriptions are model-generated and have not been reviewed by a phonetician.
Known inconsistencies survive in the data: tɕ appears where tʃ is meant (Nyantakyi),
and r/ɹ are not used consistently across entries. Corrections by PR are welcome — the
lexicon is a plain TSV.
To rebuild it from a fresh source file:
python tools/build_lexicon.py path/to/ipa.jsonl
Notes
espeak-englishpins espeak-ng to 1.51 and bundles it, so there is no system dependency and no drift between machines.- The lexicon loads once and is cached; it is 0.72 MB gzipped.
- Lookup is case-insensitive. Punctuation is dropped. Digits inside a word are kept
(
COVID19); bare numerals are left to espeak, which reads them out (2024→t uː θ a ʊ z ə n d t w ɛ n t i f oː ɹ).
Licence
MIT.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ghana_english_g2p-0.1.0.tar.gz.
File metadata
- Download URL: ghana_english_g2p-0.1.0.tar.gz
- Upload date:
- Size: 734.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5677866cb16127c0187199c02cba0d3f4c5980a26df8c9db3a3d398ba67814fa
|
|
| MD5 |
50652aea165dcb9657385f4f906404dd
|
|
| BLAKE2b-256 |
1e266b3fd9253ebda86e35a64107a659ef4d9d5a71a3a05232c729ce4c3beab4
|
File details
Details for the file ghana_english_g2p-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ghana_english_g2p-0.1.0-py3-none-any.whl
- Upload date:
- Size: 729.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9e0debbf889a2adda3b8a80d5e7b8662cc0fee6d6abceb5d141863ae15552c2
|
|
| MD5 |
965821e83ffdd6179bc9752c6fabfa59
|
|
| BLAKE2b-256 |
9f1c93dc2712216f98dc8ee6924b230697fb05fb76acd28fe4f92061f65b6df9
|