Skip to content

fix(postprocess): keep word timestamps aligned after filtered tokens - #3802

Open
ANDROIDHASSAN wants to merge 1 commit into
modelscope:mainfrom
ANDROIDHASSAN:fix/timestamps-after-filtered-tokens
Open

ANDROIDHASSAN wants to merge 1 commit into
modelscope:mainfrom
ANDROIDHASSAN:fix/timestamps-after-filtered-tokens

Conversation

@ANDROIDHASSAN

Copy link
Copy Markdown

Summary

sentence_postprocess removes <s>, </s>, <unk> and <OOV> from the tokens, then reads time_stamp by the position in the cleaned list. ts_prediction_lfr6_standard and time_stamp_lfr6_onnx give one timestamp per token, including <unk>, so every word after a filtered token gets the previous token's time. The last word's real end is lost as well.

Paraformer only strips eos, sos and blank from token_int, so <unk> reaches this function. Tokens 今 <unk> 天 好 through ts_prediction_lfr6_standard, sentence_postprocess and timestamp_sentence:

今 天 好 sentence end
Timestamps for that token 210–809 1410–2009 2009–3105 3105
Before 210–809 809–1410 1410–2009 2009
After 210–809 1410–2009 2009–3105 3105

The fix keeps the timestamps of the tokens that survive the cleaning loop, in the three copies of the function (funasr, funasr_onnx, funasr_torch). If the list is too short to cover those tokens, it is left as it was before this change, because the branches below index it directly and would raise IndexError.

tests/test_sentence_postprocess_timestamps.py loads all three files by path, so it needs no model or torch. I added it to test-text-postprocessing.yml, which lists its tests by name and would otherwise skip it.

Type of change

  • Bug fix
  • Documentation
  • Example or demo
  • Runtime or deployment
  • Benchmark or evaluation
  • Model/training change

Validation

  • python -m compileall funasr examples tests
  • Docs or links checked
  • Runtime/deployment command tested

With pytest 8.1.1, pypinyin 0.55.0 and rapidfuzz 3.14.5, the versions the workflow pins:

  • New tests on main source: 3 failed, 2 passed. The Chinese, English and mixed cases fail, for example [[0, 100], [100, 200], [200, 300]] != [[0, 100], [200, 300], [300, 400]]. The other two are guards that pass before and after: a trailing </s> without a timestamp, and too few timestamps.
  • With this change: tests/test_postprocess_hotwords.py tests/test_rich_transcription_postprocess.py tests/test_sentence_postprocess_timestamps.py gives 27 passed.
  • Also with this change: tests/test_paraformer_timestamp_contract.py tests/test_paraformer_timestamp_padding.py plus the new file gives 13 passed.

These are unit tests plus the function chain above with synthetic CIF peaks. I did not run a real Paraformer model or the ONNX/libtorch runtime.

User impact

Anyone using Paraformer, BiCif Paraformer, SeACo Paraformer, E-Paraformer, the monotonic aligner, or the ONNX and libtorch runtimes gets correct word and sentence times when the output contains <unk>.

Notes for reviewers

  • Output only changes for token lists that contain a filtered token before the last word.
  • A short list keeps the old misaligned output, since it can't be matched to tokens reliably.
  • Left out to keep this to one cause: in the core copy, the mixed branch's else appends a word with no timestamp, which shifts later words the same way (["你", "g5", "好", "吗"]). The runtime copies raise ValueError there. The runtime wash lists also lack <OOV>.

sentence_postprocess drops <s>, </s>, <unk> and <OOV> from the tokens but
then indexed time_stamp by the washed position. time_stamp has one entry per
token, so every word after a filtered token took the previous token's time.

Keep the entries of the surviving tokens. A list too short to cover them
stays as it was, because the branches below index it directly.

This branch has not been deployed

No deployments
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.

1 participant