Bangla Heteronym Reader (XLM-R-large, candidate scorer)
Many Bangla words are written the same way but read differently depending on the sentence. This model reads the sentence and picks the right pronunciation, for use in the front end of a Bangla text-to-speech system.
| Sentence | Word | Reading |
|---|---|---|
| সময়মতো কর না দিলে জরিমানা গুনতে হবে। (tax) | কর | কর্ |
| তুমি আমার জন্য একটু অপেক্ষা কর। (do, now) | কর | করো |
| আগে কর কাজটা, তারপর আবার কর। (do, later) | কর | কোরো |
It covers the heteronyms of the
bangla-heteronyms dataset. Each reading is a
respelling in Bangla script, and a visible hasanta is written as hasanta + ZWNJ (কর্).
Results
Test set of the main split: 1,104 sentences, 3 per reading.
| Accuracy | Macro-F1 | |
|---|---|---|
| This checkpoint (seed 43) | 97.10% | 96.90% |
| Mean of 3 seeds | 83.30 ± 23.82% | 81.52 ± 26.59% |
Speed per sentence (batch size 1, whole pipeline): 19.9 ms on a Tesla T4 GPU (fp16), 175 ms on 4 CPU threads. On the GPU it reads about 310 sentences per second at batch size 32.
The XLM-R-large classifier reached 98.43% with the same data. For most uses we recommend bangla-heteronym-banglabert (99.46%, 12.5 ms on a T4).
Because the model reads each reading itself, candidate scoring also works for words it was not trained on. In the benchmark, the same setup trained without 37 held-out words reached 62.0% on them (mean of 3 seeds).
Usage
The model has a small custom head, so load it with the code from the GitHub repository:
git clone https://github.com/kawshikbuet17/bangla-heteronym-benchmark
cd bangla-heteronym-benchmark
pip install -r requirements.txt
from huggingface_hub import snapshot_download
from src.predict import Predictor
model = Predictor.load(snapshot_download("kawshikbuet17/bangla-heteronym-xlm-roberta-large-candidate"), "cuda") # or "cpu"
Sample outputs
These are the real outputs of this checkpoint. The cards of all models in the benchmark use the same sentences, so the outputs can be compared.
phoneticize(text): replaces every heteronym in the text with its reading. Everything else stays unchanged.
model.phoneticize("আগে কর কাজটা, তারপর আবার কর।")
# 'আগে করো কাজটা, তারপর আবার করো।'
model.phoneticize("আজ আকাশ পরিষ্কার।") # no heteronym
# 'আজ আকাশ পরিষ্কার।'
phoneticize_detailed(text): the same text, plus the position, reading and confidence of every heteronym.
model.phoneticize_detailed("আগে কর কাজটা, তারপর আবার কর।")
# ('আগে করো কাজটা, তারপর আবার করো।',
# [{'word': 'কর', 'position': 4, 'prediction': 'করো', 'confidence': 0.5365},
# {'word': 'কর', 'position': 25, 'prediction': 'করো', 'confidence': 0.5102}])
predict(sentence, word): the reading of one heteronym in a sentence (its first occurrence).
model.predict("সময়মতো কর না দিলে জরিমানা গুনতে হবে।", "কর")
# 'কর্'
predict_marked(text): the reading of the word you mark with [ ]. Use it when the word occurs more than once.
model.predict_marked("সরকার কর বাড়িয়েছে, তাই হিসাবটা আবার [কর]।")
# 'কর্'
phoneticize_marked(text): replaces only the marked words and removes the marks.
model.phoneticize_marked("সরকার কর বাড়িয়েছে, তাই হিসাবটা আবার [কর]।")
# 'সরকার কর বাড়িয়েছে, তাই হিসাবটা আবার কর্।'
Batch versions: every method has a _batch version that takes a list and sends all inputs through the model
together, which is much faster for many sentences.
model.phoneticize_batch(["আগে কর কাজটা, তারপর আবার কর।", "বিকেলে মাঠে বল নিয়ে যাব।"])
# ['আগে করো কাজটা, তারপর আবার করো।', 'বিকেলে মাঠে বল্ নিয়ে যাব।']
model.predict_batch([("সময়মতো কর না দিলে জরিমানা গুনতে হবে।", "কর"), ("বিকেলে মাঠে বল নিয়ে যাব।", "বল")])
# ['কর্', 'বল্']
model.predict_marked_batch(["তুমি একটু অপেক্ষা [কর]।", "বিকেলে মাঠে [বল] নিয়ে যাব।"])
# ['কোরো', 'বল্']
model.phoneticize_marked_batch(["সরকার [কর] বাড়িয়েছে।", "সে [বল] নিয়ে এল, তুমি কথাটা বল।"])
# ['সরকার কর্ বাড়িয়েছে।', 'সে বল্ নিয়ে এল, তুমি কথাটা বল।']
For a word that is not in the dataset, predict raises a ValueError. The known words and their readings are in
model.hconfig["candidates"], for example model.hconfig["candidates"]["কর"] gives ['কর্', 'করো', 'কোরো'].
How it works
The input is the sentence with the word marked, paired with each of the word's readings:
আগে @ কর @ কাজটা, তারপর আবার কর। + কর্ / করো / কোরো.
XLM-R-large encodes each pair, and a linear layer on the opening marker gives it a score. The reading with the highest score wins.
Training: fine-tuned from xlm-roberta-large on 14 sentences per reading, AdamW, learning rate 2e-5, batch size 32, fp16, at most 10 epochs with early stopping on development accuracy, on one Tesla T4.
Limitations
- The code covers only the heteronyms in the dataset, although the model itself can score the readings of other words.
- The sentences were written for the dataset, so accuracy on real text can be lower.
- Training is unstable with the benchmark recipe: the three seeds reached 97.01%, 97.10%, 55.80%. This checkpoint is the best one by development accuracy. A lower learning rate or a longer warm-up might help.
License
MIT, the license of the base model xlm-roberta-large. The LICENSE file keeps the original copyright notice.
Prepared by
Kawshik Kumar Paul
Senior Software Engineer | Researcher
Department of Computer Science and Engineering (CSE)
Bangladesh University of Engineering and Technology (BUET)
Email: kawshikbuet17@gmail.com