Skip to content

fix(asr): collect whole labels in FeatureLabel.uniq_labels - #16107

Open
udsy19 wants to merge 2 commits into
NVIDIA-NeMo:mainfrom
udsy19:fix/feature-label-uniq-labels
Open

fix(asr): collect whole labels in FeatureLabel.uniq_labels#16107
udsy19 wants to merge 2 commits into
NVIDIA-NeMo:mainfrom
udsy19:fix/feature-label-uniq-labels

Conversation

@udsy19

@udsy19 udsy19 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

What does this PR do ?

Makes FeatureLabel collect whole labels instead of the characters of each label string.

Collection: ASR

Fixes #16106.

Changelog

FeatureLabel.__init__ accumulated self.uniq_labels |= set(label). label is the manifest's label
string, so set() yielded its characters: a corpus labelled speech / background produced a
14-entry vocabulary of single letters instead of ['background', 'speech'].

uniq_labels is the label-vocabulary fallback for FeatureToLabelDataset
(self.labels = labels if labels else self.collection.uniq_labels), so three failures follow from that
one line:

  1. wrong vocabulary — 14 characters instead of 2 labels;
  2. TypeError: 'set' object is not subscriptable at feature_to_label.py:358 (self.labels[:5]),
    because uniq_labels is a bare set while every other producer of self.labels yields a list —
    so the documented labels=None fallback cannot work at all;
  3. TypeError: 'float' object is not iterable on the regression path, where ASRFeatureLabel sets
    label = float(item['label']). This raises inside ASRFeatureLabel.__init__, before labels is
    consulted, so passing an explicit label list does not avoid it.

The fix computes uniq_labels after the loop, exactly the way the audio-side sibling SpeechLabel
already does in the same module:

self.uniq_labels = sorted(set(map(lambda x: x.label, data)))

That single line fixes all three, and makes FeatureLabel agree with both SpeechLabel and
FeatureToMultiLabelDataset._get_label_set().

A second, separate commit fixes the adjacent log line in the same function, which divided the filtered
duration by 2600 instead of 3600 — the line immediately below it, and every other collection in
this module, use 3600. It is log output only and is kept as its own commit so it can be dropped
independently if preferred.

Testing

Extended the existing tests/collections/asr/test_label_datasets.py::TestASRDatasets (which already
has a tempfile-based test_feat_label_dataset) with 5 unit tests:

  • uniq_labels holds whole labels, not characters;
  • it matches ASRSpeechLabel.uniq_labels on an equivalent manifest (sibling control);
  • FeatureToLabelDataset(labels=None) builds labels / num_classes / label2id and yields the
    right label tensor;
  • its vocabulary matches FeatureToMultiLabelDataset(labels=None) on the same manifest (sibling
    control);
  • ASRFeatureLabel(..., is_regression_task=True) constructs and returns [0.5, 1.5].

Results on this branch:

state result
before the fix 5 failed, 1 passed (assert {'a','b','c',...} == ['background','speech']; TypeError: 'set' object is not subscriptable; TypeError: 'float' object is not iterable)
with this fix 6 passed

The test that passes in both states is the pre-existing test_feat_label_dataset, which passes an
explicit labels= list — included to show the existing behaviour is preserved.

Whole file: 10 passed. Wider run on this branch —
tests/collections/asr/test_asr_classification_model.py and
tests/collections/asr/test_asr_regression_model.py: 19 passed.

Style: black 24.10.0 and isort 5.13.2 (repo settings, line length 119) report no changes;
flake8 --config .flake8.other exits 0; pylint --rcfile .pylintrc.other rates collections.py
10.00/10; pre-commit run --from-ref main --to-ref HEAD passes.

No documentation change: this restores the behaviour the FeatureToLabelDataset docstring already
describes ("if None then automatically picks from the collection") rather than changing an API.

GitHub Actions CI

Trusted PRs run automatically through copy-pr-bot. For an untrusted PR, a maintainer can trigger CI by commenting
/ok to test <head-sha>; repeat this after a new push if the PR remains untrusted.

Before your PR is "Ready for review"

Pre checks:

  • Make sure you read and followed Contributor guidelines
  • Did you write any new necessary tests?
  • Did you add or update any necessary documentation?
  • Does the PR affect components that are optional to install? (Ex: Numba, Pynini, Apex etc)
    • Reviewer: Does the PR have correct import guards for all optional libraries?

PR Type:

  • New Feature
  • Bugfix
  • Documentation

udsy19 added 2 commits August 18, 2026 13:03
`FeatureLabel.__init__` accumulated `self.uniq_labels |= set(label)`. `label`
is the manifest's label string, so `set()` yielded its characters: a corpus
labelled `speech`/`background` produced a 14-entry vocabulary of single
letters instead of `['background', 'speech']`.

`uniq_labels` is the label-vocabulary fallback for `FeatureToLabelDataset`
(`self.labels = labels if labels else self.collection.uniq_labels`), so the
documented `labels=None` behaviour was unusable in two further ways: the
result was a bare `set` while every other producer yields a list, making
`self.labels[:5]` raise `TypeError: 'set' object is not subscriptable`; and on
the regression path `label` is a `float`, so `set(label)` raised
`TypeError: 'float' object is not iterable` before `labels` was ever consulted.

Compute it after the loop, exactly as the audio-side sibling `SpeechLabel`
already does, which fixes all three at once.

Signed-off-by: Udaya Tejas <udayatejas2004@gmail.com>
The filtered-duration log line divided seconds by 2600; the total-duration
line immediately below it, and every other collection in this module, divide
by 3600. Log output only.

Signed-off-by: Udaya Tejas <udayatejas2004@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 18, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FeatureLabel.uniq_labels collects the characters of each label, breaking FeatureToLabelDataset

2 participants