Skip to content

feat: add automatic recovery for streaming ASR/TTS - #189

Open
pgowda1107 wants to merge 2 commits into
nvidia-riva:mainfrom
pgowda1107:feat/resilient-streaming
Open

feat: add automatic recovery for streaming ASR/TTS#189
pgowda1107 wants to merge 2 commits into
nvidia-riva:mainfrom
pgowda1107:feat/resilient-streaming

Conversation

@pgowda1107

@pgowda1107 pgowda1107 commented Aug 30, 2026

Copy link
Copy Markdown

Summary

Adds optional automatic recovery for streaming ASR and TTS when a transient gRPC failure occurs (UNAVAILABLE, DEADLINE_EXCEEDED, INTERNAL, RESOURCE_EXHAUSTED, or ABORTED).

Changes

File | Change -- | -- riva/client/retry.py | Shared retryable-status detection and exponential backoff with jitter. riva/client/asr.py | Adds ResilientStreamingASR, which reconnects and replays a bounded recent PCM-audio lookback buffer. Recovery is best effort; callers that require exactly-once transcript output should handle duplicate transcripts after reconnect. riva/client/tts.py | Adds ResilientStreamingTTS, which retries a failed text segment and buffers that segment’s responses before delivery so retrying does not duplicate already delivered audio. Segment size is the latency/recovery trade-off. scripts/asr/transcribe_file.py | Adds --auto-recover, --max-retries, and --lookback-seconds. scripts/tts/talk.py | Adds --auto-recover and --max-retries. tests/unit/test_retry.py | Adds unit coverage for retryable status detection, backoff behaviour, and TTS partial-stream failure recovery.

Usage

python scripts/asr/transcribe_file.py \
  --input-file data/examples/example.wav \
  --auto-recover \
  --max-retries 3 \
  --lookback-seconds 2.0
python scripts/tts/talk.py \
  --text "Hello from Riva" \
  --stream \
  --auto-recover \
  --max-retries 3

Validation

python -m pytest -q tests/unit/test_retry.py
7 passed

Add resilient streaming wrappers that automatically reconnect on transient
gRPC failures (UNAVAILABLE, DEADLINE_EXCEEDED, INTERNAL, etc.).

- riva/client/retry.py: shared retry utilities with exponential backoff
- riva/client/asr.py: ResilientStreamingASR with audio lookback buffer
  and final-transcript deduplication
- riva/client/tts.py: ResilientStreamingTTS with segment-level retry
- riva/client/auth.py: default gRPC keepalive for faster dead-connection detection
- scripts/asr/transcribe_file.py: --auto-recover, --max-retries, --lookback-seconds
- scripts/tts/talk.py: --auto-recover, --max-retries
- tests/unit/test_retry.py: unit tests for retry logic
pgowda1107

This comment was marked as duplicate.

Comment thread riva/client/auth.py
uri: str = "localhost:50051",
metadata: Optional[List[Tuple[str, str]]] = None,
options: Optional[List[Tuple[str, str]]] = [],
options: Optional[List[Tuple[str, Union[str, int]]]] = None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

didn't get why this change is needed?

"--auto-recover",
action="store_true",
help="Retry retryable streaming gRPC failures using a bounded audio lookback.",
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

instead of adding new arguments to the script, can we utilize generic custom_configuration argument to pass these as key value pairs?

Comment thread riva/client/asr.py



class ResilientStreamingASR:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

instead of new wrapper classes, is it possible to add this logic into existing recognize/synthesize functions? default disabled and only take effect when custom_configuration arguments are sent

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