Find word stress for texts in Ukrainian
Project description
Ukrainian word stress
Word stress is an emphasis we place on a particular syllable of a word as we pronounce it: ма́ма
This package takes text in Ukrainian and adds the stress mark after an accented vowel. This is useful in speech synthesis applications and for preparing text for language learners.
Example
From Python
>>> from ukrainian_word_stress import Stressifier
>>> text = """Потяг зупинився, ми зійшли на платформу. Було тихо, широкі навскісні промені золотили повітря, заважаючи бачити речі такими, якими вони були. Третя по обіді. Жодноі живоі душі. Найкращий час для урочистих відвідин померлих. Взяли в привокзальному торбу вина, рушили вздовж колій, піщаною стежкою."""
>>> stressify = Stressifier()
>>> stressify(text)
'Потяг зупини´вся, ми зійшли´ на платфо´рму. Було´ ти´хо, широ´кі навскі´сні
про´мені золоти´ли пові´тря, заважа´ючи ба´чити ре´чі таки´ми, яки´ми вони´
були´. Тре´тя по обі´ді. Жодноі живоі душі´. Найкра´щий час для урочи´стих
відві´дин поме´рлих. Взя´ли в привокза´льному то´рбу вина, ру´шили вздовж
ко´лій, піща´ною сте´жкою.'
The ukrainian_word_stress.Stressifier class has optional arguments for
fine-graded configuration (see sections below). For example:
>>> from ukrainian_word_stress import Stressifier, StressSymbol
>>> stressify = Stressifier(stress_symbol=StressSymbol.CombiningAcuteAccent)
>>> stressify(text)
'Потяг зупини́вся, ми зійшли́ на платфо́рму. Було́ ти́хо, широ́кі навскі́сні про́мені
золоти́ли пові́тря, заважа́ючи ба́чити ре́чі таки́ми, яки́ми вони́ були́. Тре́тя по
обі́ді. Жодноі живоі душі́. Найкра́щий час для урочи́стих відві́дин поме́рлих. Взя́ли
в привокза́льному то́рбу вина, ру́шили вздовж ко́лій, піща́ною сте́жкою.'
From command-line
$ echo 'Золоті яйця, але нема ні яйця' | ukrainian-word-stress
Золоті´ я´йця, але´ нема´ ні яйця´
Note: this example resolves the two different readings of яйця from
context, which requires the Stanza backend
(pip install ukrainian-word-stress[stanza]). The default lightweight
install skips such ambiguous words instead of guessing — see
Disambiguation modes.
Setup
Requires Python 3.9+.
$ pip install ukrainian-word-stress
This installs the lightweight dictionary-only version (megabytes, no model downloads). It covers the ~98.7% of dictionary word forms that have a single valid stress pattern and skips heteronyms (see Disambiguation modes below).
For the highest accuracy, install the Stanza backend as well:
$ pip install ukrainian-word-stress[stanza]
With Stanza installed, the first call downloads around 500M of Stanza
resources. The default location for this is ~/stanza_resources
Upgrading from 1.x: stanza is no longer installed by default. Use
pip install ukrainian-word-stress[stanza]to keep the previous behavior. Environments that already have stanza installed keep using the Stanza backend automatically. Note that 2.0 also closes a few lookup gaps in both modes (typographic apostrophes, words whose readings all agree on stress), so some words that 1.x left unstressed now receive a stress mark.
Disambiguation modes
Most Ukrainian word forms (98.7% of the 2.9M dictionary entries) have
exactly one valid stress pattern — a dictionary lookup answers them
without any NLP. The rest are heteronyms (за́мок/замо́к) that need context.
The disambiguation parameter controls how they are handled:
-
auto(default): use Stanza if it is installed, otherwise dictionary-only. -
stanza: parse the text with Stanza's POS/morphology pipeline and pick the reading that matches. Best accuracy. Requires the[stanza]extra (PyTorch, ~500MB of models). -
dictionary: lookup only, no dependencies beyond the bundled trie. Unambiguous words are handled identically to the Stanza mode; heteronyms follow theon_ambiguitystrategy (skipby default, i.e. no stress mark rather than a wrong one).
>>> from ukrainian_word_stress import Stressifier, Disambiguation
>>> stressify = Stressifier(disambiguation=Disambiguation.Dictionary)
>>> stressify("Привіт, як справи?")
'Приві´т, як спра´ви?'
Or from the command line:
$ echo 'Привіт, як справи?' | ukrainian-word-stress --disambiguation=dictionary
Offline installation
The dictionary-only mode works fully offline out of the box.
For the Stanza mode on a machine with no internet access (or behind a firewall), the models can be downloaded elsewhere and copied over:
-
On a machine with internet access, run:
python -c "import stanza; stanza.download('uk')"
-
Copy the resulting
~/stanza_resourcesdirectory to the same location on the target machine.
A custom location can be set with the STANZA_RESOURCES_DIR environment
variable on both machines.
Handling ambiguity
Some words have different pronunciation and meaning but share the same spelling. These are so called heteronyms.
In most cases, this happens when a word used in its form (singular/plural, case). For example:
- блохи́ - родовий відмінок в однині ("немає ані блохи́")
- бло́хи - множина називного відмінку ("повсюди були бло́хи")
We handle this more or less correctly by doing morphological and POS text parse
with Stanza (in the stanza disambiguation mode; the dictionary mode
falls back to the strategies below for all heteronyms).
A much smaller category of heteronyms is where words have completely different meanings:
- а́тлас - збірник карт
- атла́с - тканина
Resolving this is much harder and sometimes impossible.
There's no ideal solution to heteronyms ambiguity. We let you decide what to do for such cases. Possible strategies are:
-
skip: do not place stress at all (this is the default). -
all: return all possible options at once. This will look as multiple stress symbols in one word (за´мо´к). -
first: place a stress of the first match with a high chance of being incorrect. Essentially, means a random guess on the heteronyms meaning.
The strategy can be configured via --on-ambiguity parameter of the
command-line utility. In Python, use on_ambiguity parameter of the
ukrainian_word_stress.Stressifier class.
Stress mark symbols
By default, the Unicode Acute Acent symbol is used: “´” (U+00B4).
On print, Combining Acute Acent is more common and visually less intrusive.
This can be turned on by passing "--symbol=combining" to the CLI utility,
or stress_symbol=StressSymbol.CombiningAcuteAccent in the Stressifier class.
Note, that some platforms (Windows, for example) render it incorrectly.
You can also pass custom characters in place of these two:
$ echo 'олені небриті і не голені.' | ukrainian-word-stress --symbol +
о+лені небри+ті і не го+лені.
$ echo 'олені небриті і не голені.' | ukrainian-word-stress --symbol combining
о́лені небри́ті і не го́лені.
Variative stress
Some words allow for multiple stress positions. For example, по́милка and поми́лка are both acceptable. For such words we return double stress:
$ echo помилка | ukrainian-word-stress
по´ми´лка
Debugging and reporting issues
Use the --verbose switch to get info useful for debugging.
If you believe that you found a bug, please open a Github issue
But first, make sure that the bug is not related to heteronyms disambiguation.
For example, if you see that some word lacks accent, add the --on-ambiguity=all
switch to see if this was a heteronym. If the word of question has
multiple accents, that's a heteronym, not a bug:
$ echo замок | ukrainian-word-stress --on-ambiguity=all
за´мо´к
More docs
Project details
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 ukrainian_word_stress-2.0.0.tar.gz.
File metadata
- Download URL: ukrainian_word_stress-2.0.0.tar.gz
- Upload date:
- Size: 7.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f8365a881bacfd822aba3aafc3275e81c7898d57023f5b8398753a7faf5948f
|
|
| MD5 |
34d5f61949802bdcceff02b2fbffafb4
|
|
| BLAKE2b-256 |
855a107af17ca87fc33a80f4d4ce321e69822af73a1b4bb41ceec54fc6f0974e
|
Provenance
The following attestation bundles were made for ukrainian_word_stress-2.0.0.tar.gz:
Publisher:
publish.yml on lang-uk/ukrainian-word-stress
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ukrainian_word_stress-2.0.0.tar.gz -
Subject digest:
0f8365a881bacfd822aba3aafc3275e81c7898d57023f5b8398753a7faf5948f - Sigstore transparency entry: 2205417546
- Sigstore integration time:
-
Permalink:
lang-uk/ukrainian-word-stress@54e2d2ecbba973f3f671e9ab90d77fc10135d6cc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/lang-uk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@54e2d2ecbba973f3f671e9ab90d77fc10135d6cc -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file ukrainian_word_stress-2.0.0-py3-none-any.whl.
File metadata
- Download URL: ukrainian_word_stress-2.0.0-py3-none-any.whl
- Upload date:
- Size: 7.1 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4edc45d311984e5ce9f6f26f72626fb677eb78fbdfb2673f7a97e91855b1d7d7
|
|
| MD5 |
03e8264c81cc588bffca865b1fbd145b
|
|
| BLAKE2b-256 |
0de609910ea5c1494071659dfdc3c16a34e4ec2d883d578fa33bf7e8b9c4b2dd
|
Provenance
The following attestation bundles were made for ukrainian_word_stress-2.0.0-py3-none-any.whl:
Publisher:
publish.yml on lang-uk/ukrainian-word-stress
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ukrainian_word_stress-2.0.0-py3-none-any.whl -
Subject digest:
4edc45d311984e5ce9f6f26f72626fb677eb78fbdfb2673f7a97e91855b1d7d7 - Sigstore transparency entry: 2205417562
- Sigstore integration time:
-
Permalink:
lang-uk/ukrainian-word-stress@54e2d2ecbba973f3f671e9ab90d77fc10135d6cc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/lang-uk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@54e2d2ecbba973f3f671e9ab90d77fc10135d6cc -
Trigger Event:
workflow_dispatch
-
Statement type: