Skip to content

Hi TN: Add support for Range normalization - #513

Open
shrpawar-alt wants to merge 5 commits into
NVIDIA:staging/hi_tn_v4from
shrpawar-alt:hi_tn_range
Open

shrpawar-alt wants to merge 5 commits into
NVIDIA:staging/hi_tn_v4from
shrpawar-alt:hi_tn_range

Conversation

@shrpawar-alt

Copy link
Copy Markdown
Contributor

What does this PR do ?

Problem

  • Hindi TN had no range handling. Inputs like 10-20, $10-$20, 10:00-11:00 or 3kg-6kg kept the dash and
    each side was normalized on its own (e.g. "दस डॉलर-बीस डॉलर").
  • Bare two-number pairs such as 99-1 were picked up by SerialFst, which kept the dash
    ("निन्यानबे-एक").

Fix

  • Added RangeFst tagger and verbalizer. A dash between two time, date, cardinal, decimal, measure or
    money values is now read as "X से Y" (10-20 -> "दस से बीस", $10-$20 -> "दस डॉलर से बीस डॉलर").
  • SerialFst no longer takes a bare N-N pair, so Range handles it (99-1 -> "निन्यानबे से एक").
    The serial test case was moved to the range tests.
  • Enabled the range class in the Hindi Sparrowhawk test.

Other changes made while fixing

  • The first version of Range made the exported grammar much larger and Sparrowhawk much slower,
    because it paired the full measure and money graphs with themselves. To fix this:
    • MeasureFst now exposes plain_fst, which leaves out the address graphs. Range uses it;
      standalone measure is unchanged.
    • Money ranges use the money tagger on both sides with a separate "से" token between them
      (same approach as the English money range).
    • MoneyFst: the minor-unit word (पैसे, सेंट, पेंस, ...) is now chosen by the verbalizer from
      major_minor_currencies.tsv, and the tagger emits currency_min: "true". The number graph is built
      once instead of once per currency. Spoken output is unchanged.

Before your PR is "Ready for review"

Pre checks:

  • Have you signed your commits? Use git commit -s to sign.
  • Do all unittests finish successfully before sending PR?
    1. pytest or (if your machine does not have GPU) pytest --cpu from the root folder (given you marked your test cases accordingly @pytest.mark.run_only_on('CPU')).
    2. Sparrowhawk tests bash tools/text_processing_deployment/export_grammars.sh --MODE=test ...
  • If you are adding a new feature: Have you added test cases for both pytest and Sparrowhawk here.
  • Have you added __init__.py for every folder and subfolder, including data folder which has .TSV files?
  • Have you followed codeQL results and removed unused variables and imports (report is at the bottom of the PR in github review box) ?
  • Have you added the correct license header Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. to all newly added Python files?
  • If you copied nemo_text_processing/text_normalization/en/graph_utils.py your header's second line should be Copyright 2015 and onwards Google, Inc.. See an example here.
  • Remove import guards (try import: ... except: ...) if not already done.
  • If you added a new language or a new feature please update the NeMo documentation (lives in different repo).
  • Have you added your language support to tools/text_processing_deployment/pynini_export.py.

PR Type:

  • New Feature
  • Bugfix
  • Documentation
  • Test

If you haven't finished some of the above items you can still open "Draft" PR.

shrpawar-alt and others added 3 commits October 23, 2026 12:20
Signed-off-by: Shreyas Pawar <shrpawar@nvidia.com>
Signed-off-by: Shreyas Pawar <shrpawar@nvidia.com>
@shrpawar-alt
shrpawar-alt marked this pull request as ready for review October 23, 2026 15:13
@folivoramanh
folivoramanh self-requested a review October 24, 2026 01:34
major_minor_graphs = []
minor_only_graphs = []

for major in all_major_names:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any solution for not looping all major_minor_currencies?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the loop has to stay: the token has the currency before the number, but the spoken output needs it after, so each currency needs its own branch (and the minor-unit word, पैसे / सेंट / पेंस, depends on the currency too). Having the tagger emit the number first would avoid the loop here, but then the tagger needs a copy of the number graph per currency, which is what made the classify grammar 55 MB (now ~45 MB). Added a comment above the loop for more clarity.

all_currencies += [maj for _, maj in load_labels(get_abs_path("data/money/currency_singular.tsv"))]

native_major_only_graphs = []
for major in set(all_currencies):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any solution for not looping all all_currencies?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch; that block was redundant. Removed it, as all tests are passing without it.

shrpawar-alt and others added 2 commits October 27, 2026 11:05
Signed-off-by: Shreyas Pawar <shrpawar@nvidia.com>
# says the currency after the number). Emit two money tokens with "से" between them instead.
money_separator = pynutil.insert(' } tokens { name: "से" } tokens { ')
range_money = money + delete_space + pynutil.delete("-") + delete_space + money_separator + money
range_money = pynutil.add_weight(range_money, 0.1)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try to remove/limit the use of custom weight

range_tagger = RangeFst(
time=time_final,
date=date_final,
cardinal=pynini.compose(cardinal_graph, v_cardinal.fst),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might cause error in the future, leave eye on it

@folivoramanh folivoramanh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolve the conflict for merging, too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants