Skip to content

fix(kws): ignore empty keyword entries in KwsCtcPrefixDecoder - #3800

Merged
LauraGPT merged 1 commit into
modelscope:mainfrom
MohammadHijjawi97:fix/kws-skip-empty-keywords
Oct 28, 2026
Merged

LauraGPT merged 1 commit into
modelscope:mainfrom
MohammadHijjawi97:fix/kws-skip-empty-keywords

Conversation

@MohammadHijjawi97

Copy link
Copy Markdown
Contributor

Summary

KwsCtcPrefixDecoder splits keywords on commas. A trailing, leading or doubled comma (keywords="小云小云,"), or an entry made only of punctuation, produces a keyword with no token ids. An empty token sequence matches every hypothesis, so:

  • silence is reported as a detection of the empty keyword with score 1.0 (detected 1.0);
  • a hypothesis that contains only part of the real keyword raises IndexError: tuple index out of range in is_sublist.

This change skips keywords that map to no tokens and logs a warning. Real keywords are decoded exactly as before.

Before (token list <blank> <unk> 小 云, keywords "小云小云,"):

silence posteriors      -> (True, '', 1.0)
only "小" then blanks   -> IndexError: tuple index out of range

After:

silence posteriors      -> (False, None, None)
only "小" then blanks   -> (False, None, None)
"小云" "小云"           -> (True, '小云小云', 1.0)

Type of change

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

Validation

  • python -m compileall on the changed files
  • Docs or links checked
  • Runtime/deployment command tested

New regression test tests/test_kws_utils.py::KwsUtilsTest::test_empty_keyword_entries_do_not_produce_detections uses synthetic CTC posteriors (no model download). It fails on main (4 failed subtests: (True, '', 1.0) != (False, None, None)) and passes with this change. tests/test_kws_utils.py, tests/test_kws_optional_output.py, tests/test_kws_streaming_continuity.py and tests/test_kws_docs.py show no new failures.

User impact

Users of the FSMN/SANM KWS models who pass several keywords as a comma-separated string no longer get false detections or crashes from an extra comma.

Notes for reviewers

The fix is in the keyword parsing only; the beam search and is_sublist are unchanged. Keywords with no tokens are skipped with a warning rather than raising, so an existing configuration with a stray comma keeps working.

The keywords string is split on commas, so a trailing comma
("小云小云,"), a doubled comma, or an entry made only of punctuation
produced a keyword with no token ids. An empty token sequence matched
every hypothesis: decoding silence returned "detected" with score 1.0
for the empty keyword, and a non-empty hypothesis without the real
keyword could raise IndexError in is_sublist.

Skip keywords that map to no tokens and log a warning instead.

@LauraGPT LauraGPT 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.

Independent agent-assisted review of external head d1ef17d4fd18f02505063e71c8e57090a0798901 against current main 940b0d2463141a2e9ace8a9fd965b4aea93f2db5, tested potential-merge tree 45a85334e8896db83d3e62224bf7edb593a0fb0d.

I read both changed files, the full decoder implementation, and all current PR discussion (none). No blocking issue found: the constructor drops only entries whose token sequence is empty; valid keyword parsing and beam search are unchanged. All 4,153 source blobs match the exact merge export, with only the two declared files different from main.

Verification on Python 3.12.3 / PyTorch 2.8.0a0+5228986c39.nv25.06:

  • The new regression against the unchanged decoder fails with the reported (True, '', 1.0) silence detection.
  • Exact merge source: all 45 tests in test_kws_utils, test_kws_optional_output, test_kws_streaming_continuity and test_kws_docs pass, with no skips.
  • Real NVIDIA L20Z CUDA 12.9 execution: 48 CPU/CUDA comparisons (96 decode calls) across FP32/BF16, valid/leading/trailing/doubled-comma/punctuation/all-empty configurations, silence/partial/full-keyword posteriors. Expected detections and scores agree in every case. Softmax runs on the selected device; the production decoder then transfers its posterior tensor to CPU as designed.
  • Exact-head hosted kws-output check is successful.

These are focused KWS tests and synthetic CTC inputs, not pretrained acoustic-model inference, audio-quality evaluation or the full repository suite. No model download or reference/threshold modification. Approval is from a different account than the contributor and does not bypass branch protection.

@LauraGPT
LauraGPT merged commit c9c42c0 into modelscope:main Oct 28, 2026
1 check passed
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