Skip to content

Audio: add local duration-aware ASR batching - #2346

Open
mohammadaaftabv wants to merge 5 commits into
NVIDIA-NeMo:mainfrom
mohammadaaftabv:aaftabv/audio-local-bucketing
Open

Audio: add local duration-aware ASR batching#2346
mohammadaaftabv wants to merge 5 commits into
NVIDIA-NeMo:mainfrom
mohammadaaftabv:aaftabv/audio-local-bucketing

Conversation

@mohammadaaftabv

Copy link
Copy Markdown
Contributor

Summary

Validation

  • 256 passed, 7 deselected across audio inference, ASR adapters, and segmentation
  • Ruff format/check and git diff --check pass
  • local RTX 3080 Ti parity passed against nithinraok/Curator:nkoluguri/integration-test
  • policy-on calls: [1, 2]; policy-off and reference calls: [3]
  • raw transcripts, normalized transcripts, identities, and row order match exactly across all arms

This PR intentionally remains a draft.

@copy-pr-bot

copy-pr-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

Signed-off-by: aaftaabv@gmail.com <aaftaabv@gmail.com>
Signed-off-by: aaftaabv@gmail.com <aaftaabv@gmail.com>
@mohammadaaftabv
mohammadaaftabv force-pushed the aaftabv/audio-local-bucketing branch from ed2cd89 to a082cf4 Compare August 28, 2026 09:39
Signed-off-by: aaftaabv@gmail.com <aaftaabv@gmail.com>
Signed-off-by: aaftaabv@gmail.com <aaftaabv@gmail.com>
Signed-off-by: aaftaabv@gmail.com <aaftaabv@gmail.com>
@mohammadaaftabv
mohammadaaftabv marked this pull request as ready for review August 31, 2026 08:46
@mohammadaaftabv
mohammadaaftabv requested a review from a team as a code owner August 31, 2026 08:46
@mohammadaaftabv
mohammadaaftabv requested review from abhinavg4 and removed request for a team August 31, 2026 08:46
@greptile-apps

greptile-apps Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds local duration-aware ASR batching, fixed-duration model-input segmentation, ordered result scattering, and parent transcript stitching, together with configuration documentation and tests.

  • Introduces a validated duration bucket and aggregate-audio packing policy.
  • Adds independent adapter-call item caps and restores results to original item order.
  • Splits long waveforms into bounded model inputs and reassembles their parent results.
  • Expands tutorial, Hydra configuration, adapter-mapping, segmentation, and batching coverage.

Confidence Score: 4/5

The fixed context-free segmentation should be corrected before merging because it can corrupt transcripts around chunk boundaries; the segmented diagnostics schema should also be stabilized.

Long inputs are cut at arbitrary sample positions and independently decoded without overlap before plain text concatenation, while multi-segment adapter diagnostics are emitted under a different schema than single-segment results.

Files Needing Attention: nemo_curator/stages/audio/inference/asr/stage.py, nemo_curator/stages/audio/model_input_segmentation.py

Important Files Changed

Filename Overview
nemo_curator/stages/audio/inference/asr/stage.py Integrates segmentation, local batching, result scattering, and stitching; fixed context-free cuts can damage boundary transcription and stitched diagnostics acquire a duration-dependent schema.
nemo_curator/stages/audio/inference/batch_policy.py Implements validated, stable duration bucketing and greedy aggregate-duration packing while preserving original indices.
nemo_curator/stages/audio/model_input_segmentation.py Produces complete bounded sample intervals, but its hard boundaries provide no overlap or speech-aware context for ASR.
nemo_curator/models/asr/base.py Extends the documented adapter input contract with actual chunk duration.
tests/stages/audio/inference/test_asr_stage.py Thoroughly covers batch membership, caps, scattering, and literal stitching behavior, but does not test speech spanning a real model boundary or stable extras schema.
tests/stages/audio/inference/test_batch_policy.py Covers policy validation, boundaries, packing, ordering, and exact-once index behavior.
tests/stages/audio/test_model_input_segmentation.py Covers sample interval completeness and duration-boundary edge cases.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Parent audio rows] --> B[Load and resample]
  B --> C[Fixed-duration segments]
  C --> D[Duration buckets]
  D --> E[Audio and item caps]
  E --> F[Adapter calls]
  F --> G[Scatter to segment order]
  G --> H[Stitch parent transcripts]
  H --> I[Original parent-row order]
Loading

Reviews (1): Last reviewed commit: "docs(audio): document local duration buc..." | Re-trigger Greptile

Comment on lines +377 to 382
segments = plan_audio_segments(
num_samples=int(waveform.shape[0]),
sample_rate=self.target_sample_rate,
max_duration_s=self.max_inference_duration_s,
owner="ASRStage",
)

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.

P1 Hard cuts lose speech context

When speech crosses max_inference_duration_s, the waveform is cut at a fixed sample offset and each side is decoded independently without overlap before their text is joined, causing words around the boundary to be omitted, duplicated, or mistranscribed.

Knowledge Base Used: Audio curation stages

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +438 to +445
chunk_extras = [dict(result.extras) for result in results]
extras = {"chunks": chunk_extras} if any(chunk_extras) else {}
return ASRResult(
text=" ".join(texts),
skipped=all_skipped,
skip_reason=skip_reason if all_skipped else None,
unsupported_language=unsupported_language,
extras=extras,

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.

P2 Segmenting changes diagnostics schema

For a segmented parent with adapter extras, this replaces the documented adapter-specific dictionary with {"chunks": [...]}, so consumers must handle a second duration-dependent schema instead of reading established keys such as detected_language at their normal location.

Knowledge Base Used: Model integrations and inference

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

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