diff --git a/Jenkinsfile b/Jenkinsfile index f0ac60196..9b60089b1 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -27,7 +27,7 @@ pipeline { HY_TN_CACHE='/home/jenkins/TestData/text_norm/ci/grammars/03-12-24-0' MR_TN_CACHE='/home/jenkins/TestData/text_norm/ci/grammars/03-12-24-1' JA_TN_CACHE='/home/jenkins/TestData/text_norm/ci/grammars/10-17-24-1' - HI_TN_CACHE='/home/jenkins/TestData/text_norm/ci/grammars/10-31-25-0' + HI_TN_CACHE='/home/jenkins/TestData/text_norm/ci/grammars/01-29-26-0' DEFAULT_TN_CACHE='/home/jenkins/TestData/text_norm/ci/grammars/06-08-23-0' } stages { diff --git a/nemo_text_processing/text_normalization/hi/data/address/__init__.py b/nemo_text_processing/text_normalization/hi/data/address/__init__.py new file mode 100644 index 000000000..4fc25d0d3 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/address/__init__.py @@ -0,0 +1,13 @@ +# Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/nemo_text_processing/text_normalization/hi/data/address/cities.tsv b/nemo_text_processing/text_normalization/hi/data/address/cities.tsv new file mode 100644 index 000000000..0199bf0cb --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/address/cities.tsv @@ -0,0 +1,36 @@ +अमरावती +ईटानगर +दिसपुर +पटना +रायपुर +पणजी +गांधीनगर +चंडीगढ़ +शिमला +रांची +बेंगलुरु +तिरुवनंतपुरम +भोपाल +मुंबई +इम्फाल +शिलांग +आइजोल +कोहिमा +भुवनेश्वर +जयपुर +गंगटोक +चेन्नई +हैदराबाद +अगरतला +लखनऊ +देहरादून +कोलकाता +पोर्ट ब्लेयर +दमन +नई दिल्ली +श्रीनगर +जम्मू +लेह +कारगिल +कवरत्ती +पुडुचेरी diff --git a/nemo_text_processing/text_normalization/hi/data/address/context.tsv b/nemo_text_processing/text_normalization/hi/data/address/context.tsv new file mode 100644 index 000000000..9faadaa3b --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/address/context.tsv @@ -0,0 +1,48 @@ +हाउस +प्लॉट +बूथ +अपार्टमेंट +फ्लैट +यूनिट +टावर +कॉम्प्लेक्स +मंजिल +फ्लोर +ब्लॉक +सेक्टर +फेज +रोड +सड़क +मार्ग +स्ट्रीट +गली +राजमार्ग +ड्राइव +डिस्ट्रिक्ट +बाईपास +हाइवे +पार्कवे +कॉलोनी +नगर +पार्क +एस्टेट +बोलवार्ड +मार्केट +सेंटर +पिन +गांव +पास +ब्रिगेड +नियर +स्क्वेर +मॉल +टॉवर +इंस्टीट्यूट +पिलर +मेट्रो +एवेन्यू +वेस्ट +सामने +पीछे +वीया +आर डी \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/address/en_to_hi_mapping.tsv b/nemo_text_processing/text_normalization/hi/data/address/en_to_hi_mapping.tsv new file mode 100644 index 000000000..15929b547 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/address/en_to_hi_mapping.tsv @@ -0,0 +1,2 @@ +street स्ट्रीट +southern सदर्न \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/address/letters.tsv b/nemo_text_processing/text_normalization/hi/data/address/letters.tsv new file mode 100644 index 000000000..68889ca3f --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/address/letters.tsv @@ -0,0 +1,26 @@ +A ए +B बी +C सी +D डी +E ई +F एफ +G जी +H एच +I आई +J जे +K के +L एल +M एम +N एन +O ओ +P पी +Q क्यू +R आर +S एस +T टी +U यू +V वी +W डब्ल्यू +X एक्स +Y वाई +Z ज़ेड \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/address/special_characters.tsv b/nemo_text_processing/text_normalization/hi/data/address/special_characters.tsv new file mode 100644 index 000000000..ca5b068bd --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/address/special_characters.tsv @@ -0,0 +1,2 @@ +- हाइफ़न +/ बटा \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/address/states.tsv b/nemo_text_processing/text_normalization/hi/data/address/states.tsv new file mode 100644 index 000000000..1e2b6c358 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/address/states.tsv @@ -0,0 +1,36 @@ +आंध्र प्रदेश +अरुणाचल प्रदेश +असम +बिहार +छत्तीसगढ़ +गोवा +गुजरात +हरियाणा +हिमाचल प्रदेश +झारखंड +कर्नाटक +केरल +मध्य प्रदेश +महाराष्ट्र +मणिपुर +मेघालय +मिज़ोरम +नागालैंड +ओडिशा +पंजाब +राजस्थान +सिक्किम +तमिलनाडु +तेलंगाना +त्रिपुरा +उत्तर प्रदेश +उत्तराखंड +पश्चिम बंगाल +अंडमान और निकोबार द्वीप समूह +चंडीगढ़ +दादरा और नगर हवेली और दमन और दीव +दिल्ली +जम्मू और कश्मीर +लद्दाख +लक्षद्वीप +पुडुचेरी diff --git a/nemo_text_processing/text_normalization/hi/data/date/days.tsv b/nemo_text_processing/text_normalization/hi/data/date/days.tsv index b210f5207..633e2aec0 100644 --- a/nemo_text_processing/text_normalization/hi/data/date/days.tsv +++ b/nemo_text_processing/text_normalization/hi/data/date/days.tsv @@ -29,3 +29,34 @@ २९ उनतीस ३० तीस ३१ इकतीस +01 एक +02 दो +03 तीन +04 चार +05 पाँच +06 छः +07 सात +08 आठ +09 नौ +10 दस +11 ग्यारह +12 बारह +13 तेरह +14 चौदह +15 पंद्रह +16 सोलह +17 सत्रह +18 अठारह +19 उन्नीस +20 बीस +21 इक्कीस +22 बाईस +23 तेईस +24 चौबीस +25 पच्चीस +26 छब्बीस +27 सत्ताईस +28 अट्ठाईस +29 उनतीस +30 तीस +31 इकतीस \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/date/months.tsv b/nemo_text_processing/text_normalization/hi/data/date/months.tsv index 8b27041ac..af770dafc 100644 --- a/nemo_text_processing/text_normalization/hi/data/date/months.tsv +++ b/nemo_text_processing/text_normalization/hi/data/date/months.tsv @@ -10,3 +10,15 @@ १० अक्टूबर ११ नवंबर १२ दिसंबर +01 जनवरी +02 फ़रवरी +03 मार्च +04 अप्रैल +05 मई +06 जून +07 जुलाई +08 अगस्त +09 सितंबर +10 अक्टूबर +11 नवंबर +12 दिसंबर \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/measure/quarterly_units_map.tsv b/nemo_text_processing/text_normalization/hi/data/measure/quarterly_units_map.tsv index dc20bcb21..e190a80ef 100644 --- a/nemo_text_processing/text_normalization/hi/data/measure/quarterly_units_map.tsv +++ b/nemo_text_processing/text_normalization/hi/data/measure/quarterly_units_map.tsv @@ -8,4 +8,3 @@ hp हॉर्सपॉवर d दिन month महीना months महीने - diff --git a/nemo_text_processing/text_normalization/hi/data/measure/unit_year_formal.tsv b/nemo_text_processing/text_normalization/hi/data/measure/unit_year_formal.tsv new file mode 100644 index 000000000..a3c7b2162 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/measure/unit_year_formal.tsv @@ -0,0 +1 @@ +yr वर्ष diff --git a/nemo_text_processing/text_normalization/hi/data/numbers/digit.tsv b/nemo_text_processing/text_normalization/hi/data/numbers/digit.tsv index 2ab9af461..6bacb7fc3 100644 --- a/nemo_text_processing/text_normalization/hi/data/numbers/digit.tsv +++ b/nemo_text_processing/text_normalization/hi/data/numbers/digit.tsv @@ -7,3 +7,12 @@ ७ सात ८ आठ ९ नौ +1 एक +2 दो +3 तीन +4 चार +5 पाँच +6 छह +7 सात +8 आठ +9 नौ \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/numbers/teens_and_ties_en.tsv b/nemo_text_processing/text_normalization/hi/data/numbers/teens_and_ties_en.tsv new file mode 100644 index 000000000..59071c8e0 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/numbers/teens_and_ties_en.tsv @@ -0,0 +1,90 @@ +10 दस +11 ग्यारह +12 बारह +13 तेरह +14 चौदह +15 पंद्रह +16 सोलह +17 सत्रह +18 अठारह +19 उन्नीस +20 बीस +21 इक्कीस +22 बाईस +23 तेईस +24 चौबीस +25 पच्चीस +26 छब्बीस +27 सत्ताईस +28 अट्ठाईस +29 उनतीस +30 तीस +31 इकतीस +32 बत्तीस +33 तैंतीस +34 चौंतीस +35 पैंतीस +36 छत्तीस +37 सैंतीस +38 अड़तीस +39 उनतालीस +40 चालीस +41 इकतालीस +42 बयालीस +43 तैंतालीस +44 चौवालीस +45 पैंतालीस +46 छियालीस +47 सैंतालीस +48 अड़तालीस +49 उनचास +50 पचास +51 इक्यावन +52 बावन +53 तिरेपन +54 चौवन +55 पचपन +56 छप्पन +57 सत्तावन +58 अट्ठावन +59 उनसठ +60 साठ +61 इकसठ +62 बासठ +63 तिरेसठ +64 चौंसठ +65 पैंसठ +66 छियासठ +67 सड़सठ +68 अड़सठ +69 उनहत्तर +70 सत्तर +71 इकहत्तर +72 बहत्तर +73 तिहत्तर +74 चौहत्तर +75 पचहत्तर +76 छिहत्तर +77 सतहत्तर +78 अठहत्तर +79 उनासी +80 अस्सी +81 इक्यासी +82 बयासी +83 तिरासी +84 चौरासी +85 पचासी +86 छियासी +87 सत्तासी +88 अट्ठासी +89 नवासी +90 नब्बे +91 इक्यानबे +92 बानबे +93 तिरानबे +94 चौरानबे +95 पंचानबे +96 छियानबे +97 सत्तानबे +98 अट्ठानबे +99 निन्यानबे diff --git a/nemo_text_processing/text_normalization/hi/data/numbers/zero.tsv b/nemo_text_processing/text_normalization/hi/data/numbers/zero.tsv index 0735899fe..0e0c50b9b 100644 --- a/nemo_text_processing/text_normalization/hi/data/numbers/zero.tsv +++ b/nemo_text_processing/text_normalization/hi/data/numbers/zero.tsv @@ -1 +1,2 @@ ० शून्य +0 शून्य \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/ordinal/en_to_hi_digit.tsv b/nemo_text_processing/text_normalization/hi/data/ordinal/en_to_hi_digit.tsv new file mode 100644 index 000000000..a89e99b3c --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/ordinal/en_to_hi_digit.tsv @@ -0,0 +1,10 @@ +0 ० +1 १ +2 २ +3 ३ +4 ४ +5 ५ +6 ६ +7 ७ +8 ८ +9 ९ diff --git a/nemo_text_processing/text_normalization/hi/data/ordinal/exceptions.tsv b/nemo_text_processing/text_normalization/hi/data/ordinal/exceptions.tsv index bfe5738d0..1f14d3161 100644 --- a/nemo_text_processing/text_normalization/hi/data/ordinal/exceptions.tsv +++ b/nemo_text_processing/text_normalization/hi/data/ordinal/exceptions.tsv @@ -6,7 +6,45 @@ ३री तीसरी ४था चौथा ४थी चौथी -५वां पाँचवां -५वीं पाँचवीं ६ठा छठा ६ठी छठी +1ला पहला +1ली पहली +2रा दूसरा +2री दूसरी +3रा तीसरा +3री तीसरी +4था चौथा +4थी चौथी +6ठा छठा +6ठी छठी +१st फ़र्स्ट +२nd सेकंड +३rd थर्ड +४th फ़ोर्थ +५th फ़िफ्थ +६th सिक्स्थ +७th सेवंथ +८th एटथ +९th नाइंथ +१०th टेंथ +११th इलेवंथ +१२th ट्वेल्फ्थ +१३th थर्टींथ +१४th फोर्टींथ +१५th फिफ्टींथ +1st फ़र्स्ट +2nd सेकंड +3rd थर्ड +4th फ़ोर्थ +5th फ़िफ्थ +6th सिक्स्थ +7th सेवंथ +8th एटथ +9th नाइंथ +10th टेंथ +11th इलेवंथ +12th ट्वेल्फ्थ +13th थर्टींथ +14th फोर्टींथ +15th फिफ्टींथ \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/time/hours.tsv b/nemo_text_processing/text_normalization/hi/data/time/hours.tsv index dd8623284..7d6e552f3 100644 --- a/nemo_text_processing/text_normalization/hi/data/time/hours.tsv +++ b/nemo_text_processing/text_normalization/hi/data/time/hours.tsv @@ -23,3 +23,28 @@ २२ बाईस २३ तेईस २४ चौबीस +0 शून्य +1 एक +2 दो +3 तीन +4 चार +5 पाँच +6 छह +7 सात +8 आठ +9 नौ +10 दस +11 ग्यारह +12 बारह +13 तेरह +14 चौदह +15 पंद्रह +16 सोलह +17 सत्रह +18 अठारह +19 उन्नीस +20 बीस +21 इक्कीस +22 बाईस +23 तेईस +24 चौबीस \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/time/minutes.tsv b/nemo_text_processing/text_normalization/hi/data/time/minutes.tsv index 6689d8070..895ab481a 100644 --- a/nemo_text_processing/text_normalization/hi/data/time/minutes.tsv +++ b/nemo_text_processing/text_normalization/hi/data/time/minutes.tsv @@ -58,3 +58,63 @@ ५८ अट्ठावन ५९ उनसठ ६० साठ +01 एक +02 दो +03 तीन +04 चार +05 पाँच +06 छह +07 सात +08 आठ +09 नौ +10 दस +11 ग्यारह +12 बारह +13 तेरह +14 चौदह +15 पंद्रह +16 सोलह +17 सत्रह +18 अठारह +19 उन्नीस +20 बीस +21 इक्कीस +22 बाईस +23 तेईस +24 चौबीस +25 पच्चीस +26 छब्बीस +27 सत्ताईस +28 अट्ठाईस +29 उनतीस +30 तीस +31 इकतीस +32 बत्तीस +33 तैंतीस +34 चौंतीस +35 पैंतीस +36 छत्तीस +37 सैंतीस +38 अड़तीस +39 उनतालीस +40 चालीस +41 इकतालीस +42 बयालीस +43 तैंतालीस +44 चौवालीस +45 पैंतालीस +46 छियालीस +47 सैंतालीस +48 अड़तालीस +49 उनचास +50 पचास +51 इक्यावन +52 बावन +53 तिरेपन +54 चौवन +55 पचपन +56 छप्पन +57 सत्तावन +58 अट्ठावन +59 उनसठ +60 साठ \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/time/seconds.tsv b/nemo_text_processing/text_normalization/hi/data/time/seconds.tsv index 6689d8070..895ab481a 100644 --- a/nemo_text_processing/text_normalization/hi/data/time/seconds.tsv +++ b/nemo_text_processing/text_normalization/hi/data/time/seconds.tsv @@ -58,3 +58,63 @@ ५८ अट्ठावन ५९ उनसठ ६० साठ +01 एक +02 दो +03 तीन +04 चार +05 पाँच +06 छह +07 सात +08 आठ +09 नौ +10 दस +11 ग्यारह +12 बारह +13 तेरह +14 चौदह +15 पंद्रह +16 सोलह +17 सत्रह +18 अठारह +19 उन्नीस +20 बीस +21 इक्कीस +22 बाईस +23 तेईस +24 चौबीस +25 पच्चीस +26 छब्बीस +27 सत्ताईस +28 अट्ठाईस +29 उनतीस +30 तीस +31 इकतीस +32 बत्तीस +33 तैंतीस +34 चौंतीस +35 पैंतीस +36 छत्तीस +37 सैंतीस +38 अड़तीस +39 उनतालीस +40 चालीस +41 इकतालीस +42 बयालीस +43 तैंतालीस +44 चौवालीस +45 पैंतालीस +46 छियालीस +47 सैंतालीस +48 अड़तालीस +49 उनचास +50 पचास +51 इक्यावन +52 बावन +53 तिरेपन +54 चौवन +55 पचपन +56 छप्पन +57 सत्तावन +58 अट्ठावन +59 उनसठ +60 साठ \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/graph_utils.py b/nemo_text_processing/text_normalization/hi/graph_utils.py index 5bbc736fd..e8543d9ad 100644 --- a/nemo_text_processing/text_normalization/hi/graph_utils.py +++ b/nemo_text_processing/text_normalization/hi/graph_utils.py @@ -30,6 +30,10 @@ NEMO_HI_DIGIT = pynini.union("०", "१", "२", "३", "४", "५", "६", "७", "८", "९").optimize() NEMO_HI_NON_ZERO = pynini.union("१", "२", "३", "४", "५", "६", "७", "८", "९").optimize() NEMO_HI_ZERO = "०" +# Combined Hindi and Arabic digits for graphs that need to accept both +NEMO_ALL_DIGIT = pynini.union(NEMO_HI_DIGIT, NEMO_DIGIT).optimize() +NEMO_ALL_ZERO = pynini.union("०", "0").optimize() +NEMO_ALL_NON_ZERO = pynini.union(NEMO_HI_NON_ZERO, "1", "2", "3", "4", "5", "6", "7", "8", "9").optimize() HI_DEDH = "डेढ़" # 1.5 HI_DHAI = "ढाई" # 2.5 @@ -37,6 +41,38 @@ HI_SADHE = "साढ़े" # half more (X.5) HI_PAUNE = "पौने" # quarter less (0.75) +# Hindi decimal representations +HI_POINT_FIVE = ".५" # .5 +HI_ONE_POINT_FIVE = "१.५" # 1.5 +HI_TWO_POINT_FIVE = "२.५" # 2.5 +HI_DECIMAL_25 = ".२५" # .25 +HI_DECIMAL_75 = ".७५" # .75 + +# Arabic/English decimal representations +EN_POINT_FIVE = ".5" +EN_ONE_POINT_FIVE = "1.5" +EN_TWO_POINT_FIVE = "2.5" +EN_DECIMAL_25 = ".25" +EN_DECIMAL_75 = ".75" + +# Combined Hindi and English decimal patterns +POINT_FIVE = pynini.union(HI_POINT_FIVE, EN_POINT_FIVE).optimize() +ONE_POINT_FIVE = pynini.union(HI_ONE_POINT_FIVE, EN_ONE_POINT_FIVE).optimize() +TWO_POINT_FIVE = pynini.union(HI_TWO_POINT_FIVE, EN_TWO_POINT_FIVE).optimize() +DECIMAL_25 = pynini.union(HI_DECIMAL_25, EN_DECIMAL_25).optimize() +DECIMAL_75 = pynini.union(HI_DECIMAL_75, EN_DECIMAL_75).optimize() + +# Symbol constants +HI_BY = "बाई" +LOWERCASE_X = "x" +UPPERCASE_X = "X" +ASTERISK = "*" +HYPHEN = "-" +SLASH = "/" +COMMA = "," +PERIOD = "." +HI_PERIOD = "।" + NEMO_LOWER = pynini.union(*string.ascii_lowercase).optimize() NEMO_UPPER = pynini.union(*string.ascii_uppercase).optimize() NEMO_ALPHA = pynini.union(NEMO_LOWER, NEMO_UPPER).optimize() diff --git a/nemo_text_processing/text_normalization/hi/taggers/cardinal.py b/nemo_text_processing/text_normalization/hi/taggers/cardinal.py index f361416f4..c29ccaa59 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/cardinal.py +++ b/nemo_text_processing/text_normalization/hi/taggers/cardinal.py @@ -15,7 +15,12 @@ import pynini from pynini.lib import pynutil -from nemo_text_processing.text_normalization.hi.graph_utils import GraphFst, insert_space +from nemo_text_processing.text_normalization.hi.graph_utils import ( + NEMO_ALL_DIGIT, + NEMO_ALL_ZERO, + GraphFst, + insert_space, +) from nemo_text_processing.text_normalization.hi.utils import get_abs_path @@ -34,15 +39,23 @@ def __init__(self, deterministic: bool = True, lm: bool = False): digit = pynini.string_file(get_abs_path("data/numbers/digit.tsv")) zero = pynini.string_file(get_abs_path("data/numbers/zero.tsv")) - teens_ties = pynini.string_file(get_abs_path("data/numbers/teens_and_ties.tsv")) + # Load both Hindi (Devanagari) and English (Arabic) number mappings + teens_ties_hi = pynini.string_file(get_abs_path("data/numbers/teens_and_ties.tsv")) + teens_ties_en = pynini.string_file(get_abs_path("data/numbers/teens_and_ties_en.tsv")) + teens_ties = pynini.union(teens_ties_hi, teens_ties_en) teens_and_ties = pynutil.add_weight(teens_ties, -0.1) self.digit = digit self.zero = zero self.teens_and_ties = teens_and_ties + # Single digit graph for digit-by-digit reading + # e.g., "०७३" -> "शून्य सात तीन" + single_digit_graph = digit | zero + self.single_digits_graph = single_digit_graph + pynini.closure(insert_space + single_digit_graph) + def create_graph_suffix(digit_graph, suffix, zeros_counts): - zero = pynutil.add_weight(pynutil.delete("०"), -0.1) + zero = pynutil.add_weight(pynutil.delete(NEMO_ALL_ZERO), -0.1) if zeros_counts == 0: return digit_graph + suffix @@ -50,7 +63,7 @@ def create_graph_suffix(digit_graph, suffix, zeros_counts): def create_larger_number_graph(digit_graph, suffix, zeros_counts, sub_graph): insert_space = pynutil.insert(" ") - zero = pynutil.add_weight(pynutil.delete("०"), -0.1) + zero = pynutil.add_weight(pynutil.delete(NEMO_ALL_ZERO), -0.1) if zeros_counts == 0: return digit_graph + suffix + insert_space + sub_graph @@ -304,7 +317,7 @@ def create_larger_number_graph(digit_graph, suffix, zeros_counts, sub_graph): graph_leading_zero = zero + insert_space + single_digit graph_leading_zero = pynutil.add_weight(graph_leading_zero, 0.5) - final_graph = ( + graph_without_leading_zeros = ( digit | zero | teens_and_ties @@ -325,8 +338,18 @@ def create_larger_number_graph(digit_graph, suffix, zeros_counts, sub_graph): | graph_ten_padmas | graph_shankhs | graph_ten_shankhs - | graph_leading_zero ) + self.graph_without_leading_zeros = graph_without_leading_zeros.optimize() + + # Handle numbers with leading zeros by reading digit-by-digit + # e.g., English/arabic "073" -> "शून्य सात तीन", Hindi/devnagri "००५" -> "शून्य शून्य पाँच" + cardinal_with_leading_zeros = pynini.compose( + NEMO_ALL_ZERO + pynini.closure(NEMO_ALL_DIGIT), self.single_digits_graph + ) + cardinal_with_leading_zeros = pynutil.add_weight(cardinal_with_leading_zeros, 0.5) + + # Full graph including leading zeros - for standalone cardinal matching + final_graph = graph_without_leading_zeros | cardinal_with_leading_zeros optional_minus_graph = pynini.closure(pynutil.insert("negative: ") + pynini.cross("-", "\"true\" "), 0, 1) diff --git a/nemo_text_processing/text_normalization/hi/taggers/date.py b/nemo_text_processing/text_normalization/hi/taggers/date.py index b25abcac6..da917f3de 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/date.py +++ b/nemo_text_processing/text_normalization/hi/taggers/date.py @@ -16,9 +16,9 @@ from pynini.lib import pynutil from nemo_text_processing.text_normalization.hi.graph_utils import ( - NEMO_HI_DIGIT, - NEMO_HI_NON_ZERO, - NEMO_HI_ZERO, + NEMO_ALL_DIGIT, + NEMO_ALL_NON_ZERO, + NEMO_ALL_ZERO, GraphFst, insert_space, ) @@ -28,7 +28,9 @@ months = pynini.string_file(get_abs_path("data/date/months.tsv")) year_suffix = pynini.string_file(get_abs_path("data/date/year_suffix.tsv")) digit = pynini.string_file(get_abs_path("data/numbers/digit.tsv")) -teens_ties = pynini.string_file(get_abs_path("data/numbers/teens_and_ties.tsv")) +teens_ties_hi = pynini.string_file(get_abs_path("data/numbers/teens_and_ties.tsv")) +teens_ties_en = pynini.string_file(get_abs_path("data/numbers/teens_and_ties_en.tsv")) +teens_ties = pynini.union(teens_ties_hi, teens_ties_en) teens_and_ties = pynutil.add_weight(teens_ties, -0.1) # Read suffixes from file into a list @@ -59,10 +61,10 @@ def __init__(self, cardinal: GraphFst): super().__init__(name="date", kind="classify") graph_year_thousands = pynini.compose( - (NEMO_HI_DIGIT + NEMO_HI_ZERO + NEMO_HI_DIGIT + NEMO_HI_DIGIT), cardinal.graph_thousands + (NEMO_ALL_DIGIT + NEMO_ALL_ZERO + NEMO_ALL_DIGIT + NEMO_ALL_DIGIT), cardinal.graph_thousands ) graph_year_hundreds_as_thousands = pynini.compose( - (NEMO_HI_DIGIT + NEMO_HI_NON_ZERO + NEMO_HI_DIGIT + NEMO_HI_DIGIT), cardinal.graph_hundreds_as_thousand + (NEMO_ALL_DIGIT + NEMO_ALL_NON_ZERO + NEMO_ALL_DIGIT + NEMO_ALL_DIGIT), cardinal.graph_hundreds_as_thousand ) cardinal_graph = pynini.union( @@ -92,7 +94,7 @@ def __init__(self, cardinal: GraphFst): range_graph = pynini.cross("-", "से") # Graph for year - century_number = pynini.compose(pynini.closure(NEMO_HI_DIGIT, 1), cardinal_graph) + pynini.accep("वीं") + century_number = pynini.compose(pynini.closure(NEMO_ALL_DIGIT, 1), cardinal_graph) + pynini.accep("वीं") century_text = pynutil.insert("era: \"") + century_number + pynutil.insert("\"") + insert_space # Updated logic to use suffix_union diff --git a/nemo_text_processing/text_normalization/hi/taggers/decimal.py b/nemo_text_processing/text_normalization/hi/taggers/decimal.py index cb21d85b1..7522de2bb 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/decimal.py +++ b/nemo_text_processing/text_normalization/hi/taggers/decimal.py @@ -59,7 +59,7 @@ def __init__(self, cardinal: GraphFst, deterministic: bool = True): super().__init__(name="decimal", kind="classify", deterministic=deterministic) graph_digit = cardinal.digit | cardinal.zero - cardinal_graph = cardinal.final_graph + cardinal_graph = cardinal.graph_without_leading_zeros self.graph = graph_digit + pynini.closure(insert_space + graph_digit).optimize() diff --git a/nemo_text_processing/text_normalization/hi/taggers/measure.py b/nemo_text_processing/text_normalization/hi/taggers/measure.py index b7d74731e..ba5ce2123 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/measure.py +++ b/nemo_text_processing/text_normalization/hi/taggers/measure.py @@ -16,26 +16,44 @@ from pynini.lib import pynutil from nemo_text_processing.text_normalization.hi.graph_utils import ( + ASTERISK, + COMMA, + DECIMAL_25, + DECIMAL_75, + HI_BY, HI_DEDH, HI_DHAI, HI_PAUNE, + HI_PERIOD, HI_SADHE, HI_SAVVA, + HYPHEN, + INPUT_LOWER_CASED, + LOWERCASE_X, + NEMO_CHAR, + NEMO_DIGIT, + NEMO_HI_DIGIT, + NEMO_NOT_SPACE, NEMO_SPACE, + NEMO_WHITE_SPACE, + ONE_POINT_FIVE, + PERIOD, + POINT_FIVE, + SLASH, + TWO_POINT_FIVE, + UPPERCASE_X, GraphFst, + capitalized_input_graph, delete_space, insert_space, ) from nemo_text_processing.text_normalization.hi.utils import get_abs_path -HI_POINT_FIVE = ".५" # .5 -HI_ONE_POINT_FIVE = "१.५" # 1.5 -HI_TWO_POINT_FIVE = "२.५" # 2.5 -HI_DECIMAL_25 = ".२५" # .25 -HI_DECIMAL_75 = ".७५" # .75 - digit = pynini.string_file(get_abs_path("data/numbers/digit.tsv")) -teens_ties = pynini.string_file(get_abs_path("data/numbers/teens_and_ties.tsv")) +# Load both Hindi (Devanagari) and English (Arabic) number mappings +teens_ties_hi = pynini.string_file(get_abs_path("data/numbers/teens_and_ties.tsv")) +teens_ties_en = pynini.string_file(get_abs_path("data/numbers/teens_and_ties_en.tsv")) +teens_ties = pynini.union(teens_ties_hi, teens_ties_en) teens_and_ties = pynutil.add_weight(teens_ties, -0.1) @@ -44,6 +62,7 @@ class MeasureFst(GraphFst): Finite state transducer for classifying measure, suppletive aware, e.g. -१२kg -> measure { negative: "true" cardinal { integer: "बारह" } units: "किलोग्राम" } -१२.२kg -> measure { decimal { negative: "true" integer_part: "बारह" fractional_part: "दो"} units: "किलोग्राम" } + मुंबई ८८४४०४ -> measure { units: "address" cardinal { integer: "मुंबई आठ आठ चार चार शून्य चार" } preserve_order: true } Args: cardinal: CardinalFst @@ -52,7 +71,139 @@ class MeasureFst(GraphFst): for False multiple transduction are generated (used for audio-based normalization) """ - def __init__(self, cardinal: GraphFst, decimal: GraphFst): + def get_structured_address_graph(self, ordinal: GraphFst, input_case: str): + """ + Minimal address tagger for state/city + pincode patterns only. + Highly optimized for performance. + + Examples: + "मुंबई ८८४४०४" -> "मुंबई आठ आठ चार चार शून्य चार" + "गोवा १२३४५६" -> "गोवा एक दो तीन चार पाँच छह" + """ + # State/city keywords + states = pynini.string_file(get_abs_path("data/address/states.tsv")) + cities = pynini.string_file(get_abs_path("data/address/cities.tsv")) + state_city_names = pynini.union(states, cities).optimize() + + # Digit mappings + num_token = ( + digit + | pynini.string_file(get_abs_path("data/numbers/zero.tsv")) + | pynini.string_file(get_abs_path("data/telephone/number.tsv")) + ).optimize() + + # Pincode (6 digits) + pincode = (num_token + pynini.closure(insert_space + num_token, 5, 5)).optimize() + + # Street number (1-4 digits) + street_num = (num_token + pynini.closure(insert_space + num_token, 0, 3)).optimize() + + # Text: words with trailing separator (comma? + space) + any_digit = pynini.union(NEMO_HI_DIGIT, NEMO_DIGIT).optimize() + punctuation = pynini.union(COMMA, PERIOD, HI_PERIOD).optimize() + word_char = pynini.difference(NEMO_NOT_SPACE, pynini.union(any_digit, punctuation)).optimize() + word = pynini.closure(word_char, 1) + + # Separator: optional comma followed by mandatory space + sep = pynini.closure(pynini.accep(COMMA), 0, 1) + pynini.accep(NEMO_SPACE) + word_with_sep = word + sep + text = pynini.closure(word_with_sep, 0, 5).optimize() + + # Pattern: [street_num + sep]? text state/city [space pincode] + pattern = ( + pynini.closure(street_num + sep, 0, 1) + + text + + state_city_names + + pynini.closure(pynini.accep(NEMO_SPACE) + pincode, 0, 1) + ).optimize() + + graph = ( + pynutil.insert('units: "address" cardinal { integer: "') + + pattern + + pynutil.insert('" } preserve_order: true') + ) + return pynutil.add_weight(graph, 1.0).optimize() + + def get_address_graph(self, ordinal: GraphFst, input_case: str): + """ + Address tagger that converts digits/hyphens/slashes character-by-character + when address context keywords are present. + English words and ordinals are converted to Hindi transliterations. + + Examples: + "७०० ओक स्ट्रीट" -> "सात शून्य शून्य ओक स्ट्रीट" + "६६-४ पार्क रोड" -> "छह छह हाइफ़न चार पार्क रोड" + """ + ordinal_graph = ordinal.graph + # Alphanumeric to word mappings (digits, special characters, telephone digits) + char_to_word = ( + digit + | pynini.string_file(get_abs_path("data/numbers/zero.tsv")) + | pynini.string_file(get_abs_path("data/address/special_characters.tsv")) + | pynini.string_file(get_abs_path("data/telephone/number.tsv")) + ).optimize() + # Letter to transliterated word mapping (A -> ए, B -> बी, ...) + letter_to_word = pynini.string_file(get_abs_path("data/address/letters.tsv")) + address_keywords_hi = pynini.string_file(get_abs_path("data/address/context.tsv")) + + # English address keywords with Hindi translation (case-insensitive) + en_to_hi_map = pynini.string_file(get_abs_path("data/address/en_to_hi_mapping.tsv")) + if input_case != INPUT_LOWER_CASED: + en_to_hi_map = capitalized_input_graph(en_to_hi_map) + address_keywords_en = pynini.project(en_to_hi_map, "input") + address_keywords = pynini.union(address_keywords_hi, address_keywords_en) + + # Alphanumeric processing: treat digits, letters, and -/ as convertible tokens + single_digit = pynini.union(NEMO_DIGIT, NEMO_HI_DIGIT).optimize() + special_chars = pynini.union(HYPHEN, SLASH).optimize() + single_letter = pynini.project(letter_to_word, "input").optimize() + convertible_char = pynini.union(single_digit, special_chars, single_letter) + non_space_char = pynini.difference( + NEMO_CHAR, pynini.union(NEMO_WHITE_SPACE, convertible_char, pynini.accep(COMMA)) + ).optimize() + + # Token processors with weights: prefer ordinals and known English→Hindi words + # Delete space before comma to avoid Sparrowhawk "sil" issue + comma_processor = pynutil.add_weight(delete_space + pynini.accep(COMMA), 0.0) + ordinal_processor = pynutil.add_weight(insert_space + ordinal_graph, -5.0) + english_word_processor = pynutil.add_weight(insert_space + en_to_hi_map, -3.0) + letter_processor = pynutil.add_weight(insert_space + pynini.compose(single_letter, letter_to_word), 0.5) + digit_char_processor = pynutil.add_weight(insert_space + pynini.compose(convertible_char, char_to_word), 0.0) + other_word_processor = pynutil.add_weight(insert_space + pynini.closure(non_space_char, 1), 0.1) + + token_processor = ( + ordinal_processor + | english_word_processor + | letter_processor + | digit_char_processor + | pynini.accep(NEMO_SPACE) + | comma_processor + | other_word_processor + ).optimize() + full_string_processor = pynini.closure(token_processor, 1).optimize() + + # Window-based context matching around address keywords for robust detection + word_boundary = pynini.union( + NEMO_WHITE_SPACE, pynini.accep(COMMA), pynini.accep(HI_PERIOD), pynini.accep(PERIOD) + ).optimize() + non_boundary_char = pynini.difference(NEMO_CHAR, word_boundary) + word = pynini.closure(non_boundary_char, 1).optimize() + word_with_boundary = word + pynini.closure(word_boundary) + window = pynini.closure(word_with_boundary, 0, 5).optimize() + boundary = pynini.closure(word_boundary, 1).optimize() + input_pattern = pynini.union( + address_keywords + boundary + window, + window + boundary + address_keywords + pynini.closure(boundary + window, 0, 1), + ).optimize() + address_graph = pynini.compose(input_pattern, full_string_processor).optimize() + graph = ( + pynutil.insert('units: "address" cardinal { integer: "') + + address_graph + + pynutil.insert('" } preserve_order: true') + ) + return pynutil.add_weight(graph, 1.05).optimize() + + def __init__(self, cardinal: GraphFst, decimal: GraphFst, ordinal: GraphFst, input_case: str): super().__init__(name="measure", kind="classify") cardinal_graph = ( @@ -70,6 +221,14 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): decimal_graph = decimal_integers + point + insert_space + decimal.graph_fractional unit_graph = pynini.string_file(get_abs_path("data/measure/unit.tsv")) + # Year unit variants for formal/informal handling + year_informal = pynini.string_map([("yr", "साल")]) + year_formal = pynini.string_file(get_abs_path("data/measure/unit_year_formal.tsv")) + + # All units EXCEPT year + unit_inputs_except_yr = pynini.difference(pynini.project(unit_graph, "input"), pynini.accep("yr")) + unit_graph_no_year = pynini.compose(unit_inputs_except_yr, unit_graph) + # Load quarterly units from separate files: map (FST) and list (FSA) quarterly_units_map = pynini.string_file(get_abs_path("data/measure/quarterly_units_map.tsv")) quarterly_units_list = pynini.string_file(get_abs_path("data/measure/quarterly_units_list.tsv")) @@ -81,13 +240,11 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): 1, ) - # Define the quarterly measurements - quarter = pynini.string_map( - [ - (HI_POINT_FIVE, HI_SADHE), - (HI_ONE_POINT_FIVE, HI_DEDH), - (HI_TWO_POINT_FIVE, HI_DHAI), - ] + # Define the quarterly measurements - support both Devanagari and Arabic digits + quarter = pynini.union( + pynini.cross(POINT_FIVE, HI_SADHE), + pynini.cross(ONE_POINT_FIVE, HI_DEDH), + pynini.cross(TWO_POINT_FIVE, HI_DHAI), ) quarter_graph = pynutil.insert("integer_part: \"") + quarter + pynutil.insert("\"") @@ -95,7 +252,7 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): unit = ( pynutil.insert(NEMO_SPACE) + pynutil.insert("units: \"") - + unit_graph + + unit_graph_no_year + pynutil.insert("\"") + pynutil.insert(NEMO_SPACE) ) @@ -107,12 +264,34 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): + pynutil.insert(NEMO_SPACE) ) - # Handling symbols like x, X, * + # Year-specific unit wrappers + unit_year_informal = ( + pynutil.insert(NEMO_SPACE) + + pynutil.insert("units: \"") + + year_informal + + pynutil.insert("\"") + + pynutil.insert(NEMO_SPACE) + ) + unit_year_formal = ( + pynutil.insert(NEMO_SPACE) + + pynutil.insert("units: \"") + + year_formal + + pynutil.insert("\"") + + pynutil.insert(NEMO_SPACE) + ) + + # Cardinal >= 1000 -> formal year (वर्ष) + # Use graph_without_leading_zeros which covers all number ranges (thousands to shankhs) + cardinal_large = cardinal.graph_without_leading_zeros + + # Cardinal < 1000 -> informal year (साल) + cardinal_small = cardinal.zero | cardinal.digit | cardinal.teens_and_ties | cardinal.graph_hundreds + symbol_graph = pynini.string_map( [ - ("x", "बाई"), - ("X", "बाई"), - ("*", "बाई"), + (LOWERCASE_X, HI_BY), + (UPPERCASE_X, HI_BY), + (ASTERISK, HI_BY), ] ) @@ -125,10 +304,15 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): + unit ) - dedh_dhai = pynini.string_map([(HI_ONE_POINT_FIVE, HI_DEDH), (HI_TWO_POINT_FIVE, HI_DHAI)]) + # Support both Devanagari and Arabic digits for dedh/dhai patterns + dedh_dhai = pynini.union( + pynini.cross(ONE_POINT_FIVE, HI_DEDH), + pynini.cross(TWO_POINT_FIVE, HI_DHAI), + ) dedh_dhai_graph = pynutil.insert("integer: \"") + dedh_dhai + pynutil.insert("\"") - savva_numbers = cardinal_graph + pynini.cross(HI_DECIMAL_25, "") + # Support both Devanagari and Arabic digits for savva pattern + savva_numbers = cardinal_graph + pynini.cross(DECIMAL_25, "") savva_graph = ( pynutil.insert("integer: \"") + pynutil.insert(HI_SAVVA) @@ -137,7 +321,8 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): + pynutil.insert("\"") ) - sadhe_numbers = cardinal_graph + pynini.cross(HI_POINT_FIVE, "") + # Support both Devanagari and Arabic digits for sadhe pattern + sadhe_numbers = cardinal_graph + pynini.cross(POINT_FIVE, "") sadhe_graph = ( pynutil.insert("integer: \"") + pynutil.insert(HI_SADHE) @@ -147,7 +332,8 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): ) paune = pynini.string_file(get_abs_path("data/whitelist/paune_mappings.tsv")) - paune_numbers = paune + pynini.cross(HI_DECIMAL_75, "") + # Support both Devanagari and Arabic digits for paune pattern + paune_numbers = paune + pynini.cross(DECIMAL_75, "") paune_graph = ( pynutil.insert("integer: \"") + pynutil.insert(HI_PAUNE) @@ -207,6 +393,42 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): + unit ) + # Large numbers (>=1000) + yr -> formal (वर्ष) + graph_cardinal_year_formal = ( + pynutil.insert("cardinal { ") + + optional_graph_negative + + pynutil.insert("integer: \"") + + cardinal_large + + pynutil.insert("\"") + + pynutil.insert(NEMO_SPACE) + + pynutil.insert("}") + + delete_space + + unit_year_formal + ) + + # Small numbers (<1000) + yr -> informal (साल) + graph_cardinal_year_informal = ( + pynutil.insert("cardinal { ") + + optional_graph_negative + + pynutil.insert("integer: \"") + + cardinal_small + + pynutil.insert("\"") + + pynutil.insert(NEMO_SPACE) + + pynutil.insert("}") + + delete_space + + unit_year_informal + ) + + # Regular decimals (e.g., 16.07) + yr -> formal (वर्ष) + graph_decimal_year_formal = ( + pynutil.insert("decimal { ") + + optional_graph_negative + + decimal_graph + + pynutil.insert(" }") + + delete_space + + unit_year_formal + ) + # Handling cardinal clubbed with symbol as single token graph_exceptions = ( pynutil.insert("cardinal { ") @@ -229,14 +451,22 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): + pynutil.insert("\"") ) + address_graph = self.get_address_graph(ordinal, input_case) + structured_address_graph = self.get_structured_address_graph(ordinal, input_case) + graph = ( pynutil.add_weight(graph_decimal, 0.1) + | pynutil.add_weight(graph_decimal_year_formal, 0.1) | pynutil.add_weight(graph_cardinal, 0.1) + | pynutil.add_weight(graph_cardinal_year_formal, 0.1) + | pynutil.add_weight(graph_cardinal_year_informal, -0.1) # Higher priority for small numbers | pynutil.add_weight(graph_exceptions, 0.1) | pynutil.add_weight(graph_dedh_dhai, -0.2) | pynutil.add_weight(graph_savva, -0.1) | pynutil.add_weight(graph_sadhe, -0.1) | pynutil.add_weight(graph_paune, -0.5) + | address_graph + | structured_address_graph ) self.graph = graph.optimize() diff --git a/nemo_text_processing/text_normalization/hi/taggers/ordinal.py b/nemo_text_processing/text_normalization/hi/taggers/ordinal.py index 5f1cefed4..bef7ba426 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/ordinal.py +++ b/nemo_text_processing/text_normalization/hi/taggers/ordinal.py @@ -24,7 +24,7 @@ class OrdinalFst(GraphFst): """ Finite state transducer for classifying Hindi ordinals, e.g. १०वां -> ordinal { integer: "दसवां" } - २१वीं -> ordinal { integer: "इक्कीसवीं" } + 12वीं -> ordinal { integer: "इक्कीसवीं" } # English/arabic digits also supported Args: deterministic: if True will provide a single transduction option, @@ -39,10 +39,22 @@ def __init__(self, cardinal: CardinalFst, deterministic: bool = True): suffixes_fst = pynini.union(suffixes_list, suffixes_map) exceptions = pynini.string_file(get_abs_path("data/ordinal/exceptions.tsv")) - graph = cardinal.final_graph + suffixes_fst + # Limit cardinal graph to thousands range for faster compilation + limited_cardinal_graph = ( + cardinal.digit + | cardinal.zero + | cardinal.teens_and_ties + | cardinal.graph_hundreds + | cardinal.graph_thousands + | cardinal.graph_ten_thousands + ).optimize() + + graph = limited_cardinal_graph + suffixes_fst exceptions = pynutil.add_weight(exceptions, -0.1) graph = pynini.union(exceptions, graph) + self.graph = graph.optimize() + final_graph = pynutil.insert("integer: \"") + graph + pynutil.insert("\"") final_graph = self.add_tokens(final_graph) diff --git a/nemo_text_processing/text_normalization/hi/taggers/time.py b/nemo_text_processing/text_normalization/hi/taggers/time.py index 09defaab2..fc598c2b1 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/time.py +++ b/nemo_text_processing/text_normalization/hi/taggers/time.py @@ -27,11 +27,11 @@ ) from nemo_text_processing.text_normalization.hi.utils import get_abs_path -# Time patterns specific to time tagger -HI_DOUBLE_ZERO = "००" -HI_TIME_FIFTEEN = ":१५" # :15 -HI_TIME_THIRTY = ":३०" # :30 -HI_TIME_FORTYFIVE = ":४५" # :45 +# Time patterns specific to time tagger - support both Devanagari and Arabic digits +HI_DOUBLE_ZERO = pynini.union("००", "00") +HI_TIME_FIFTEEN = pynini.union(":१५", ":15") +HI_TIME_THIRTY = pynini.union(":३०", ":30") +HI_TIME_FORTYFIVE = pynini.union(":४५", ":45") hours_graph = pynini.string_file(get_abs_path("data/time/hours.tsv")) minutes_graph = pynini.string_file(get_abs_path("data/time/minutes.tsv")) @@ -72,7 +72,19 @@ def __init__(self, cardinal: GraphFst): # hour graph_h = self.hours + delete_colon + pynutil.delete(HI_DOUBLE_ZERO) - dedh_dhai_graph = pynini.string_map([("१" + HI_TIME_THIRTY, HI_DEDH), ("२" + HI_TIME_THIRTY, HI_DHAI)]) + # Support all combinations of Devanagari and Arabic digits for dedh/dhai patterns + dedh_dhai_graph = pynini.string_map( + [ + ("१:३०", HI_DEDH), + ("१:30", HI_DEDH), + ("1:३०", HI_DEDH), + ("1:30", HI_DEDH), + ("२:३०", HI_DHAI), + ("२:30", HI_DHAI), + ("2:३०", HI_DHAI), + ("2:30", HI_DHAI), + ] + ) savva_numbers = cardinal_graph + pynini.cross(HI_TIME_FIFTEEN, "") savva_graph = pynutil.insert(HI_SAVVA) + pynutil.insert(NEMO_SPACE) + savva_numbers diff --git a/nemo_text_processing/text_normalization/hi/taggers/tokenize_and_classify.py b/nemo_text_processing/text_normalization/hi/taggers/tokenize_and_classify.py index e3e6fc5d8..cb03ebce6 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/tokenize_and_classify.py +++ b/nemo_text_processing/text_normalization/hi/taggers/tokenize_and_classify.py @@ -94,15 +94,15 @@ def __init__( timefst = TimeFst(cardinal=cardinal) time_graph = timefst.fst - measure = MeasureFst(cardinal=cardinal, decimal=decimal) + ordinal = OrdinalFst(cardinal=cardinal, deterministic=deterministic) + ordinal_graph = ordinal.fst + + measure = MeasureFst(cardinal=cardinal, decimal=decimal, ordinal=ordinal, input_case=input_case) measure_graph = measure.fst money = MoneyFst(cardinal=cardinal) money_graph = money.fst - ordinal = OrdinalFst(cardinal=cardinal, deterministic=deterministic) - ordinal_graph = ordinal.fst - whitelist_graph = WhiteListFst( input_case=input_case, deterministic=deterministic, input_file=whitelist ).fst diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/measure.py b/nemo_text_processing/text_normalization/hi/verbalizers/measure.py index d6d17ac37..cba08057d 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/measure.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/measure.py @@ -27,7 +27,7 @@ class MeasureFst(GraphFst): Args: decimal: DecimalFst - cardinal: CardinalFs + cardinal: CardinalFst deterministic: if True will provide a single transduction option, for False multiple transduction are generated (used for audio-based normalization) """ @@ -41,7 +41,12 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): 1, ) - unit = pynutil.delete("units: \"") + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete("\"") + delete_space + unit = ( + pynutil.delete("units: \"") + + pynini.difference(pynini.closure(NEMO_NOT_QUOTE, 1), pynini.accep("address")) + + pynutil.delete("\"") + + delete_space + ) graph_decimal = ( pynutil.delete("decimal {") @@ -64,6 +69,18 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): ) graph = (graph_cardinal | graph_decimal) + delete_space + insert_space + unit + + preserve_order = pynutil.delete("preserve_order:") + delete_space + pynutil.delete("true") + delete_space + address = ( + pynutil.delete("units: \"address\" ") + + delete_space + + graph_cardinal + + delete_space + + pynini.closure(preserve_order) + ) + + graph |= address + self.decimal = graph_decimal delete_tokens = self.delete_tokens(graph) self.fst = delete_tokens.optimize() diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/post_processing.py b/nemo_text_processing/text_normalization/hi/verbalizers/post_processing.py index d838ca6ff..595180241 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/post_processing.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/post_processing.py @@ -16,13 +16,15 @@ import os import pynini +from pynini.lib import pynutil -from nemo_text_processing.text_normalization.en.graph_utils import ( - NEMO_NOT_SPACE, +from nemo_text_processing.text_normalization.hi.graph_utils import ( + MIN_NEG_WEIGHT, + NEMO_CHAR, NEMO_SIGMA, - delete_space, generator_main, ) +from nemo_text_processing.text_normalization.hi.taggers.punctuation import PunctuationFst from nemo_text_processing.utils.logging import logger @@ -46,68 +48,49 @@ def __init__(self, cache_dir: str = None, overwrite_cache: bool = False): self.fst = pynini.Far(far_file, mode="r")["post_process_graph"] logger.info(f'Post processing graph was restored from {far_file}.') else: - self.set_punct_dict() self.fst = self.get_punct_postprocess_graph() if far_file: generator_main(far_file, {"post_process_graph": self.fst}) - def set_punct_dict(self): - self.punct_marks = { - "'": [ - "'", - '´', - 'ʹ', - 'ʻ', - 'ʼ', - 'ʽ', - 'ʾ', - 'ˈ', - 'ˊ', - 'ˋ', - '˴', - 'ʹ', - '΄', - '՚', - '՝', - 'י', - '׳', - 'ߴ', - 'ߵ', - 'ᑊ', - 'ᛌ', - '᾽', - '᾿', - '`', - '´', - '῾', - '‘', - '’', - '‛', - '′', - '‵', - 'ꞌ', - ''', - '`', - '𖽑', - '𖽒', - ], - } - def get_punct_postprocess_graph(self): """ Returns graph to post process punctuation marks. - {``} quotes are converted to {"}. Note, if there are spaces around single quote {'}, they will be kept. - By default, a space is added after a punctuation mark, and spaces are removed before punctuation marks. + By default, spaces are removed before punctuation marks like comma, period, etc. """ - - remove_space_around_single_quote = pynini.cdrewrite( - delete_space, NEMO_NOT_SPACE, NEMO_NOT_SPACE, pynini.closure(NEMO_SIGMA) + punct_marks_all = PunctuationFst().punct_marks + + # Punctuation marks that should NOT have space before them + # (most punctuation except quotes, dashes, and opening brackets) + quotes = ["'", "\"", "«"] + dashes = ["-", "—"] + brackets = ["<", "{", "(", r"\["] + allow_space_before_punct = quotes + dashes + brackets + + no_space_before_punct = [m for m in punct_marks_all if m not in allow_space_before_punct] + # Add Hindi-specific punctuation + no_space_before_punct.extend(["।", ",", ".", ";", ":", "!", "?"]) + # Remove duplicates + no_space_before_punct = list(set(no_space_before_punct)) + no_space_before_punct = pynini.union(*no_space_before_punct) + + delete_space = pynutil.delete(" ") + + # Delete space before no_space_before_punct marks + non_punct = pynini.difference(NEMO_CHAR, no_space_before_punct).optimize() + graph = ( + pynini.closure(non_punct) + + pynini.closure( + no_space_before_punct | pynutil.add_weight(delete_space + no_space_before_punct, MIN_NEG_WEIGHT) + ) + + pynini.closure(non_punct) ) - # this works if spaces in between (good) - # delete space between 2 NEMO_NOT_SPACE(left and right to the space) that are with in a content of NEMO_SIGMA + graph = pynini.closure(graph).optimize() - graph = remove_space_around_single_quote.optimize() + # Remove space after opening brackets + no_space_after_punct = pynini.union(*brackets) + no_space_after_punct = pynini.cdrewrite(delete_space, no_space_after_punct, NEMO_SIGMA, NEMO_SIGMA).optimize() + graph = pynini.compose(graph, no_space_after_punct).optimize() return graph diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py b/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py index 12ae316b1..30d076c93 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py @@ -54,6 +54,9 @@ def __init__(self, deterministic: bool = True): time = TimeFst(cardinal=cardinal) time_graph = time.fst + ordinal = OrdinalFst(deterministic=deterministic) + ordinal_graph = ordinal.fst + measure = MeasureFst(cardinal=cardinal, decimal=decimal) measure_graph = measure.fst @@ -62,8 +65,6 @@ def __init__(self, deterministic: bool = True): telephone = TelephoneFst() telephone_graph = telephone.fst - ordinal = OrdinalFst(deterministic=deterministic) - ordinal_graph = ordinal.fst whitelist_graph = WhiteListFst(deterministic=deterministic).fst diff --git a/nemo_text_processing/text_normalization/normalize.py b/nemo_text_processing/text_normalization/normalize.py index ad044e9fd..e9badbf89 100644 --- a/nemo_text_processing/text_normalization/normalize.py +++ b/nemo_text_processing/text_normalization/normalize.py @@ -161,7 +161,11 @@ def __init__( from nemo_text_processing.text_normalization.ar.verbalizers.verbalize_final import VerbalizeFinalFst elif lang == 'hi': from nemo_text_processing.text_normalization.hi.taggers.tokenize_and_classify import ClassifyFst + from nemo_text_processing.text_normalization.hi.verbalizers.post_processing import PostProcessingFst from nemo_text_processing.text_normalization.hi.verbalizers.verbalize_final import VerbalizeFinalFst + + if post_process: + self.post_processor = PostProcessingFst(cache_dir=cache_dir, overwrite_cache=overwrite_cache) elif lang == 'it': from nemo_text_processing.text_normalization.it.taggers.tokenize_and_classify import ClassifyFst from nemo_text_processing.text_normalization.it.verbalizers.verbalize_final import VerbalizeFinalFst @@ -381,7 +385,7 @@ def normalize( return text output = SPACE_DUP.sub(' ', output[1:]) - if self.lang in ["en", "vi"] and hasattr(self, 'post_processor'): + if self.lang in ["en", "hi"] and hasattr(self, 'post_processor') and self.post_processor is not None: output = self.post_process(output) if punct_post_process: diff --git a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_address.txt b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_address.txt new file mode 100644 index 000000000..9989fa75c --- /dev/null +++ b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_address.txt @@ -0,0 +1,55 @@ +700 ओक स्ट्रीट~सात शून्य शून्य ओक स्ट्रीट +११ जंगल रोड~एक एक जंगल रोड +301 पार्क एवेन्यू~तीन शून्य एक पार्क एवेन्यू +गली नंबर १७ जीएकगढ़~गली नंबर एक सात जीएकगढ़ +अदनान अपार्टमेंट फ्लैट नंबर 55~अदनान अपार्टमेंट फ्लैट नंबर पाँच पाँच +प्लॉट नंबर ८ बालाजी मार्केट~प्लॉट नंबर आठ बालाजी मार्केट +शॉप नंबर 109 9 और 10 डिवाइडिंग रोड सेक्टर 10 फरीदाबाद~शॉप नंबर एक शून्य नौ नौ और एक शून्य डिवाइडिंग रोड सेक्टर एक शून्य फरीदाबाद +बूथ ७०, सेक्टर ८, चंडीगढ़~बूथ सात शून्य, सेक्टर आठ, चंडीगढ़ +2221 Southern Street~दो दो दो एक सदर्न स्ट्रीट +७०० ओक स्ट्रीट~सात शून्य शून्य ओक स्ट्रीट +625 स्कूल स्ट्रीट~छह दो पाँच स्कूल स्ट्रीट +१४७० एस वाशिंगटन स्ट्रीट~एक चार सात शून्य एस वाशिंगटन स्ट्रीट +506 स्टेट रोड~पाँच शून्य छह स्टेट रोड +६६-४ पार्कहर्स्ट आर डी~छह छह हाइफ़न चार पार्कहर्स्ट आर डी +579 ट्रॉय-शेंक्टाडी रोड~पाँच सात नौ ट्रॉय हाइफ़न शेंक्टाडी रोड +७८३० - ई वेटरन्स पार्कवे, कोलंबस, जी ए ३१९०९~सात आठ तीन शून्य हाइफ़न ई वेटरन्स पार्कवे, कोलंबस, जी ए तीन एक नौ शून्य नौ +66-4, पार्कहर्स्ट रोड~छह छह हाइफ़न चार, पार्कहर्स्ट रोड +८४०/१, १०० फीट रोड, मेट्रो पिलर ५६-५७, इंदिरानगर, बैंगलोर~आठ चार शून्य बटा एक, एक शून्य शून्य फीट रोड, मेट्रो पिलर पाँच छह हाइफ़न पाँच सात, इंदिरानगर, बैंगलोर +17-18, राजलक्ष्मी नगर, 7th क्रॉस स्ट्रीट, 100 फीट बाईपास रोड, वेलाचेरी, चेन्नई~एक सात हाइफ़न एक आठ, राजलक्ष्मी नगर, सेवंथ क्रॉस स्ट्रीट, एक शून्य शून्य फीट बाईपास रोड, वेलाचेरी, चेन्नई +४/५ न्यू म्युनिसिपल मार्केट रोड नंबर ५ और ६ सेन्टाक्रूज़ वेस्ट~चार बटा पाँच न्यू म्युनिसिपल मार्केट रोड नंबर पाँच और छह सेन्टाक्रूज़ वेस्ट +16/17 4th फ्लोर जवाहर नगर मटरू मंदिर रोड नंबर 2~एक छह बटा एक सात फ़ोर्थ फ्लोर जवाहर नगर मटरू मंदिर रोड नंबर दो +५/३०४ सिक्का कॉम्प्लेक्स विकास मार्ग एक्सटेंशन~पाँच बटा तीन शून्य चार सिक्का कॉम्प्लेक्स विकास मार्ग एक्सटेंशन +21/2 2nd फ्लोर 1st मेन रोड गांधी नगर~दो एक बटा दो सेकंड फ्लोर फ़र्स्ट मेन रोड गांधी नगर +नंबर २२/१८ ३rd फ्लोर सराय बोउ अली शू मार्केट~नंबर दो दो बटा एक आठ थर्ड फ्लोर सराय बोउ अली शू मार्केट +14/3, मथुरा रोड~एक चार बटा तीन, मथुरा रोड +यूनिट ३ १st फ्लोर नंबर ३७ सोलेमान खतर स्ट्रीट~यूनिट तीन फ़र्स्ट फ्लोर नंबर तीन सात सोलेमान खतर स्ट्रीट +1st फ्लोर नंबर 52 नॉर्थ अबूज़र स्ट्रीट खान ए अंसारी स्ट्रीट शरीयती स्ट्रीट 16617~फ़र्स्ट फ्लोर नंबर पाँच दो नॉर्थ अबूज़र स्ट्रीट खान ए अंसारी स्ट्रीट शरीयती स्ट्रीट एक छह छह एक सात +२०६ जय कॉम कॉम्प्लेक्स १st पोखरन रोड~दो शून्य छह जय कॉम कॉम्प्लेक्स फ़र्स्ट पोखरन रोड +नंबर 36 2nd फ्लोर सुपर 8 फेज 1 एकबतन टाउन तेहरान 13947~नंबर तीन छह सेकंड फ्लोर सुपर आठ फेज एक एकबतन टाउन तेहरान एक तीन नौ चार सात +२nd फ्लोर नंबर ८०८ आजादी स्ट्रीट~सेकंड फ्लोर नंबर आठ शून्य आठ आजादी स्ट्रीट +2nd फ्लोर नंबर 15 बिफ़ोर कांदि स्ट्रीट नॉर्थ सोहरावर्दी स्ट्रीट 15669~सेकंड फ्लोर नंबर एक पाँच बिफ़ोर कांदि स्ट्रीट नॉर्थ सोहरावर्दी स्ट्रीट एक पाँच छह छह नौ +यूनिट ४ नंबर २५ २nd गोलहा स्ट्रीट काशनी स्ट्रीट नूर स्क्वेर~यूनिट चार नंबर दो पाँच सेकंड गोलहा स्ट्रीट काशनी स्ट्रीट नूर स्क्वेर +ईस्ट 3rd फ्लोर नंबर 70 नेक्स्ट दो तोहीद इंस्टीट्यूट परचम स्ट्रीट~ईस्ट थर्ड फ्लोर नंबर सात शून्य नेक्स्ट दो तोहीद इंस्टीट्यूट परचम स्ट्रीट +३rd फ्लोर नंबर ५ हमेदन एली अपोज़िट लाले पार्क नॉर्थ कारगर स्ट्रीट~थर्ड फ्लोर नंबर पाँच हमेदन एली अपोज़िट लाले पार्क नॉर्थ कारगर स्ट्रीट +4th फ्लोर नंबर 1124 जमहोरी स्ट्रीट~फ़ोर्थ फ्लोर नंबर एक एक दो चार जमहोरी स्ट्रीट +५th फ्लोर नंबर ७/१ १३th एली शाहिद अराबली स्ट्रीट~फ़िफ्थ फ्लोर नंबर सात बटा एक थर्टींथ एली शाहिद अराबली स्ट्रीट +11, 80 फीट रोड, इंडियन ऑयल पेट्रोल पंप, कोरमंगला 6th ब्लॉक, बैंगलोर के सामने~एक एक, आठ शून्य फीट रोड, इंडियन ऑयल पेट्रोल पंप, कोरमंगला सिक्स्थ ब्लॉक, बैंगलोर के सामने +२१/११, जे ब्लॉक, ६th एवेन्यू मेन रोड, अन्ना नगर पूर्व, चेन्नई~दो एक बटा एक एक, जे ब्लॉक, सिक्स्थ एवेन्यू मेन रोड, अन्ना नगर पूर्व, चेन्नई +32A नाज़ प्लाज़ा मेरिस रोड~तीन दो ए नाज़ प्लाज़ा मेरिस रोड +२१४ बी गोविंद पूरी स्ट्रीट नंबर २~दो एक चार बी गोविंद पूरी स्ट्रीट नंबर दो +4362 16वीं एवेन्यू एसडब्ल्यू, देवदार रैपिड्स, आई ए 52404~चार तीन छह दो सोलहवीं एवेन्यू एसडब्ल्यू, देवदार रैपिड्स, आई ए बावन हज़ार चार सौ चार +अमरावती ६५५९३०~अमरावती छह पाँच पाँच नौ तीन शून्य +शिमला, हिमाचल प्रदेश 593988~शिमला, हिमाचल प्रदेश पाँच नौ तीन नौ आठ आठ +२७०४४० डॉसन आर डी, अल्बानी, जीए ३१७०७~दो सात शून्य चार चार शून्य डॉसन आर डी, अल्बानी, जीए तीन एक सात शून्य सात +रांची, झारखंड 736557~रांची, झारखंड सात तीन छह पाँच पाँच सात +कोहिमा, नागालैंड ४४८३७७~कोहिमा, नागालैंड चार चार आठ तीन सात सात +मुंबई, महाराष्ट्र 839488~मुंबई, महाराष्ट्र आठ तीन नौ चार आठ आठ +अमरावती ४६८२५२~अमरावती चार छह आठ दो पाँच दो +गांधीनगर, गुजरात 808374~गांधीनगर, गुजरात आठ शून्य आठ तीन सात चार +मुंबई, महाराष्ट्र २९०९३७~मुंबई, महाराष्ट्र दो नौ शून्य नौ तीन सात +श्रीनगर, जम्मू और कश्मीर 964523~श्रीनगर, जम्मू और कश्मीर नौ छह चार पाँच दो तीन +रायपुर, छत्तीसगढ़ ११०६३५~रायपुर, छत्तीसगढ़ एक एक शून्य छह तीन पाँच +भोपाल, मध्य प्रदेश 751225~भोपाल, मध्य प्रदेश सात पाँच एक दो दो पाँच +अगरतला, त्रिपुरा ९१५३०५~अगरतला, त्रिपुरा नौ एक पाँच तीन शून्य पाँच +लखनऊ, उत्तर प्रदेश 802481~लखनऊ, उत्तर प्रदेश आठ शून्य दो चार आठ एक diff --git a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_cardinal.txt b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_cardinal.txt index 2a52b2a20..d607992d7 100644 --- a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_cardinal.txt +++ b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_cardinal.txt @@ -1,147 +1,150 @@ -४ चौके~चार चौके +4 चौके~चार चौके ६ खिलाड़ी आउट~छह खिलाड़ी आउट -वनप्लस ८ प्रो~वनप्लस आठ प्रो +वनप्लस 8 प्रो~वनप्लस आठ प्रो ५ चार्जर~पाँच चार्जर -४ ओवर में १७ रन~चार ओवर में सत्रह रन +4 ओवर में 17 रन~चार ओवर में सत्रह रन ५ चॉकलेट्स ९ टॉफ़िज़~पाँच चॉकलेट्स नौ टॉफ़िज़ -१००९९~दस हज़ार निन्यानबे +10099~दस हज़ार निन्यानबे १००००१~एक लाख एक -४ छक्के १४ चौके~चार छक्के चौदह चौके +4 छक्के 14 चौके~चार छक्के चौदह चौके ६ रन बनाए~छह रन बनाए -३ गोल मारे~तीन गोल मारे +3 गोल मारे~तीन गोल मारे ६ रन बनाए~छह रन बनाए -३ गोल मारे~तीन गोल मारे +3 गोल मारे~तीन गोल मारे ५ चौके~पाँच चौके -२ छक्के १२ रन~दो छक्के बारह रन +2 छक्के 12 रन~दो छक्के बारह रन ९ पॉइंट्स~नौ पॉइंट्स -४ मृत १८ घायल~चार मृत अठारह घायल +4 मृत 18 घायल~चार मृत अठारह घायल ५ गोल मार~पाँच गोल मार -३ बैट्समैन १२ खिलाड़ी~तीन बैट्समैन बारह खिलाड़ी +3 बैट्समैन 12 खिलाड़ी~तीन बैट्समैन बारह खिलाड़ी ५ हार १ ड्रॉ १७ जीत~पाँच हार एक ड्रॉ सत्रह जीत -५१०२२३४५५६७~इक्यावन अरब दो करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ +51022345567~इक्यावन अरब दो करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ पाठ १० श्लोक २~पाठ दस श्लोक दो -१०१~एक सौ एक +101~एक सौ एक १०२~एक सौ दो -१०३~एक सौ तीन +103~एक सौ तीन १०४~एक सौ चार -१०५~एक सौ पाँच +105~एक सौ पाँच १०६~एक सौ छह -१०७~एक सौ सात +107~एक सौ सात १०८~एक सौ आठ -१०९~एक सौ नौ +109~एक सौ नौ ११०~एक सौ दस -१११~एक सौ ग्यारह +111~एक सौ ग्यारह ११२~एक सौ बारह -११३~एक सौ तेरह +113~एक सौ तेरह ११४~एक सौ चौदह -११५~एक सौ पंद्रह +115~एक सौ पंद्रह ११६~एक सौ सोलह -८१७~आठ सौ सत्रह +817~आठ सौ सत्रह ८१८~आठ सौ अठारह -८१९~आठ सौ उन्नीस +819~आठ सौ उन्नीस ८२०~आठ सौ बीस -८२१~आठ सौ इक्कीस +821~आठ सौ इक्कीस ८२२~आठ सौ बाईस -८२३~आठ सौ तेईस +823~आठ सौ तेईस ८२४~आठ सौ चौबीस -८२५~आठ सौ पच्चीस +825~आठ सौ पच्चीस ८२६~आठ सौ छब्बीस -८२७~आठ सौ सत्ताईस +827~आठ सौ सत्ताईस ८२८~आठ सौ अट्ठाईस -८२९~आठ सौ उनतीस +829~आठ सौ उनतीस ८३०~आठ सौ तीस -८३१~आठ सौ इकतीस +831~आठ सौ इकतीस ८३२~आठ सौ बत्तीस -८३३~आठ सौ तैंतीस +833~आठ सौ तैंतीस ८३४~आठ सौ चौंतीस -८३५~आठ सौ पैंतीस +835~आठ सौ पैंतीस ८३६~आठ सौ छत्तीस -७३७~सात सौ सैंतीस +737~सात सौ सैंतीस ७३८~सात सौ अड़तीस -७३९~सात सौ उनतालीस +739~सात सौ उनतालीस ७४०~सात सौ चालीस -७४१~सात सौ इकतालीस +741~सात सौ इकतालीस ७४२~सात सौ बयालीस -७४३~सात सौ तैंतालीस +743~सात सौ तैंतालीस ७४४~सात सौ चौवालीस -७४५~सात सौ पैंतालीस +745~सात सौ पैंतालीस ४४६~चार सौ छियालीस -४४७~चार सौ सैंतालीस +447~चार सौ सैंतालीस ४४८~चार सौ अड़तालीस -४४९~चार सौ उनचास +449~चार सौ उनचास ४५०~चार सौ पचास -४६१~चार सौ इकसठ +461~चार सौ इकसठ १७५~एक सौ पचहत्तर -१८१~एक सौ इक्यासी +181~एक सौ इक्यासी १९०~एक सौ नब्बे -१९१~एक सौ इक्यानबे +191~एक सौ इक्यानबे १९९~एक सौ निन्यानबे -१००१~एक हज़ार एक +1001~एक हज़ार एक १०९९~एक हज़ार निन्यानबे -५५५१ केले~पाँच हज़ार पाँच सौ इक्यावन केले +5551 केले~पाँच हज़ार पाँच सौ इक्यावन केले ५५५५२ सेब~पचपन हज़ार पाँच सौ बावन सेब -५३~तिरेपन +53~तिरेपन ५४~चौवन -५५~पचपन +55~पचपन ५६~छप्पन -५७~सत्तावन +57~सत्तावन ५८~अट्ठावन -५९~उनसठ +59~उनसठ ६०~साठ -६१~इकसठ +61~इकसठ ६२~बासठ -६३~तिरेसठ +63~तिरेसठ ६४~चौंसठ -६५~पैंसठ +65~पैंसठ ६६~छियासठ -६७~सड़सठ +67~सड़सठ ६८~अड़सठ -६९~उनहत्तर +69~उनहत्तर ७०~सत्तर -७१~इकहत्तर +71~इकहत्तर ७२~बहत्तर -७३~तिहत्तर +73~तिहत्तर ७४~चौहत्तर -७५~पचहत्तर +75~पचहत्तर ७६~छिहत्तर -७७~सतहत्तर +77~सतहत्तर ७८~अठहत्तर -७९~उनासी +79~उनासी ८०~अस्सी -८१~इक्यासी +81~इक्यासी ८२~बयासी -८३~तिरासी +83~तिरासी ८४~चौरासी -८५~पचासी +85~पचासी ८६~छियासी -८७~सत्तासी +87~सत्तासी ८८~अट्ठासी -८९~नवासी +89~नवासी ९०~नब्बे -९१~इक्यानबे +91~इक्यानबे ९२~बानबे -९३~तिरानबे +93~तिरानबे ९४~चौरानबे -९५~पंचानबे +95~पंचानबे ९६~छियानबे -९७~सत्तानबे +97~सत्तानबे ९८~अट्ठानबे -९९~निन्यानबे +99~निन्यानबे १३२३~एक हज़ार तीन सौ तेईस -१३४५~एक हज़ार तीन सौ पैंतालीस +1345~एक हज़ार तीन सौ पैंतालीस १३४५६~तेरह हज़ार चार सौ छप्पन -१२३४६~बारह हज़ार तीन सौ छियालीस +12346~बारह हज़ार तीन सौ छियालीस १२३४५६~एक लाख तेईस हज़ार चार सौ छप्पन -८७२९८७~आठ लाख बहत्तर हज़ार नौ सौ सत्तासी +872987~आठ लाख बहत्तर हज़ार नौ सौ सत्तासी ९८७६०९~नौ लाख सत्तासी हज़ार छह सौ नौ -९८७६७८९~अट्ठानबे लाख छिहत्तर हज़ार सात सौ नवासी +9876789~अट्ठानबे लाख छिहत्तर हज़ार सात सौ नवासी २३४५५६७~तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ -१२३४५५६७~एक करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ +12345567~एक करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ १२१२१२१२~एक करोड़ इक्कीस लाख इक्कीस हज़ार दो सौ बारह -११२२३४५५६७~एक अरब बारह करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ +1122345567~एक अरब बारह करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ १०२२३४५५६७~एक अरब दो करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ -११०२२३४५५६७~ग्यारह अरब दो करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ +11022345567~ग्यारह अरब दो करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ ५१०२२३४५५६७~इक्यावन अरब दो करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ -२ पॉइंट्स १२ गोल~दो पॉइंट्स बारह गोल +2 पॉइंट्स 12 गोल~दो पॉइंट्स बारह गोल ०५~शून्य पाँच -०१~शून्य एक \ No newline at end of file +01~शून्य एक +०७३~शून्य सात तीन +0001~शून्य शून्य शून्य एक +०००~शून्य शून्य शून्य diff --git a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_date.txt b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_date.txt index a4b3caf07..86f1f6678 100644 --- a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_date.txt +++ b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_date.txt @@ -1,34 +1,34 @@ -०६-०५~छः मई +06-05~छः मई ३१-०६~इकतीस जून -०२-०१~दो जनवरी +02-01~दो जनवरी ०४-०१~चार जनवरी -०१-१०~एक अक्टूबर +01-10~एक अक्टूबर १२-०७~बारह जुलाई -०२-२७~फ़रवरी सत्ताईस +02-27~फ़रवरी सत्ताईस ०४-०३~चार मार्च -२५-०३-२०२०~पच्चीस मार्च दो हज़ार बीस +25-03-2020~पच्चीस मार्च दो हज़ार बीस ३०-०५-२०७०~तीस मई दो हज़ार सत्तर -१२-०७-१९७०~बारह जुलाई उन्नीस सौ सत्तर +12-07-1970~बारह जुलाई उन्नीस सौ सत्तर ०९-१२-२१०१~नौ दिसंबर इक्कीस सौ एक -२३-०८-२०२४~तेईस अगस्त दो हज़ार चौबीस +23-08-2024~तेईस अगस्त दो हज़ार चौबीस १०-२९-२०००~अक्टूबर उनतीस दो हज़ार -११-१४-११००~नवंबर चौदह ग्यारह सौ +11-14-1100~नवंबर चौदह ग्यारह सौ ०३-२०१०~मार्च दो हज़ार दस -११-२०२४~नवंबर दो हज़ार चौबीस +11-2024~नवंबर दो हज़ार चौबीस २०७०~दो हज़ार सत्तर -२०२४~दो हज़ार चौबीस +2024~दो हज़ार चौबीस १२० ई. पू.~एक सौ बीस ईसा पूर्व -२९७-२७२ ई. पू.~दो सौ सत्तानबे से दो सौ बहत्तर ईसा पूर्व +297-272 ई. पू.~दो सौ सत्तानबे से दो सौ बहत्तर ईसा पूर्व ३२७वीं सदी~तीन सौ सत्ताईसवीं सदी -१८वीं शताब्दी~अठारहवीं शताब्दी +18वीं शताब्दी~अठारहवीं शताब्दी १९वीं दशक~उन्नीसवीं दशक -१९९९ में~उन्नीस सौ निन्यानबे में +1999 में~उन्नीस सौ निन्यानबे में १९९० का~उन्नीस सौ नब्बे का -१९९२ की~उन्नीस सौ बानबे की +1992 की~उन्नीस सौ बानबे की १९६० के अभिनेता है~उन्नीस सौ साठ के अभिनेता है -१७८८ से~सत्रह सौ अट्ठासी से +1788 से~सत्रह सौ अट्ठासी से १९५४ तक~उन्नीस सौ चौवन तक -सन १९९९~सन उन्नीस सौ निन्यानबे +सन 1999~सन उन्नीस सौ निन्यानबे सन् १९२०~सन् उन्नीस सौ बीस -साल १९७१~साल उन्नीस सौ इकहत्तर +साल 1971~साल उन्नीस सौ इकहत्तर १९२०-२६ तक~उन्नीस सौ बीस से छब्बीस तक \ No newline at end of file diff --git a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_decimal.txt b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_decimal.txt index 3ec53dd4b..3582aff50 100644 --- a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_decimal.txt +++ b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_decimal.txt @@ -1,20 +1,20 @@ -९९.९९~निन्यानबे दशमलव नौ नौ +99.99~निन्यानबे दशमलव नौ नौ ९७.०~सत्तानबे दशमलव शून्य -२५६३.४१२~दो हज़ार पाँच सौ तिरेसठ दशमलव चार एक दो +2563.412~दो हज़ार पाँच सौ तिरेसठ दशमलव चार एक दो ७२८६०.७०~बहत्तर हज़ार आठ सौ साठ दशमलव सात शून्य -०.००८~शून्य दशमलव शून्य शून्य आठ +0.008~शून्य दशमलव शून्य शून्य आठ ०.०००३~शून्य दशमलव शून्य शून्य शून्य तीन -४०.०~चालीस दशमलव शून्य +40.0~चालीस दशमलव शून्य ८०.०~अस्सी दशमलव शून्य -१५००.२२~एक हज़ार पाँच सौ दशमलव दो दो +1500.22~एक हज़ार पाँच सौ दशमलव दो दो ५०००.१२३५६~पाँच हज़ार दशमलव एक दो तीन पाँच छह -१०००.३१~एक हज़ार दशमलव तीन एक +1000.31~एक हज़ार दशमलव तीन एक ५१४६.१७~पाँच हज़ार एक सौ छियालीस दशमलव एक सात -१००००.९९९~दस हज़ार दशमलव नौ नौ नौ +10000.999~दस हज़ार दशमलव नौ नौ नौ १०००००.१७~एक लाख दशमलव एक सात -१०००००००.३१~एक करोड़ दशमलव तीन एक +10000000.31~एक करोड़ दशमलव तीन एक १०००००००००.२२~एक अरब दशमलव दो दो -१०००००००००००.७०~एक खरब दशमलव सात शून्य +100000000000.70~एक खरब दशमलव सात शून्य १०००००००००००००.०००३~एक नील दशमलव शून्य शून्य शून्य तीन -१०००००००००००००००.००८~एक पद्म दशमलव शून्य शून्य आठ +1000000000000000.008~एक पद्म दशमलव शून्य शून्य आठ १०००००००००००००००००.४१२~एक शंख दशमलव चार एक दो diff --git a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_fraction.txt b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_fraction.txt index d1473412e..4184ae9ee 100644 --- a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_fraction.txt +++ b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_fraction.txt @@ -1,23 +1,23 @@ -९९/९९~निन्यानबे बटा निन्यानबे +99/99~निन्यानबे बटा निन्यानबे २२ ३१/१७~बाईस और इकतीस बटा सत्रह -९७/०~सत्तानबे बटा शून्य +97/0~सत्तानबे बटा शून्य २५६३/४१२~दो हज़ार पाँच सौ तिरेसठ बटा चार सौ बारह -७२८६०/७०~बहत्तर हज़ार आठ सौ साठ बटा सत्तर +72860/70~बहत्तर हज़ार आठ सौ साठ बटा सत्तर ०/८~शून्य बटा आठ -३/०~तीन बटा शून्य +3/0~तीन बटा शून्य ४०/०~चालीस बटा शून्य -८०/०~अस्सी बटा शून्य +80/0~अस्सी बटा शून्य १५००/२२~एक हज़ार पाँच सौ बटा बाईस -५०००/१२३५६~पाँच हज़ार बटा बारह हज़ार तीन सौ छप्पन +5000/12356~पाँच हज़ार बटा बारह हज़ार तीन सौ छप्पन १०००/३१~एक हज़ार बटा इकतीस -५१४६/१७~पाँच हज़ार एक सौ छियालीस बटा सत्रह +5146/17~पाँच हज़ार एक सौ छियालीस बटा सत्रह १००००/९९९~दस हज़ार बटा नौ सौ निन्यानबे -१०००००/१७~एक लाख बटा सत्रह +100000/17~एक लाख बटा सत्रह १०००००००/३१~एक करोड़ बटा इकतीस -१०००००००००/२२~एक अरब बटा बाईस +1000000000/22~एक अरब बटा बाईस १०००००००००००/७०~एक खरब बटा सत्तर -१०००००००००००००/३~एक नील बटा तीन +10000000000000/3~एक नील बटा तीन १०००००००००००००००/८~एक पद्म बटा आठ -१०००००००००००००००००/४१२~एक शंख बटा चार सौ बारह +100000000000000000/412~एक शंख बटा चार सौ बारह २ २/७~दो और दो बटा सात -१२० ७५/९०~एक सौ बीस और पचहत्तर बटा नब्बे \ No newline at end of file +120 75/90~एक सौ बीस और पचहत्तर बटा नब्बे \ No newline at end of file diff --git a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_measure.txt b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_measure.txt index 86a824f72..6d0cef9b1 100644 --- a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_measure.txt +++ b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_measure.txt @@ -1,66 +1,73 @@ -१९ m²~उन्नीस वर्ग मीटर +19 m²~उन्नीस वर्ग मीटर १२.१९ m²~बारह दशमलव एक नौ वर्ग मीटर -२० km²~बीस वर्ग किलोमीटर +20 km²~बीस वर्ग किलोमीटर २०.७ km²~बीस दशमलव सात वर्ग किलोमीटर -२ ha~दो हेक्टेयर +2 ha~दो हेक्टेयर २.७ ha~दो दशमलव सात हेक्टेयर -१ ac~एक एकड़ +1 ac~एक एकड़ ३.८ ac~तीन दशमलव आठ एकड़ -४ m~चार मीटर +4 m~चार मीटर ४.२ m~चार दशमलव दो मीटर -१८ mi~अठारह मील +18 mi~अठारह मील १८.५५ mi~अठारह दशमलव पाँच पाँच मील -३४ in~चौंतीस इंच +34 in~चौंतीस इंच ३४.२ in~चौंतीस दशमलव दो इंच -४० ft~चालीस फीट +40 ft~चालीस फीट ४०.३ ft~चालीस दशमलव तीन फीट -३९ yd~उनतालीस यार्ड +39 yd~उनतालीस यार्ड ३९.१८ yd~उनतालीस दशमलव एक आठ यार्ड -३५ µm~पैंतीस माइक्रोमीटर +35 µm~पैंतीस माइक्रोमीटर ३५.३ µm~पैंतीस दशमलव तीन माइक्रोमीटर -५ km/hr~पाँच किलोमीटर प्रति घंटा +5 km/hr~पाँच किलोमीटर प्रति घंटा ५.३५ km/hr~पाँच दशमलव तीन पाँच किलोमीटर प्रति घंटा -३ mi/hr~तीन मील प्रति घंटा +3 mi/hr~तीन मील प्रति घंटा ३.५ mi/hr~तीन दशमलव पाँच मील प्रति घंटा -२५ °C~पच्चीस डिग्री सेल्सियस +25 °C~पच्चीस डिग्री सेल्सियस २५.४ °C~पच्चीस दशमलव चार डिग्री सेल्सियस -२२ °F~बाईस डिग्री फारेनहाइट +22 °F~बाईस डिग्री फारेनहाइट २२.५ °F~बाईस दशमलव पाँच डिग्री फारेनहाइट -७ K~सात केल्विन +7 K~सात केल्विन ७.२२ K~सात दशमलव दो दो केल्विन -५ L~पाँच लीटर +5 L~पाँच लीटर ५.४ L~पाँच दशमलव चार लीटर -५० ml~पचास मिलीलीटर +50 ml~पचास मिलीलीटर ५०.५ ml~पचास दशमलव पाँच मिलीलीटर -१९ qt~उन्नीस क्वार्ट +19 qt~उन्नीस क्वार्ट १९.७ qt~उन्नीस दशमलव सात क्वार्ट -५ gal~पाँच गैलन +5 gal~पाँच गैलन ५.७ gal~पाँच दशमलव सात गैलन -७६ pt~छिहत्तर पिंट +76 pt~छिहत्तर पिंट ७६.८८ pt~छिहत्तर दशमलव आठ आठ पिंट -७७ g~सतहत्तर ग्राम +77 g~सतहत्तर ग्राम ७७.१९ g~सतहत्तर दशमलव एक नौ ग्राम -५ kg~पाँच किलोग्राम +5 kg~पाँच किलोग्राम ५.६ kg~पाँच दशमलव छह किलोग्राम -५० kg~पचास किलोग्राम +50 kg~पचास किलोग्राम ५०.५ kg~पचास दशमलव पाँच किलोग्राम -९० mg~नब्बे मिलीग्राम +90 mg~नब्बे मिलीग्राम ९०.७ mg~नब्बे दशमलव सात मिलीग्राम -८२ cg~बयासी सेंटीग्राम +82 cg~बयासी सेंटीग्राम ८२.५ cg~बयासी दशमलव पाँच सेंटीग्राम -९७ dg~सत्तानबे डेसीग्राम +97 dg~सत्तानबे डेसीग्राम ९७.७७ dg~सत्तानबे दशमलव सात सात डेसीग्राम -६५ t~पैंसठ टन +65 t~पैंसठ टन ६५.६ t~पैंसठ दशमलव छह टन -८८ st~अट्ठासी स्टोन +88 st~अट्ठासी स्टोन ८८.५ st~अट्ठासी दशमलव पाँच स्टोन -९३ lb~तिरानबे पाउंड +93 lb~तिरानबे पाउंड ९३.४ lb~तिरानबे दशमलव चार पाउंड -९९ oz~निन्यानबे आउन्स +99 oz~निन्यानबे आउन्स ९९.५ oz~निन्यानबे दशमलव पाँच आउन्स -८५ q~पचासी क्विंटल +85 q~पचासी क्विंटल ८५.९९ q~पचासी दशमलव नौ नौ क्विंटल -२००x१० के गद्दे~दो सौ बाई दस के गद्दे +200x10 के गद्दे~दो सौ बाई दस के गद्दे ५x५ का सोफ़ा~पाँच बाई पाँच का सोफ़ा -२x२ रुबिक्स क्यूब~दो बाई दो रुबिक्स क्यूब +2x2 रुबिक्स क्यूब~दो बाई दो रुबिक्स क्यूब १३x१३ का घर~तेरह बाई तेरह का घर +1000 yr~एक हज़ार वर्ष +९९९९ yr~नौ हज़ार नौ सौ निन्यानबे वर्ष +16.07 yr~सोलह दशमलव शून्य सात वर्ष +५ yr~पाँच साल +1.5 yr~डेढ़ साल +२.५ yr~ढाई साल +3.5 yr~साढ़े तीन साल diff --git a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_money.txt b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_money.txt index b576dac38..0b199ff37 100644 --- a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_money.txt +++ b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_money.txt @@ -1,118 +1,118 @@ -₹१११~एक सौ ग्यारह रुपए +₹111~एक सौ ग्यारह रुपए £१८००~एक हज़ार आठ सौ पाउंड -₩७६०~सात सौ साठ वॉन +₩760~सात सौ साठ वॉन $५००~पाँच सौ डॉलर -₹२२~बाईस रुपए +₹22~बाईस रुपए ₺५६००~पाँच हज़ार छह सौ लीरा -₺१२००~एक हज़ार दो सौ लीरा +₺1200~एक हज़ार दो सौ लीरा ₺१२४~एक सौ चौबीस लीरा -$६९६~छह सौ छियानबे डॉलर +$696~छह सौ छियानबे डॉलर ₹१४४~एक सौ चौवालीस रुपए -₺६१५~छह सौ पंद्रह लीरा +₺615~छह सौ पंद्रह लीरा ₩३३०~तीन सौ तीस वॉन -£७००~सात सौ पाउंड +£700~सात सौ पाउंड ₹५३०~पाँच सौ तीस रुपए -₺८५~पचासी लीरा +₺85~पचासी लीरा ₩१९०~एक सौ नब्बे वॉन -₺६~छह लीरा +₺6~छह लीरा ₺१००~एक सौ लीरा -£२०~बीस पाउंड +£20~बीस पाउंड $५०१५~पाँच हज़ार पंद्रह डॉलर -₺६७०~छह सौ सत्तर लीरा +₺670~छह सौ सत्तर लीरा $८००~आठ सौ डॉलर -$७५०००~पचहत्तर हज़ार डॉलर +$75000~पचहत्तर हज़ार डॉलर $७५०~सात सौ पचास डॉलर -₹२१३२~दो हज़ार एक सौ बत्तीस रुपए +₹2132~दो हज़ार एक सौ बत्तीस रुपए ₹१९८~एक सौ अट्ठानबे रुपए -₹१११५~एक हज़ार एक सौ पंद्रह रुपए +₹1115~एक हज़ार एक सौ पंद्रह रुपए ₺५३०~पाँच सौ तीस लीरा -₺५~पाँच लीरा +₺5~पाँच लीरा ₹३१८०~तीन हज़ार एक सौ अस्सी रुपए -₹२४५~दो सौ पैंतालीस रुपए +₹245~दो सौ पैंतालीस रुपए ₹२१४८~दो हज़ार एक सौ अड़तालीस रुपए -₺५१४~पाँच सौ चौदह लीरा +₺514~पाँच सौ चौदह लीरा ₹१५७४~एक हज़ार पाँच सौ चौहत्तर रुपए -$१५००~एक हज़ार पाँच सौ डॉलर +$1500~एक हज़ार पाँच सौ डॉलर ₹२७५~दो सौ पचहत्तर रुपए -₺२३~तेईस लीरा +₺23~तेईस लीरा ₺४०~चालीस लीरा -₺२९१~दो सौ इक्यानबे लीरा +₺291~दो सौ इक्यानबे लीरा ₩३२~बत्तीस वॉन -$५४०~पाँच सौ चालीस डॉलर +$540~पाँच सौ चालीस डॉलर $१९४६~एक हज़ार नौ सौ छियालीस डॉलर -₹६५०~छह सौ पचास रुपए +₹650~छह सौ पचास रुपए ₺४९~उनचास लीरा -₹२१९०~दो हज़ार एक सौ नब्बे रुपए +₹2190~दो हज़ार एक सौ नब्बे रुपए ₹१०००~एक हज़ार रुपए -£१००~एक सौ पाउंड +£100~एक सौ पाउंड ₹५१३५~पाँच हज़ार एक सौ पैंतीस रुपए -₹३२२~तीन सौ बाईस रुपए +₹322~तीन सौ बाईस रुपए $७~सात डॉलर -₩१९५~एक सौ पंचानबे वॉन +₩195~एक सौ पंचानबे वॉन $१०००~एक हज़ार डॉलर -₺१७०८~एक हज़ार सात सौ आठ लीरा +₺1708~एक हज़ार सात सौ आठ लीरा $९~नौ डॉलर -$४४०~चार सौ चालीस डॉलर +$440~चार सौ चालीस डॉलर $१२८~एक सौ अट्ठाईस डॉलर -₺८~आठ लीरा +₺8~आठ लीरा £३०~तीस पाउंड -₹१०००~एक हज़ार रुपए +₹1000~एक हज़ार रुपए ₩५४३~पाँच सौ तैंतालीस वॉन -₹४०५~चार सौ पाँच रुपए +₹405~चार सौ पाँच रुपए £४०~चालीस पाउंड -₹४७~सैंतालीस रुपए +₹47~सैंतालीस रुपए $६९~उनहत्तर डॉलर -₹२२०~दो सौ बीस रुपए +₹220~दो सौ बीस रुपए ₹५१~इक्यावन रुपए -₺४५~पैंतालीस लीरा +₺45~पैंतालीस लीरा ₹६३३~छह सौ तैंतीस रुपए -$१०००~एक हज़ार डॉलर +$1000~एक हज़ार डॉलर $२०००~दो हज़ार डॉलर -₹३२०~तीन सौ बीस रुपए +₹320~तीन सौ बीस रुपए ₹४६७~चार सौ सड़सठ रुपए -₹८११~आठ सौ ग्यारह रुपए +₹811~आठ सौ ग्यारह रुपए ₹१०४०~एक हज़ार चालीस रुपए -$७६५~सात सौ पैंसठ डॉलर +$765~सात सौ पैंसठ डॉलर ₩५९९~पाँच सौ निन्यानबे वॉन -₹५५०~पाँच सौ पचास रुपए +₹550~पाँच सौ पचास रुपए ₹६५६००~पैंसठ हज़ार छह सौ रुपए -$२९~उनतीस डॉलर +$29~उनतीस डॉलर ₩६००~छह सौ वॉन -₹१८९~एक सौ नवासी रुपए +₹189~एक सौ नवासी रुपए ₹५९१~पाँच सौ इक्यानबे रुपए -₹१६८९~एक हज़ार छह सौ नवासी रुपए +₹1689~एक हज़ार छह सौ नवासी रुपए ₹१०९~एक सौ नौ रुपए -₺१२~बारह लीरा +₺12~बारह लीरा ₹२०३~दो सौ तीन रुपए -₹६३५~छह सौ पैंतीस रुपए +₹635~छह सौ पैंतीस रुपए ₹४६९~चार सौ उनहत्तर रुपए -$१२७~एक सौ सत्ताईस डॉलर +$127~एक सौ सत्ताईस डॉलर $८५~पचासी डॉलर -₹५५००००००~पाँच करोड़ पचास लाख रुपए +₹55000000~पाँच करोड़ पचास लाख रुपए $२८२१~दो हज़ार आठ सौ इक्कीस डॉलर -₹१२५४०००~बारह लाख चौवन हज़ार रुपए +₹1254000~बारह लाख चौवन हज़ार रुपए ₹३१५~तीन सौ पंद्रह रुपए -₹२०४४~दो हज़ार चौवालीस रुपए +₹2044~दो हज़ार चौवालीस रुपए ₹१००००~दस हज़ार रुपए -₹५४५~पाँच सौ पैंतालीस रुपए +₹545~पाँच सौ पैंतालीस रुपए ₹१८४५~एक हज़ार आठ सौ पैंतालीस रुपए -₹३७२~तीन सौ बहत्तर रुपए +₹372~तीन सौ बहत्तर रुपए $९८~अट्ठानबे डॉलर -₹१२३.५७~एक सौ तेईस रुपए सत्तावन पैसे +₹123.57~एक सौ तेईस रुपए सत्तावन पैसे ₹९९९.५०~नौ सौ निन्यानबे रुपए पचास पैसे -£१५०.२९~एक सौ पचास पाउंड उनतीस पेंस +£150.29~एक सौ पचास पाउंड उनतीस पेंस £८०.३१~अस्सी पाउंड इकतीस पेंस -₩२३४५.१०~दो हज़ार तीन सौ पैंतालीस वॉन दस जिओन +₩2345.10~दो हज़ार तीन सौ पैंतालीस वॉन दस जिओन ₩१००.२५~एक सौ वॉन पच्चीस जिओन -$१२५.७०~एक सौ पच्चीस डॉलर सत्तर सेंट +$125.70~एक सौ पच्चीस डॉलर सत्तर सेंट $९.९९~नौ डॉलर निन्यानबे सेंट -₺८०.३६~अस्सी लीरा छत्तीस कुरस +₺80.36~अस्सी लीरा छत्तीस कुरस ₺१२३४.७८~एक हज़ार दो सौ चौंतीस लीरा अठहत्तर कुरस -৳१००.४२~एक सौ टका बयालीस पैसे +৳100.42~एक सौ टका बयालीस पैसे ৳३०२५.८७~तीन हज़ार पच्चीस टका सत्तासी पैसे -¥१००.४८~एक सौ येन अड़तालीस सेन +¥100.48~एक सौ येन अड़तालीस सेन ¥७७७.२३~सात सौ सतहत्तर येन तेईस सेन -₦८७६.५३~आठ सौ छिहत्तर नाइरा तिरेपन कोबो +₦876.53~आठ सौ छिहत्तर नाइरा तिरेपन कोबो ₦१०.२७~दस नाइरा सत्ताईस कोबो -€२००.९०~दो सौ यूरो नब्बे सेंट +€200.90~दो सौ यूरो नब्बे सेंट €१२३४.७५~एक हज़ार दो सौ चौंतीस यूरो पचहत्तर सेंट diff --git a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_ordinal.txt b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_ordinal.txt index 9bdcab2a4..7c0789404 100644 --- a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_ordinal.txt +++ b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_ordinal.txt @@ -1,62 +1,72 @@ -१ला~पहला +1ला~पहला १ली~पहली -२रा~दूसरा +2रा~दूसरा २री~दूसरी -३रा~तीसरा +3रा~तीसरा ३री~तीसरी -४था~चौथा +4था~चौथा ४थी~चौथी -५वां~पाँचवां +5वां~पाँचवां ५वीं~पाँचवीं -६ठा~छठा +6ठा~छठा ६ठी~छठी -७वां~सातवां +7वां~सातवां ७वीं~सातवीं -८वां~आठवां +8वां~आठवां ८वीं~आठवीं -९वां~नौवां +9वां~नौवां ९वीं~नौवीं -११वां~ग्यारहवां +11वां~ग्यारहवां १२वीं~बारहवीं -१४वां~चौदहवां +14वां~चौदहवां १६वीं~सोलहवीं -१७वां~सत्रहवां +17वां~सत्रहवां १८वीं~अठारहवीं -१९वां~उन्नीसवां +19वां~उन्नीसवां २०वां~बीसवां -२१वां~इक्कीसवां +21वां~इक्कीसवां २५वीं~पच्चीसवीं -२७वें~सत्ताईसवें +27वें~सत्ताईसवें ३०वीं~तीसवीं -३३वां~तैंतीसवां +33वां~तैंतीसवां ४०वीं~चालीसवीं -४५वां~पैंतालीसवां +45वां~पैंतालीसवां ५०वां~पचासवां -५६वें~छप्पनवें +56वें~छप्पनवें ६०वां~साठवां -६७वीं~सड़सठवीं +67वीं~सड़सठवीं ७५वीं~पचहत्तरवीं -८०वें~अस्सीवें +80वें~अस्सीवें ८८वां~अट्ठासीवां -९१वीं~इक्यानबेवीं +91वीं~इक्यानबेवीं ९९वां~निन्यानबेवां -१००वां~एक सौवां +100वां~एक सौवां १०१वां~एक सौ एकवां -१११वीं~एक सौ ग्यारहवीं +111वीं~एक सौ ग्यारहवीं १२५वें~एक सौ पच्चीसवें -१५३वीं~एक सौ तिरेपनवीं +153वीं~एक सौ तिरेपनवीं २००वीं~दो सौवीं -२१९वीं~दो सौ उन्नीसवीं +219वीं~दो सौ उन्नीसवीं २४०वां~दो सौ चालीसवां -३२९वां~तीन सौ उनतीसवां +329वां~तीन सौ उनतीसवां ३६५वां~तीन सौ पैंसठवां -४५५वां~चार सौ पचपनवां +455वां~चार सौ पचपनवां ५५५वीं~पाँच सौ पचपनवीं -६४०वीं~छह सौ चालीसवीं +640वीं~छह सौ चालीसवीं ८९०वां~आठ सौ नब्बेवां -१००१वीं~एक हज़ार एकवीं +1001वीं~एक हज़ार एकवीं १०९१वें~एक हज़ार इक्यानबेवें -१७८२वीं~सत्रह सौ बयासीवीं +1782वीं~सत्रह सौ बयासीवीं १८९०वां~एक हज़ार आठ सौ नब्बेवां -१९८१वीं~उन्नीस सौ इक्यासीवीं -९८२६वीं~अट्ठानबे सौ छब्बीसवीं \ No newline at end of file +1981वीं~उन्नीस सौ इक्यासीवीं +९८२६वीं~अट्ठानबे सौ छब्बीसवीं +1st~फ़र्स्ट +2nd~सेकंड +3rd~थर्ड +4th~फ़ोर्थ +5th~फ़िफ्थ +6th~सिक्स्थ +7th~सेवंथ +8th~एटथ +9th~नाइंथ +10th~टेंथ diff --git a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_telephone.txt b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_telephone.txt index 7a1b2c662..4c86259e6 100644 --- a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_telephone.txt +++ b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_telephone.txt @@ -1,10 +1,10 @@ -मेरा पुराना नंबर था ९१५७११४००७~मेरा पुराना नंबर था शून्य नौ एक पाँच सात एक एक चार शून्य शून्य सात +मेरा पुराना नंबर था 9157114007~मेरा पुराना नंबर था शून्य नौ एक पाँच सात एक एक चार शून्य शून्य सात इसपे कॉल करो ०३८६२-३५१७९१~इसपे कॉल करो शून्य तीन आठ छह दो तीन पाँच एक सात नौ एक -मेरे इस नंबर पे कॉल करो १३७४-३०९९८८~मेरे इस नंबर पे कॉल करो शून्य एक तीन सात चार तीन शून्य नौ नौ आठ आठ +मेरे इस नंबर पे कॉल करो 1374-309988~मेरे इस नंबर पे कॉल करो शून्य एक तीन सात चार तीन शून्य नौ नौ आठ आठ इसपे कॉल करो ०१६८९११-४५७३~इसपे कॉल करो शून्य एक छह आठ नौ एक एक चार पाँच सात तीन -+९१ ७४४०४३१०८३ मेरे इस नंबर पे कॉल करो~प्लस नौ एक सात चार चार शून्य चार तीन एक शून्य आठ तीन मेरे इस नंबर पे कॉल करो ++91 7440431083 मेरे इस नंबर पे कॉल करो~प्लस नौ एक सात चार चार शून्य चार तीन एक शून्य आठ तीन मेरे इस नंबर पे कॉल करो +९१ ९२१०५१५६०६ मेरे इस नंबर पे कॉल करो~प्लस नौ एक नौ दो एक शून्य पाँच एक पाँच छह शून्य छह मेरे इस नंबर पे कॉल करो -भुगतान के लिए कार्ड के आखिरी अंक १२३४ दर्ज करें~भुगतान के लिए कार्ड के आखिरी अंक एक दो तीन चार दर्ज करें +भुगतान के लिए कार्ड के आखिरी अंक 1234 दर्ज करें~भुगतान के लिए कार्ड के आखिरी अंक एक दो तीन चार दर्ज करें मेरा पिन कोड ११००२३ है~मेरा पिन कोड एक एक शून्य शून्य दो तीन है मेरा पुराना नंबर था 9157114007~मेरा पुराना नंबर था शून्य नौ एक पाँच सात एक एक चार शून्य शून्य सात इसपे कॉल करो 03862-351791~इसपे कॉल करो शून्य तीन आठ छह दो तीन पाँच एक सात नौ एक diff --git a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_time.txt b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_time.txt index 9d670aa8a..5bc796209 100644 --- a/tests/nemo_text_processing/hi/data_text_normalization/test_cases_time.txt +++ b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_time.txt @@ -1,18 +1,18 @@ -१२:१०:१०~बारह बजकर दस मिनट दस सेकंड +12:10:10~बारह बजकर दस मिनट दस सेकंड ५:१२:०१~पाँच बजकर बारह मिनट एक सेकंड -३:१८:४३~तीन बजकर अठारह मिनट तैंतालीस सेकंड +3:18:43~तीन बजकर अठारह मिनट तैंतालीस सेकंड २:१६~दो बजकर सोलह मिनट -७:२१~सात बजकर इक्कीस मिनट +7:21~सात बजकर इक्कीस मिनट ११:५७~ग्यारह बजकर सत्तावन मिनट -८:००~आठ बजे +8:00~आठ बजे ४:००~चार बजे -९:००~नौ बजे +9:00~नौ बजे सुबह के ५:२०:१२~सुबह के पाँच बजकर बीस मिनट बारह सेकंड -सुबह के ६:३९~सुबह के छह बजकर उनतालीस मिनट +सुबह के 6:39~सुबह के छह बजकर उनतालीस मिनट सुबह के २:००~सुबह के दो बजे -दोपहर के ३:५९:३६~दोपहर के तीन बजकर उनसठ मिनट छत्तीस सेकंड +दोपहर के 3:59:36~दोपहर के तीन बजकर उनसठ मिनट छत्तीस सेकंड दोपहर के १:३६~दोपहर के एक बजकर छत्तीस मिनट -दोपहर के ३:००~दोपहर के तीन बजे +दोपहर के 3:00~दोपहर के तीन बजे रात के १०:४८:५०~रात के दस बजकर अड़तालीस मिनट पचास सेकंड -रात के ११:५०~रात के ग्यारह बजकर पचास मिनट +रात के 11:50~रात के ग्यारह बजकर पचास मिनट रात के ८:००~रात के आठ बजे \ No newline at end of file diff --git a/tests/nemo_text_processing/hi/test_address.py b/tests/nemo_text_processing/hi/test_address.py new file mode 100644 index 000000000..41b905f11 --- /dev/null +++ b/tests/nemo_text_processing/hi/test_address.py @@ -0,0 +1,33 @@ +# Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest +from parameterized import parameterized + +from nemo_text_processing.text_normalization.normalize import Normalizer + +from ..utils import CACHE_DIR, parse_test_case_file + + +class TestAddress: + normalizer = Normalizer( + input_case='cased', lang='hi', cache_dir=CACHE_DIR, overwrite_cache=False, post_process=True + ) + + @parameterized.expand(parse_test_case_file('hi/data_text_normalization/test_cases_address.txt')) + @pytest.mark.run_only_on('CPU') + @pytest.mark.unit + def test_norm(self, test_input, expected): + pred = self.normalizer.normalize(test_input, verbose=False, punct_post_process=True) + assert pred == expected diff --git a/tests/nemo_text_processing/hi/test_sparrowhawk_normalization.sh b/tests/nemo_text_processing/hi/test_sparrowhawk_normalization.sh index a0b0931e2..621383a8d 100644 --- a/tests/nemo_text_processing/hi/test_sparrowhawk_normalization.sh +++ b/tests/nemo_text_processing/hi/test_sparrowhawk_normalization.sh @@ -106,10 +106,10 @@ testTNWord() { runtest $input } -#testTNAddress() { -# input=$PROJECT_DIR/en/data_text_normalization/test_cases_address.txt -# runtest $input -#} +testTNAddress() { + input=$PROJECT_DIR/hi/data_text_normalization/test_cases_address.txt + runtest $input +} #testTNMath() { # input=$PROJECT_DIR/en/data_text_normalization/test_cases_math.txt