Bangla Heteronym Reader (mT5-small)
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 44) | 93.48% | 93.02% |
| Mean of 3 seeds | 93.36 ± 0.21% | 92.99 ± 0.18% |
Speed per sentence (batch size 1, whole pipeline): 308 ms on a Tesla T4 GPU (fp32), 924 ms on 4 CPU threads. On the GPU it reads about 42 sentences per second at batch size 32.
By mean test accuracy it ranked twelfth of the 12 models in the benchmark. For most uses we recommend bangla-heteronym-banglabert (99.46%, 12.5 ms on a T4).
On words it was not trained on it is much weaker: in the benchmark, the same setup trained without 37 held-out words reached 51.7% on them (mean of 3 seeds).
Usage
The model expects the input format of the benchmark code, 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-mt5-small"), "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 (here the mean probability of the generated tokens) of every heteronym.
model.phoneticize_detailed("আগে কর কাজটা, তারপর আবার কর।")
# ('আগে কর্ কাজটা, তারপর আবার কোরো।',
# [{'word': 'কর', 'position': 4, 'prediction': 'কর্', 'confidence': 0.995},
# {'word': 'কর', 'position': 25, 'prediction': 'কোরো', 'confidence': 0.9497}])
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 phonetic: and the sentence with the word marked:
phonetic: আগে @ কর @ কাজটা, তারপর আবার কর।.
mT5-small rewrites the whole sentence with the reading in place of the word, and the word at the marked position is the answer.
The T5 tokenizer cannot keep the ZWNJ, so it is removed from the input, and the output word is mapped back to the reading with its ZWNJ.
Training: fine-tuned from google/mt5-small on 14 sentences per reading, AdamW, learning rate 3e-4, batch size 16, fp32, at most 15 epochs with early stopping on development accuracy, on one Tesla T4.
Limitations
- Trained only on the heteronyms in the dataset. It can return a reading that is not in the word's list.
- The sentences were written for the dataset, so accuracy on real text can be lower.
- Slow, because it generates the sentence token by token (308 ms per sentence on a T4, against 12.5 ms for the BanglaBERT classifier).
- It was still improving at the 15-epoch limit, so longer training may help.
License
Apache 2.0, the license of the base model google/mt5-small. The weights were modified by fine-tuning them on the bangla-heteronyms dataset.
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