Skip to content

ASR long-form: mid-file window ending inside a dead-silence run drops nearby speech (same pathology as #747, interior windows) #803

Description

@Alex-Wengg

Summary

A sliding window whose fixed-stride end lands inside a dead-silence run decodes degenerately, dropping speech near that window's end — mid-file, on any long recording with extended silences. This is the same encoder pathology that PR #800 fixed for the final window (#747), but for interior windows, where #800 deliberately did not touch the layout.

Evidence

Measured mechanism (Earnings-22 shard0_rg0_0, recording ends with ~3 s of digital zeros; decoded in isolation with a stock binary):

Window content Decode
12 s speech perfect, full text
12 s speech + 1 s of the silent run loses the first ~6 s of content
12 s speech + 3 s of the silent run completely empty

Zero padding beyond the declared audio_length is masked and harmless (the 12 s clip above is speech + masked padding). Dead silence inside the declared length is what poisons the window — the FastConformer encoder computes every real frame's features over the whole valid window.

In-the-wild instance (musan/speech/librivox/speech-librivox-0000.wav, 444 s): the quiet chapter-outro credit ("…overwhelmed by numbers. End of Four Classes That Constitute a Menace, by Grace Duffield Goodwin", ≈ 428–438 s) falls in a window [425.0 s, 439.9 s] whose end lands inside the recording's trailing silence run (438–444 s). The outro is dropped from the transcript on main today. Verified real by isolated decode of the last 40 s.

Why PR #800 didn't fix this

#800 ends the final window at the last speech-bearing frame (speechEndSamples()), which fixes the EOF case. Snapping every window end the same way was implemented and reverted during that PR: it perturbs dozens of mid-file windows per hour of audio (any window ending in a ≥ 80 ms sub-floor run) for a net-neutral WER change on the 4-file hour-long Earnings-22 A/B — a blast radius that needs its own regression run, not a rider on #747.

Sketch of a targeted fix

Snap a window's audio end back to the last speech-bearing frame only when the trailing sub-floor run is long enough to be dangerous (the measured series suggests ≥ ~1 s; an 80 ms pause at the window edge is normal speech and must not trigger). Concretely: in ChunkProcessor, compute audioEnd per chunk via a bounded backward scan (threshold speechRmsFloor, same as #800's trim), gated on run length ≥ N frames; the masked padding takes over from there — the proven-safe construction. Needs:

  • A/B against main on the Earnings-22 longform set + long MUSAN files (the fix(asr): end-align the final window at the last speech-bearing frame (#747) #800 methodology; diffs must be confined to windows whose ends sit in long silence runs)
  • The librivox-0000 outro as the acceptance case
  • Care with the silence-aligned starts path (melChunkContext = false), whose boundary search already tries to end windows near silence

See "Cost and Known Limitations" in Documentation/ASR/LongTranscription.md (added by #800) for the documented state.

Impact

Silent, high-confidence content drops near long pauses on long-form audio: recordings with scene breaks, operator holds, chapter gaps, meeting silences. Same failure texture as #747/#758 — no error, transcript simply has a hole.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions