From ac07488b145262a15fd5c2d7e204be53cb0b6037 Mon Sep 17 00:00:00 2001 From: Mariana <47233618+mgrafu@users.noreply.github.com> Date: Thu, 24 Apr 2025 11:20:30 -0400 Subject: [PATCH 01/16] Staging hi tn (#271) * Future Implementations for classes - Measure, Money, and Date (#258) * Future Implementations for classes - Measure, Money, and Date Signed-off-by: Namrata Gachchi * Resolved the conflicts with mm_yyyy and date ranges and added the previously removed failing test cases. Signed-off-by: Namrata Gachchi * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * removed the unused empty string implementation Signed-off-by: Namrata Gachchi * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * minor fixes for the tagger files Signed-off-by: Namrata Gachchi * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * reformatted decimal final graph Signed-off-by: Namrata Gachchi * incorporated the suggestion for decimal graph Signed-off-by: Namrata Gachchi * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Century implementations Signed-off-by: Namrata Gachchi * Working on the yyyy format for the date class Signed-off-by: Namrata Gachchi * reverted yyyy code Signed-off-by: Namrata Gachchi * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * working on future implementations Signed-off-by: Namrata Gachchi * working on improving the date class accuracy Signed-off-by: Namrata Gachchi * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * added year prefix for the date class Signed-off-by: Namrata Gachchi * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * working on the commma cases for date class Signed-off-by: Namrata Gachchi * minor fixes Signed-off-by: Namrata Gachchi * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * implemented mixed fractions Signed-off-by: Namrata Gachchi * rectified the test case Signed-off-by: Namrata Gachchi * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * working on quarterly measurements Signed-off-by: Namrata Gachchi * reformatted the prefixes and suffixes for date tagger class Signed-off-by: Namrata Gachchi * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * replaced text tag with era tag for the date class Signed-off-by: Namrata Gachchi * Removed the text tag reference from date class verbalizer Signed-off-by: Namrata Gachchi --------- Signed-off-by: Namrata Gachchi Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * update jenkins cache Signed-off-by: Mariana Graterol Fuenmayor * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Potential fix for code scanning alert no. 821: Unused local variable Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: Mariana <47233618+mgrafu@users.noreply.github.com> --------- Signed-off-by: Namrata Gachchi Signed-off-by: Mariana Graterol Fuenmayor Signed-off-by: Mariana <47233618+mgrafu@users.noreply.github.com> Co-authored-by: Namrata Gachchi Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- Jenkinsfile | 2 +- .../hi/data/date/prefixes.tsv | 3 + .../hi/data/date/suffixes.tsv | 10 +++ .../hi/data/date/year_suffix.tsv | 2 + .../hi/data/measure/quarterly_units.tsv | 12 +++ .../hi/data/measure/unit.tsv | 4 +- .../hi/data/money/currency.tsv | 3 +- .../hi/data/money/major_minor_currencies.tsv | 9 ++ .../hi/data/numbers/teens_and_ties.tsv | 16 ++-- .../text_normalization/hi/data/time/hours.tsv | 1 + .../text_normalization/hi/taggers/cardinal.py | 3 + .../text_normalization/hi/taggers/date.py | 56 +++++++++++- .../text_normalization/hi/taggers/measure.py | 87 +++++++++++++++++-- .../text_normalization/hi/taggers/money.py | 34 +++++--- .../hi/taggers/tokenize_and_classify.py | 7 +- .../text_normalization/hi/verbalizers/date.py | 4 +- .../hi/verbalizers/fraction.py | 7 +- .../hi/verbalizers/money.py | 79 ++++++++++++----- .../hi/verbalizers/verbalize.py | 20 +++-- .../hi/verbalizers/whitelist.py | 2 + .../test_cases_date.txt | 15 ++++ .../test_cases_fraction.txt | 4 +- .../test_cases_measure.txt | 4 + .../test_cases_money.txt | 20 ++++- 24 files changed, 334 insertions(+), 70 deletions(-) create mode 100644 nemo_text_processing/text_normalization/hi/data/date/prefixes.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/date/suffixes.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/date/year_suffix.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/measure/quarterly_units.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/money/major_minor_currencies.tsv diff --git a/Jenkinsfile b/Jenkinsfile index c94c107c6..51ce37a10 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -27,7 +27,7 @@ pipeline { HY_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/03-12-24-0' MR_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/03-12-24-1' JA_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/10-17-24-1' - HI_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/04-03-25-1' + HI_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/04-22-25-0' DEFAULT_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/06-08-23-0' } stages { diff --git a/nemo_text_processing/text_normalization/hi/data/date/prefixes.tsv b/nemo_text_processing/text_normalization/hi/data/date/prefixes.tsv new file mode 100644 index 000000000..d4c1ca0b1 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/date/prefixes.tsv @@ -0,0 +1,3 @@ +सन् +सन +साल \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/date/suffixes.tsv b/nemo_text_processing/text_normalization/hi/data/date/suffixes.tsv new file mode 100644 index 000000000..6806d3f12 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/date/suffixes.tsv @@ -0,0 +1,10 @@ + में + का + की + के + से + तक + ईस्वी + शताब्दी + दशक + सदी \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/date/year_suffix.tsv b/nemo_text_processing/text_normalization/hi/data/date/year_suffix.tsv new file mode 100644 index 000000000..acb37d534 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/date/year_suffix.tsv @@ -0,0 +1,2 @@ +ई. पू. ईसा पूर्व +ई. ईसवी \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/measure/quarterly_units.tsv b/nemo_text_processing/text_normalization/hi/data/measure/quarterly_units.tsv new file mode 100644 index 000000000..eaddf930a --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/measure/quarterly_units.tsv @@ -0,0 +1,12 @@ +s सेकंड +hr घंटा +h घंटे +min मिनट +doz दर्जन +yr साल +yr वर्ष +hp हॉर्सपॉवर +d दिन +month महीना +months महीने +हफ़्ते हफ़्ते \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/measure/unit.tsv b/nemo_text_processing/text_normalization/hi/data/measure/unit.tsv index 0bf561379..189512687 100644 --- a/nemo_text_processing/text_normalization/hi/data/measure/unit.tsv +++ b/nemo_text_processing/text_normalization/hi/data/measure/unit.tsv @@ -141,14 +141,16 @@ month महीना months महीने ct कैरेट pH पीएच +km/h किलोमीटर प्रति घंटा km/hr किलोमीटर प्रति घंटा km/min किलोमीटर प्रति मिनट +m/h मीटर प्रति घंटा m/hr मीटर प्रति घंटा mi/s मील प्रति सेकंड +mi/h मील प्रति घंटा mi/hr मील प्रति घंटा mi/min मील प्रति मिनट ₹/ac रुपए प्रति एकड़ x बाई X बाई * बाई -- से diff --git a/nemo_text_processing/text_normalization/hi/data/money/currency.tsv b/nemo_text_processing/text_normalization/hi/data/money/currency.tsv index 88633ec7c..8f4a955cc 100644 --- a/nemo_text_processing/text_normalization/hi/data/money/currency.tsv +++ b/nemo_text_processing/text_normalization/hi/data/money/currency.tsv @@ -1,5 +1,4 @@ ₹ रुपए -P पैसे £ पाउंड ₩ वॉन $ डॉलर @@ -7,4 +6,4 @@ $ डॉलर ৳ टका ¥ येन ₦ नाइरा -€ यूरो +€ यूरो \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/money/major_minor_currencies.tsv b/nemo_text_processing/text_normalization/hi/data/money/major_minor_currencies.tsv new file mode 100644 index 000000000..cf62891d1 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/money/major_minor_currencies.tsv @@ -0,0 +1,9 @@ +रुपए पैसे +पाउंड पेंस +वॉन जिओन +डॉलर सेंट +लीरा कुरस +टका पैसे +येन सेन +नाइरा कोबो +यूरो सेंट diff --git a/nemo_text_processing/text_normalization/hi/data/numbers/teens_and_ties.tsv b/nemo_text_processing/text_normalization/hi/data/numbers/teens_and_ties.tsv index 1d61c77b7..fbf248266 100644 --- a/nemo_text_processing/text_normalization/hi/data/numbers/teens_and_ties.tsv +++ b/nemo_text_processing/text_normalization/hi/data/numbers/teens_and_ties.tsv @@ -79,12 +79,12 @@ ८८ अट्ठासी ८९ नवासी ९० नब्बे -९१ इक्यानबे -९२ बानबे -९३ तिरानबे -९४ चौरानबे -९५ पंचानबे -९६ छियानबे -९७ सत्तानबे -९८ अट्ठानबे +९१ इक्यानबे +९२ बानबे +९३ तिरानबे +९४ चौरानबे +९५ पंचानबे +९६ छियानबे +९७ सत्तानबे +९८ अट्ठानबे ९९ निन्यानबे 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 d5e85a784..dd8623284 100644 --- a/nemo_text_processing/text_normalization/hi/data/time/hours.tsv +++ b/nemo_text_processing/text_normalization/hi/data/time/hours.tsv @@ -1,3 +1,4 @@ +० शून्य १ एक २ दो ३ तीन diff --git a/nemo_text_processing/text_normalization/hi/taggers/cardinal.py b/nemo_text_processing/text_normalization/hi/taggers/cardinal.py index f6a8bdd65..c50384acf 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/cardinal.py +++ b/nemo_text_processing/text_normalization/hi/taggers/cardinal.py @@ -80,6 +80,7 @@ def create_larger_number_graph(digit_graph, suffix, zeros_counts, sub_graph): graph_ten_thousands |= create_larger_number_graph(teens_and_ties, suffix_thousands, 1, teens_ties) graph_ten_thousands |= create_larger_number_graph(teens_and_ties, suffix_thousands, 0, graph_hundreds) graph_ten_thousands.optimize() + self.graph_ten_thousands = graph_ten_thousands # Lakhs graph and ten lakhs graph suffix_lakhs = pynutil.insert(" लाख") @@ -90,6 +91,7 @@ def create_larger_number_graph(digit_graph, suffix, zeros_counts, sub_graph): graph_lakhs |= create_larger_number_graph(digit, suffix_lakhs, 1, graph_thousands) graph_lakhs |= create_larger_number_graph(digit, suffix_lakhs, 0, graph_ten_thousands) graph_lakhs.optimize() + self.graph_lakhs = graph_lakhs graph_ten_lakhs = create_graph_suffix(teens_and_ties, suffix_lakhs, 5) graph_ten_lakhs |= create_larger_number_graph(teens_and_ties, suffix_lakhs, 4, digit) @@ -98,6 +100,7 @@ def create_larger_number_graph(digit_graph, suffix, zeros_counts, sub_graph): graph_ten_lakhs |= create_larger_number_graph(teens_and_ties, suffix_lakhs, 1, graph_thousands) graph_ten_lakhs |= create_larger_number_graph(teens_and_ties, suffix_lakhs, 0, graph_ten_thousands) graph_ten_lakhs.optimize() + self.graph_ten_lakhs = graph_ten_lakhs # Crores graph ten crores graph suffix_crores = pynutil.insert(" करोड़") diff --git a/nemo_text_processing/text_normalization/hi/taggers/date.py b/nemo_text_processing/text_normalization/hi/taggers/date.py index 42135add7..37b192165 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/date.py +++ b/nemo_text_processing/text_normalization/hi/taggers/date.py @@ -26,6 +26,20 @@ days = pynini.string_file(get_abs_path("data/date/days.tsv")) 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_and_ties = pynutil.add_weight(teens_ties, -0.1) + +# Read suffixes from file into a list +with open(get_abs_path("data/date/suffixes.tsv"), "r", encoding="utf-8") as f: + suffixes_list = f.read().splitlines() +with open(get_abs_path("data/date/prefixes.tsv"), "r", encoding="utf-8") as f: + prefixes_list = f.read().splitlines() + +# Create union of suffixes and prefixes +suffix_union = pynini.union(*suffixes_list) +prefix_union = pynini.union(*prefixes_list) class DateFst(GraphFst): @@ -51,6 +65,10 @@ def __init__(self, cardinal: GraphFst): (NEMO_HI_DIGIT + NEMO_HI_NON_ZERO + NEMO_HI_DIGIT + NEMO_HI_DIGIT), cardinal.graph_hundreds_as_thousand ) + cardinal_graph = ( + digit | teens_and_ties | cardinal.graph_hundreds | graph_year_thousands | graph_year_hundreds_as_thousands + ) + graph_year = graph_year_thousands | graph_year_hundreds_as_thousands delete_dash = pynutil.delete("-") @@ -68,6 +86,22 @@ def __init__(self, cardinal: GraphFst): graph_mm_dd += pynutil.insert(" preserve_order: true ") + # Graph for era + era_graph = pynutil.insert("era: \"") + year_suffix + pynutil.insert("\"") + insert_space + + range_graph = pynini.cross("-", "से") + + # Graph for year + century_number = pynini.compose(pynini.closure(NEMO_HI_DIGIT, 1), cardinal_graph) + pynini.accep("वीं") + century_text = pynutil.insert("era: \"") + century_number + pynutil.insert("\"") + insert_space + + # Updated logic to use suffix_union + year_number = graph_year + suffix_union + year_text = pynutil.insert("era: \"") + year_number + pynutil.insert("\"") + insert_space + + # Updated logic to use prefix_union + year_prefix = pynutil.insert("era: \"") + prefix_union + insert_space + graph_year + pynutil.insert("\"") + graph_dd_mm_yyyy = ( days_graph + (delete_dash | delete_slash) + months_graph + (delete_dash | delete_slash) + years_graph ) @@ -78,7 +112,20 @@ def __init__(self, cardinal: GraphFst): graph_mm_dd_yyyy += pynutil.insert(" preserve_order: true ") - graph_mm_yyyy = months_graph + delete_dash + years_graph + graph_mm_yyyy = months_graph + delete_dash + insert_space + years_graph + + graph_year_suffix = era_graph + + graph_range = ( + pynutil.insert("era: \"") + + cardinal_graph + + insert_space + + range_graph + + insert_space + + cardinal_graph + + pynutil.insert("\"") + + pynutil.insert(" preserve_order: true ") + ) # default assume dd_mm_yyyy @@ -87,7 +134,12 @@ def __init__(self, cardinal: GraphFst): | graph_mm_dd | pynutil.add_weight(graph_dd_mm_yyyy, -0.001) | graph_mm_dd_yyyy - | graph_mm_yyyy + | pynutil.add_weight(graph_mm_yyyy, -0.2) + | pynutil.add_weight(graph_year_suffix, -0.001) + | pynutil.add_weight(graph_range, -0.005) + | pynutil.add_weight(century_text, -0.001) + | pynutil.add_weight(year_text, -0.001) + | pynutil.add_weight(year_prefix, -0.009) ) self.final_graph = final_graph.optimize() diff --git a/nemo_text_processing/text_normalization/hi/taggers/measure.py b/nemo_text_processing/text_normalization/hi/taggers/measure.py index 55279f4da..9f1ffbd39 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/measure.py +++ b/nemo_text_processing/text_normalization/hi/taggers/measure.py @@ -19,6 +19,11 @@ from nemo_text_processing.text_normalization.hi.utils import get_abs_path +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_and_ties = pynutil.add_weight(teens_ties, -0.1) + + class MeasureFst(GraphFst): """ Finite state transducer for classifying measure, suppletive aware, e.g. @@ -35,9 +40,20 @@ class MeasureFst(GraphFst): def __init__(self, cardinal: GraphFst, decimal: GraphFst): super().__init__(name="measure", kind="classify") - cardinal_graph = cardinal.final_graph - decimal_graph = decimal.final_graph_wo_negative + cardinal_graph = ( + digit + | teens_and_ties + | cardinal.graph_hundreds + | cardinal.graph_thousands + | cardinal.graph_ten_thousands + | cardinal.graph_lakhs + | cardinal.graph_ten_lakhs + ) + point = pynutil.delete(".") + decimal_integers = pynutil.insert("integer_part: \"") + cardinal_graph + pynutil.insert("\"") + decimal_graph = decimal_integers + point + insert_space + decimal.graph_fractional unit_graph = pynini.string_file(get_abs_path("data/measure/unit.tsv")) + quarterly_units_graph = pynini.string_file(get_abs_path("data/measure/quarterly_units.tsv")) optional_graph_negative = pynini.closure( pynutil.insert("negative: ") + pynini.cross("-", "\"true\"") + insert_space, @@ -45,18 +61,48 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): 1, ) + # Define the quarterly measurements + quarter = pynini.string_map( + [ + (".५", "साढ़े"), + ("१.५", "डेढ़"), + ("२.५", "ढाई"), + ] + ) + quarter_graph = pynutil.insert("integer_part: \"") + quarter + pynutil.insert("\"") + # Define the unit handling - self.unit = pynutil.insert("units: \"") + unit_graph + pynutil.insert("\" ") + unit = pynutil.insert(" units: \"") + unit_graph + pynutil.insert("\" ") + units = pynutil.insert(" units: \"") + quarterly_units_graph + pynutil.insert("\" ") + + # Handling symbols like x, X, * + symbol_graph = pynini.string_map( + [ + ("x", "बाई"), + ("X", "बाई"), + ("*", "बाई"), + ] + ) - graph_measurements = ( + graph_decimal = ( pynutil.insert("decimal { ") + optional_graph_negative + decimal_graph + pynutil.insert(" }") + delete_space - + self.unit + + unit ) - graph_measurements |= ( + + graph_quarter = ( + pynutil.insert("cardinal { ") + + optional_graph_negative + + quarter_graph + + pynutil.insert(" }") + + delete_space + + units + ) + + graph_cardinal = ( pynutil.insert("cardinal { ") + optional_graph_negative + pynutil.insert("integer: \"") @@ -64,10 +110,35 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): + pynutil.insert("\"") + pynutil.insert(" }") + delete_space - + self.unit + + unit ) - graph = graph_measurements + # Handling cardinal clubbed with symbol as single token + graph_exceptions = ( + pynutil.insert("cardinal { ") + + optional_graph_negative + + pynutil.insert("integer: \"") + + cardinal_graph + + pynutil.insert("\"") + + pynutil.insert(" }") + + pynutil.insert(" units: \"") + + symbol_graph + + pynutil.insert("\" ") + + pynutil.insert("} }") + + insert_space + + pynutil.insert("tokens { cardinal { ") + + optional_graph_negative + + pynutil.insert("integer: \"") + + cardinal_graph + + pynutil.insert("\"") + ) + + graph = ( + pynutil.add_weight(graph_decimal, 0.01) + | pynutil.add_weight(graph_quarter, 0.005) + | pynutil.add_weight(graph_cardinal, 0.01) + | pynutil.add_weight(graph_exceptions, 0.01) + ) self.graph = graph.optimize() final_graph = self.add_tokens(graph) diff --git a/nemo_text_processing/text_normalization/hi/taggers/money.py b/nemo_text_processing/text_normalization/hi/taggers/money.py index 7446b77e5..01e46352f 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/money.py +++ b/nemo_text_processing/text_normalization/hi/taggers/money.py @@ -24,8 +24,10 @@ class MoneyFst(GraphFst): """ Finite state transducer for classifying money, suppletive aware, e.g. - ₹1 -> money { currency: "रुपए" integer_part: "एक" } - ₹1.2 -> money { currency: "रुपए" integer_part: "एक" fractional_part: "दो" } + ₹५० -> money { money { currency_maj: "रुपए" integer_part: "पचास" } + ₹५०.५० -> money { currency_maj: "रुपए" integer_part: "पचास" fractional_part: "पचास" currency_min: "centiles" } + ₹०.५० -> money { currency_maj: "रुपए" integer_part: "शून्य" fractional_part: "पचास" currency_min: "centiles" } + Note that the 'centiles' string is a placeholder to handle by the verbalizer by applying the corresponding minor currency denomination Args: cardinal: CardinalFst @@ -34,7 +36,7 @@ class MoneyFst(GraphFst): for False multiple transduction are generated (used for audio-based normalization) """ - def __init__(self, cardinal: GraphFst, decimal: GraphFst): + def __init__(self, cardinal: GraphFst): super().__init__(name="money", kind="classify") cardinal_graph = cardinal.final_graph @@ -44,21 +46,25 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): 0, 1, ) - self.currency = pynutil.insert("currency: \"") + currency_graph + pynutil.insert("\" ") - self.interger = pynutil.insert("integer_part: \"") + cardinal_graph + pynutil.insert("\" ") - self.fraction = pynutil.insert("fractional_part: \"") + cardinal_graph + pynutil.insert("\" ") + currency_major = pynutil.insert('currency_maj: "') + currency_graph + pynutil.insert('"') + integer = pynutil.insert('integer_part: "') + cardinal_graph + pynutil.insert('"') + fraction = pynutil.insert('fractional_part: "') + cardinal_graph + pynutil.insert('"') + currency_minor = pynutil.insert('currency_min: "') + pynutil.insert("centiles") + pynutil.insert('"') - graph_currencies = optional_graph_negative + self.currency + insert_space + self.interger - graph_currencies |= ( + graph_major_only = optional_graph_negative + currency_major + insert_space + integer + graph_major_and_minor = ( optional_graph_negative - + self.currency + + currency_major + insert_space - + self.interger - + pynutil.delete(".") + + integer + + pynini.cross(".", " ") + + fraction + insert_space - + self.fraction + + currency_minor ) - graph = graph_currencies - self.graph = graph.optimize() + + graph_currencies = graph_major_only | graph_major_and_minor + + graph = graph_currencies.optimize() final_graph = self.add_tokens(graph) self.fst = final_graph 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 cc22a99f5..b1bbd2a10 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 @@ -68,11 +68,12 @@ def __init__( os.makedirs(cache_dir, exist_ok=True) whitelist_file = os.path.basename(whitelist) if whitelist else "" far_file = os.path.join( - cache_dir, f"hi_tn_{deterministic}_deterministic_{input_case}_{whitelist_file}_tokenize.far" + cache_dir, + f"hi_tn_{deterministic}_deterministic_{input_case}_{whitelist_file}_tokenize.far", ) if not overwrite_cache and far_file and os.path.exists(far_file): self.fst = pynini.Far(far_file, mode="r")["tokenize_and_classify"] - logging.info(f'ClassifyFst.fst was restored from {far_file}.') + logging.info(f"ClassifyFst.fst was restored from {far_file}.") else: logging.info(f"Creating ClassifyFst grammars.") @@ -107,7 +108,7 @@ def __init__( logging.debug(f"measure: {time.time() - start_time: .2f}s -- {measure_graph.num_states()} nodes") start_time = time.time() - money = MoneyFst(cardinal=cardinal, decimal=decimal) + money = MoneyFst(cardinal=cardinal) money_graph = money.fst logging.debug(f"money: {time.time() - start_time: .2f}s -- {money_graph.num_states()} nodes") diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/date.py b/nemo_text_processing/text_normalization/hi/verbalizers/date.py index f0af1a2d4..8904f63c8 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/date.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/date.py @@ -39,6 +39,8 @@ def __init__(self): year = pynutil.delete("year: \"") + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete("\"") + graph_era = pynutil.delete("era: \"") + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete("\"") + graph_dd_mm = day + NEMO_SPACE + month graph_mm_dd = month + NEMO_SPACE + day @@ -60,7 +62,7 @@ def __init__(self): ) self.graph = ( - (graph_dd_mm | graph_mm_dd | graph_dd_mm_yyyy | graph_mm_dd_yyyy | graph_mm_yyyy) + (graph_dd_mm | graph_mm_dd | graph_dd_mm_yyyy | graph_mm_dd_yyyy | graph_mm_yyyy | graph_era) + delete_space + optional_preserve_order ) diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py index 39b16b423..7e3b33b7c 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py @@ -39,10 +39,15 @@ def __init__(self, cardinal: GraphFst, deterministic: bool = True): numerator = pynutil.delete("numerator: \"") + pynini.closure(NEMO_NOT_QUOTE) + pynutil.delete("\" ") denominator = pynutil.delete("denominator: \"") + pynini.closure(NEMO_NOT_QUOTE) + pynutil.delete("\"") insert_bata = pynutil.insert(" बटा ") + insert_aur = pynutil.insert(" और ") fraction_default = numerator + insert_bata + denominator - self.graph = optional_sign + pynini.closure(pynini.closure(integer, 0, 1) + insert_space) + fraction_default + self.graph = ( + optional_sign + + pynini.closure(pynini.closure(integer, 0, 1) + insert_space + insert_aur) + + fraction_default + ) graph = self.graph diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/money.py b/nemo_text_processing/text_normalization/hi/verbalizers/money.py index d5cab33d8..048140295 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/money.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/money.py @@ -15,14 +15,26 @@ import pynini from pynini.lib import pynutil -from nemo_text_processing.text_normalization.hi.graph_utils import NEMO_NOT_QUOTE, GraphFst, delete_space, insert_space +major_minor_currencies = { + "रुपए": "पैसे", + "पाउंड": "पेंस", + "वॉन": "जिओन", + "डॉलर": "सेंट", + "लीरा": "कुरस", + "टका": "पैसे", + "येन": "सेन", + "नाइरा": "कोबो", + "यूरो": "सेंट", +} +from nemo_text_processing.text_normalization.hi.graph_utils import NEMO_NOT_QUOTE, NEMO_SPACE, GraphFst class MoneyFst(GraphFst): """ Finite state transducer for verbalizing money, e.g. - money { integer_part: "बारह" currency: "रुपए" } -> बारह रुपए - money { integer_part: "बारह" currency: "रुपए" fractional_part: "पचास" currency: "पैसे" } -> बारह रुपए पचास पैसे + money { integer_part: "बारह" currency_maj: "रुपए" } -> बारह रुपए + money { integer_part: "बारह" currency_maj: "रुपए" fractional_part: "पचास" currency_min: "centiles" } -> बारह रुपए पचास पैसे + money { currency_maj: "रुपए" integer_part: "शून्य" fractional_part: "पचास" currency_min: "centiles" } -> पचास पैसे Args: cardinal: CardinalFst @@ -31,33 +43,58 @@ class MoneyFst(GraphFst): for False multiple transduction are generated (used for audio-based normalization) """ - def __init__(self, cardinal: GraphFst, decimal: GraphFst): + def __init__(self): super().__init__(name="money", kind="verbalize") - insert_paise = pynutil.insert("पैसे") + currency_major = pynutil.delete('currency_maj: "') + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete('"') - currency = ( - pynutil.delete('currency: "') + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete('" ') + insert_space - ) - - integer_part = ( - pynutil.delete('integer_part: "') + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete('" ') + insert_space - ) + integer_part = pynutil.delete('integer_part: "') + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete('"') fractional_part = ( - pynutil.delete('fractional_part: "') - + pynini.closure(NEMO_NOT_QUOTE, 1) - + pynutil.delete('" ') - + insert_space + pynutil.delete('fractional_part: "') + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete('"') ) - graph_integer = integer_part + delete_space + currency + # Handles major denominations only + graph_major_only = integer_part + pynini.accep(NEMO_SPACE) + currency_major - graph_interger_fraction = ( - integer_part + delete_space + currency + delete_space + fractional_part + delete_space + insert_paise - ) + # Handles both major and minor denominations + major_minor_graphs = [] + + # Handles minor denominations only + minor_graphs = [] + + # Logic for handling minor denominations + for major, minor in major_minor_currencies.items(): + graph_major = pynutil.delete('currency_maj: "') + pynini.accep(major) + pynutil.delete('"') + graph_minor = pynutil.delete('currency_min: "') + pynini.cross("centiles", minor) + pynutil.delete('"') + graph_major_minor_partial = ( + integer_part + + pynini.accep(NEMO_SPACE) + + graph_major + + pynini.accep(NEMO_SPACE) + + fractional_part + + pynini.accep(NEMO_SPACE) + + graph_minor + ) + major_minor_graphs.append(graph_major_minor_partial) + + graph_minor_partial = ( + pynutil.delete('integer_part: "शून्य"') + + pynutil.delete(NEMO_SPACE) + + pynutil.delete('currency_maj: "') + + pynutil.delete(major) + + pynutil.delete('"') + + pynutil.delete(NEMO_SPACE) + + fractional_part + + pynini.accep(NEMO_SPACE) + + graph_minor + ) + minor_graphs.append(graph_minor_partial) + + graph_major_minor = pynini.union(*major_minor_graphs) + graph_minor_only = pynini.union(*minor_graphs) - graph = graph_integer | graph_interger_fraction + graph = graph_major_only | graph_major_minor | pynutil.add_weight(graph_minor_only, -0.1) delete_tokens = self.delete_tokens(graph) self.fst = delete_tokens.optimize() diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py b/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py index ca06fc9c3..e91f0d9f6 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py @@ -20,8 +20,7 @@ from nemo_text_processing.text_normalization.hi.verbalizers.measure import MeasureFst from nemo_text_processing.text_normalization.hi.verbalizers.money import MoneyFst from nemo_text_processing.text_normalization.hi.verbalizers.time import TimeFst - -# from nemo_text_processing.text_normalization.hi.verbalizers.whitelist import WhiteListFst +from nemo_text_processing.text_normalization.hi.verbalizers.whitelist import WhiteListFst class VerbalizeFst(GraphFst): @@ -56,11 +55,20 @@ def __init__(self, deterministic: bool = True): measure = MeasureFst(cardinal=cardinal, decimal=decimal) measure_graph = measure.fst - money = MoneyFst(cardinal=cardinal, decimal=decimal) + money = MoneyFst() money_graph = money.fst - # whitelist_graph = WhiteListFst(deterministic=deterministic).fst - - graph = cardinal_graph | decimal_graph | fraction_graph | date_graph | time_graph | measure_graph | money_graph + whitelist_graph = WhiteListFst(deterministic=deterministic).fst + + graph = ( + cardinal_graph + | decimal_graph + | fraction_graph + | date_graph + | time_graph + | measure_graph + | money_graph + | whitelist_graph + ) self.fst = graph diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/whitelist.py b/nemo_text_processing/text_normalization/hi/verbalizers/whitelist.py index 58dbc9583..d846dfa58 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/whitelist.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/whitelist.py @@ -11,6 +11,8 @@ # 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 pynini from pynini.lib import pynutil 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 d92a53852..a4b3caf07 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 @@ -17,3 +17,18 @@ ११-२०२४~नवंबर दो हज़ार चौबीस २०७०~दो हज़ार सत्तर २०२४~दो हज़ार चौबीस +१२० ई. पू.~एक सौ बीस ईसा पूर्व +२९७-२७२ ई. पू.~दो सौ सत्तानबे से दो सौ बहत्तर ईसा पूर्व +३२७वीं सदी~तीन सौ सत्ताईसवीं सदी +१८वीं शताब्दी~अठारहवीं शताब्दी +१९वीं दशक~उन्नीसवीं दशक +१९९९ में~उन्नीस सौ निन्यानबे में +१९९० का~उन्नीस सौ नब्बे का +१९९२ की~उन्नीस सौ बानबे की +१९६० के अभिनेता है~उन्नीस सौ साठ के अभिनेता है +१७८८ से~सत्रह सौ अट्ठासी से +१९५४ तक~उन्नीस सौ चौवन तक +सन १९९९~सन उन्नीस सौ निन्यानबे +सन् १९२०~सन् उन्नीस सौ बीस +साल १९७१~साल उन्नीस सौ इकहत्तर +१९२०-२६ तक~उन्नीस सौ बीस से छब्बीस तक \ No newline at end of file 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 25c18b777..d1473412e 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,5 +1,5 @@ ९९/९९~निन्यानबे बटा निन्यानबे -२२ ३१/१७~बाईस इकतीस बटा सत्रह +२२ ३१/१७~बाईस और इकतीस बटा सत्रह ९७/०~सत्तानबे बटा शून्य २५६३/४१२~दो हज़ार पाँच सौ तिरेसठ बटा चार सौ बारह ७२८६०/७०~बहत्तर हज़ार आठ सौ साठ बटा सत्तर @@ -19,3 +19,5 @@ १०००००००००००००/३~एक नील बटा तीन १०००००००००००००००/८~एक पद्म बटा आठ १०००००००००००००००००/४१२~एक शंख बटा चार सौ बारह +२ २/७~दो और दो बटा सात +१२० ७५/९०~एक सौ बीस और पचहत्तर बटा नब्बे \ 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 453369f82..86a824f72 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 @@ -60,3 +60,7 @@ ९९.५ oz~निन्यानबे दशमलव पाँच आउन्स ८५ q~पचासी क्विंटल ८५.९९ q~पचासी दशमलव नौ नौ क्विंटल +२००x१० के गद्दे~दो सौ बाई दस के गद्दे +५x५ का सोफ़ा~पाँच बाई पाँच का सोफ़ा +२x२ रुबिक्स क्यूब~दो बाई दो रुबिक्स क्यूब +१३x१३ का घर~तेरह बाई तेरह का घर 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 c7b32628b..b576dac38 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 @@ -97,4 +97,22 @@ $२८२१~दो हज़ार आठ सौ इक्कीस डॉल ₹५४५~पाँच सौ पैंतालीस रुपए ₹१८४५~एक हज़ार आठ सौ पैंतालीस रुपए ₹३७२~तीन सौ बहत्तर रुपए -$९८~अट्ठानबे डॉलर \ No newline at end of file +$९८~अट्ठानबे डॉलर +₹१२३.५७~एक सौ तेईस रुपए सत्तावन पैसे +₹९९९.५०~नौ सौ निन्यानबे रुपए पचास पैसे +£१५०.२९~एक सौ पचास पाउंड उनतीस पेंस +£८०.३१~अस्सी पाउंड इकतीस पेंस +₩२३४५.१०~दो हज़ार तीन सौ पैंतालीस वॉन दस जिओन +₩१००.२५~एक सौ वॉन पच्चीस जिओन +$१२५.७०~एक सौ पच्चीस डॉलर सत्तर सेंट +$९.९९~नौ डॉलर निन्यानबे सेंट +₺८०.३६~अस्सी लीरा छत्तीस कुरस +₺१२३४.७८~एक हज़ार दो सौ चौंतीस लीरा अठहत्तर कुरस +৳१००.४२~एक सौ टका बयालीस पैसे +৳३०२५.८७~तीन हज़ार पच्चीस टका सत्तासी पैसे +¥१००.४८~एक सौ येन अड़तालीस सेन +¥७७७.२३~सात सौ सतहत्तर येन तेईस सेन +₦८७६.५३~आठ सौ छिहत्तर नाइरा तिरेपन कोबो +₦१०.२७~दस नाइरा सत्ताईस कोबो +€२००.९०~दो सौ यूरो नब्बे सेंट +€१२३४.७५~एक हज़ार दो सौ चौंतीस यूरो पचहत्तर सेंट From e165e631e9d2c3a3f7b49c55f58c0345c3d585ad Mon Sep 17 00:00:00 2001 From: Namrata Gachchi Date: Tue, 24 Jun 2025 15:05:08 +0530 Subject: [PATCH 02/16] telephone changes and other future implementations Signed-off-by: Namrata Gachchi --- .../hi/data/date/year_suffix.tsv | 2 +- .../hi/data/measure/quarterly_units.tsv | 6 +- .../hi/data/measure/unit.tsv | 1 - .../hi/data/telephone/STD_codes.tsv | 948 ++++++++++++++++++ .../hi/data/telephone/__init__.py | 13 + .../hi/data/telephone/country_codes.tsv | 2 + .../hi/data/telephone/landline_digits.tsv | 8 + .../hi/data/telephone/mobile_digits.tsv | 8 + .../hi/data/telephone/number.tsv | 20 + .../text_normalization/hi/data/time/hours.tsv | 1 - .../hi/data/whitelist/paune_mappings.tsv | 100 ++ .../text_normalization/hi/taggers/cardinal.py | 24 +- .../text_normalization/hi/taggers/date.py | 1 + .../text_normalization/hi/taggers/decimal.py | 4 +- .../text_normalization/hi/taggers/fraction.py | 37 +- .../text_normalization/hi/taggers/measure.py | 70 +- .../hi/taggers/telephone.py | 140 +++ .../text_normalization/hi/taggers/time.py | 33 +- .../hi/taggers/tokenize_and_classify.py | 9 +- .../text_normalization/hi/taggers/word.py | 2 +- .../hi/verbalizers/fraction.py | 11 +- .../hi/verbalizers/telephone.py | 65 ++ .../text_normalization/hi/verbalizers/time.py | 6 +- .../hi/verbalizers/verbalize.py | 7 +- .../test_cases_cardinal.txt | 2 +- .../test_cases_fraction.txt | 6 +- .../test_cases_measure.txt | 5 + .../test_cases_telephone.txt | 6 + .../test_cases_time.txt | 7 +- .../hi/test_sparrowhawk_normalization.sh | 8 +- .../nemo_text_processing/hi/test_telephone.py | 11 + 31 files changed, 1510 insertions(+), 53 deletions(-) create mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/STD_codes.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/__init__.py create mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/country_codes.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/landline_digits.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/mobile_digits.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/number.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/whitelist/paune_mappings.tsv create mode 100644 nemo_text_processing/text_normalization/hi/taggers/telephone.py create mode 100644 nemo_text_processing/text_normalization/hi/verbalizers/telephone.py create mode 100644 tests/nemo_text_processing/hi/data_text_normalization/test_cases_telephone.txt diff --git a/nemo_text_processing/text_normalization/hi/data/date/year_suffix.tsv b/nemo_text_processing/text_normalization/hi/data/date/year_suffix.tsv index acb37d534..3e0b56527 100644 --- a/nemo_text_processing/text_normalization/hi/data/date/year_suffix.tsv +++ b/nemo_text_processing/text_normalization/hi/data/date/year_suffix.tsv @@ -1,2 +1,2 @@ ई. पू. ईसा पूर्व -ई. ईसवी \ No newline at end of file +ई. ईसवी diff --git a/nemo_text_processing/text_normalization/hi/data/measure/quarterly_units.tsv b/nemo_text_processing/text_normalization/hi/data/measure/quarterly_units.tsv index eaddf930a..5466df709 100644 --- a/nemo_text_processing/text_normalization/hi/data/measure/quarterly_units.tsv +++ b/nemo_text_processing/text_normalization/hi/data/measure/quarterly_units.tsv @@ -4,9 +4,11 @@ h घंटे min मिनट doz दर्जन yr साल -yr वर्ष hp हॉर्सपॉवर d दिन month महीना months महीने -हफ़्ते हफ़्ते \ No newline at end of file +हफ़्ते +सप्ताह +सदियां +सदियों diff --git a/nemo_text_processing/text_normalization/hi/data/measure/unit.tsv b/nemo_text_processing/text_normalization/hi/data/measure/unit.tsv index 189512687..4065bc86b 100644 --- a/nemo_text_processing/text_normalization/hi/data/measure/unit.tsv +++ b/nemo_text_processing/text_normalization/hi/data/measure/unit.tsv @@ -134,7 +134,6 @@ KHz किलोहर्ट्ज़ N न्यूटन dB डेसीबल yr साल -yr वर्ष hp हॉर्सपॉवर d दिन month महीना diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/STD_codes.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/STD_codes.tsv new file mode 100644 index 000000000..9e1fb6569 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/telephone/STD_codes.tsv @@ -0,0 +1,948 @@ +११ एक एक +१९१ एक नौ एक +११९१ एक एक नौ एक +१२१ एक दो एक +१२२ एक दो दो +१२३२ एक दो तीन दो +१२३४ एक दो तीन चार +१२४ एक दो चार +१२६२ एक दो छह दो +१२६४ एक दो छह चार +१२७४ एक दो सात चार +१२९ एक दो नौ +१३२ एक तीन दो +१३३२ एक तीन तीन दो +१३३६ एक तीन तीन छह +१३४२ एक तीन चार दो +१३५ एक तीन पाँच +१३६४ एक तीन छह चार +१३७४ एक तीन सात चार +१४१ एक चार एक +१४४ एक चार चार +१४५ एक चार पाँच +१४६२ एक चार छह दो +१५१ एक पाँच एक +१५४ एक पाँच चार +१५६२ एक पाँच छह दो +१५७२ एक पाँच सात दो +१५८२ एक पाँच आठ दो +१५९२ एक पाँच नौ दो +१६१ एक छह एक +१६२४ एक छह दो चार +१६२७ एक छह दो सात +१६२८ एक छह दो आठ +१६३२ एक छह तीन दो +१६३४ एक छह तीन चार +१६३५ एक छह तीन पाँच +१६३६ एक छह तीन छह +१६३८ एक छह तीन आठ +१६३९ एक छह तीन नौ +१६४ एक छह चार +१६६२ एक छह छह दो +१६६४ एक छह छह चार +१६६६ एक छह छह छह +१६६९६ एक छह छह नौ छह +१६७२७२ एक छह सात दो सात दो +१६७५ एक छह सात पाँच +१६७६ एक छह सात छह +१६७९ एक छह सात नौ +१६८२ एक छह आठ दो +१६८४ एक छह आठ चार +१६८९११ एक छह आठ नौ एक एक +१७१ एक सात एक +१७२ एक सात दो +१७३२ एक सात तीन दो +१७३३ एक सात तीन तीन +१७४२ एक सात चार दो +१७४४ एक सात चार चार +१७५ एक सात पाँच +१७६२ एक सात छह दो +१७६३ एक सात छह तीन +१७६४ एक सात छह चार +१७६५ एक सात छह पाँच +१७७ एक सात सात +१८१ एक आठ एक +१८३ एक आठ तीन +१८४ एक आठ चार +१८६ एक आठ छह +१८७४ एक आठ सात चार +१८८२ एक आठ आठ दो +१९०५ एक नौ शून्य पाँच +१९१ एक नौ एक +१९२२ एक नौ दो दो +१९३२ एक नौ तीन दो +१९४ एक नौ चार +१९५२ एक नौ पाँच दो +१९५३ एक नौ पाँच तीन +१९७२ एक नौ सात दो +१९७८ एक नौ सात आठ +१९९२ एक नौ नौ दो +२० दो शून्य +२११२ दो एक एक दो +२१४८ दो एक चार आठ +२१६२ दो एक छह दो +२१६४ दो एक छह चार +२१६६ दो एक छह छह +२१६८ दो एक छह आठ +२१७ दो एक सात +२१८४ दो एक आठ चार +२१९२ दो एक नौ दो +२२ दो दो +२३० दो तीन शून्य +२३१ दो तीन एक +२३३ दो तीन तीन +२३५२ दो तीन पाँच दो +२३५५ दो तीन पाँच पाँच +२३६२ दो तीन छह दो +२३८२ दो तीन आठ दो +२३८५ दो तीन आठ पाँच +२४० दो चार शून्य +२४१ दो चार एक +२४२२ दो चार दो दो +२४३१ दो चार तीन एक +२४५२ दो चार पाँच दो +२४६२ दो चार छह दो +२४७२ दो चार सात दो +२४७८ दो चार सात आठ +२४८२ दो चार आठ दो +२४८७ दो चार आठ सात +२५१ दो पाँच एक +२५२२ दो पाँच दो दो +२५२६ दो पाँच दो छह +२५३ दो पाँच तीन +२५६२ दो पाँच छह दो +२५७ दो पाँच सात +२५८० दो पाँच आठ शून्य +२५८२ दो पाँच आठ दो +२५९१ दो पाँच नौ एक +२६० दो छह शून्य +२६१ दो छह एक +२६२२ दो छह दो दो +२६२६ दो छह दो छह +२६३१ दो छह तीन एक +२६३२ दो छह तीन दो +२६३४ दो छह तीन चार +२६३७ दो छह तीन सात +२६३९ दो छह तीन नौ +२६४२ दो छह चार दो +२६४३ दो छह चार तीन +२६४६ दो छह चार छह +२६५ दो छह पाँच +२६६२ दो छह छह दो +२६६३ दो छह छह तीन +२६७२ दो छह सात दो +२६७६ दो छह सात छह +२६७७ दो छह सात सात +२६८ दो छह आठ +२६९१ दो छह नौ एक +२६९२ दो छह नौ दो +२६९७ दो छह नौ सात +२६९९८१ दो छह नौ नौ आठ एक +२७१२ दो सात एक दो +२७१३ दो सात एक तीन +२७१४ दो सात एक चार +२७१५ दो सात एक पाँच +२७३३४४९ दो सात तीन तीन चार चार नौ +२७४२ दो सात चार दो +२७४४ दो सात चार चार +२७५२ दो सात पाँच दो +२७६२ दो सात छह दो +२७६४ दो सात छह चार +२७६५ दो सात छह पाँच +२७६६ दो सात छह छह +२७६७ दो सात छह सात +२७७० दो सात सात शून्य +२७७२ दो सात सात दो +२७७४ दो सात सात चार +२७८ दो सात आठ +२७९२ दो सात नौ दो +२७९५ दो सात नौ पाँच +२८१ दो आठ एक +२८२२ दो आठ दो दो +२८२४ दो आठ दो चार +२८२६ दो आठ दो छह +२८३२ दो आठ तीन दो +२८३३ दो आठ तीन तीन +२८३४ दो आठ तीन चार +२८३६ दो आठ तीन छह +२८४४ दो आठ चार चार +२८४५ दो आठ चार पाँच +२८५ दो आठ पाँच +२८६ दो आठ छह +२८७६ दो आठ सात छह +२८७६८३३ दो आठ सात छह आठ तीन तीन +२८९२ दो आठ नौ दो +२९१ दो नौ एक +२९३२ दो नौ तीन दो +२९४ दो नौ चार +२९९२ दो नौ नौ दो +३१७४ तीन एक सात चार +३१९२ तीन एक नौ दो +३२२२ तीन दो दो दो +३२२४ तीन दो दो चार +३२४२ तीन दो चार दो +३२६ तीन दो छह +३३ तीन तीन +३४१ तीन चार एक +३४२ तीन चार दो +३४३ तीन चार तीन +३४६१ तीन चार छह एक +३४६२ तीन चार छह दो +३४६३ तीन चार छह तीन +३४७२ तीन चार सात दो +३४८२ तीन चार आठ दो +३५२२ तीन पाँच दो दो +३५३ तीन पाँच तीन +३५४ तीन पाँच चार +३५५२ तीन पाँच पाँच दो +३५५४ तीन पाँच पाँच चार +३५६१ तीन पाँच छह एक +३५६१५५ तीन पाँच छह एक पाँच पाँच +३५८२ तीन पाँच आठ दो +३५९२ तीन पाँच नौ दो +३६० तीन छह शून्य +३६१ तीन छह एक +३६५२ तीन छह पाँच दो +३६५८ तीन छह पाँच आठ +३६६२ तीन छह छह दो +३६६४ तीन छह छह चार +३६६५ तीन छह छह पाँच +३६७३ तीन छह सात तीन +३६८ तीन छह आठ +३७० तीन सात शून्य +३७३ तीन सात तीन +३७४ तीन सात चार +३७६ तीन सात छह +३७७२ तीन सात सात दो +३८४२ तीन आठ चार दो +३८५ तीन आठ पाँच +३८६२ तीन आठ छह दो +३८९ तीन आठ नौ +४० चार शून्य +४११२ चार एक एक दो +४११४ चार एक एक चार +४११६ चार एक एक छह +४११८ चार एक एक आठ +४११९ चार एक एक नौ +४१३ चार एक तीन +४१४२ चार एक चार दो +४१४४ चार एक चार चार +४१४६ चार एक चार छह +४१४७ चार एक चार सात +४१४८ चार एक चार आठ +४१६ चार एक छह +४१७२ चार एक सात दो +४१७३ चार एक सात तीन +४१७४ चार एक सात चार +४१७५ चार एक सात पाँच +४१७७ चार एक सात सात +४२१ चार दो एक +४२२ चार दो दो +४२२८८ चार दो दो आठ आठ +४२२८९ चार दो दो आठ नौ +४२३ चार दो तीन +४२४ चार दो चार +४२५२ चार दो पाँच दो +४२५३८ चार दो पाँच तीन आठ +४२५५ चार दो पाँच पाँच +४२५६ चार दो पाँच छह +४२५७ चार दो पाँच सात +४२५८ चार दो पाँच आठ +४२५९ चार दो पाँच नौ +४२७ चार दो सात +७३१ सात तीन एक +४८८ चार आठ आठ +७५७२ सात पाँच दो +७६१ सात छह एक +८५४४ आठ पाँच चार चार +७७८२ सात सात आठ दो +६७१ छह सात एक +६५७ छह पाँच सात +७४१४ सात चार एक चार +६७५४ छह सात पाँच चार +५४५२ पाँच चार पाँच दो +६८५४ छह आठ पाँच चार +७४३२ सात चार तीन दो +६६४५ छह छह चार पाँच +६५३४ छह पाँच तीन चार +६७६७ छह सात छह सात +८३८२ आठ तीन आठ दो +८८४ आठ आठ चार +९५२५१ नौ पाँच दो पाँच एक +४९९ चार नौ नौ +४९१ चार नौ एक +५१२ पाँच एक दो +४६५२ चार छह पाँच दो +४३६८ चार तीन छह आठ +४५६५ चार पाँच छह पाँच +८७२२ आठ सात दो दो +४३२४ चार तीन दो चार +५७४४ पाँच सात चार चार +६४५२ छह चार पाँच दो +८६२६ आठ छह दो छह +४८९६ चार आठ नौ छह +४७९ चार सात नौ +८७१२ आठ सात एक दो +६७२७ छह सात दो सात +८० आठ शून्य +६७६६ छह सात छह छह +५४१४ पाँच चार एक चार +७२६३ सात दो छह तीन +८७४२ आठ सात चार दो +७३३ सात तीन तीन +८२२३ आठ दो दो तीन +८६८३ आठ छह आठ तीन +४५४२ चार पाँच चार दो +८१५२ आठ एक पाँच दो +८१५३ आठ एक पाँच तीन +८२४ आठ दो चार +८५३९ आठ पाँच तीन नौ +६८५२ छह आठ पाँच दो +५६६२ पाँच छह छह दो +८६२४ आठ छह दो चार +८७४४ आठ सात चार चार +८५२५ आठ पाँच दो पाँच +४८५ चार आठ पाँच +४९३ चार नौ तीन +४७४ चार सात चार +४८१ चार आठ एक +४३३२ चार तीन तीन दो +८८१७ आठ आठ एक सात +८४४३ आठ चार चार तीन +४३२३ चार तीन दो तीन +४३५ चार तीन पाँच +८५१८ आठ पाँच एक आठ +४३६४ चार तीन छह चार +८८१२ आठ आठ एक दो +५१७६ पाँच एक सात छह +८४१३ आठ चार एक तीन +९५०२११४ नौ पाँच शून्य दो एक एक चार +५२२ पाँच दो दो +८६७२ आठ छह सात दो +८५४३ आठ पाँच चार तीन +८२७२ आठ दो सात दो +४४ चार चार +४५२ चार पाँच दो +४९० चार नौ शून्य +५६७२ पाँच छह सात दो +३५१२ तीन पाँच एक दो +४३१८२ चार तीन एक आठ दो +६७४ छह सात चार +७४२२ सात चार दो दो +८२३२ आठ दो तीन दो +८२५२ आठ दो पाँच दो +४९२ चार नौ दो +८३२ आठ तीन दो +५६५ पाँच छह पाँच +४७८ चार सात आठ +८५९३ आठ पाँच नौ तीन +८२१ आठ दो एक +७३२४ सात तीन दो चार +४८९२ चार आठ नौ दो +५४४२ पाँच चार चार दो +५४१२ पाँच चार एक दो +७५३२ सात पाँच तीन दो +६२५२ छह दो पाँच दो +४८७ चार आठ सात +४८४ चार आठ चार +४८६५ चार आठ छह पाँच +४३२६ चार तीन दो छह +६२१ छह दो एक +४३६५ चार तीन छह पाँच +८५४० आठ पाँच चार शून्य +७१२ सात एक दो +५३२ पाँच तीन दो +५९४२ पाँच नौ चार दो +८६८२ आठ छह आठ दो +४२८६ चार दो आठ छह +८६७८ आठ छह सात आठ +८५१३ आठ पाँच एक तीन +४६३५ चार छह तीन पाँच +८२२१ आठ दो दो एक +८६४७ आठ छह चार सात +६३२४ छह तीन दो चार +८६१ आठ छह एक +४७१ चार सात एक +८३३८ आठ तीन तीन आठ +८४६२ आठ चार छह दो +८५९२ आठ पाँच नौ दो +४८२१ चार आठ दो एक +८८१४ आठ आठ एक चार +४५४५ चार पाँच चार पाँच +४६२ चार छह दो +८२४७ आठ दो चार सात +४७३ चार सात तीन +४३७४ चार तीन सात चार +६७२२ छह सात दो दो +४५६४ चार पाँच छह चार +४९४ चार नौ चार +८४५३ आठ चार पाँच तीन +६१२ छह एक दो +७१८५ सात एक आठ पाँच +४९८ चार नौ आठ +८८५२ आठ आठ पाँच दो +४२९४ चार दो नौ चार +६८४२ छह आठ चार दो +५८८२ पाँच आठ आठ दो +५९६४ पाँच नौ छह चार +४८२ चार आठ दो +८६४८ आठ छह चार आठ +८६६ आठ छह छह +४६१ चार छह एक +४७५ चार सात पाँच +९५२० नौ पाँच दो शून्य +६४५४ छह चार पाँच चार +८२५१ आठ दो पाँच एक +८५७७ आठ पाँच सात सात +५३५ पाँच तीन पाँच +८५३२ आठ पाँच तीन दो +७७६२ सात सात छह दो +७७१ सात सात एक +८८३ आठ आठ तीन +४५६३ चार पाँच छह तीन +८८५७ आठ आठ पाँच सात +८११७ आठ एक एक सात +४५६७ चार पाँच छह सात +४५७३ चार पाँच सात तीन +७११४ सात एक एक चार +६५१ छह पाँच एक +८३७३ आठ तीन सात तीन +५४९६ पाँच चार नौ छह +७४१२ सात चार एक दो +८८५५ आठ आठ पाँच पाँच +१८५३ एक आठ पाँच तीन +८५७४ आठ पाँच सात चार +७६६२ सात छह छह दो +५४४४ पाँच चार चार चार +६६१ छह छह एक +७५८२ सात पाँच आठ दो +४३४१ चार तीन चार एक +६२७४ छह दो सात चार +६६३ छह छह तीन +८४५५ आठ चार पाँच पाँच +४२८३ चार दो आठ तीन +४६३६ चार छह तीन छह +६१८४ छह एक आठ चार +४२९५ चार दो नौ पाँच +७६७२ सात छह सात दो +४५६२ चार पाँच छह दो +७५६२ सात पाँच छह दो +७६९२ सात छह नौ दो +८५४८ आठ पाँच चार आठ +८४७४ आठ चार सात चार +५८४२ पाँच आठ चार दो +४६३३ चार छह तीन तीन +५६७६ पाँच छह सात छह +३६४ तीन छह चार +८१८२ आठ एक आठ दो +८४५७ आठ चार पाँच सात +५३६२ पाँच तीन छह दो +४३६३ चार तीन छह तीन +८७३८ आठ सात तीन आठ +८३८४ आठ तीन आठ चार +५८६२ पाँच आठ छह दो +४३१ चार तीन एक +८९४२ आठ नौ चार दो +८५७८ आठ पाँच सात आठ +८२३६ आठ दो तीन छह +६८५३ छह आठ पाँच तीन +६६२२ छह छह दो +५७३६ पाँच सात तीन छह +८८१८ आठ आठ एक आठ +८५५८ आठ पाँच पाँच आठ +८८१९ आठ आठ एक नौ +८६४४ आठ छह चार चार +४३६२ चार तीन छह दो +४५४६ चार पाँच चार छह +४८६२ चार आठ छह दो +४२८८ चार दो आठ आठ +४५४९ चार पाँच चार नौ +४३१८३ चार तीन एक आठ तीन +४३६६ चार तीन छह छह +८१६ आठ एक छह +७१८३ सात एक आठ तीन +७३४ सात तीन चार +४८२९ चार आठ दो नौ +४६३७ चार छह तीन सात +४६४६ चार छह चार छह +६७६८ छह सात छह आठ +८२७४ आठ दो सात चार +४३३९ चार तीन तीन नौ +८९१ आठ नौ एक +७१५२ सात एक पाँच दो +८०४५ आठ चार पाँच +७९८४ सात नौ आठ चार +11 एक एक +191 एक नौ एक +1191 एक एक नौ एक +121 एक दो एक +122 एक दो दो +1232 एक दो तीन दो +1234 एक दो तीन चार +124 एक दो चार +1262 एक दो छह दो +1264 एक दो छह चार +1274 एक दो सात चार +129 एक दो नौ +132 एक तीन दो +1332 एक तीन तीन दो +1336 एक तीन तीन छह +1342 एक तीन चार दो +135 एक तीन पाँच +1364 एक तीन छह चार +1374 एक तीन सात चार +141 एक चार एक +144 एक चार चार +145 एक चार पाँच +1462 एक चार छह दो +151 एक पाँच एक +154 एक पाँच चार +1562 एक पाँच छह दो +1572 एक पाँच सात दो +1582 एक पाँच आठ दो +1592 एक पाँच नौ दो +161 एक छह एक +1624 एक छह दो चार +1627 एक छह दो सात +1628 एक छह दो आठ +1632 एक छह तीन दो +1634 एक छह तीन चार +1635 एक छह तीन पाँच +1636 एक छह तीन छह +1638 एक छह तीन आठ +1639 एक छह तीन नौ +164 एक छह चार +1662 एक छह छह दो +1664 एक छह छह चार +1666 एक छह छह छह +16696 एक छह छह नौ छह +167272 एक छह सात दो सात दो +1675 एक छह सात पाँच +1676 एक छह सात छह +1679 एक छह सात नौ +1682 एक छह आठ दो +1684 एक छह आठ चार +168911 एक छह आठ नौ एक एक +171 एक सात एक +172 एक सात दो +1732 एक सात तीन दो +1733 एक सात तीन तीन +1742 एक सात चार दो +1744 एक सात चार चार +175 एक सात पाँच +1762 एक सात छह दो +1763 एक सात छह तीन +1764 एक सात छह चार +1765 एक सात छह पाँच +177 एक सात सात +181 एक आठ एक +183 एक आठ तीन +184 एक आठ चार +186 एक आठ छह +1874 एक आठ सात चार +1882 एक आठ आठ दो +1905 एक नौ शून्य पाँच +191 एक नौ एक +1922 एक नौ दो दो +1932 एक नौ तीन दो +194 एक नौ चार +1952 एक नौ पाँच दो +1953 एक नौ पाँच तीन +1972 एक नौ सात दो +1978 एक नौ सात आठ +1992 एक नौ नौ दो +20 दो शून्य +2112 दो एक एक दो +2148 दो एक चार आठ +2162 दो एक छह दो +2164 दो एक छह चार +2166 दो एक छह छह +2168 दो एक छह आठ +217 दो एक सात +2184 दो एक आठ चार +2192 दो एक नौ दो +22 दो दो +230 दो तीन शून्य +231 दो तीन एक +233 दो तीन तीन +2352 दो तीन पाँच दो +2355 दो तीन पाँच पाँच +2362 दो तीन छह दो +2382 दो तीन आठ दो +2385 दो तीन आठ पाँच +240 दो चार शून्य +241 दो चार एक +2422 दो चार दो दो +2431 दो चार तीन एक +2452 दो चार पाँच दो +2462 दो चार छह दो +2472 दो चार सात दो +2478 दो चार सात आठ +2482 दो चार आठ दो +2487 दो चार आठ सात +251 दो पाँच एक +2522 दो पाँच दो दो +2526 दो पाँच दो छह +253 दो पाँच तीन +2562 दो पाँच छह दो +257 दो पाँच सात +2580 दो पाँच आठ शून्य +2582 दो पाँच आठ दो +2591 दो पाँच नौ एक +260 दो छह शून्य +261 दो छह एक +2622 दो छह दो दो +2626 दो छह दो छह +2631 दो छह तीन एक +2632 दो छह तीन दो +2634 दो छह तीन चार +2637 दो छह तीन सात +2639 दो छह तीन नौ +2642 दो छह चार दो +2643 दो छह चार तीन +2646 दो छह चार छह +265 दो छह पाँच +2662 दो छह छह दो +2663 दो छह छह तीन +2672 दो छह सात दो +2676 दो छह सात छह +2677 दो छह सात सात +268 दो छह आठ +2691 दो छह नौ एक +2692 दो छह नौ दो +2697 दो छह नौ सात +269981 दो छह नौ नौ आठ एक +2712 दो सात एक दो +2713 दो सात एक तीन +2714 दो सात एक चार +2715 दो सात एक पाँच +2733449 दो सात तीन तीन चार चार नौ +2742 दो सात चार दो +2744 दो सात चार चार +2752 दो सात पाँच दो +2762 दो सात छह दो +2764 दो सात छह चार +2765 दो सात छह पाँच +2766 दो सात छह छह +2767 दो सात छह सात +2770 दो सात सात शून्य +2772 दो सात सात दो +2774 दो सात सात चार +278 दो सात आठ +2792 दो सात नौ दो +2795 दो सात नौ पाँच +281 दो आठ एक +2822 दो आठ दो दो +2824 दो आठ दो चार +2826 दो आठ दो छह +2832 दो आठ तीन दो +2833 दो आठ तीन तीन +2834 दो आठ तीन चार +2836 दो आठ तीन छह +2844 दो आठ चार चार +2845 दो आठ चार पाँच +285 दो आठ पाँच +286 दो आठ छह +2876 दो आठ सात छह +2876833 दो आठ सात छह आठ तीन तीन +2892 दो आठ नौ दो +291 दो नौ एक +2932 दो नौ तीन दो +294 दो नौ चार +2992 दो नौ नौ दो +3174 तीन एक सात चार +3192 तीन एक नौ दो +3222 तीन दो दो दो +3224 तीन दो दो चार +3242 तीन दो चार दो +326 तीन दो छह +33 तीन तीन +341 तीन चार एक +342 तीन चार दो +343 तीन चार तीन +3461 तीन चार छह एक +3462 तीन चार छह दो +3463 तीन चार छह तीन +3472 तीन चार सात दो +3482 तीन चार आठ दो +3522 तीन पाँच दो दो +353 तीन पाँच तीन +354 तीन पाँच चार +3552 तीन पाँच पाँच दो +3554 तीन पाँच पाँच चार +3561 तीन पाँच छह एक +356155 तीन पाँच छह एक पाँच पाँच +3582 तीन पाँच आठ दो +3592 तीन पाँच नौ दो +360 तीन छह शून्य +361 तीन छह एक +3652 तीन छह पाँच दो +3658 तीन छह पाँच आठ +3662 तीन छह छह दो +3664 तीन छह छह चार +3665 तीन छह छह पाँच +3673 तीन छह सात तीन +368 तीन छह आठ +370 तीन सात शून्य +373 तीन सात तीन +374 तीन सात चार +376 तीन सात छह +3772 तीन सात सात दो +3842 तीन आठ चार दो +385 तीन आठ पाँच +3862 तीन आठ छह दो +389 तीन आठ नौ +40 चार शून्य +4112 चार एक एक दो +4114 चार एक एक चार +4116 चार एक एक छह +4118 चार एक एक आठ +4119 चार एक एक नौ +413 चार एक तीन +4142 चार एक चार दो +4144 चार एक चार चार +4146 चार एक चार छह +4147 चार एक चार सात +4148 चार एक चार आठ +416 चार एक छह +4172 चार एक सात दो +4173 चार एक सात तीन +4174 चार एक सात चार +4175 चार एक सात पाँच +4177 चार एक सात सात +421 चार दो एक +422 चार दो दो +42288 चार दो दो आठ आठ +42289 चार दो दो आठ नौ +423 चार दो तीन +424 चार दो चार +4252 चार दो पाँच दो +42538 चार दो पाँच तीन आठ +4255 चार दो पाँच पाँच +4256 चार दो पाँच छह +4257 चार दो पाँच सात +4258 चार दो पाँच आठ +4259 चार दो पाँच नौ +427 चार दो सात +731 सात तीन एक +488 चार आठ आठ +7572 सात पाँच दो +761 सात छह एक +8544 आठ पाँच चार चार +7782 सात सात आठ दो +671 छह सात एक +657 छह पाँच सात +7414 सात चार एक चार +6754 छह सात पाँच चार +5452 पाँच चार पाँच दो +6854 छह आठ पाँच चार +7432 सात चार तीन दो +6645 छह छह चार पाँच +6534 छह पाँच तीन चार +6767 छह सात छह सात +8382 आठ तीन आठ दो +884 आठ आठ चार +95251 नौ पाँच दो पाँच एक +499 चार नौ नौ +491 चार नौ एक +512 पाँच एक दो +4652 चार छह पाँच दो +4368 चार तीन छह आठ +4565 चार पाँच छह पाँच +8722 आठ सात दो दो +4324 चार तीन दो चार +5744 पाँच सात चार चार +6452 छह चार पाँच दो +8626 आठ छह दो छह +4896 चार आठ नौ छह +479 चार सात नौ +8712 आठ सात एक दो +6727 छह सात दो सात +80 आठ शून्य +6766 छह सात छह छह +5414 पाँच चार एक चार +7263 सात दो छह तीन +8742 आठ सात चार दो +733 सात तीन तीन +8223 आठ दो दो तीन +8683 आठ छह आठ तीन +4542 चार पाँच चार दो +8152 आठ एक पाँच दो +8153 आठ एक पाँच तीन +824 आठ दो चार +8539 आठ पाँच तीन नौ +6852 छह आठ पाँच दो +5662 पाँच छह छह दो +8624 आठ छह दो चार +8744 आठ सात चार चार +8525 आठ पाँच दो पाँच +485 चार आठ पाँच +493 चार नौ तीन +474 चार सात चार +481 चार आठ एक +4332 चार तीन तीन दो +8817 आठ आठ एक सात +8443 आठ चार चार तीन +4323 चार तीन दो तीन +435 चार तीन पाँच +8518 आठ पाँच एक आठ +4364 चार तीन छह चार +8812 आठ आठ एक दो +5176 पाँच एक सात छह +8413 आठ चार एक तीन +9502114 नौ पाँच शून्य दो एक एक चार +522 पाँच दो दो +8672 आठ छह सात दो +8543 आठ पाँच चार तीन +8272 आठ दो सात दो +44 चार चार +452 चार पाँच दो +490 चार नौ शून्य +5672 पाँच छह सात दो +3512 तीन पाँच एक दो +43182 चार तीन एक आठ दो +674 छह सात चार +7422 सात चार दो दो +8232 आठ दो तीन दो +8252 आठ दो पाँच दो +492 चार नौ दो +832 आठ तीन दो +565 पाँच छह पाँच +478 चार सात आठ +8593 आठ पाँच नौ तीन +821 आठ दो एक +7324 सात तीन दो चार +4892 चार आठ नौ दो +5442 पाँच चार चार दो +5412 पाँच चार एक दो +7532 सात पाँच तीन दो +6252 छह दो पाँच दो +487 चार आठ सात +484 चार आठ चार +4865 चार आठ छह पाँच +4326 चार तीन दो छह +621 छह दो एक +4365 चार तीन छह पाँच +8540 आठ पाँच चार शून्य +712 सात एक दो +532 पाँच तीन दो +5942 पाँच नौ चार दो +8682 आठ छह आठ दो +4286 चार दो आठ छह +8678 आठ छह सात आठ +8513 आठ पाँच एक तीन +4635 चार छह तीन पाँच +8221 आठ दो दो एक +8647 आठ छह चार सात +6324 छह तीन दो चार +861 आठ छह एक +471 चार सात एक +8338 आठ तीन तीन आठ +8462 आठ चार छह दो +8592 आठ पाँच नौ दो +4821 चार आठ दो एक +8814 आठ आठ एक चार +4545 चार पाँच चार पाँच +462 चार छह दो +8247 आठ दो चार सात +473 चार सात तीन +4374 चार तीन सात चार +6722 छह सात दो दो +4564 चार पाँच छह चार +494 चार नौ चार +8453 आठ चार पाँच तीन +612 छह एक दो +7185 सात एक आठ पाँच +498 चार नौ आठ +8852 आठ आठ पाँच दो +4294 चार दो नौ चार +6842 छह आठ चार दो +5882 पाँच आठ आठ दो +5964 पाँच नौ छह चार +482 चार आठ दो +8648 आठ छह चार आठ +866 आठ छह छह +461 चार छह एक +475 चार सात पाँच +9520 नौ पाँच दो शून्य +6454 छह चार पाँच चार +8251 आठ दो पाँच एक +8577 आठ पाँच सात सात +535 पाँच तीन पाँच +8532 आठ पाँच तीन दो +7762 सात सात छह दो +771 सात सात एक +883 आठ आठ तीन +4563 चार पाँच छह तीन +8857 आठ आठ पाँच सात +8117 आठ एक एक सात +4567 चार पाँच छह सात +4573 चार पाँच सात तीन +7114 सात एक एक चार +651 छह पाँच एक +8373 आठ तीन सात तीन +5496 पाँच चार नौ छह +7412 सात चार एक दो +8855 आठ आठ पाँच पाँच +1853 एक आठ पाँच तीन +8574 आठ पाँच सात चार +7662 सात छह छह दो +5444 पाँच चार चार चार +661 छह छह एक +7582 सात पाँच आठ दो +4341 चार तीन चार एक +6274 छह दो सात चार +663 छह छह तीन +8455 आठ चार पाँच पाँच +4283 चार दो आठ तीन +4636 चार छह तीन छह +6184 छह एक आठ चार +4295 चार दो नौ पाँच +7672 सात छह सात दो +4562 चार पाँच छह दो +7562 सात पाँच छह दो +7692 सात छह नौ दो +8548 आठ पाँच चार आठ +8474 आठ चार सात चार +5842 पाँच आठ चार दो +4633 चार छह तीन तीन +5676 पाँच छह सात छह +364 तीन छह चार +8182 आठ एक आठ दो +8457 आठ चार पाँच सात +5362 पाँच तीन छह दो +4363 चार तीन छह तीन +8738 आठ सात तीन आठ +8384 आठ तीन आठ चार +5862 पाँच आठ छह दो +431 चार तीन एक +8942 आठ नौ चार दो +8578 आठ पाँच सात आठ +8236 आठ दो तीन छह +6853 छह आठ पाँच तीन +6622 छह छह दो +5736 पाँच सात तीन छह +8818 आठ आठ एक आठ +8558 आठ पाँच पाँच आठ +8819 आठ आठ एक नौ +8644 आठ छह चार चार +4362 चार तीन छह दो +4546 चार पाँच चार छह +4862 चार आठ छह दो +4288 चार दो आठ आठ +4549 चार पाँच चार नौ +43183 चार तीन एक आठ तीन +4366 चार तीन छह छह +816 आठ एक छह +7183 सात एक आठ तीन +734 सात तीन चार +4829 चार आठ दो नौ +4637 चार छह तीन सात +4646 चार छह चार छह +6768 छह सात छह आठ +8274 आठ दो सात चार +4339 चार तीन तीन नौ +891 आठ नौ एक +7152 सात एक पाँच दो +8045 आठ चार पाँच +7984 सात नौ आठ चार diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/__init__.py b/nemo_text_processing/text_normalization/hi/data/telephone/__init__.py new file mode 100644 index 000000000..341a77c5b --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/telephone/__init__.py @@ -0,0 +1,13 @@ +# Copyright (c) 2025, 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/telephone/country_codes.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/country_codes.tsv new file mode 100644 index 000000000..685a5866d --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/telephone/country_codes.tsv @@ -0,0 +1,2 @@ +९१ नौ एक +91 नौ एक diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/landline_digits.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/landline_digits.tsv new file mode 100644 index 000000000..0a658c8ea --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/telephone/landline_digits.tsv @@ -0,0 +1,8 @@ +२ दो +३ तीन +४ चार +६ छह +2 दो +3 तीन +4 चार +6 छह \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/mobile_digits.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/mobile_digits.tsv new file mode 100644 index 000000000..bfd892d0e --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/telephone/mobile_digits.tsv @@ -0,0 +1,8 @@ +६ छह +७ सात +८ आठ +९ नौ +6 छह +7 सात +8 आठ +9 नौ \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/number.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/number.tsv new file mode 100644 index 000000000..d30ef902d --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/telephone/number.tsv @@ -0,0 +1,20 @@ +० शून्य +१ एक +२ दो +३ तीन +४ चार +५ पाँच +६ छह +७ सात +८ आठ +९ नौ +0 शून्य +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/time/hours.tsv b/nemo_text_processing/text_normalization/hi/data/time/hours.tsv index dd8623284..d5e85a784 100644 --- a/nemo_text_processing/text_normalization/hi/data/time/hours.tsv +++ b/nemo_text_processing/text_normalization/hi/data/time/hours.tsv @@ -1,4 +1,3 @@ -० शून्य १ एक २ दो ३ तीन diff --git a/nemo_text_processing/text_normalization/hi/data/whitelist/paune_mappings.tsv b/nemo_text_processing/text_normalization/hi/data/whitelist/paune_mappings.tsv new file mode 100644 index 000000000..3477871e4 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/whitelist/paune_mappings.tsv @@ -0,0 +1,100 @@ +० एक +१ दो +२ तीन +३ चार +४ पाँच +५ छह +६ सात +७ आठ +८ नौ +९ दस +१० ग्यारह +११ बारह +१२ तेरह +१३ चौदह +१४ पंद्रह +१५ सोलह +१६ सत्रह +१७ अठारह +१८ उन्नीस +१९ बीस +२० इक्कीस +२१ बाईस +२२ तेईस +२३ चौबीस +२४ पच्चीस +२५ छब्बीस +२६ सत्ताईस +२७ अट्ठाईस +२८ उनतीस +२९ तीस +३० इकतीस +३१ बत्तीस +३२ तैंतीस +३३ चौंतीस +३४ पैंतीस +३५ छत्तीस +३६ सैंतीस +३७ अड़तीस +३८ उनतालीस +३९ चालीस +४० इकतालीस +४१ बयालीस +४२ तैंतालीस +४३ चौवालीस +४४ पैंतालीस +४५ छियालीस +४६ सैंतालीस +४७ अड़तालीस +४८ उनचास +४९ पचास +५० इक्यावन +५१ बावन +५२ तिरेपन +५३ चौवन +५४ पचपन +५५ छप्पन +५६ सत्तावन +५७ अट्ठावन +५८ उनसठ +५९ साठ +६० इकसठ +६१ बासठ +६२ तिरेसठ +६३ चौंसठ +६४ पैंसठ +६५ छियासठ +६६ सड़सठ +६७ अड़सठ +६८ उनहत्तर +६९ सत्तर +७० इकहत्तर +७१ बहत्तर +७२ तिहत्तर +७३ चौहत्तर +७४ पचहत्तर +७५ छिहत्तर +७६ सतहत्तर +७७ अठहत्तर +७८ उनासी +७९ अस्सी +८० इक्यासी +८१ बयासी +८२ तिरासी +८३ चौरासी +८४ पचासी +८५ छियासी +८६ सत्तासी +८७ अट्ठासी +८८ नवासी +८९ नब्बे +९० इक्यानबे +९१ बानबे +९२ तिरानबे +९३ चौरानबे +९४ पंचानबे +९५ छियानबे +९६ सत्तानबे +९७ अट्ठानबे +९८ निन्यानबे +९९ एक सौ diff --git a/nemo_text_processing/text_normalization/hi/taggers/cardinal.py b/nemo_text_processing/text_normalization/hi/taggers/cardinal.py index c50384acf..b22f28cb1 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/cardinal.py +++ b/nemo_text_processing/text_normalization/hi/taggers/cardinal.py @@ -21,12 +21,12 @@ class CardinalFst(GraphFst): """ - Finite state transducer for classifying cardinals, e.g. - -२३ -> cardinal { negative: "true" integer: "तेइस" } } - s - Args: - deterministic: if True will provide a single transduction option, - for False multiple transduction are generated (used for audio-based normalization) + Finite state transducer for classifying cardinals, e.g. + -२३ -> cardinal { negative: "true" integer: "तेइस" } + + Args: + deterministic: if True will provide a single transduction option, + for False multiple transduction are generated (used for audio-based normalization) """ def __init__(self, deterministic: bool = True, lm: bool = False): @@ -37,6 +37,10 @@ def __init__(self, deterministic: bool = True, lm: bool = False): teens_ties = pynini.string_file(get_abs_path("data/numbers/teens_and_ties.tsv")) teens_and_ties = pynutil.add_weight(teens_ties, -0.1) + self.digit = digit + self.zero = zero + self.teens_and_ties = teens_and_ties + def create_graph_suffix(digit_graph, suffix, zeros_counts): zero = pynutil.add_weight(pynutil.delete("०"), -0.1) if zeros_counts == 0: @@ -323,3 +327,11 @@ def create_larger_number_graph(digit_graph, suffix, zeros_counts, sub_graph): final_graph = optional_minus_graph + pynutil.insert("integer: \"") + self.final_graph + pynutil.insert("\"") final_graph = self.add_tokens(final_graph) self.fst = final_graph + + +if __name__ == '__main__': + from nemo_text_processing.text_normalization.hi.utils import apply_fst + + cardinal = CardinalFst() + input_text = "११०१११११११११११" + apply_fst(input_text, cardinal.fst) diff --git a/nemo_text_processing/text_normalization/hi/taggers/date.py b/nemo_text_processing/text_normalization/hi/taggers/date.py index 37b192165..b8b652128 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/date.py +++ b/nemo_text_processing/text_normalization/hi/taggers/date.py @@ -73,6 +73,7 @@ def __init__(self, cardinal: GraphFst): delete_dash = pynutil.delete("-") delete_slash = pynutil.delete("/") + delete_comma = pynutil.delete(",") days_graph = pynutil.insert("day: \"") + days + pynutil.insert("\"") + insert_space diff --git a/nemo_text_processing/text_normalization/hi/taggers/decimal.py b/nemo_text_processing/text_normalization/hi/taggers/decimal.py index 955e8c0d3..cb21d85b1 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/decimal.py +++ b/nemo_text_processing/text_normalization/hi/taggers/decimal.py @@ -58,9 +58,7 @@ class DecimalFst(GraphFst): def __init__(self, cardinal: GraphFst, deterministic: bool = True): super().__init__(name="decimal", kind="classify", deterministic=deterministic) - graph_digit = pynini.string_file(get_abs_path("data/numbers/digit.tsv")) - graph_digit |= pynini.string_file(get_abs_path("data/numbers/zero.tsv")) - + graph_digit = cardinal.digit | cardinal.zero cardinal_graph = cardinal.final_graph self.graph = graph_digit + pynini.closure(insert_space + graph_digit).optimize() diff --git a/nemo_text_processing/text_normalization/hi/taggers/fraction.py b/nemo_text_processing/text_normalization/hi/taggers/fraction.py index 8971cd3dd..d995608da 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/fraction.py +++ b/nemo_text_processing/text_normalization/hi/taggers/fraction.py @@ -16,6 +16,7 @@ from pynini.lib import pynutil from nemo_text_processing.text_normalization.hi.graph_utils import GraphFst +from nemo_text_processing.text_normalization.hi.utils import get_abs_path class FractionFst(GraphFst): @@ -47,13 +48,43 @@ def __init__(self, cardinal, deterministic: bool = True): ) self.denominator = pynutil.insert("denominator: \"") + cardinal_graph + pynutil.insert("\"") - self.graph = ( + dedh_dhai_graph = pynini.string_map([("१ १/२", "डेढ़"), ("२ १/२", "ढाई")]) + + savva_numbers = cardinal_graph + pynini.cross(" १/४", "") + savva_graph = pynutil.insert("सवा ") + savva_numbers + + sadhe_numbers = cardinal_graph + pynini.cross(" १/२", "") + sadhe_graph = pynutil.insert("साढ़े ") + sadhe_numbers + + paune = pynini.string_file(get_abs_path("data/whitelist/paune_mappings.tsv")) + paune_numbers = paune + pynini.cross(" ३/४", "") + paune_graph = pynutil.insert("पौने ") + paune_numbers + + graph_dedh_dhai = pynutil.insert("morphosyntactic_features: \"") + dedh_dhai_graph + pynutil.insert("\" ") + + graph_savva = pynutil.insert("morphosyntactic_features: \"") + savva_graph + pynutil.insert("\" ") + + graph_sadhe = pynutil.insert("morphosyntactic_features: \"") + sadhe_graph + pynutil.insert("\" ") + + graph_paune = pynutil.insert("morphosyntactic_features: \"") + paune_graph + pynutil.insert("\" ") + + final_graph = ( self.optional_graph_negative + pynini.closure(self.integer + pynini.accep(" "), 0, 1) + self.numerator + self.denominator ) + weighted_graph = ( + final_graph + | 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.2) + ) + + self.graph = weighted_graph + graph = self.graph - final_graph = self.add_tokens(graph) - self.fst = final_graph.optimize() + graph = self.add_tokens(graph) + self.fst = graph.optimize() diff --git a/nemo_text_processing/text_normalization/hi/taggers/measure.py b/nemo_text_processing/text_normalization/hi/taggers/measure.py index 9f1ffbd39..fe27ef76f 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/measure.py +++ b/nemo_text_processing/text_normalization/hi/taggers/measure.py @@ -19,11 +19,6 @@ from nemo_text_processing.text_normalization.hi.utils import get_abs_path -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_and_ties = pynutil.add_weight(teens_ties, -0.1) - - class MeasureFst(GraphFst): """ Finite state transducer for classifying measure, suppletive aware, e.g. @@ -41,8 +36,9 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): super().__init__(name="measure", kind="classify") cardinal_graph = ( - digit - | teens_and_ties + cardinal.zero + | cardinal.digit + | cardinal.teens_and_ties | cardinal.graph_hundreds | cardinal.graph_thousands | cardinal.graph_ten_thousands @@ -52,6 +48,7 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): point = pynutil.delete(".") decimal_integers = pynutil.insert("integer_part: \"") + cardinal_graph + pynutil.insert("\"") decimal_graph = decimal_integers + point + insert_space + decimal.graph_fractional + unit_graph = pynini.string_file(get_abs_path("data/measure/unit.tsv")) quarterly_units_graph = pynini.string_file(get_abs_path("data/measure/quarterly_units.tsv")) @@ -61,16 +58,6 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): 1, ) - # Define the quarterly measurements - quarter = pynini.string_map( - [ - (".५", "साढ़े"), - ("१.५", "डेढ़"), - ("२.५", "ढाई"), - ] - ) - quarter_graph = pynutil.insert("integer_part: \"") + quarter + pynutil.insert("\"") - # Define the unit handling unit = pynutil.insert(" units: \"") + unit_graph + pynutil.insert("\" ") units = pynutil.insert(" units: \"") + quarterly_units_graph + pynutil.insert("\" ") @@ -93,10 +80,50 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): + unit ) - graph_quarter = ( + dedh_dhai = pynini.string_map([("१.५", "डेढ़"), ("२.५", "ढाई")]) + dedh_dhai_graph = pynutil.insert("integer: \"") + dedh_dhai + pynutil.insert("\"") + + savva_numbers = cardinal_graph + pynini.cross(".२५", "") + savva_graph = pynutil.insert("integer: \"सवा ") + savva_numbers + pynutil.insert("\"") + + sadhe_numbers = cardinal_graph + pynini.cross(".५", "") + sadhe_graph = pynutil.insert("integer: \"साढ़े ") + sadhe_numbers + pynutil.insert("\"") + + paune = pynini.string_file(get_abs_path("data/whitelist/paune_mappings.tsv")) + paune_numbers = paune + pynini.cross(".७५", "") + paune_graph = pynutil.insert("integer: \"पौने ") + paune_numbers + pynutil.insert("\"") + + graph_dedh_dhai = ( + pynutil.insert("cardinal { ") + + optional_graph_negative + + dedh_dhai_graph + + pynutil.insert(" }") + + delete_space + + units + ) + + graph_savva = ( + pynutil.insert("cardinal { ") + + optional_graph_negative + + savva_graph + + pynutil.insert(" }") + + delete_space + + units + ) + + graph_sadhe = ( + pynutil.insert("cardinal { ") + + optional_graph_negative + + sadhe_graph + + pynutil.insert(" }") + + delete_space + + units + ) + + graph_paune = ( pynutil.insert("cardinal { ") + optional_graph_negative - + quarter_graph + + paune_graph + pynutil.insert(" }") + delete_space + units @@ -135,9 +162,12 @@ def __init__(self, cardinal: GraphFst, decimal: GraphFst): graph = ( pynutil.add_weight(graph_decimal, 0.01) - | pynutil.add_weight(graph_quarter, 0.005) | pynutil.add_weight(graph_cardinal, 0.01) | pynutil.add_weight(graph_exceptions, 0.01) + | pynutil.add_weight(graph_dedh_dhai, 0.001) + | pynutil.add_weight(graph_savva, 0.005) + | pynutil.add_weight(graph_sadhe, 0.005) + | pynutil.add_weight(graph_paune, -0.2) ) self.graph = graph.optimize() diff --git a/nemo_text_processing/text_normalization/hi/taggers/telephone.py b/nemo_text_processing/text_normalization/hi/taggers/telephone.py new file mode 100644 index 000000000..fe384fd13 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/taggers/telephone.py @@ -0,0 +1,140 @@ +# Copyright (c) 2024, 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 pynini +from pynini.lib import pynutil + +from nemo_text_processing.text_normalization.hi.graph_utils import NEMO_DIGIT, GraphFst, delete_space, insert_space +from nemo_text_processing.text_normalization.hi.utils import get_abs_path + + +def load_column_from_tsv(filepath, column_index=1): + with open(filepath, encoding='utf-8') as tsv: + return [line.strip().split("\t")[column_index] for line in tsv if line.strip()] + + +# Load the number mappings from the TSV file +digit_to_word = pynini.string_file(get_abs_path("data/telephone/number.tsv")) +std_codes = pynini.string_file(get_abs_path("data/telephone/STD_codes.tsv")) +country_codes = pynini.string_file(get_abs_path("data/telephone/country_codes.tsv")) +landline_start_digit = pynini.string_file(get_abs_path("data/telephone/landline_digits.tsv")) +mobile_start_digit = pynini.string_file(get_abs_path("data/telephone/mobile_digits.tsv")) + + +class TelephoneFst(GraphFst): + """ + Finite state transducer for tagging telephone numbers, e.g. + 9876543210 -> telephone { number_part: "नौ आठ सात छह पाँच चार तीन दो एक शून्य" } + +91 9876543210 -> telephone { country_code: "प्लस नौ एक", number_part: "नौ आठ सात छह पाँच चार तीन दो एक शून्य" } + +91 9876543210 123 -> telephone { country_code: "प्लस नौ एक", number_part: "नौ आठ सात छह पाँच चार तीन दो एक शून्य", extension: "एक दो तीन" } + + Args: + deterministic: if True will provide a single transduction option, + for False multiple transduction are generated (used for audio-based normalization + """ + + def __init__(self): + super().__init__(name="telephone", kind="classify") + + country_code_optional = pynini.closure( + pynutil.insert("country_code: \"") + + pynini.cross("+", "प्लस") + + insert_space + + country_codes + + pynutil.insert("\" ") + + delete_space, + 0, + 1, + ) + + number_part = ( + pynutil.insert("number_part: \"") + + mobile_start_digit + + insert_space + + pynini.closure(digit_to_word + insert_space, 9) + + pynutil.insert("\" ") + + delete_space + ) + + extension_optional = pynini.closure( + pynutil.insert("extension: \"") + + pynini.closure(digit_to_word + insert_space, 1, 3) + + pynutil.insert("\" ") + + delete_space, + 0, + 1, + ) + + mobile_number = country_code_optional + number_part + extension_optional + + credit_card = ( + pynutil.insert("number_part: \"") + + pynini.closure(digit_to_word + insert_space, 4) + + pynutil.insert("\" ") + + delete_space + ) + + pincode = ( + pynutil.insert("number_part: \"") + + pynini.closure(digit_to_word + insert_space, 6) + + pynutil.insert("\" ") + + delete_space + ) + + delete_zero = pynini.closure(pynini.string_map([("0", ""), ("०", "")]), 0, 1) + insert_shunya = pynutil.insert('शून्य') + insert_space + default_mobile = delete_zero + insert_shunya + number_part + + def generate_landline(std_list, std_length): + + std_digits = pynini.union(*[std for std in std_list if len(std.strip()) == std_length]) + std_graph = delete_zero + insert_shunya + std_digits @ std_codes + insert_space + + landline_digits = pynini.closure(digit_to_word + insert_space, 1, 9 - std_length) + landline_graph = landline_start_digit + insert_space + landline_digits + + seperator_optional = pynini.closure(pynini.cross("-", " "), 0, 1) + + return ( + pynutil.insert("number_part: \"") + + std_graph + + seperator_optional + + delete_space + + landline_graph + + pynutil.insert("\" ") + ) + + std_list = load_column_from_tsv(get_abs_path("data/telephone/STD_codes.tsv"), 0) + + landline_graph = ( + generate_landline(std_list, 2) + | generate_landline(std_list, 3) + | generate_landline(std_list, 4) + | generate_landline(std_list, 5) + | generate_landline(std_list, 6) + | generate_landline(std_list, 7) + ) + + graph = ( + pynutil.add_weight(number_part, -0.009) + | pynutil.add_weight(default_mobile, -0.002) + | pynutil.add_weight(mobile_number, -0.05) + | landline_graph + | pynutil.add_weight(credit_card, -0.4) + | pynutil.add_weight(pincode, -0.6) + ) + + graph = graph.optimize() + self.fst = self.add_tokens(graph) diff --git a/nemo_text_processing/text_normalization/hi/taggers/time.py b/nemo_text_processing/text_normalization/hi/taggers/time.py index 6c87c9aad..e78b31380 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/time.py +++ b/nemo_text_processing/text_normalization/hi/taggers/time.py @@ -36,10 +36,11 @@ class TimeFst(GraphFst): for False multiple transduction are generated (used for audio-based normalization) """ - def __init__(self): + def __init__(self, cardinal: GraphFst): super().__init__(name="time", kind="classify") delete_colon = pynutil.delete(":") + cardinal_graph = cardinal.digit | cardinal.teens_and_ties self.hours = pynutil.insert("hours: \"") + hours_graph + pynutil.insert("\" ") self.minutes = pynutil.insert("minutes: \"") + minutes_graph + pynutil.insert("\" ") @@ -56,7 +57,35 @@ def __init__(self): # hour graph_h = self.hours + delete_colon + pynutil.delete("००") - final_graph = graph_hms | graph_hm | graph_h + dedh_dhai_graph = pynini.string_map([("१:३०", "डेढ़"), ("२:३०", "ढाई")]) + + savva_numbers = cardinal_graph + pynini.cross(":१५", "") + savva_graph = pynutil.insert("सवा ") + savva_numbers + + sadhe_numbers = cardinal_graph + pynini.cross(":३०", "") + sadhe_graph = pynutil.insert("साढ़े ") + sadhe_numbers + + paune = pynini.string_file(get_abs_path("data/whitelist/paune_mappings.tsv")) + paune_numbers = paune + pynini.cross(":४५", "") + paune_graph = pynutil.insert("पौने ") + paune_numbers + + graph_dedh_dhai = pynutil.insert("morphosyntactic_features: \"") + dedh_dhai_graph + pynutil.insert("\" ") + + graph_savva = pynutil.insert("morphosyntactic_features: \"") + savva_graph + pynutil.insert("\" ") + + graph_sadhe = pynutil.insert("morphosyntactic_features: \"") + sadhe_graph + pynutil.insert("\" ") + + graph_paune = pynutil.insert("morphosyntactic_features: \"") + paune_graph + pynutil.insert("\" ") + + final_graph = ( + graph_hms + | pynutil.add_weight(graph_hm, 0.01) + | pynutil.add_weight(graph_h, 0.01) + | pynutil.add_weight(graph_dedh_dhai, 0.001) + | pynutil.add_weight(graph_savva, 0.005) + | pynutil.add_weight(graph_sadhe, 0.005) + | pynutil.add_weight(graph_paune, 0.001) + ) final_graph = self.add_tokens(final_graph) self.fst = final_graph.optimize() 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 b1bbd2a10..efc9a9cfe 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 @@ -33,6 +33,7 @@ from nemo_text_processing.text_normalization.hi.taggers.measure import MeasureFst from nemo_text_processing.text_normalization.hi.taggers.money import MoneyFst from nemo_text_processing.text_normalization.hi.taggers.punctuation import PunctuationFst +from nemo_text_processing.text_normalization.hi.taggers.telephone import TelephoneFst from nemo_text_processing.text_normalization.hi.taggers.time import TimeFst from nemo_text_processing.text_normalization.hi.taggers.whitelist import WhiteListFst from nemo_text_processing.text_normalization.hi.taggers.word import WordFst @@ -98,7 +99,7 @@ def __init__( logging.debug(f"date: {time.time() - start_time: .2f}s -- {date_graph.num_states()} nodes") start_time = time.time() - timefst = TimeFst() + timefst = TimeFst(cardinal=cardinal) time_graph = timefst.fst logging.debug(f"time: {time.time() - start_time: .2f}s -- {time_graph.num_states()} nodes") @@ -123,6 +124,11 @@ def __init__( punct_graph = punctuation.fst logging.debug(f"punct: {time.time() - start_time: .2f}s -- {punct_graph.num_states()} nodes") + start_time = time.time() + telephone = TelephoneFst() + telephone_graph = telephone.fst + logging.debug(f"telephone: {time.time() - start_time: .2f}s -- {telephone_graph.num_states()} nodes") + classify = ( pynutil.add_weight(whitelist_graph, 1.01) | pynutil.add_weight(cardinal_graph, 1.1) @@ -132,6 +138,7 @@ def __init__( | pynutil.add_weight(time_graph, 1.1) | pynutil.add_weight(measure_graph, 1.1) | pynutil.add_weight(money_graph, 1.1) + | pynutil.add_weight(telephone_graph, 1.61) ) start_time = time.time() diff --git a/nemo_text_processing/text_normalization/hi/taggers/word.py b/nemo_text_processing/text_normalization/hi/taggers/word.py index bc354232b..88350dea3 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/word.py +++ b/nemo_text_processing/text_normalization/hi/taggers/word.py @@ -43,7 +43,7 @@ def __init__(self, punctuation: PunctuationFst, deterministic: bool = True): *[chr(i) for i in range(ord("ऀ"), ord("ः") + 1)], # Hindi vowels and consonants *[chr(i) for i in range(ord("अ"), ord("ह") + 1)], # More Hindi characters *[chr(i) for i in range(ord("ा"), ord("्") + 1)], # Hindi diacritics - *[chr(i) for i in range(ord("०"), ord("९") + 1)], # Hindi digits + # *[chr(i) for i in range(ord("०"), ord("९") + 1)], # Hindi digits ).optimize() # Include punctuation in the graph diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py index 7e3b33b7c..0c2588b4c 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py @@ -15,7 +15,13 @@ import pynini from pynini.lib import pynutil -from nemo_text_processing.text_normalization.hi.graph_utils import MINUS, NEMO_NOT_QUOTE, GraphFst, insert_space +from nemo_text_processing.text_normalization.hi.graph_utils import ( + MINUS, + NEMO_NOT_QUOTE, + GraphFst, + delete_space, + insert_space, +) class FractionFst(GraphFst): @@ -40,6 +46,7 @@ def __init__(self, cardinal: GraphFst, deterministic: bool = True): denominator = pynutil.delete("denominator: \"") + pynini.closure(NEMO_NOT_QUOTE) + pynutil.delete("\"") insert_bata = pynutil.insert(" बटा ") insert_aur = pynutil.insert(" और ") + graph_quarter = pynutil.delete("morphosyntactic_features: \"") + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete("\"") fraction_default = numerator + insert_bata + denominator @@ -47,7 +54,7 @@ def __init__(self, cardinal: GraphFst, deterministic: bool = True): optional_sign + pynini.closure(pynini.closure(integer, 0, 1) + insert_space + insert_aur) + fraction_default - ) + ) | graph_quarter graph = self.graph diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/telephone.py b/nemo_text_processing/text_normalization/hi/verbalizers/telephone.py new file mode 100644 index 000000000..2ec4fb8c8 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/verbalizers/telephone.py @@ -0,0 +1,65 @@ +# Copyright (c) 2024, 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 pynini +from pynini.lib import pynutil + +from nemo_text_processing.text_normalization.hi.graph_utils import NEMO_NOT_QUOTE, GraphFst, delete_space, insert_space + + +class TelephoneFst(GraphFst): + """ + Finite state transducer for verbalizing telephone numbers, e.g. + telephone { country_code: "प्लस नौ एक", number_part: "नौ आठ सात छह पाँच चार तीन दो एक शून्य", extension: "एक दो तीन" } + -> प्लस नौ एक नौ आठ सात छह पाँच चार तीन दो एक शून्य एक दो तीन + + Args: + deterministic: if True will provide a single transduction option, + for False multiple transduction are generated (used for audio-based normalization) + """ + + def __init__(self, deterministic: bool = True): + super().__init__(name="telephone", kind="verbalize", deterministic=deterministic) + + optional_country_code = pynini.closure( + pynutil.delete("country_code: \"") + + pynini.closure(NEMO_NOT_QUOTE, 1) + + pynutil.delete("\"") + + delete_space + + insert_space, + 0, + 1, + ) + + number_part = ( + pynutil.delete("number_part: \"") + + pynini.closure(NEMO_NOT_QUOTE, 1) + + pynini.closure(pynutil.add_weight(pynutil.delete(" "), -0.0001), 0, 1) + + pynutil.delete("\"") + ) + + optional_extension = pynini.closure( + delete_space + + insert_space + + pynutil.delete("extension: \"") + + pynini.closure(NEMO_NOT_QUOTE, 1) + + pynutil.delete("\""), + 0, + 1, + ) + + graph = optional_country_code + number_part + optional_extension + delete_tokens = self.delete_tokens(graph) + self.fst = delete_tokens.optimize() diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/time.py b/nemo_text_processing/text_normalization/hi/verbalizers/time.py index da10df4a0..3898c8155 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/time.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/time.py @@ -30,7 +30,7 @@ class TimeFst(GraphFst): for False multiple transduction are generated (used for audio-based normalization) """ - def __init__(self): + def __init__(self, cardinal: GraphFst): super().__init__(name="time", kind="verbalize") hour = pynutil.delete("hours: \"") + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete("\"") + insert_space @@ -63,13 +63,15 @@ def __init__(self): + insert_second ) + graph_quarter = pynutil.delete("morphosyntactic_features: \"") + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete("\"") + # hour minute graph_hm = hour + delete_space + insert_bajkar + insert_space + minute + delete_space + insert_minute # hour graph_h = hour + delete_space + insert_baje - self.graph = graph_hms | graph_hm | graph_h + self.graph = graph_hms | graph_hm | graph_h | graph_quarter final_graph = self.graph diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py b/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py index e91f0d9f6..f824a075a 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/verbalize.py @@ -19,6 +19,7 @@ from nemo_text_processing.text_normalization.hi.verbalizers.fraction import FractionFst from nemo_text_processing.text_normalization.hi.verbalizers.measure import MeasureFst from nemo_text_processing.text_normalization.hi.verbalizers.money import MoneyFst +from nemo_text_processing.text_normalization.hi.verbalizers.telephone import TelephoneFst from nemo_text_processing.text_normalization.hi.verbalizers.time import TimeFst from nemo_text_processing.text_normalization.hi.verbalizers.whitelist import WhiteListFst @@ -49,7 +50,7 @@ def __init__(self, deterministic: bool = True): date = DateFst() date_graph = date.fst - time = TimeFst() + time = TimeFst(cardinal=cardinal) time_graph = time.fst measure = MeasureFst(cardinal=cardinal, decimal=decimal) @@ -58,6 +59,9 @@ def __init__(self, deterministic: bool = True): money = MoneyFst() money_graph = money.fst + telephone = TelephoneFst() + telephone_graph = telephone.fst + whitelist_graph = WhiteListFst(deterministic=deterministic).fst graph = ( @@ -69,6 +73,7 @@ def __init__(self, deterministic: bool = True): | measure_graph | money_graph | whitelist_graph + | telephone_graph ) self.fst = graph 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 6ba21de69..c7015e938 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 @@ -142,4 +142,4 @@ १०२२३४५५६७~एक अरब दो करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ ११०२२३४५५६७~ग्यारह अरब दो करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ ५१०२२३४५५६७~इक्यावन अरब दो करोड़ तेईस लाख पैंतालीस हज़ार पाँच सौ सड़सठ -२ पॉइंट्स १२ गोल~दो पॉइंट्स बारह गोल +२ पॉइंट्स १२ गोल~दो पॉइंट्स बारह गोल \ No newline at end of file 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..189e6d4ef 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 @@ -20,4 +20,8 @@ १०००००००००००००००/८~एक पद्म बटा आठ १०००००००००००००००००/४१२~एक शंख बटा चार सौ बारह २ २/७~दो और दो बटा सात -१२० ७५/९०~एक सौ बीस और पचहत्तर बटा नब्बे \ No newline at end of file +१२० ७५/९०~एक सौ बीस और पचहत्तर बटा नब्बे +१ १/२~डेढ़ +२ १/२~ढाई +८ १/२~साढ़े आठ +१०००० १/४~सवा दस हज़ार \ 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..0d31a5833 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 @@ -64,3 +64,8 @@ ५x५ का सोफ़ा~पाँच बाई पाँच का सोफ़ा २x२ रुबिक्स क्यूब~दो बाई दो रुबिक्स क्यूब १३x१३ का घर~तेरह बाई तेरह का घर +५७.२५ hp~सवा सत्तावन हॉर्सपॉवर +७.५ हफ़्ते~साढ़े सात हफ़्ते +१०.७५ min~पौने ग्यारह मिनट +१.५ doz~डेढ़ दर्जन +२.५ yr~ढाई साल \ No newline at end of file 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 new file mode 100644 index 000000000..6766ab6a5 --- /dev/null +++ b/tests/nemo_text_processing/hi/data_text_normalization/test_cases_telephone.txt @@ -0,0 +1,6 @@ +मेरा पुराना नंबर था ०९१५७११४००७~मेरा पुराना नंबर था शून्य नौ एक पाँच सात एक एक चार शून्य शून्य सात +इसपे कॉल करो ०३८६२-३५१७९१~इसपे कॉल करो शून्य तीन आठ छह दो तीन पाँच एक सात नौ एक +मेरे इस नंबर पे कॉल करो १३७४-३०९९८८~मेरे इस नंबर पे कॉल करो शून्य एक तीन सात चार तीन शून्य नौ नौ आठ आठ +इसपे कॉल करो ०१६८९११-४५७३~इसपे कॉल करो शून्य एक छह आठ नौ एक एक चार पाँच सात तीन ++९१ ७४४०४३१०८३ मेरे इस नंबर पे कॉल करो~प्लस नौ एक सात चार चार शून्य चार तीन एक शून्य आठ तीन मेरे इस नंबर पे कॉल करो ++९१ ९२१०५१५६०६ मेरे इस नंबर पे कॉल करो~प्लस नौ एक नौ दो एक शून्य पाँच एक पाँच छह शून्य छह मेरे इस नंबर पे कॉल करो 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..6b059a626 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 @@ -15,4 +15,9 @@ दोपहर के ३:००~दोपहर के तीन बजे रात के १०:४८:५०~रात के दस बजकर अड़तालीस मिनट पचास सेकंड रात के ११:५०~रात के ग्यारह बजकर पचास मिनट -रात के ८:००~रात के आठ बजे \ No newline at end of file +रात के ८:००~रात के आठ बजे +१:३०~डेढ़ +२:३०~ढाई +४:४५~पौने पाँच +१०:१५~सवा दस +१२:३०~साढ़े बारह \ No newline at end of file diff --git a/tests/nemo_text_processing/hi/test_sparrowhawk_normalization.sh b/tests/nemo_text_processing/hi/test_sparrowhawk_normalization.sh index 498443f71..39d710120 100644 --- a/tests/nemo_text_processing/hi/test_sparrowhawk_normalization.sh +++ b/tests/nemo_text_processing/hi/test_sparrowhawk_normalization.sh @@ -81,10 +81,10 @@ testTNMoney() { # runtest $input #} -#testTNTelephone() { -# input=$PROJECT_DIR/en/data_text_normalization/test_cases_telephone.txt -# runtest $input -#} +testTNTelephone() { + input=$PROJECT_DIR/hi/data_text_normalization/test_cases_telephone.txt + runtest $input +} testTNTime() { input=$PROJECT_DIR/hi/data_text_normalization/test_cases_time.txt diff --git a/tests/nemo_text_processing/hi/test_telephone.py b/tests/nemo_text_processing/hi/test_telephone.py index 7e43f7e82..e7b9f1c3d 100644 --- a/tests/nemo_text_processing/hi/test_telephone.py +++ b/tests/nemo_text_processing/hi/test_telephone.py @@ -16,12 +16,16 @@ from parameterized import parameterized from nemo_text_processing.inverse_text_normalization.inverse_normalize import InverseNormalizer +from nemo_text_processing.text_normalization.normalize import Normalizer from ..utils import CACHE_DIR, parse_test_case_file class TestTelephone: inverse_normalizer = InverseNormalizer(lang='hi', cache_dir=CACHE_DIR, overwrite_cache=False) + 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_inverse_text_normalization/test_cases_telephone.txt')) @pytest.mark.run_only_on('CPU') @@ -29,3 +33,10 @@ class TestTelephone: def test_denorm(self, test_input, expected): pred = self.inverse_normalizer.inverse_normalize(test_input, verbose=False) assert pred.strip() == expected.strip() + + @parameterized.expand(parse_test_case_file('hi/data_text_normalization/test_cases_telephone.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 From 3963e4fccf111108cb8cb7f8ff4608be05006cb0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 05:47:59 +0000 Subject: [PATCH 03/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../text_normalization/hi/verbalizers/fraction.py | 4 +++- .../text_normalization/hi/verbalizers/time.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py index 0c2588b4c..6fd79e2d1 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py @@ -46,7 +46,9 @@ def __init__(self, cardinal: GraphFst, deterministic: bool = True): denominator = pynutil.delete("denominator: \"") + pynini.closure(NEMO_NOT_QUOTE) + pynutil.delete("\"") insert_bata = pynutil.insert(" बटा ") insert_aur = pynutil.insert(" और ") - graph_quarter = pynutil.delete("morphosyntactic_features: \"") + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete("\"") + graph_quarter = ( + pynutil.delete("morphosyntactic_features: \"") + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete("\"") + ) fraction_default = numerator + insert_bata + denominator diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/time.py b/nemo_text_processing/text_normalization/hi/verbalizers/time.py index 3898c8155..df232e3cd 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/time.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/time.py @@ -63,7 +63,9 @@ def __init__(self, cardinal: GraphFst): + insert_second ) - graph_quarter = pynutil.delete("morphosyntactic_features: \"") + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete("\"") + graph_quarter = ( + pynutil.delete("morphosyntactic_features: \"") + pynini.closure(NEMO_NOT_QUOTE, 1) + pynutil.delete("\"") + ) # hour minute graph_hm = hour + delete_space + insert_bajkar + insert_space + minute + delete_space + insert_minute From 775e08edd7bc97f0cae73a4bb7daa083828dfb3e Mon Sep 17 00:00:00 2001 From: Namrata Gachchi Date: Wed, 25 Jun 2025 14:51:20 +0530 Subject: [PATCH 04/16] updated Jenkins file Signed-off-by: Namrata Gachchi --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 51ce37a10..8a6fd760b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -27,7 +27,7 @@ pipeline { HY_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/03-12-24-0' MR_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/03-12-24-1' JA_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/10-17-24-1' - HI_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/04-22-25-0' + HI_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/06-25-25-0' DEFAULT_TN_CACHE='/home/jenkinsci/TestData/text_norm/ci/grammars/06-08-23-0' } stages { From e0a4a85dfa24e2ef7cd083d6e848fc2455c0de8f Mon Sep 17 00:00:00 2001 From: Namrata Gachchi Date: Thu, 26 Jun 2025 10:03:56 +0530 Subject: [PATCH 05/16] removed unused imports and variable Signed-off-by: Namrata Gachchi --- nemo_text_processing/text_normalization/hi/taggers/date.py | 1 - nemo_text_processing/text_normalization/hi/taggers/telephone.py | 2 +- .../text_normalization/hi/verbalizers/fraction.py | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/nemo_text_processing/text_normalization/hi/taggers/date.py b/nemo_text_processing/text_normalization/hi/taggers/date.py index b8b652128..37b192165 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/date.py +++ b/nemo_text_processing/text_normalization/hi/taggers/date.py @@ -73,7 +73,6 @@ def __init__(self, cardinal: GraphFst): delete_dash = pynutil.delete("-") delete_slash = pynutil.delete("/") - delete_comma = pynutil.delete(",") days_graph = pynutil.insert("day: \"") + days + pynutil.insert("\"") + insert_space diff --git a/nemo_text_processing/text_normalization/hi/taggers/telephone.py b/nemo_text_processing/text_normalization/hi/taggers/telephone.py index fe384fd13..cf824744e 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/telephone.py +++ b/nemo_text_processing/text_normalization/hi/taggers/telephone.py @@ -16,7 +16,7 @@ import pynini from pynini.lib import pynutil -from nemo_text_processing.text_normalization.hi.graph_utils import NEMO_DIGIT, GraphFst, delete_space, insert_space +from nemo_text_processing.text_normalization.hi.graph_utils import GraphFst, delete_space, insert_space from nemo_text_processing.text_normalization.hi.utils import get_abs_path diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py index 6fd79e2d1..a1eb0655c 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py @@ -19,7 +19,6 @@ MINUS, NEMO_NOT_QUOTE, GraphFst, - delete_space, insert_space, ) From 2740172c04d8d5a3172fac800edd419de5be7e82 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 04:35:38 +0000 Subject: [PATCH 06/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../text_normalization/hi/verbalizers/fraction.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py index a1eb0655c..a07c41eae 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py @@ -15,12 +15,7 @@ import pynini from pynini.lib import pynutil -from nemo_text_processing.text_normalization.hi.graph_utils import ( - MINUS, - NEMO_NOT_QUOTE, - GraphFst, - insert_space, -) +from nemo_text_processing.text_normalization.hi.graph_utils import MINUS, NEMO_NOT_QUOTE, GraphFst, insert_space class FractionFst(GraphFst): From a09def4cc5f25756b43452d7c196f6d19cadd3b5 Mon Sep 17 00:00:00 2001 From: Namrata Gachchi Date: Mon, 7 Jul 2025 16:34:51 +0530 Subject: [PATCH 07/16] pincode and last four digits of credit card implementations within the telephone class Signed-off-by: Namrata Gachchi --- .../hi/taggers/telephone.py | 244 +++++++++++------- .../hi/taggers/tokenize_and_classify.py | 2 +- .../hi/verbalizers/telephone.py | 4 +- .../text_normalization/token_parser.py | 2 +- .../test_cases_telephone.txt | 4 +- 5 files changed, 155 insertions(+), 101 deletions(-) diff --git a/nemo_text_processing/text_normalization/hi/taggers/telephone.py b/nemo_text_processing/text_normalization/hi/taggers/telephone.py index cf824744e..7132fe598 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/telephone.py +++ b/nemo_text_processing/text_normalization/hi/taggers/telephone.py @@ -16,125 +16,177 @@ import pynini from pynini.lib import pynutil -from nemo_text_processing.text_normalization.hi.graph_utils import GraphFst, delete_space, insert_space +from nemo_text_processing.text_normalization.hi.graph_utils import GraphFst, delete_space, insert_space, NEMO_CHAR, NEMO_WHITE_SPACE from nemo_text_processing.text_normalization.hi.utils import get_abs_path +delete_zero = pynutil.delete(pynini.union("0", "०")) +delete_zero_optional = pynini.closure(delete_zero, 0, 1) +insert_shunya = pynutil.insert('शून्य') + insert_space -def load_column_from_tsv(filepath, column_index=1): - with open(filepath, encoding='utf-8') as tsv: - return [line.strip().split("\t")[column_index] for line in tsv if line.strip()] - - -# Load the number mappings from the TSV file +#Load the number mappings from the TSV file digit_to_word = pynini.string_file(get_abs_path("data/telephone/number.tsv")) std_codes = pynini.string_file(get_abs_path("data/telephone/STD_codes.tsv")) country_codes = pynini.string_file(get_abs_path("data/telephone/country_codes.tsv")) landline_start_digit = pynini.string_file(get_abs_path("data/telephone/landline_digits.tsv")) mobile_start_digit = pynini.string_file(get_abs_path("data/telephone/mobile_digits.tsv")) - -class TelephoneFst(GraphFst): - """ - Finite state transducer for tagging telephone numbers, e.g. - 9876543210 -> telephone { number_part: "नौ आठ सात छह पाँच चार तीन दो एक शून्य" } - +91 9876543210 -> telephone { country_code: "प्लस नौ एक", number_part: "नौ आठ सात छह पाँच चार तीन दो एक शून्य" } - +91 9876543210 123 -> telephone { country_code: "प्लस नौ एक", number_part: "नौ आठ सात छह पाँच चार तीन दो एक शून्य", extension: "एक दो तीन" } - - Args: - deterministic: if True will provide a single transduction option, - for False multiple transduction are generated (used for audio-based normalization - """ - - def __init__(self): - super().__init__(name="telephone", kind="classify") - - country_code_optional = pynini.closure( - pynutil.insert("country_code: \"") - + pynini.cross("+", "प्लस") - + insert_space - + country_codes - + pynutil.insert("\" ") - + delete_space, - 0, - 1, - ) - - number_part = ( - pynutil.insert("number_part: \"") - + mobile_start_digit - + insert_space - + pynini.closure(digit_to_word + insert_space, 9) - + pynutil.insert("\" ") - + delete_space - ) - - extension_optional = pynini.closure( - pynutil.insert("extension: \"") - + pynini.closure(digit_to_word + insert_space, 1, 3) - + pynutil.insert("\" ") - + delete_space, - 0, - 1, - ) - - mobile_number = country_code_optional + number_part + extension_optional - - credit_card = ( +def load_column_from_tsv(filepath, column_index=1): + with open(filepath, encoding='utf-8') as tsv: + return [line.strip().split("\t")[column_index] for line in tsv if line.strip()] + +def generate_mobile(context_keywords): + context_before, context_after = get_context(context_keywords) + country_code = ( + pynutil.insert("country_code: \"") + + context_before + + pynini.cross("+", "प्लस") + + insert_space + country_codes + + pynutil.insert("\" ") + + pynini.closure(delete_space, 0, 1) + ) + + extension_optional = pynini.closure( + pynutil.insert("extension: \"") + + pynini.closure(digit_to_word + insert_space, 1, 3) + + context_after + + pynutil.insert("\" ") + + delete_space + ,0,1 + ) + + number_without_country = ( + pynutil.insert("number_part: \"") + + context_before + + delete_zero_optional + + insert_shunya + + mobile_start_digit + insert_space + + pynini.closure(digit_to_word + insert_space, 9) + + context_after + + pynutil.insert("\" ") + delete_space + ) + + number_with_country = ( + country_code + + pynutil.insert("number_part: \"") + + mobile_start_digit + insert_space + + pynini.closure(digit_to_word + insert_space, 9) + + context_after + + pynutil.insert("\" ") + delete_space + ) + + return (number_with_country | number_without_country) + extension_optional + +def get_landline(std_list, std_length, context_keywords): + context_before, context_after = get_context(context_keywords) + std_digits = pynini.union(*[std for std in std_list if len(std.strip()) == std_length]) + std_graph = delete_zero_optional + insert_shunya + std_digits @ std_codes + insert_space + + landline_digits = pynini.closure(digit_to_word + insert_space, 1, 9-std_length) + landline_graph = landline_start_digit + insert_space + landline_digits + + seperator_optional = pynini.closure(pynini.cross("-", ""), 0, 1) + + return ( + pynutil.insert("number_part: \"") + + context_before + + std_graph + + seperator_optional + + delete_space + + landline_graph + + context_after + + pynutil.insert("\" ") + ) + +def generate_landline(context_keywords): + std_list = load_column_from_tsv(get_abs_path("data/telephone/STD_codes.tsv"),0) + graph = ( + get_landline(std_list, 2, context_keywords) + | get_landline(std_list, 3, context_keywords) + | get_landline(std_list, 4, context_keywords) + | get_landline(std_list, 5, context_keywords) + | get_landline(std_list, 6, context_keywords) + | get_landline(std_list, 7, context_keywords) + ) + + return graph + +def get_context(keywords: list): + keywords = pynini.union(*keywords) + + hindi_digits = pynini.union("०", "१", "२", "३", "४", "५", "६", "७", "८", "९") + english_digits = pynini.union("0", "1", "2", "3", "4", "5", "6", "7", "8", "9") + all_digits = pynini.union(hindi_digits, english_digits) + + non_digit_char = pynini.difference(NEMO_CHAR, pynini.union(all_digits, NEMO_WHITE_SPACE)) + word = pynini.closure(non_digit_char, 1) + pynini.accep(" ") + + window = pynini.closure(word, 0, 5) + + before = pynini.closure( + keywords + + pynini.accep(" ") + + window + ,0,1 + ) + + after = pynini.closure( + pynutil.delete(" ") + + window + + keywords + ,0,1 + ) + + return before.optimize(), after.optimize() + +def generate_credit(context_keywords): + context_before, context_after = get_context(context_keywords) + return ( pynutil.insert("number_part: \"") + + context_before + pynini.closure(digit_to_word + insert_space, 4) - + pynutil.insert("\" ") + + context_after + + pynutil.insert("\" ") + delete_space ) - pincode = ( +def generate_pincode(context_keywords): + context_before, context_after = get_context(context_keywords) + return ( pynutil.insert("number_part: \"") + + context_before + pynini.closure(digit_to_word + insert_space, 6) - + pynutil.insert("\" ") + + context_after + + pynutil.insert("\" ") + delete_space ) - delete_zero = pynini.closure(pynini.string_map([("0", ""), ("०", "")]), 0, 1) - insert_shunya = pynutil.insert('शून्य') + insert_space - default_mobile = delete_zero + insert_shunya + number_part - - def generate_landline(std_list, std_length): - - std_digits = pynini.union(*[std for std in std_list if len(std.strip()) == std_length]) - std_graph = delete_zero + insert_shunya + std_digits @ std_codes + insert_space - - landline_digits = pynini.closure(digit_to_word + insert_space, 1, 9 - std_length) - landline_graph = landline_start_digit + insert_space + landline_digits - - seperator_optional = pynini.closure(pynini.cross("-", " "), 0, 1) +class TelephoneFst(GraphFst): + """ + Finite state transducer for tagging telephone numbers, e.g. + ९१५७११४००७ -> telephone { number_part: "शून्य नौ एक पाँच सात एक एक चार शून्य शून्य सात" } + +९१ ९२१०५१५६०६ -> telephone { country_code: "प्लस नौ एक", number_part: "नौ दो एक शून्य पाँच एक पाँच छह शून्य छह" } + १३७४-३०९९८८ -> telephone { number_part: "शून्य एक तीन सात चार तीन शून्य नौ नौ आठ आठ" } + + Args: + deterministic: if True will provide a single transduction option, + for False multiple transduction are generated (used for audio-based normalization + """ - return ( - pynutil.insert("number_part: \"") - + std_graph - + seperator_optional - + delete_space - + landline_graph - + pynutil.insert("\" ") - ) + def __init__(self): + super().__init__(name="telephone", kind="classify") - std_list = load_column_from_tsv(get_abs_path("data/telephone/STD_codes.tsv"), 0) + mobile_number = generate_mobile(["नंबर", "मोबाइल", "फोन", "कॉल"]) + landline = generate_landline(["नंबर", "मोबाइल", "फोन", "लैंडलाइन", "कॉल"]) + credit_card = generate_credit(["नंबर", "कार्ड", "क्रेडिट"]) + pincode = generate_pincode(["नंबर", "पिन", "कोड", "पिनकोड"]) - landline_graph = ( - generate_landline(std_list, 2) - | generate_landline(std_list, 3) - | generate_landline(std_list, 4) - | generate_landline(std_list, 5) - | generate_landline(std_list, 6) - | generate_landline(std_list, 7) - ) graph = ( - pynutil.add_weight(number_part, -0.009) - | pynutil.add_weight(default_mobile, -0.002) - | pynutil.add_weight(mobile_number, -0.05) - | landline_graph - | pynutil.add_weight(credit_card, -0.4) - | pynutil.add_weight(pincode, -0.6) + pynutil.add_weight(mobile_number, 0.7) + | pynutil.add_weight(landline, 0.8) + | pynutil.add_weight(credit_card, 0.9) + | pynutil.add_weight(pincode, 1) ) - graph = graph.optimize() - self.fst = self.add_tokens(graph) + self.final = graph.optimize() + self.fst = self.add_tokens(self.final) 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 efc9a9cfe..08182b34d 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 @@ -138,7 +138,7 @@ def __init__( | pynutil.add_weight(time_graph, 1.1) | pynutil.add_weight(measure_graph, 1.1) | pynutil.add_weight(money_graph, 1.1) - | pynutil.add_weight(telephone_graph, 1.61) + | pynutil.add_weight(telephone_graph, 1.1) ) start_time = time.time() diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/telephone.py b/nemo_text_processing/text_normalization/hi/verbalizers/telephone.py index 2ec4fb8c8..f55cf4241 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/telephone.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/telephone.py @@ -22,8 +22,8 @@ class TelephoneFst(GraphFst): """ Finite state transducer for verbalizing telephone numbers, e.g. - telephone { country_code: "प्लस नौ एक", number_part: "नौ आठ सात छह पाँच चार तीन दो एक शून्य", extension: "एक दो तीन" } - -> प्लस नौ एक नौ आठ सात छह पाँच चार तीन दो एक शून्य एक दो तीन + telephone { country_code: "प्लस नौ एक", number_part: "नौ दो एक शून्य पाँच एक पाँच छह शून्य छह" } -> प्लस नौ एक नौ दो एक शून्य पाँच एक पाँच छह शून्य छह + telephone { number_part: "शून्य एक तीन सात चार तीन शून्य नौ नौ आठ आठ" } -> शून्य एक तीन सात चार तीन शून्य नौ नौ आठ आठ Args: deterministic: if True will provide a single transduction option, diff --git a/nemo_text_processing/text_normalization/token_parser.py b/nemo_text_processing/text_normalization/token_parser.py index 4adcd7d7f..8aee200e5 100644 --- a/nemo_text_processing/text_normalization/token_parser.py +++ b/nemo_text_processing/text_normalization/token_parser.py @@ -114,7 +114,7 @@ def parse_char(self, exp) -> bool: Returns true if successful """ - assert self.char == exp + assert (self.char == exp) self.read() return True 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 6766ab6a5..275fdc2ad 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,6 +1,8 @@ -मेरा पुराना नंबर था ०९१५७११४००७~मेरा पुराना नंबर था शून्य नौ एक पाँच सात एक एक चार शून्य शून्य सात +मेरा पुराना नंबर था ९१५७११४००७~मेरा पुराना नंबर था शून्य नौ एक पाँच सात एक एक चार शून्य शून्य सात इसपे कॉल करो ०३८६२-३५१७९१~इसपे कॉल करो शून्य तीन आठ छह दो तीन पाँच एक सात नौ एक मेरे इस नंबर पे कॉल करो १३७४-३०९९८८~मेरे इस नंबर पे कॉल करो शून्य एक तीन सात चार तीन शून्य नौ नौ आठ आठ इसपे कॉल करो ०१६८९११-४५७३~इसपे कॉल करो शून्य एक छह आठ नौ एक एक चार पाँच सात तीन +९१ ७४४०४३१०८३ मेरे इस नंबर पे कॉल करो~प्लस नौ एक सात चार चार शून्य चार तीन एक शून्य आठ तीन मेरे इस नंबर पे कॉल करो +९१ ९२१०५१५६०६ मेरे इस नंबर पे कॉल करो~प्लस नौ एक नौ दो एक शून्य पाँच एक पाँच छह शून्य छह मेरे इस नंबर पे कॉल करो +भुगतान के लिए कार्ड के आखिरी अंक १२३४ दर्ज करें~भुगतान के लिए कार्ड के आखिरी अंक एक दो तीन चार दर्ज करें +मेरा पिन कोड ११००२३ है~मेरा पिन कोड एक एक शून्य शून्य दो तीन है \ No newline at end of file From 052b396e0ebb8db8428cb280c59b822635de6575 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 11:07:27 +0000 Subject: [PATCH 08/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../hi/taggers/telephone.py | 125 ++++++++++-------- .../text_normalization/token_parser.py | 2 +- 2 files changed, 68 insertions(+), 59 deletions(-) diff --git a/nemo_text_processing/text_normalization/hi/taggers/telephone.py b/nemo_text_processing/text_normalization/hi/taggers/telephone.py index 7132fe598..3a0dc1863 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/telephone.py +++ b/nemo_text_processing/text_normalization/hi/taggers/telephone.py @@ -16,89 +16,105 @@ import pynini from pynini.lib import pynutil -from nemo_text_processing.text_normalization.hi.graph_utils import GraphFst, delete_space, insert_space, NEMO_CHAR, NEMO_WHITE_SPACE +from nemo_text_processing.text_normalization.hi.graph_utils import ( + NEMO_CHAR, + NEMO_WHITE_SPACE, + GraphFst, + delete_space, + insert_space, +) from nemo_text_processing.text_normalization.hi.utils import get_abs_path delete_zero = pynutil.delete(pynini.union("0", "०")) delete_zero_optional = pynini.closure(delete_zero, 0, 1) insert_shunya = pynutil.insert('शून्य') + insert_space -#Load the number mappings from the TSV file +# Load the number mappings from the TSV file digit_to_word = pynini.string_file(get_abs_path("data/telephone/number.tsv")) std_codes = pynini.string_file(get_abs_path("data/telephone/STD_codes.tsv")) country_codes = pynini.string_file(get_abs_path("data/telephone/country_codes.tsv")) landline_start_digit = pynini.string_file(get_abs_path("data/telephone/landline_digits.tsv")) mobile_start_digit = pynini.string_file(get_abs_path("data/telephone/mobile_digits.tsv")) + def load_column_from_tsv(filepath, column_index=1): with open(filepath, encoding='utf-8') as tsv: return [line.strip().split("\t")[column_index] for line in tsv if line.strip()] - + + def generate_mobile(context_keywords): context_before, context_after = get_context(context_keywords) country_code = ( pynutil.insert("country_code: \"") + context_before + pynini.cross("+", "प्लस") - + insert_space + country_codes + + insert_space + + country_codes + pynutil.insert("\" ") + pynini.closure(delete_space, 0, 1) ) extension_optional = pynini.closure( - pynutil.insert("extension: \"") - + pynini.closure(digit_to_word + insert_space, 1, 3) + pynutil.insert("extension: \"") + + pynini.closure(digit_to_word + insert_space, 1, 3) + context_after - + pynutil.insert("\" ") - + delete_space - ,0,1 + + pynutil.insert("\" ") + + delete_space, + 0, + 1, ) number_without_country = ( pynutil.insert("number_part: \"") + context_before - + delete_zero_optional - + insert_shunya - + mobile_start_digit + insert_space + + delete_zero_optional + + insert_shunya + + mobile_start_digit + + insert_space + pynini.closure(digit_to_word + insert_space, 9) + context_after - + pynutil.insert("\" ") + delete_space + + pynutil.insert("\" ") + + delete_space ) number_with_country = ( country_code + pynutil.insert("number_part: \"") - + mobile_start_digit + insert_space + + mobile_start_digit + + insert_space + pynini.closure(digit_to_word + insert_space, 9) + context_after - + pynutil.insert("\" ") + delete_space - ) - + + pynutil.insert("\" ") + + delete_space + ) + return (number_with_country | number_without_country) + extension_optional - + + def get_landline(std_list, std_length, context_keywords): context_before, context_after = get_context(context_keywords) std_digits = pynini.union(*[std for std in std_list if len(std.strip()) == std_length]) std_graph = delete_zero_optional + insert_shunya + std_digits @ std_codes + insert_space - - landline_digits = pynini.closure(digit_to_word + insert_space, 1, 9-std_length) + + landline_digits = pynini.closure(digit_to_word + insert_space, 1, 9 - std_length) landline_graph = landline_start_digit + insert_space + landline_digits - + seperator_optional = pynini.closure(pynini.cross("-", ""), 0, 1) return ( - pynutil.insert("number_part: \"") - + context_before - + std_graph - + seperator_optional - + delete_space - + landline_graph - + context_after + pynutil.insert("number_part: \"") + + context_before + + std_graph + + seperator_optional + + delete_space + + landline_graph + + context_after + pynutil.insert("\" ") ) + def generate_landline(context_keywords): - std_list = load_column_from_tsv(get_abs_path("data/telephone/STD_codes.tsv"),0) + std_list = load_column_from_tsv(get_abs_path("data/telephone/STD_codes.tsv"), 0) graph = ( get_landline(std_list, 2, context_keywords) | get_landline(std_list, 3, context_keywords) @@ -107,9 +123,10 @@ def generate_landline(context_keywords): | get_landline(std_list, 6, context_keywords) | get_landline(std_list, 7, context_keywords) ) - + return graph + def get_context(keywords: list): keywords = pynini.union(*keywords) @@ -122,43 +139,36 @@ def get_context(keywords: list): window = pynini.closure(word, 0, 5) - before = pynini.closure( - keywords - + pynini.accep(" ") - + window - ,0,1 - ) + before = pynini.closure(keywords + pynini.accep(" ") + window, 0, 1) - after = pynini.closure( - pynutil.delete(" ") - + window - + keywords - ,0,1 - ) + after = pynini.closure(pynutil.delete(" ") + window + keywords, 0, 1) return before.optimize(), after.optimize() + def generate_credit(context_keywords): context_before, context_after = get_context(context_keywords) return ( - pynutil.insert("number_part: \"") - + context_before - + pynini.closure(digit_to_word + insert_space, 4) - + context_after - + pynutil.insert("\" ") - + delete_space - ) + pynutil.insert("number_part: \"") + + context_before + + pynini.closure(digit_to_word + insert_space, 4) + + context_after + + pynutil.insert("\" ") + + delete_space + ) + def generate_pincode(context_keywords): context_before, context_after = get_context(context_keywords) return ( - pynutil.insert("number_part: \"") - + context_before - + pynini.closure(digit_to_word + insert_space, 6) - + context_after - + pynutil.insert("\" ") - + delete_space - ) + pynutil.insert("number_part: \"") + + context_before + + pynini.closure(digit_to_word + insert_space, 6) + + context_after + + pynutil.insert("\" ") + + delete_space + ) + class TelephoneFst(GraphFst): """ @@ -166,7 +176,7 @@ class TelephoneFst(GraphFst): ९१५७११४००७ -> telephone { number_part: "शून्य नौ एक पाँच सात एक एक चार शून्य शून्य सात" } +९१ ९२१०५१५६०६ -> telephone { country_code: "प्लस नौ एक", number_part: "नौ दो एक शून्य पाँच एक पाँच छह शून्य छह" } १३७४-३०९९८८ -> telephone { number_part: "शून्य एक तीन सात चार तीन शून्य नौ नौ आठ आठ" } - + Args: deterministic: if True will provide a single transduction option, for False multiple transduction are generated (used for audio-based normalization @@ -180,7 +190,6 @@ def __init__(self): credit_card = generate_credit(["नंबर", "कार्ड", "क्रेडिट"]) pincode = generate_pincode(["नंबर", "पिन", "कोड", "पिनकोड"]) - graph = ( pynutil.add_weight(mobile_number, 0.7) | pynutil.add_weight(landline, 0.8) diff --git a/nemo_text_processing/text_normalization/token_parser.py b/nemo_text_processing/text_normalization/token_parser.py index 8aee200e5..4adcd7d7f 100644 --- a/nemo_text_processing/text_normalization/token_parser.py +++ b/nemo_text_processing/text_normalization/token_parser.py @@ -114,7 +114,7 @@ def parse_char(self, exp) -> bool: Returns true if successful """ - assert (self.char == exp) + assert self.char == exp self.read() return True From 81c664ab4826d9bf442adb63a5350b457434ddb1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 03:58:14 +0000 Subject: [PATCH 09/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../text_normalization/hi/verbalizers/fraction.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py index f0cb1330b..a07c41eae 100644 --- a/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py +++ b/nemo_text_processing/text_normalization/hi/verbalizers/fraction.py @@ -52,7 +52,6 @@ def __init__(self, cardinal: GraphFst, deterministic: bool = True): + fraction_default ) | graph_quarter - graph = self.graph delete_tokens = self.delete_tokens(graph) From 6f56d08fd65e7cfb34f8445a0268b215bdaf8b11 Mon Sep 17 00:00:00 2001 From: Namrata Gachchi Date: Wed, 9 Jul 2025 09:57:38 +0530 Subject: [PATCH 10/16] removed dependency from STD_codes.tsv file Signed-off-by: Namrata Gachchi --- .../hi/taggers/telephone.py | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/nemo_text_processing/text_normalization/hi/taggers/telephone.py b/nemo_text_processing/text_normalization/hi/taggers/telephone.py index 3a0dc1863..68378091a 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/telephone.py +++ b/nemo_text_processing/text_normalization/hi/taggers/telephone.py @@ -91,21 +91,29 @@ def generate_mobile(context_keywords): return (number_with_country | number_without_country) + extension_optional -def get_landline(std_list, std_length, context_keywords): +def get_landline(std_length, context_keywords): context_before, context_after = get_context(context_keywords) - std_digits = pynini.union(*[std for std in std_list if len(std.strip()) == std_length]) - std_graph = delete_zero_optional + insert_shunya + std_digits @ std_codes + insert_space - landline_digits = pynini.closure(digit_to_word + insert_space, 1, 9 - std_length) - landline_graph = landline_start_digit + insert_space + landline_digits + std_code_graph = ( + delete_zero_optional + + insert_shunya + + pynini.closure(digit_to_word + insert_space, std_length, std_length) + ) + + landline_digit_count = 9 - std_length + landline_graph = ( + landline_start_digit + + insert_space + + pynini.closure(digit_to_word + insert_space, landline_digit_count, landline_digit_count) + ) - seperator_optional = pynini.closure(pynini.cross("-", ""), 0, 1) + separator_optional = pynini.closure(pynini.cross("-", ""), 0, 1) return ( pynutil.insert("number_part: \"") + context_before - + std_graph - + seperator_optional + + std_code_graph + + separator_optional + delete_space + landline_graph + context_after @@ -114,14 +122,13 @@ def get_landline(std_list, std_length, context_keywords): def generate_landline(context_keywords): - std_list = load_column_from_tsv(get_abs_path("data/telephone/STD_codes.tsv"), 0) graph = ( - get_landline(std_list, 2, context_keywords) - | get_landline(std_list, 3, context_keywords) - | get_landline(std_list, 4, context_keywords) - | get_landline(std_list, 5, context_keywords) - | get_landline(std_list, 6, context_keywords) - | get_landline(std_list, 7, context_keywords) + get_landline(2, context_keywords) + | get_landline(3, context_keywords) + | get_landline(4, context_keywords) + | get_landline(5, context_keywords) + | get_landline(6, context_keywords) + | get_landline(7, context_keywords) ) return graph From 764b57785a2a5e432f8d27578eb59224daae5eb2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 9 Jul 2025 04:29:01 +0000 Subject: [PATCH 11/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../text_normalization/hi/taggers/telephone.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nemo_text_processing/text_normalization/hi/taggers/telephone.py b/nemo_text_processing/text_normalization/hi/taggers/telephone.py index 68378091a..fd936a061 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/telephone.py +++ b/nemo_text_processing/text_normalization/hi/taggers/telephone.py @@ -95,9 +95,7 @@ def get_landline(std_length, context_keywords): context_before, context_after = get_context(context_keywords) std_code_graph = ( - delete_zero_optional - + insert_shunya - + pynini.closure(digit_to_word + insert_space, std_length, std_length) + delete_zero_optional + insert_shunya + pynini.closure(digit_to_word + insert_space, std_length, std_length) ) landline_digit_count = 9 - std_length From aaaaa8fd5923700b4aa80b22cd3b12cb2a25c370 Mon Sep 17 00:00:00 2001 From: Namrata Gachchi Date: Mon, 14 Jul 2025 11:05:57 +0530 Subject: [PATCH 12/16] removed unused lines Signed-off-by: Namrata Gachchi --- .../text_normalization/hi/taggers/cardinal.py | 7 ------- .../text_normalization/hi/taggers/telephone.py | 5 ----- nemo_text_processing/text_normalization/hi/taggers/word.py | 1 - 3 files changed, 13 deletions(-) diff --git a/nemo_text_processing/text_normalization/hi/taggers/cardinal.py b/nemo_text_processing/text_normalization/hi/taggers/cardinal.py index b22f28cb1..926585a89 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/cardinal.py +++ b/nemo_text_processing/text_normalization/hi/taggers/cardinal.py @@ -328,10 +328,3 @@ def create_larger_number_graph(digit_graph, suffix, zeros_counts, sub_graph): final_graph = self.add_tokens(final_graph) self.fst = final_graph - -if __name__ == '__main__': - from nemo_text_processing.text_normalization.hi.utils import apply_fst - - cardinal = CardinalFst() - input_text = "११०१११११११११११" - apply_fst(input_text, cardinal.fst) diff --git a/nemo_text_processing/text_normalization/hi/taggers/telephone.py b/nemo_text_processing/text_normalization/hi/taggers/telephone.py index fd936a061..9a3da1202 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/telephone.py +++ b/nemo_text_processing/text_normalization/hi/taggers/telephone.py @@ -37,11 +37,6 @@ mobile_start_digit = pynini.string_file(get_abs_path("data/telephone/mobile_digits.tsv")) -def load_column_from_tsv(filepath, column_index=1): - with open(filepath, encoding='utf-8') as tsv: - return [line.strip().split("\t")[column_index] for line in tsv if line.strip()] - - def generate_mobile(context_keywords): context_before, context_after = get_context(context_keywords) country_code = ( diff --git a/nemo_text_processing/text_normalization/hi/taggers/word.py b/nemo_text_processing/text_normalization/hi/taggers/word.py index 88350dea3..151a72e99 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/word.py +++ b/nemo_text_processing/text_normalization/hi/taggers/word.py @@ -43,7 +43,6 @@ def __init__(self, punctuation: PunctuationFst, deterministic: bool = True): *[chr(i) for i in range(ord("ऀ"), ord("ः") + 1)], # Hindi vowels and consonants *[chr(i) for i in range(ord("अ"), ord("ह") + 1)], # More Hindi characters *[chr(i) for i in range(ord("ा"), ord("्") + 1)], # Hindi diacritics - # *[chr(i) for i in range(ord("०"), ord("९") + 1)], # Hindi digits ).optimize() # Include punctuation in the graph From f1d74e63e377334c7a604a20323ab0710a1d61a3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 05:39:55 +0000 Subject: [PATCH 13/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- nemo_text_processing/text_normalization/hi/taggers/cardinal.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nemo_text_processing/text_normalization/hi/taggers/cardinal.py b/nemo_text_processing/text_normalization/hi/taggers/cardinal.py index 926585a89..bc7594ad9 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/cardinal.py +++ b/nemo_text_processing/text_normalization/hi/taggers/cardinal.py @@ -327,4 +327,3 @@ def create_larger_number_graph(digit_graph, suffix, zeros_counts, sub_graph): final_graph = optional_minus_graph + pynutil.insert("integer: \"") + self.final_graph + pynutil.insert("\"") final_graph = self.add_tokens(final_graph) self.fst = final_graph - From 1e214d198a3fbfcb6d1ca8f07be3a740d2158c8a Mon Sep 17 00:00:00 2001 From: Namrata Gachchi Date: Wed, 23 Jul 2025 11:31:03 +0530 Subject: [PATCH 14/16] added support for context words through tsv files Signed-off-by: Namrata Gachchi --- .../hi/data/telephone/STD_codes.tsv | 948 ------------------ .../hi/data/telephone/credit_context.tsv | 3 + .../hi/data/telephone/landline_context.tsv | 5 + .../hi/data/telephone/mobile_context.tsv | 4 + .../hi/data/telephone/number.tsv | 10 - .../hi/data/telephone/pincode_context.tsv | 4 + .../hi/taggers/telephone.py | 30 +- 7 files changed, 33 insertions(+), 971 deletions(-) delete mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/STD_codes.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/credit_context.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/landline_context.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/mobile_context.tsv create mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/pincode_context.tsv diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/STD_codes.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/STD_codes.tsv deleted file mode 100644 index 9e1fb6569..000000000 --- a/nemo_text_processing/text_normalization/hi/data/telephone/STD_codes.tsv +++ /dev/null @@ -1,948 +0,0 @@ -११ एक एक -१९१ एक नौ एक -११९१ एक एक नौ एक -१२१ एक दो एक -१२२ एक दो दो -१२३२ एक दो तीन दो -१२३४ एक दो तीन चार -१२४ एक दो चार -१२६२ एक दो छह दो -१२६४ एक दो छह चार -१२७४ एक दो सात चार -१२९ एक दो नौ -१३२ एक तीन दो -१३३२ एक तीन तीन दो -१३३६ एक तीन तीन छह -१३४२ एक तीन चार दो -१३५ एक तीन पाँच -१३६४ एक तीन छह चार -१३७४ एक तीन सात चार -१४१ एक चार एक -१४४ एक चार चार -१४५ एक चार पाँच -१४६२ एक चार छह दो -१५१ एक पाँच एक -१५४ एक पाँच चार -१५६२ एक पाँच छह दो -१५७२ एक पाँच सात दो -१५८२ एक पाँच आठ दो -१५९२ एक पाँच नौ दो -१६१ एक छह एक -१६२४ एक छह दो चार -१६२७ एक छह दो सात -१६२८ एक छह दो आठ -१६३२ एक छह तीन दो -१६३४ एक छह तीन चार -१६३५ एक छह तीन पाँच -१६३६ एक छह तीन छह -१६३८ एक छह तीन आठ -१६३९ एक छह तीन नौ -१६४ एक छह चार -१६६२ एक छह छह दो -१६६४ एक छह छह चार -१६६६ एक छह छह छह -१६६९६ एक छह छह नौ छह -१६७२७२ एक छह सात दो सात दो -१६७५ एक छह सात पाँच -१६७६ एक छह सात छह -१६७९ एक छह सात नौ -१६८२ एक छह आठ दो -१६८४ एक छह आठ चार -१६८९११ एक छह आठ नौ एक एक -१७१ एक सात एक -१७२ एक सात दो -१७३२ एक सात तीन दो -१७३३ एक सात तीन तीन -१७४२ एक सात चार दो -१७४४ एक सात चार चार -१७५ एक सात पाँच -१७६२ एक सात छह दो -१७६३ एक सात छह तीन -१७६४ एक सात छह चार -१७६५ एक सात छह पाँच -१७७ एक सात सात -१८१ एक आठ एक -१८३ एक आठ तीन -१८४ एक आठ चार -१८६ एक आठ छह -१८७४ एक आठ सात चार -१८८२ एक आठ आठ दो -१९०५ एक नौ शून्य पाँच -१९१ एक नौ एक -१९२२ एक नौ दो दो -१९३२ एक नौ तीन दो -१९४ एक नौ चार -१९५२ एक नौ पाँच दो -१९५३ एक नौ पाँच तीन -१९७२ एक नौ सात दो -१९७८ एक नौ सात आठ -१९९२ एक नौ नौ दो -२० दो शून्य -२११२ दो एक एक दो -२१४८ दो एक चार आठ -२१६२ दो एक छह दो -२१६४ दो एक छह चार -२१६६ दो एक छह छह -२१६८ दो एक छह आठ -२१७ दो एक सात -२१८४ दो एक आठ चार -२१९२ दो एक नौ दो -२२ दो दो -२३० दो तीन शून्य -२३१ दो तीन एक -२३३ दो तीन तीन -२३५२ दो तीन पाँच दो -२३५५ दो तीन पाँच पाँच -२३६२ दो तीन छह दो -२३८२ दो तीन आठ दो -२३८५ दो तीन आठ पाँच -२४० दो चार शून्य -२४१ दो चार एक -२४२२ दो चार दो दो -२४३१ दो चार तीन एक -२४५२ दो चार पाँच दो -२४६२ दो चार छह दो -२४७२ दो चार सात दो -२४७८ दो चार सात आठ -२४८२ दो चार आठ दो -२४८७ दो चार आठ सात -२५१ दो पाँच एक -२५२२ दो पाँच दो दो -२५२६ दो पाँच दो छह -२५३ दो पाँच तीन -२५६२ दो पाँच छह दो -२५७ दो पाँच सात -२५८० दो पाँच आठ शून्य -२५८२ दो पाँच आठ दो -२५९१ दो पाँच नौ एक -२६० दो छह शून्य -२६१ दो छह एक -२६२२ दो छह दो दो -२६२६ दो छह दो छह -२६३१ दो छह तीन एक -२६३२ दो छह तीन दो -२६३४ दो छह तीन चार -२६३७ दो छह तीन सात -२६३९ दो छह तीन नौ -२६४२ दो छह चार दो -२६४३ दो छह चार तीन -२६४६ दो छह चार छह -२६५ दो छह पाँच -२६६२ दो छह छह दो -२६६३ दो छह छह तीन -२६७२ दो छह सात दो -२६७६ दो छह सात छह -२६७७ दो छह सात सात -२६८ दो छह आठ -२६९१ दो छह नौ एक -२६९२ दो छह नौ दो -२६९७ दो छह नौ सात -२६९९८१ दो छह नौ नौ आठ एक -२७१२ दो सात एक दो -२७१३ दो सात एक तीन -२७१४ दो सात एक चार -२७१५ दो सात एक पाँच -२७३३४४९ दो सात तीन तीन चार चार नौ -२७४२ दो सात चार दो -२७४४ दो सात चार चार -२७५२ दो सात पाँच दो -२७६२ दो सात छह दो -२७६४ दो सात छह चार -२७६५ दो सात छह पाँच -२७६६ दो सात छह छह -२७६७ दो सात छह सात -२७७० दो सात सात शून्य -२७७२ दो सात सात दो -२७७४ दो सात सात चार -२७८ दो सात आठ -२७९२ दो सात नौ दो -२७९५ दो सात नौ पाँच -२८१ दो आठ एक -२८२२ दो आठ दो दो -२८२४ दो आठ दो चार -२८२६ दो आठ दो छह -२८३२ दो आठ तीन दो -२८३३ दो आठ तीन तीन -२८३४ दो आठ तीन चार -२८३६ दो आठ तीन छह -२८४४ दो आठ चार चार -२८४५ दो आठ चार पाँच -२८५ दो आठ पाँच -२८६ दो आठ छह -२८७६ दो आठ सात छह -२८७६८३३ दो आठ सात छह आठ तीन तीन -२८९२ दो आठ नौ दो -२९१ दो नौ एक -२९३२ दो नौ तीन दो -२९४ दो नौ चार -२९९२ दो नौ नौ दो -३१७४ तीन एक सात चार -३१९२ तीन एक नौ दो -३२२२ तीन दो दो दो -३२२४ तीन दो दो चार -३२४२ तीन दो चार दो -३२६ तीन दो छह -३३ तीन तीन -३४१ तीन चार एक -३४२ तीन चार दो -३४३ तीन चार तीन -३४६१ तीन चार छह एक -३४६२ तीन चार छह दो -३४६३ तीन चार छह तीन -३४७२ तीन चार सात दो -३४८२ तीन चार आठ दो -३५२२ तीन पाँच दो दो -३५३ तीन पाँच तीन -३५४ तीन पाँच चार -३५५२ तीन पाँच पाँच दो -३५५४ तीन पाँच पाँच चार -३५६१ तीन पाँच छह एक -३५६१५५ तीन पाँच छह एक पाँच पाँच -३५८२ तीन पाँच आठ दो -३५९२ तीन पाँच नौ दो -३६० तीन छह शून्य -३६१ तीन छह एक -३६५२ तीन छह पाँच दो -३६५८ तीन छह पाँच आठ -३६६२ तीन छह छह दो -३६६४ तीन छह छह चार -३६६५ तीन छह छह पाँच -३६७३ तीन छह सात तीन -३६८ तीन छह आठ -३७० तीन सात शून्य -३७३ तीन सात तीन -३७४ तीन सात चार -३७६ तीन सात छह -३७७२ तीन सात सात दो -३८४२ तीन आठ चार दो -३८५ तीन आठ पाँच -३८६२ तीन आठ छह दो -३८९ तीन आठ नौ -४० चार शून्य -४११२ चार एक एक दो -४११४ चार एक एक चार -४११६ चार एक एक छह -४११८ चार एक एक आठ -४११९ चार एक एक नौ -४१३ चार एक तीन -४१४२ चार एक चार दो -४१४४ चार एक चार चार -४१४६ चार एक चार छह -४१४७ चार एक चार सात -४१४८ चार एक चार आठ -४१६ चार एक छह -४१७२ चार एक सात दो -४१७३ चार एक सात तीन -४१७४ चार एक सात चार -४१७५ चार एक सात पाँच -४१७७ चार एक सात सात -४२१ चार दो एक -४२२ चार दो दो -४२२८८ चार दो दो आठ आठ -४२२८९ चार दो दो आठ नौ -४२३ चार दो तीन -४२४ चार दो चार -४२५२ चार दो पाँच दो -४२५३८ चार दो पाँच तीन आठ -४२५५ चार दो पाँच पाँच -४२५६ चार दो पाँच छह -४२५७ चार दो पाँच सात -४२५८ चार दो पाँच आठ -४२५९ चार दो पाँच नौ -४२७ चार दो सात -७३१ सात तीन एक -४८८ चार आठ आठ -७५७२ सात पाँच दो -७६१ सात छह एक -८५४४ आठ पाँच चार चार -७७८२ सात सात आठ दो -६७१ छह सात एक -६५७ छह पाँच सात -७४१४ सात चार एक चार -६७५४ छह सात पाँच चार -५४५२ पाँच चार पाँच दो -६८५४ छह आठ पाँच चार -७४३२ सात चार तीन दो -६६४५ छह छह चार पाँच -६५३४ छह पाँच तीन चार -६७६७ छह सात छह सात -८३८२ आठ तीन आठ दो -८८४ आठ आठ चार -९५२५१ नौ पाँच दो पाँच एक -४९९ चार नौ नौ -४९१ चार नौ एक -५१२ पाँच एक दो -४६५२ चार छह पाँच दो -४३६८ चार तीन छह आठ -४५६५ चार पाँच छह पाँच -८७२२ आठ सात दो दो -४३२४ चार तीन दो चार -५७४४ पाँच सात चार चार -६४५२ छह चार पाँच दो -८६२६ आठ छह दो छह -४८९६ चार आठ नौ छह -४७९ चार सात नौ -८७१२ आठ सात एक दो -६७२७ छह सात दो सात -८० आठ शून्य -६७६६ छह सात छह छह -५४१४ पाँच चार एक चार -७२६३ सात दो छह तीन -८७४२ आठ सात चार दो -७३३ सात तीन तीन -८२२३ आठ दो दो तीन -८६८३ आठ छह आठ तीन -४५४२ चार पाँच चार दो -८१५२ आठ एक पाँच दो -८१५३ आठ एक पाँच तीन -८२४ आठ दो चार -८५३९ आठ पाँच तीन नौ -६८५२ छह आठ पाँच दो -५६६२ पाँच छह छह दो -८६२४ आठ छह दो चार -८७४४ आठ सात चार चार -८५२५ आठ पाँच दो पाँच -४८५ चार आठ पाँच -४९३ चार नौ तीन -४७४ चार सात चार -४८१ चार आठ एक -४३३२ चार तीन तीन दो -८८१७ आठ आठ एक सात -८४४३ आठ चार चार तीन -४३२३ चार तीन दो तीन -४३५ चार तीन पाँच -८५१८ आठ पाँच एक आठ -४३६४ चार तीन छह चार -८८१२ आठ आठ एक दो -५१७६ पाँच एक सात छह -८४१३ आठ चार एक तीन -९५०२११४ नौ पाँच शून्य दो एक एक चार -५२२ पाँच दो दो -८६७२ आठ छह सात दो -८५४३ आठ पाँच चार तीन -८२७२ आठ दो सात दो -४४ चार चार -४५२ चार पाँच दो -४९० चार नौ शून्य -५६७२ पाँच छह सात दो -३५१२ तीन पाँच एक दो -४३१८२ चार तीन एक आठ दो -६७४ छह सात चार -७४२२ सात चार दो दो -८२३२ आठ दो तीन दो -८२५२ आठ दो पाँच दो -४९२ चार नौ दो -८३२ आठ तीन दो -५६५ पाँच छह पाँच -४७८ चार सात आठ -८५९३ आठ पाँच नौ तीन -८२१ आठ दो एक -७३२४ सात तीन दो चार -४८९२ चार आठ नौ दो -५४४२ पाँच चार चार दो -५४१२ पाँच चार एक दो -७५३२ सात पाँच तीन दो -६२५२ छह दो पाँच दो -४८७ चार आठ सात -४८४ चार आठ चार -४८६५ चार आठ छह पाँच -४३२६ चार तीन दो छह -६२१ छह दो एक -४३६५ चार तीन छह पाँच -८५४० आठ पाँच चार शून्य -७१२ सात एक दो -५३२ पाँच तीन दो -५९४२ पाँच नौ चार दो -८६८२ आठ छह आठ दो -४२८६ चार दो आठ छह -८६७८ आठ छह सात आठ -८५१३ आठ पाँच एक तीन -४६३५ चार छह तीन पाँच -८२२१ आठ दो दो एक -८६४७ आठ छह चार सात -६३२४ छह तीन दो चार -८६१ आठ छह एक -४७१ चार सात एक -८३३८ आठ तीन तीन आठ -८४६२ आठ चार छह दो -८५९२ आठ पाँच नौ दो -४८२१ चार आठ दो एक -८८१४ आठ आठ एक चार -४५४५ चार पाँच चार पाँच -४६२ चार छह दो -८२४७ आठ दो चार सात -४७३ चार सात तीन -४३७४ चार तीन सात चार -६७२२ छह सात दो दो -४५६४ चार पाँच छह चार -४९४ चार नौ चार -८४५३ आठ चार पाँच तीन -६१२ छह एक दो -७१८५ सात एक आठ पाँच -४९८ चार नौ आठ -८८५२ आठ आठ पाँच दो -४२९४ चार दो नौ चार -६८४२ छह आठ चार दो -५८८२ पाँच आठ आठ दो -५९६४ पाँच नौ छह चार -४८२ चार आठ दो -८६४८ आठ छह चार आठ -८६६ आठ छह छह -४६१ चार छह एक -४७५ चार सात पाँच -९५२० नौ पाँच दो शून्य -६४५४ छह चार पाँच चार -८२५१ आठ दो पाँच एक -८५७७ आठ पाँच सात सात -५३५ पाँच तीन पाँच -८५३२ आठ पाँच तीन दो -७७६२ सात सात छह दो -७७१ सात सात एक -८८३ आठ आठ तीन -४५६३ चार पाँच छह तीन -८८५७ आठ आठ पाँच सात -८११७ आठ एक एक सात -४५६७ चार पाँच छह सात -४५७३ चार पाँच सात तीन -७११४ सात एक एक चार -६५१ छह पाँच एक -८३७३ आठ तीन सात तीन -५४९६ पाँच चार नौ छह -७४१२ सात चार एक दो -८८५५ आठ आठ पाँच पाँच -१८५३ एक आठ पाँच तीन -८५७४ आठ पाँच सात चार -७६६२ सात छह छह दो -५४४४ पाँच चार चार चार -६६१ छह छह एक -७५८२ सात पाँच आठ दो -४३४१ चार तीन चार एक -६२७४ छह दो सात चार -६६३ छह छह तीन -८४५५ आठ चार पाँच पाँच -४२८३ चार दो आठ तीन -४६३६ चार छह तीन छह -६१८४ छह एक आठ चार -४२९५ चार दो नौ पाँच -७६७२ सात छह सात दो -४५६२ चार पाँच छह दो -७५६२ सात पाँच छह दो -७६९२ सात छह नौ दो -८५४८ आठ पाँच चार आठ -८४७४ आठ चार सात चार -५८४२ पाँच आठ चार दो -४६३३ चार छह तीन तीन -५६७६ पाँच छह सात छह -३६४ तीन छह चार -८१८२ आठ एक आठ दो -८४५७ आठ चार पाँच सात -५३६२ पाँच तीन छह दो -४३६३ चार तीन छह तीन -८७३८ आठ सात तीन आठ -८३८४ आठ तीन आठ चार -५८६२ पाँच आठ छह दो -४३१ चार तीन एक -८९४२ आठ नौ चार दो -८५७८ आठ पाँच सात आठ -८२३६ आठ दो तीन छह -६८५३ छह आठ पाँच तीन -६६२२ छह छह दो -५७३६ पाँच सात तीन छह -८८१८ आठ आठ एक आठ -८५५८ आठ पाँच पाँच आठ -८८१९ आठ आठ एक नौ -८६४४ आठ छह चार चार -४३६२ चार तीन छह दो -४५४६ चार पाँच चार छह -४८६२ चार आठ छह दो -४२८८ चार दो आठ आठ -४५४९ चार पाँच चार नौ -४३१८३ चार तीन एक आठ तीन -४३६६ चार तीन छह छह -८१६ आठ एक छह -७१८३ सात एक आठ तीन -७३४ सात तीन चार -४८२९ चार आठ दो नौ -४६३७ चार छह तीन सात -४६४६ चार छह चार छह -६७६८ छह सात छह आठ -८२७४ आठ दो सात चार -४३३९ चार तीन तीन नौ -८९१ आठ नौ एक -७१५२ सात एक पाँच दो -८०४५ आठ चार पाँच -७९८४ सात नौ आठ चार -11 एक एक -191 एक नौ एक -1191 एक एक नौ एक -121 एक दो एक -122 एक दो दो -1232 एक दो तीन दो -1234 एक दो तीन चार -124 एक दो चार -1262 एक दो छह दो -1264 एक दो छह चार -1274 एक दो सात चार -129 एक दो नौ -132 एक तीन दो -1332 एक तीन तीन दो -1336 एक तीन तीन छह -1342 एक तीन चार दो -135 एक तीन पाँच -1364 एक तीन छह चार -1374 एक तीन सात चार -141 एक चार एक -144 एक चार चार -145 एक चार पाँच -1462 एक चार छह दो -151 एक पाँच एक -154 एक पाँच चार -1562 एक पाँच छह दो -1572 एक पाँच सात दो -1582 एक पाँच आठ दो -1592 एक पाँच नौ दो -161 एक छह एक -1624 एक छह दो चार -1627 एक छह दो सात -1628 एक छह दो आठ -1632 एक छह तीन दो -1634 एक छह तीन चार -1635 एक छह तीन पाँच -1636 एक छह तीन छह -1638 एक छह तीन आठ -1639 एक छह तीन नौ -164 एक छह चार -1662 एक छह छह दो -1664 एक छह छह चार -1666 एक छह छह छह -16696 एक छह छह नौ छह -167272 एक छह सात दो सात दो -1675 एक छह सात पाँच -1676 एक छह सात छह -1679 एक छह सात नौ -1682 एक छह आठ दो -1684 एक छह आठ चार -168911 एक छह आठ नौ एक एक -171 एक सात एक -172 एक सात दो -1732 एक सात तीन दो -1733 एक सात तीन तीन -1742 एक सात चार दो -1744 एक सात चार चार -175 एक सात पाँच -1762 एक सात छह दो -1763 एक सात छह तीन -1764 एक सात छह चार -1765 एक सात छह पाँच -177 एक सात सात -181 एक आठ एक -183 एक आठ तीन -184 एक आठ चार -186 एक आठ छह -1874 एक आठ सात चार -1882 एक आठ आठ दो -1905 एक नौ शून्य पाँच -191 एक नौ एक -1922 एक नौ दो दो -1932 एक नौ तीन दो -194 एक नौ चार -1952 एक नौ पाँच दो -1953 एक नौ पाँच तीन -1972 एक नौ सात दो -1978 एक नौ सात आठ -1992 एक नौ नौ दो -20 दो शून्य -2112 दो एक एक दो -2148 दो एक चार आठ -2162 दो एक छह दो -2164 दो एक छह चार -2166 दो एक छह छह -2168 दो एक छह आठ -217 दो एक सात -2184 दो एक आठ चार -2192 दो एक नौ दो -22 दो दो -230 दो तीन शून्य -231 दो तीन एक -233 दो तीन तीन -2352 दो तीन पाँच दो -2355 दो तीन पाँच पाँच -2362 दो तीन छह दो -2382 दो तीन आठ दो -2385 दो तीन आठ पाँच -240 दो चार शून्य -241 दो चार एक -2422 दो चार दो दो -2431 दो चार तीन एक -2452 दो चार पाँच दो -2462 दो चार छह दो -2472 दो चार सात दो -2478 दो चार सात आठ -2482 दो चार आठ दो -2487 दो चार आठ सात -251 दो पाँच एक -2522 दो पाँच दो दो -2526 दो पाँच दो छह -253 दो पाँच तीन -2562 दो पाँच छह दो -257 दो पाँच सात -2580 दो पाँच आठ शून्य -2582 दो पाँच आठ दो -2591 दो पाँच नौ एक -260 दो छह शून्य -261 दो छह एक -2622 दो छह दो दो -2626 दो छह दो छह -2631 दो छह तीन एक -2632 दो छह तीन दो -2634 दो छह तीन चार -2637 दो छह तीन सात -2639 दो छह तीन नौ -2642 दो छह चार दो -2643 दो छह चार तीन -2646 दो छह चार छह -265 दो छह पाँच -2662 दो छह छह दो -2663 दो छह छह तीन -2672 दो छह सात दो -2676 दो छह सात छह -2677 दो छह सात सात -268 दो छह आठ -2691 दो छह नौ एक -2692 दो छह नौ दो -2697 दो छह नौ सात -269981 दो छह नौ नौ आठ एक -2712 दो सात एक दो -2713 दो सात एक तीन -2714 दो सात एक चार -2715 दो सात एक पाँच -2733449 दो सात तीन तीन चार चार नौ -2742 दो सात चार दो -2744 दो सात चार चार -2752 दो सात पाँच दो -2762 दो सात छह दो -2764 दो सात छह चार -2765 दो सात छह पाँच -2766 दो सात छह छह -2767 दो सात छह सात -2770 दो सात सात शून्य -2772 दो सात सात दो -2774 दो सात सात चार -278 दो सात आठ -2792 दो सात नौ दो -2795 दो सात नौ पाँच -281 दो आठ एक -2822 दो आठ दो दो -2824 दो आठ दो चार -2826 दो आठ दो छह -2832 दो आठ तीन दो -2833 दो आठ तीन तीन -2834 दो आठ तीन चार -2836 दो आठ तीन छह -2844 दो आठ चार चार -2845 दो आठ चार पाँच -285 दो आठ पाँच -286 दो आठ छह -2876 दो आठ सात छह -2876833 दो आठ सात छह आठ तीन तीन -2892 दो आठ नौ दो -291 दो नौ एक -2932 दो नौ तीन दो -294 दो नौ चार -2992 दो नौ नौ दो -3174 तीन एक सात चार -3192 तीन एक नौ दो -3222 तीन दो दो दो -3224 तीन दो दो चार -3242 तीन दो चार दो -326 तीन दो छह -33 तीन तीन -341 तीन चार एक -342 तीन चार दो -343 तीन चार तीन -3461 तीन चार छह एक -3462 तीन चार छह दो -3463 तीन चार छह तीन -3472 तीन चार सात दो -3482 तीन चार आठ दो -3522 तीन पाँच दो दो -353 तीन पाँच तीन -354 तीन पाँच चार -3552 तीन पाँच पाँच दो -3554 तीन पाँच पाँच चार -3561 तीन पाँच छह एक -356155 तीन पाँच छह एक पाँच पाँच -3582 तीन पाँच आठ दो -3592 तीन पाँच नौ दो -360 तीन छह शून्य -361 तीन छह एक -3652 तीन छह पाँच दो -3658 तीन छह पाँच आठ -3662 तीन छह छह दो -3664 तीन छह छह चार -3665 तीन छह छह पाँच -3673 तीन छह सात तीन -368 तीन छह आठ -370 तीन सात शून्य -373 तीन सात तीन -374 तीन सात चार -376 तीन सात छह -3772 तीन सात सात दो -3842 तीन आठ चार दो -385 तीन आठ पाँच -3862 तीन आठ छह दो -389 तीन आठ नौ -40 चार शून्य -4112 चार एक एक दो -4114 चार एक एक चार -4116 चार एक एक छह -4118 चार एक एक आठ -4119 चार एक एक नौ -413 चार एक तीन -4142 चार एक चार दो -4144 चार एक चार चार -4146 चार एक चार छह -4147 चार एक चार सात -4148 चार एक चार आठ -416 चार एक छह -4172 चार एक सात दो -4173 चार एक सात तीन -4174 चार एक सात चार -4175 चार एक सात पाँच -4177 चार एक सात सात -421 चार दो एक -422 चार दो दो -42288 चार दो दो आठ आठ -42289 चार दो दो आठ नौ -423 चार दो तीन -424 चार दो चार -4252 चार दो पाँच दो -42538 चार दो पाँच तीन आठ -4255 चार दो पाँच पाँच -4256 चार दो पाँच छह -4257 चार दो पाँच सात -4258 चार दो पाँच आठ -4259 चार दो पाँच नौ -427 चार दो सात -731 सात तीन एक -488 चार आठ आठ -7572 सात पाँच दो -761 सात छह एक -8544 आठ पाँच चार चार -7782 सात सात आठ दो -671 छह सात एक -657 छह पाँच सात -7414 सात चार एक चार -6754 छह सात पाँच चार -5452 पाँच चार पाँच दो -6854 छह आठ पाँच चार -7432 सात चार तीन दो -6645 छह छह चार पाँच -6534 छह पाँच तीन चार -6767 छह सात छह सात -8382 आठ तीन आठ दो -884 आठ आठ चार -95251 नौ पाँच दो पाँच एक -499 चार नौ नौ -491 चार नौ एक -512 पाँच एक दो -4652 चार छह पाँच दो -4368 चार तीन छह आठ -4565 चार पाँच छह पाँच -8722 आठ सात दो दो -4324 चार तीन दो चार -5744 पाँच सात चार चार -6452 छह चार पाँच दो -8626 आठ छह दो छह -4896 चार आठ नौ छह -479 चार सात नौ -8712 आठ सात एक दो -6727 छह सात दो सात -80 आठ शून्य -6766 छह सात छह छह -5414 पाँच चार एक चार -7263 सात दो छह तीन -8742 आठ सात चार दो -733 सात तीन तीन -8223 आठ दो दो तीन -8683 आठ छह आठ तीन -4542 चार पाँच चार दो -8152 आठ एक पाँच दो -8153 आठ एक पाँच तीन -824 आठ दो चार -8539 आठ पाँच तीन नौ -6852 छह आठ पाँच दो -5662 पाँच छह छह दो -8624 आठ छह दो चार -8744 आठ सात चार चार -8525 आठ पाँच दो पाँच -485 चार आठ पाँच -493 चार नौ तीन -474 चार सात चार -481 चार आठ एक -4332 चार तीन तीन दो -8817 आठ आठ एक सात -8443 आठ चार चार तीन -4323 चार तीन दो तीन -435 चार तीन पाँच -8518 आठ पाँच एक आठ -4364 चार तीन छह चार -8812 आठ आठ एक दो -5176 पाँच एक सात छह -8413 आठ चार एक तीन -9502114 नौ पाँच शून्य दो एक एक चार -522 पाँच दो दो -8672 आठ छह सात दो -8543 आठ पाँच चार तीन -8272 आठ दो सात दो -44 चार चार -452 चार पाँच दो -490 चार नौ शून्य -5672 पाँच छह सात दो -3512 तीन पाँच एक दो -43182 चार तीन एक आठ दो -674 छह सात चार -7422 सात चार दो दो -8232 आठ दो तीन दो -8252 आठ दो पाँच दो -492 चार नौ दो -832 आठ तीन दो -565 पाँच छह पाँच -478 चार सात आठ -8593 आठ पाँच नौ तीन -821 आठ दो एक -7324 सात तीन दो चार -4892 चार आठ नौ दो -5442 पाँच चार चार दो -5412 पाँच चार एक दो -7532 सात पाँच तीन दो -6252 छह दो पाँच दो -487 चार आठ सात -484 चार आठ चार -4865 चार आठ छह पाँच -4326 चार तीन दो छह -621 छह दो एक -4365 चार तीन छह पाँच -8540 आठ पाँच चार शून्य -712 सात एक दो -532 पाँच तीन दो -5942 पाँच नौ चार दो -8682 आठ छह आठ दो -4286 चार दो आठ छह -8678 आठ छह सात आठ -8513 आठ पाँच एक तीन -4635 चार छह तीन पाँच -8221 आठ दो दो एक -8647 आठ छह चार सात -6324 छह तीन दो चार -861 आठ छह एक -471 चार सात एक -8338 आठ तीन तीन आठ -8462 आठ चार छह दो -8592 आठ पाँच नौ दो -4821 चार आठ दो एक -8814 आठ आठ एक चार -4545 चार पाँच चार पाँच -462 चार छह दो -8247 आठ दो चार सात -473 चार सात तीन -4374 चार तीन सात चार -6722 छह सात दो दो -4564 चार पाँच छह चार -494 चार नौ चार -8453 आठ चार पाँच तीन -612 छह एक दो -7185 सात एक आठ पाँच -498 चार नौ आठ -8852 आठ आठ पाँच दो -4294 चार दो नौ चार -6842 छह आठ चार दो -5882 पाँच आठ आठ दो -5964 पाँच नौ छह चार -482 चार आठ दो -8648 आठ छह चार आठ -866 आठ छह छह -461 चार छह एक -475 चार सात पाँच -9520 नौ पाँच दो शून्य -6454 छह चार पाँच चार -8251 आठ दो पाँच एक -8577 आठ पाँच सात सात -535 पाँच तीन पाँच -8532 आठ पाँच तीन दो -7762 सात सात छह दो -771 सात सात एक -883 आठ आठ तीन -4563 चार पाँच छह तीन -8857 आठ आठ पाँच सात -8117 आठ एक एक सात -4567 चार पाँच छह सात -4573 चार पाँच सात तीन -7114 सात एक एक चार -651 छह पाँच एक -8373 आठ तीन सात तीन -5496 पाँच चार नौ छह -7412 सात चार एक दो -8855 आठ आठ पाँच पाँच -1853 एक आठ पाँच तीन -8574 आठ पाँच सात चार -7662 सात छह छह दो -5444 पाँच चार चार चार -661 छह छह एक -7582 सात पाँच आठ दो -4341 चार तीन चार एक -6274 छह दो सात चार -663 छह छह तीन -8455 आठ चार पाँच पाँच -4283 चार दो आठ तीन -4636 चार छह तीन छह -6184 छह एक आठ चार -4295 चार दो नौ पाँच -7672 सात छह सात दो -4562 चार पाँच छह दो -7562 सात पाँच छह दो -7692 सात छह नौ दो -8548 आठ पाँच चार आठ -8474 आठ चार सात चार -5842 पाँच आठ चार दो -4633 चार छह तीन तीन -5676 पाँच छह सात छह -364 तीन छह चार -8182 आठ एक आठ दो -8457 आठ चार पाँच सात -5362 पाँच तीन छह दो -4363 चार तीन छह तीन -8738 आठ सात तीन आठ -8384 आठ तीन आठ चार -5862 पाँच आठ छह दो -431 चार तीन एक -8942 आठ नौ चार दो -8578 आठ पाँच सात आठ -8236 आठ दो तीन छह -6853 छह आठ पाँच तीन -6622 छह छह दो -5736 पाँच सात तीन छह -8818 आठ आठ एक आठ -8558 आठ पाँच पाँच आठ -8819 आठ आठ एक नौ -8644 आठ छह चार चार -4362 चार तीन छह दो -4546 चार पाँच चार छह -4862 चार आठ छह दो -4288 चार दो आठ आठ -4549 चार पाँच चार नौ -43183 चार तीन एक आठ तीन -4366 चार तीन छह छह -816 आठ एक छह -7183 सात एक आठ तीन -734 सात तीन चार -4829 चार आठ दो नौ -4637 चार छह तीन सात -4646 चार छह चार छह -6768 छह सात छह आठ -8274 आठ दो सात चार -4339 चार तीन तीन नौ -891 आठ नौ एक -7152 सात एक पाँच दो -8045 आठ चार पाँच -7984 सात नौ आठ चार diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/credit_context.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/credit_context.tsv new file mode 100644 index 000000000..46b485af6 --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/telephone/credit_context.tsv @@ -0,0 +1,3 @@ +नंबर +कार्ड +क्रेडिट \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/landline_context.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/landline_context.tsv new file mode 100644 index 000000000..17a123bee --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/telephone/landline_context.tsv @@ -0,0 +1,5 @@ +नंबर +मोबाइल +फोन +लैंडलाइन +कॉल \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/mobile_context.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/mobile_context.tsv new file mode 100644 index 000000000..f2fa6e52f --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/telephone/mobile_context.tsv @@ -0,0 +1,4 @@ +नंबर +मोबाइल +फोन +कॉल \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/number.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/number.tsv index d30ef902d..e8c04b723 100644 --- a/nemo_text_processing/text_normalization/hi/data/telephone/number.tsv +++ b/nemo_text_processing/text_normalization/hi/data/telephone/number.tsv @@ -1,13 +1,3 @@ -० शून्य -१ एक -२ दो -३ तीन -४ चार -५ पाँच -६ छह -७ सात -८ आठ -९ नौ 0 शून्य 1 एक 2 दो diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/pincode_context.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/pincode_context.tsv new file mode 100644 index 000000000..322c7248e --- /dev/null +++ b/nemo_text_processing/text_normalization/hi/data/telephone/pincode_context.tsv @@ -0,0 +1,4 @@ +नंबर +पिन +कोड +पिनकोड \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/taggers/telephone.py b/nemo_text_processing/text_normalization/hi/taggers/telephone.py index 9a3da1202..3ed9d6e02 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/telephone.py +++ b/nemo_text_processing/text_normalization/hi/taggers/telephone.py @@ -31,10 +31,15 @@ # Load the number mappings from the TSV file digit_to_word = pynini.string_file(get_abs_path("data/telephone/number.tsv")) -std_codes = pynini.string_file(get_abs_path("data/telephone/STD_codes.tsv")) +digits = pynini.string_file(get_abs_path("data/numbers/digit.tsv")) +zero = pynini.string_file(get_abs_path("data/numbers/zero.tsv")) country_codes = pynini.string_file(get_abs_path("data/telephone/country_codes.tsv")) landline_start_digit = pynini.string_file(get_abs_path("data/telephone/landline_digits.tsv")) mobile_start_digit = pynini.string_file(get_abs_path("data/telephone/mobile_digits.tsv")) +mobile_context = pynini.string_file(get_abs_path("data/telephone/mobile_context.tsv")) +landline_context = pynini.string_file(get_abs_path("data/telephone/landline_context.tsv")) +credit_context = pynini.string_file(get_abs_path("data/telephone/credit_context.tsv")) +pincode_context = pynini.string_file(get_abs_path("data/telephone/pincode_context.tsv")) def generate_mobile(context_keywords): @@ -51,7 +56,7 @@ def generate_mobile(context_keywords): extension_optional = pynini.closure( pynutil.insert("extension: \"") - + pynini.closure(digit_to_word + insert_space, 1, 3) + + pynini.closure((digit_to_word | digits | zero) + insert_space, 1, 3) + context_after + pynutil.insert("\" ") + delete_space, @@ -66,7 +71,7 @@ def generate_mobile(context_keywords): + insert_shunya + mobile_start_digit + insert_space - + pynini.closure(digit_to_word + insert_space, 9) + + pynini.closure((digit_to_word | digits | zero) + insert_space, 9) + context_after + pynutil.insert("\" ") + delete_space @@ -77,7 +82,7 @@ def generate_mobile(context_keywords): + pynutil.insert("number_part: \"") + mobile_start_digit + insert_space - + pynini.closure(digit_to_word + insert_space, 9) + + pynini.closure((digit_to_word | digits | zero) + insert_space, 9) + context_after + pynutil.insert("\" ") + delete_space @@ -90,14 +95,14 @@ def get_landline(std_length, context_keywords): context_before, context_after = get_context(context_keywords) std_code_graph = ( - delete_zero_optional + insert_shunya + pynini.closure(digit_to_word + insert_space, std_length, std_length) + delete_zero_optional + insert_shunya + pynini.closure((digit_to_word | digits | zero) + insert_space, std_length, std_length) ) landline_digit_count = 9 - std_length landline_graph = ( landline_start_digit + insert_space - + pynini.closure(digit_to_word + insert_space, landline_digit_count, landline_digit_count) + + pynini.closure((digit_to_word | digits | zero) + insert_space, landline_digit_count, landline_digit_count) ) separator_optional = pynini.closure(pynini.cross("-", ""), 0, 1) @@ -128,7 +133,6 @@ def generate_landline(context_keywords): def get_context(keywords: list): - keywords = pynini.union(*keywords) hindi_digits = pynini.union("०", "१", "२", "३", "४", "५", "६", "७", "८", "९") english_digits = pynini.union("0", "1", "2", "3", "4", "5", "6", "7", "8", "9") @@ -151,7 +155,7 @@ def generate_credit(context_keywords): return ( pynutil.insert("number_part: \"") + context_before - + pynini.closure(digit_to_word + insert_space, 4) + + pynini.closure((digit_to_word | digits | zero) + insert_space, 4) + context_after + pynutil.insert("\" ") + delete_space @@ -163,7 +167,7 @@ def generate_pincode(context_keywords): return ( pynutil.insert("number_part: \"") + context_before - + pynini.closure(digit_to_word + insert_space, 6) + + pynini.closure((digit_to_word | digits | zero) + insert_space, 6) + context_after + pynutil.insert("\" ") + delete_space @@ -185,10 +189,10 @@ class TelephoneFst(GraphFst): def __init__(self): super().__init__(name="telephone", kind="classify") - mobile_number = generate_mobile(["नंबर", "मोबाइल", "फोन", "कॉल"]) - landline = generate_landline(["नंबर", "मोबाइल", "फोन", "लैंडलाइन", "कॉल"]) - credit_card = generate_credit(["नंबर", "कार्ड", "क्रेडिट"]) - pincode = generate_pincode(["नंबर", "पिन", "कोड", "पिनकोड"]) + mobile_number = generate_mobile(mobile_context) + landline = generate_landline(landline_context) + credit_card = generate_credit(credit_context) + pincode = generate_pincode(pincode_context) graph = ( pynutil.add_weight(mobile_number, 0.7) From fd8cb946cc50f0c6228f40c354683e667ab05a03 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 23 Jul 2025 06:02:13 +0000 Subject: [PATCH 15/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../text_normalization/hi/taggers/telephone.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nemo_text_processing/text_normalization/hi/taggers/telephone.py b/nemo_text_processing/text_normalization/hi/taggers/telephone.py index 3ed9d6e02..12ca81d61 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/telephone.py +++ b/nemo_text_processing/text_normalization/hi/taggers/telephone.py @@ -95,7 +95,9 @@ def get_landline(std_length, context_keywords): context_before, context_after = get_context(context_keywords) std_code_graph = ( - delete_zero_optional + insert_shunya + pynini.closure((digit_to_word | digits | zero) + insert_space, std_length, std_length) + delete_zero_optional + + insert_shunya + + pynini.closure((digit_to_word | digits | zero) + insert_space, std_length, std_length) ) landline_digit_count = 9 - std_length From 285d0b316b710492884cc9d20c425a683ca7857c Mon Sep 17 00:00:00 2001 From: Namrata Gachchi Date: Thu, 24 Jul 2025 10:53:39 +0530 Subject: [PATCH 16/16] removed repetitive digits validation through multiple tsv Signed-off-by: Namrata Gachchi --- .../hi/data/telephone/landline_digits.tsv | 8 -------- .../hi/data/telephone/mobile_digits.tsv | 8 -------- .../text_normalization/hi/taggers/telephone.py | 13 +++++++++++-- .../test_cases_telephone.txt | 10 +++++++++- 4 files changed, 20 insertions(+), 19 deletions(-) delete mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/landline_digits.tsv delete mode 100644 nemo_text_processing/text_normalization/hi/data/telephone/mobile_digits.tsv diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/landline_digits.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/landline_digits.tsv deleted file mode 100644 index 0a658c8ea..000000000 --- a/nemo_text_processing/text_normalization/hi/data/telephone/landline_digits.tsv +++ /dev/null @@ -1,8 +0,0 @@ -२ दो -३ तीन -४ चार -६ छह -2 दो -3 तीन -4 चार -6 छह \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/data/telephone/mobile_digits.tsv b/nemo_text_processing/text_normalization/hi/data/telephone/mobile_digits.tsv deleted file mode 100644 index bfd892d0e..000000000 --- a/nemo_text_processing/text_normalization/hi/data/telephone/mobile_digits.tsv +++ /dev/null @@ -1,8 +0,0 @@ -६ छह -७ सात -८ आठ -९ नौ -6 छह -7 सात -8 आठ -9 नौ \ No newline at end of file diff --git a/nemo_text_processing/text_normalization/hi/taggers/telephone.py b/nemo_text_processing/text_normalization/hi/taggers/telephone.py index 12ca81d61..f47587acf 100644 --- a/nemo_text_processing/text_normalization/hi/taggers/telephone.py +++ b/nemo_text_processing/text_normalization/hi/taggers/telephone.py @@ -34,8 +34,6 @@ digits = pynini.string_file(get_abs_path("data/numbers/digit.tsv")) zero = pynini.string_file(get_abs_path("data/numbers/zero.tsv")) country_codes = pynini.string_file(get_abs_path("data/telephone/country_codes.tsv")) -landline_start_digit = pynini.string_file(get_abs_path("data/telephone/landline_digits.tsv")) -mobile_start_digit = pynini.string_file(get_abs_path("data/telephone/mobile_digits.tsv")) mobile_context = pynini.string_file(get_abs_path("data/telephone/mobile_context.tsv")) landline_context = pynini.string_file(get_abs_path("data/telephone/landline_context.tsv")) credit_context = pynini.string_file(get_abs_path("data/telephone/credit_context.tsv")) @@ -44,6 +42,12 @@ def generate_mobile(context_keywords): context_before, context_after = get_context(context_keywords) + + allowed_digits = pynini.union("६", "७", "८", "९", "6", "7", "8", "9") + + # Filter cardinals to only include allowed digits + mobile_start_digit = allowed_digits @ digits | allowed_digits @ digit_to_word + country_code = ( pynutil.insert("country_code: \"") + context_before @@ -94,6 +98,11 @@ def generate_mobile(context_keywords): def get_landline(std_length, context_keywords): context_before, context_after = get_context(context_keywords) + allowed_digits = pynini.union("२", "३", "४", "६", "2", "3", "4", "6") + + # Filter cardinals to only include allowed digits + landline_start_digit = allowed_digits @ digits | allowed_digits @ digit_to_word + std_code_graph = ( delete_zero_optional + insert_shunya 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 275fdc2ad..9004cb889 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 @@ -5,4 +5,12 @@ +९१ ७४४०४३१०८३ मेरे इस नंबर पे कॉल करो~प्लस नौ एक सात चार चार शून्य चार तीन एक शून्य आठ तीन मेरे इस नंबर पे कॉल करो +९१ ९२१०५१५६०६ मेरे इस नंबर पे कॉल करो~प्लस नौ एक नौ दो एक शून्य पाँच एक पाँच छह शून्य छह मेरे इस नंबर पे कॉल करो भुगतान के लिए कार्ड के आखिरी अंक १२३४ दर्ज करें~भुगतान के लिए कार्ड के आखिरी अंक एक दो तीन चार दर्ज करें -मेरा पिन कोड ११००२३ है~मेरा पिन कोड एक एक शून्य शून्य दो तीन है \ No newline at end of file +मेरा पिन कोड ११००२३ है~मेरा पिन कोड एक एक शून्य शून्य दो तीन है +मेरा पुराना नंबर था 9157114007~मेरा पुराना नंबर था शून्य नौ एक पाँच सात एक एक चार शून्य शून्य सात +इसपे कॉल करो 03862-351791~इसपे कॉल करो शून्य तीन आठ छह दो तीन पाँच एक सात नौ एक +मेरे इस नंबर पे कॉल करो 1374-309988~मेरे इस नंबर पे कॉल करो शून्य एक तीन सात चार तीन शून्य नौ नौ आठ आठ +इसपे कॉल करो 0168911-4573~इसपे कॉल करो शून्य एक छह आठ नौ एक एक चार पाँच सात तीन ++91 7440431083 मेरे इस नंबर पे कॉल करो~प्लस नौ एक सात चार चार शून्य चार तीन एक शून्य आठ तीन मेरे इस नंबर पे कॉल करो ++91 9210515606 मेरे इस नंबर पे कॉल करो~प्लस नौ एक नौ दो एक शून्य पाँच एक पाँच छह शून्य छह मेरे इस नंबर पे कॉल करो +भुगतान के लिए कार्ड के आखिरी अंक 1234 दर्ज करें~भुगतान के लिए कार्ड के आखिरी अंक एक दो तीन चार दर्ज करें +मेरा पिन कोड 110023 है~मेरा पिन कोड एक एक शून्य शून्य दो तीन है \ No newline at end of file