taejinp commited on
Commit
c39e97f
·
verified ·
1 Parent(s): 81d3a13

Upload ASR_INTEGRATION_GUIDE.md

Browse files
Files changed (1) hide show
  1. ASR_INTEGRATION_GUIDE.md +187 -0
ASR_INTEGRATION_GUIDE.md ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use Nemotron-3-Diarization with Streaming ASR
2
+
3
+ `nvidia/Nemotron-3-Diarization` answers **who spoke when**. To produce a
4
+ speaker-attributed transcript—**who said what**—pair it with a compatible ASR
5
+ model.
6
+
7
+ The recommended overlap-aware pairing is:
8
+
9
+ - Diarization: [`nvidia/Nemotron-3-Diarization`](https://huggingface.co/nvidia/Nemotron-3-Diarization)
10
+ - ASR: [`nvidia/multitalker-parakeet-streaming-0.6b-v1`](https://huggingface.co/nvidia/multitalker-parakeet-streaming-0.6b-v1)
11
+ - Integration: NeMo Speech's [`speech_to_text_multitalker_streaming_infer.py`](https://github.com/NVIDIA-NeMo/Speech/blob/main/examples/asr/asr_cache_aware_streaming/speech_to_text_multitalker_streaming_infer.py)
12
+
13
+ This is a coupled streaming pipeline. Sortformer produces speaker activity for
14
+ each frame, and Multitalker Parakeet uses that activity to focus an ASR stream
15
+ on each speaker. All ASR streams receive the same mixed audio. This is important
16
+ for overlapping speech: independently transcribing diarization time ranges does
17
+ not isolate speakers when two people are talking at once.
18
+
19
+ ## 1. Install NeMo Speech
20
+
21
+ Use a recent checkout of NeMo Speech because the multi-talker streaming helper
22
+ is developed alongside the models.
23
+
24
+ ```bash
25
+ apt-get update && apt-get install -y libsndfile1 ffmpeg git
26
+
27
+ git clone --branch main --single-branch https://github.com/NVIDIA-NeMo/Speech.git
28
+ cd Speech
29
+
30
+ curl -LsSf https://astral.sh/uv/install.sh | sh
31
+ uv sync --python 3.13 --extra asr --extra cu13 --no-dev
32
+ source .venv/bin/activate
33
+ ```
34
+
35
+ Use `--extra cu12` instead of `--extra cu13` when your installed NVIDIA driver
36
+ and CUDA environment require CUDA 12.
37
+
38
+ If the Hugging Face repositories require authentication, provide a token that
39
+ has access to both models:
40
+
41
+ ```bash
42
+ export HF_TOKEN="your-hugging-face-token"
43
+ ```
44
+
45
+ Do not put the token in source code or commit it to a repository.
46
+
47
+ ## 2. Prepare the audio
48
+
49
+ The paired models expect single-channel, 16 kHz audio. Convert other inputs
50
+ before inference:
51
+
52
+ ```bash
53
+ ffmpeg -i input.mp3 -ac 1 -ar 16000 -c:a pcm_s16le conversation.wav
54
+ ```
55
+
56
+ ## 3. Run speaker-attributed transcription
57
+
58
+ From the NeMo Speech repository root, run:
59
+
60
+ ```bash
61
+ python examples/asr/asr_cache_aware_streaming/speech_to_text_multitalker_streaming_infer.py \
62
+ asr_model=nvidia/multitalker-parakeet-streaming-0.6b-v1 \
63
+ diar_model=nvidia/Nemotron-3-Diarization \
64
+ audio_file=/absolute/path/to/conversation.wav \
65
+ max_num_of_spks=8 \
66
+ single_speaker_mode=false \
67
+ masked_asr=false \
68
+ parallel_speaker_strategy=true \
69
+ cache_gating=true \
70
+ binary_diar_preds=true \
71
+ att_context_size='[70,13]' \
72
+ fifo_len=264 \
73
+ spkcache_update_period=64 \
74
+ generate_realtime_scripts=false \
75
+ output_path=./speaker_attributed_output.json
76
+ ```
77
+
78
+ The script prints streaming hypotheses and writes the final result to
79
+ `speaker_attributed_output.json` in NeMo's SegLST format. Each finalized item
80
+ contains its text, time range, and anonymous speaker label.
81
+
82
+ The important settings are:
83
+
84
+ | Setting | Meaning |
85
+ |---|---|
86
+ | `max_num_of_spks=8` | Maximum number of speaker streams maintained for the session. Lower this when the use case has fewer speakers to reduce compute. |
87
+ | `parallel_speaker_strategy=true` | Processes the speaker-specific ASR streams in parallel. |
88
+ | `masked_asr=false` | Uses speaker activity as conditioning for Multitalker Parakeet rather than simply muting the mixed waveform outside one speaker's regions. |
89
+ | `att_context_size='[70,13]'` | Uses 70 left-context frames and 13 right-context frames. With the model's current geometry, the streaming advance is about 1.12 seconds. |
90
+ | `cache_gating=true` | Stabilizes speaker-cache updates during streaming. |
91
+ | `spkcache_update_period=64` | Refreshes the speaker cache frequently enough for the long, eight-speaker sessions used by this demo. Tune this for other workloads. |
92
+
93
+ `max_num_of_spks` is an upper bound, not a promise that every configured speaker
94
+ will appear. The diarization model discovers active speaker identities from the
95
+ audio.
96
+
97
+ ## 4. Minimal Python usage in this demo repository
98
+
99
+ This repository wraps the same NeMo integration in `init_nemo_models.py`. The
100
+ wrapper loads both models, validates that their feature-frame strides are
101
+ compatible, configures Sortformer to match the ASR encoder, and maintains the
102
+ streaming state.
103
+
104
+ Run the following from this demo's directory:
105
+
106
+ ```python
107
+ from init_nemo_models import MultitalkerTranscriptionConfig, StreamingSession
108
+
109
+ config = MultitalkerTranscriptionConfig(
110
+ diar_model="nvidia/Nemotron-3-Diarization",
111
+ asr_model="nvidia/multitalker-parakeet-streaming-0.6b-v1",
112
+ device="cuda",
113
+ sample_rate=16000,
114
+ max_num_of_spks=8,
115
+ att_context_size=[70, 13],
116
+ parallel_speaker_strategy=True,
117
+ masked_asr=False,
118
+ cache_gating=True,
119
+ binary_diar_preds=True,
120
+ spkcache_update_period=64,
121
+ fifo_len=264,
122
+ )
123
+
124
+ session = StreamingSession()
125
+ session.setup_streaming_session(config)
126
+ session.add_file_to_streaming_buffer("/path/to/conversation.wav")
127
+
128
+ for chunk_audio, chunk_lengths in session.streaming_buffer_iter:
129
+ session.process_audio_chunk(chunk_audio, chunk_lengths)
130
+
131
+ print(session.transcribed_speaker_texts)
132
+ ```
133
+
134
+ A typical rendered result looks like:
135
+
136
+ ```text
137
+ Speaker 0: Welcome, everyone. Let us begin.
138
+ Speaker 1: I have the latest numbers.
139
+ Speaker 2: I agree, but there is one remaining issue.
140
+ ```
141
+
142
+ Speaker numbers represent identities discovered during that stream. They do not
143
+ identify real-world names. If an application displays names, it must associate
144
+ those names separately—for example through an enrollment or application-level
145
+ mapping step.
146
+
147
+ ## Real-time microphone or service integration
148
+
149
+ For live audio, keep one `StreamingSession` for each client connection and feed
150
+ successive mono PCM chunks to `process_microphone_chunk(audio, sample_rate)`.
151
+ Do not share the session object between clients: the speaker cache, ASR decoder
152
+ state, timestamps, and transcript history are all session-specific.
153
+
154
+ Model weights may be shared across connections to save GPU memory, provided
155
+ each connection receives independent `SpeakerTaggedASR`, streaming-buffer, and
156
+ speaker-cache state. The service in this repository follows that pattern.
157
+
158
+ ## Choosing another ASR model
159
+
160
+ A conventional single-speaker ASR can be applied after diarization by cutting
161
+ the audio at each speaker segment and transcribing the cuts. That approach is
162
+ reasonable when speakers rarely overlap. It is not an equivalent replacement
163
+ for Multitalker Parakeet: an extracted time range still contains every voice
164
+ that overlaps it, so a conventional ASR may merge or select the wrong speaker's
165
+ words.
166
+
167
+ For overlap-aware speaker-attributed transcription, use an ASR model designed
168
+ to consume speaker activity and verify that its encoder frame geometry is
169
+ compatible with the diarization model.
170
+
171
+ ## Troubleshooting
172
+
173
+ - **Only plain text appears:** Ensure you launched the multi-talker inference
174
+ script with both `asr_model` and `diar_model`, rather than calling
175
+ `asr_model.transcribe()` by itself.
176
+ - **A model cannot be downloaded:** Accept any required model terms and verify
177
+ that `HF_TOKEN` can read both repositories.
178
+ - **Audio is rejected or results are poor:** Convert it to mono, 16-bit PCM at
179
+ 16 kHz.
180
+ - **CUDA out of memory:** Reduce `max_num_of_spks`. The multi-talker architecture
181
+ maintains speaker-specific ASR state, so memory and compute grow with the
182
+ number of simultaneous speaker streams.
183
+ - **Speaker labels change after reconnecting:** Labels are session-local and are
184
+ not biometric identities.
185
+ - **Streaming parameters fail validation:** Start with the configuration above.
186
+ The ASR and diarization chunk geometry must remain aligned; do not tune each
187
+ model independently.