Skip to content

Raise in vad on non-finite input instead of reporting silence (closes #4216) - #4217

Open
Kayvan-Zahiri wants to merge 1 commit into
pytorch:mainfrom
Kayvan-Zahiri:fix/vad-non-finite-input
Open

Raise in vad on non-finite input instead of reporting silence (closes #4216)#4217
Kayvan-Zahiri wants to merge 1 commit into
pytorch:mainfrom
Kayvan-Zahiri:fix/vad-non-finite-input

Conversation

@Kayvan-Zahiri

Copy link
Copy Markdown

Closes #4216.

The bug

vad builds a running trigger measure:

mean_meas[i] = mean_meas[i] * trigger_meas_time_mult + meas * (1.0 - trigger_meas_time_mult)
has_triggered = has_triggered or (mean_meas[i] >= trigger_level)

One non-finite sample makes meas non-finite, and the recurrence then keeps
mean_meas[i] non-finite for the rest of the waveform. Every later comparison
against trigger_level is false, so nothing triggers and the whole input is
reported as silence. The caller gets an empty Tensor, with no warning and no
exception.

It is position dependent, which is what makes it easy to miss:

clean                              kept 2.10s of 3.00s  shape=(33600,)
NaN in leading silence (idx 100)   kept 0.00s of 3.00s  shape=(0,)
NaN inside speech (idx 24000)      kept 2.10s of 3.00s  shape=(33600,)

The third row is not a working case. That output still contains the NaN, so
vad hands back a waveform that is just as broken, only without the obvious
symptom.

The fix

Check the input once at the top of functional.vad and raise. This file already
raises ValueError for out-of-range arguments in several places, so the shape is
consistent with the surrounding code.

Behaviour change

Input containing NaN or infinity now raises ValueError where it previously
returned a Tensor. That includes the "NaN inside speech" case above, which used to
return trimmed audio. Given that output still carried the non-finite sample, an
error seems better than a result the caller is likely to trust.

Clean input is unaffected.

Verification

  • The reproduction in the issue: clean input still returns 2.10s of 3.00s;
    NaN and infinity now raise instead of returning an empty Tensor.
  • torch.isfinite is safe for every dtype vad accepts, including integer
    tensors, where it is true everywhere.
  • TorchScript: Vad is covered by torchscript_consistency_impl.py, so I
    checked the guard compiles under torch.jit.script and raises correctly when
    scripted. bool() on the 0-dim result is required for that.
  • No existing test feeds non-finite audio to vad, so nothing already in the
    suite changes meaning.
  • transforms_cpu_test.py -k vad: 24 passed. The 6 new cases (3 values x 2
    dtypes) fail with AssertionError: ValueError not raised without the guard.
  • flake8 and black clean at the repo's 120 column setting.

I could not build torchaudio from source on this machine, so the behavioural runs
above were done by applying the same guard to an installed 2.11.0 and restoring it
afterwards. CI is authoritative over my numbers.

Note

@adityaanikam confirmed the root cause on the issue and stood aside for me to open
this, which I appreciated.

I also saw the notice that this repository is no longer actively monitored, so no
expectation of a quick review. The fix is small and self-contained if it is ever
useful.

The trigger measure is a running mean, so one NaN or infinity poisons it
permanently and every later comparison against trigger_level is false. Nothing
ever triggers, the whole waveform is treated as silence, and an empty Tensor is
returned with no warning.

The failure is position dependent, which makes it easy to miss: a non-finite
sample in the leading region that vad scans discards everything, while one
inside the speech leaves the trimming intact and returns a waveform that still
contains the non-finite sample.

Check the input up front and raise, as this file already does for out of range
arguments elsewhere.

Closes pytorch#4216
@Kayvan-Zahiri
Kayvan-Zahiri requested a review from a team as a code owner August 12, 2026 19:09
@pytorch-bot

pytorch-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/audio/4217

Note: Links to docs will display an error until the docs builds have been completed.

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla

meta-cla Bot commented Aug 12, 2026

Copy link
Copy Markdown

Hi @Kayvan-Zahiri!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@meta-cla meta-cla Bot added the CLA Signed label Aug 12, 2026
@meta-cla

meta-cla Bot commented Aug 12, 2026

Copy link
Copy Markdown

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

transforms.Vad silently returns an empty tensor when the waveform contains one non-finite sample

1 participant