Skip to content

Fix greedy search decoding for Nemo streaming transducer - #3785

Merged
csukuangfj merged 2 commits into
k2-fsa:masterfrom
csukuangfj:fix-nemo-streaming
Jul 23, 2026
Merged

csukuangfj merged 2 commits into
k2-fsa:masterfrom
csukuangfj:fix-nemo-streaming

Conversation

@csukuangfj

@csukuangfj csukuangfj commented Jul 23, 2026 •

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features
    • Added configurable left and right audio padding options (in seconds) for streaming recognition.
    • Added support for accessing and updating NeMo decoder outputs during streaming.
  • Bug Fixes
    • Improved reuse of existing decoder outputs to avoid unnecessary decoder runs when output is already available.
    • Updated decoder state/out updates to be more consistent across decoding steps, including when no tokens are emitted.
    • Ensured NeMo decoder output is cleared properly on stream reset.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Jul 23, 2026
@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2b2a7b99-ca8b-41ca-a15c-122e2989f186

📥 Commits

Reviewing files that changed from the base of the PR and between eea2f68 and e551192.

📒 Files selected for processing (2)
  • sherpa-onnx/csrc/online-recognizer-transducer-nemo-impl.h
  • sherpa-onnx/csrc/sherpa-onnx.cc
🚧 Files skipped from review as they are similar to previous changes (1)
  • sherpa-onnx/csrc/sherpa-onnx.cc

📝 Walkthrough

Walkthrough

The PR adds persistent NeMo decoder output storage and accessors, updates greedy decoding to reuse and save decoder output/state pairs, clears stored output on reset, and replaces hardcoded waveform padding with validated configurable left- and right-padding options.

Changes

NeMo decoder flow

Layer / File(s) Summary
NeMo decoder storage API
sherpa-onnx/csrc/online-stream.h, sherpa-onnx/csrc/online-stream.cc
OnlineStream adds NeMo decoder output setter/getter methods and stores decoder outputs separately from decoder states.
Decoder reuse and reset persistence
sherpa-onnx/csrc/online-transducer-greedy-search-nemo-decoder.cc, sherpa-onnx/csrc/online-recognizer-transducer-nemo-impl.h
DecodeOne reuses or runs the decoder, persists output and states unconditionally, and reset clears the stored output. Formatting-only condition changes preserve language-tag and context-score filtering logic.

Configurable stream padding

Layer / File(s) Summary
Padding configuration and application
sherpa-onnx/csrc/sherpa-onnx.cc
Adds finite, non-negative left- and right-padding options and uses their durations when constructing buffers for AcceptWaveform.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DecodeOne
  participant OnlineStream
  participant RunDecoder
  DecodeOne->>OnlineStream: read stored decoder output and states
  DecodeOne->>RunDecoder: run decoder when no stored output exists
  RunDecoder-->>DecodeOne: return decoder output and states
  DecodeOne->>OnlineStream: store decoder output and states
  OnlineStream->>OnlineStream: clear decoder output during reset
Loading

Possibly related PRs

  • k2-fsa/sherpa-onnx#3728: Adds a QNN-based NeMo transducer runtime that also initializes and resets stream decoder output and state.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: fixing greedy-search decoding behavior for NeMo streaming transducer models.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@sherpa-onnx/csrc/online-transducer-greedy-search-nemo-decoder.cc`:
- Around line 46-58: Update the NeMo decoder reset path to clear both the cached
decoder output and decoder states together, ensuring the next decode treats the
state as uninitialized and invokes RunDecoder. Add a regression test that
decodes after an endpoint reset and verifies the fresh decoder initialization
path is used.

In `@sherpa-onnx/csrc/sherpa-onnx.cc`:
- Around line 86-98: Validate left_padding_second and right_padding_second after
CLI parsing and before any conversion or vector allocation: reject non-finite or
negative values, then ensure each seconds-to-samples calculation does not exceed
INT32_MAX before converting to int or passing it to AcceptWaveform. Emit the
specified error and return -1 on invalid input, covering both padding
registration paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a3cbee41-3d60-44b2-9050-a1fc7baa6f30

📥 Commits

Reviewing files that changed from the base of the PR and between 9d15a28 and eea2f68.

📒 Files selected for processing (4)
  • sherpa-onnx/csrc/online-stream.cc
  • sherpa-onnx/csrc/online-stream.h
  • sherpa-onnx/csrc/online-transducer-greedy-search-nemo-decoder.cc
  • sherpa-onnx/csrc/sherpa-onnx.cc

Comment thread sherpa-onnx/csrc/online-transducer-greedy-search-nemo-decoder.cc
Comment thread sherpa-onnx/csrc/sherpa-onnx.cc

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets more stable and efficient NeMo streaming transducer greedy decoding by persisting decoder context across streaming steps, while also making the CLI example’s audio padding configurable.

Changes:

  • Add --left-padding / --right-padding options to the sherpa-onnx CLI example and apply them when feeding audio to streams.
  • Cache NeMo decoder output (Ort::Value) alongside decoder states in OnlineStream, and reuse it across decoding steps.
  • Update NeMo greedy-search decoding to reuse cached decoder output/state and to persist updated decoder context after each chunk.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
sherpa-onnx/csrc/sherpa-onnx.cc Adds configurable left/right padding and applies padding when feeding wave samples.
sherpa-onnx/csrc/online-transducer-greedy-search-nemo-decoder.cc Reuses cached decoder output/state across chunks and persists updated decoder context each call.
sherpa-onnx/csrc/online-stream.h Adds SetNeMoDecoderOut() / GetNeMoDecoderOut() API for caching NeMo decoder output.
sherpa-onnx/csrc/online-stream.cc Implements storage for cached NeMo decoder output and renames/organizes NeMo decoder state members.
Comments suppressed due to low confidence (1)

sherpa-onnx/csrc/sherpa-onnx.cc:155

  • right_padding_second is user-configurable; if it is negative, static_cast<int>(right_padding_second * sampling_rate) can become a huge size_t and attempt an enormous allocation. Clamp/validate the computed sample count before sizing the padding vector.
    std::vector<float> tail_paddings(
        static_cast<int>(right_padding_second * sampling_rate), 0);
    // Note: We can call AcceptWaveform() multiple times.
    s->AcceptWaveform(sampling_rate, tail_paddings.data(),
                      tail_paddings.size());

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 126 to 128
void SetNeMoDecoderStates(std::vector<Ort::Value> decoder_states) {
decoder_states_ = std::move(decoder_states);
nemo_decoder_states_ = std::move(decoder_states);
}
Comment on lines +100 to +101
s->SetNeMoDecoderOut(std::move(decoder_output_pair.first));
s->SetNeMoDecoderStates(std::move(decoder_output_pair.second));
Comment on lines +144 to 147
std::vector<float> left_paddings(
static_cast<int>(left_padding_second * sampling_rate), 0);
s->AcceptWaveform(sampling_rate, left_paddings.data(),
left_paddings.size());
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Jul 23, 2026
@csukuangfj
csukuangfj merged commit 2cbcb26 into k2-fsa:master Jul 23, 2026
18 of 28 checks passed
@csukuangfj
csukuangfj deleted the fix-nemo-streaming branch July 23, 2026 03:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants