Nodes/comfyui_nemotron_asr/Nemotron ASR Streaming (Realtime)
ComfyUI Node

Nemotron ASR Streaming (Realtime)

Words appearing while it's still listening

By Rakeshcool·Created a day ago·Updated a day ago· 0
Nemotron ASR Streaming (Realtime)
  • audio
  • transcription
server_urlhttp://127.0.0.1:8080
languageEnglish (en-US)
chunk_ms100
show_live_previewtrue
use_model_ratetrue

This is the node that explains why the model is called what it's called. Nemotron ASR's headline feature isn't accuracy, it's that it recognises speech incrementally - it emits words as audio arrives instead of waiting for the end of the utterance. This node is the thinnest way to see that from inside ComfyUI: text accumulates on the node while the audio is still being pushed.

Caveat first, because it decides whether you want this node at all: if all you have is a finished file and you just want the transcript, use Nemotron ASR Transcribe instead. It's simpler and it doesn't care about WebSockets. Streaming earns its keep when the audio is arriving over time - a live microphone, a growing buffer, a pipeline where you want to see progress instead of watching a spinner.

How it works

The plain Transcribe node does a one-shot multipart POST. This one opens a WebSocket instead, at /v1/audio/transcriptions/realtime, and speaks the server's little event protocol:

  • server sends session.created on connect
  • the node sends one session.update with sample_rate, language, automatic_punctuation (on) and word_timestamps (off)
  • audio goes out as raw binary little-endian PCM16 frames - no WAV container, just samples
  • input_audio_buffer.commit marks the end of the utterance
  • the server streams conversation.item.input_audio_transcription.delta events (the partials you watch appear) and finishes with ...completed, which is your final text

chunk_ms is how much audio each frame carries: at 16 kHz, 100 ms is 3,200 bytes. So use_model_rate on means the clip is resampled to the model's 16 kHz input rate before streaming, and chunk_ms of 20 to 1000 sets how finely it's sliced.

The transport is aiohttp, which the ComfyUI server already ships - so, again, nothing new to pip install.

One honest note about mechanism, because it's easy to assume the wrong thing. This node pushes a file as fast as it can - a 2 ms yield between chunks, then commit, then it waits. It is not playing your clip in real time, and it isn't faster than the batch node either. What you get is the model's incremental path and a live progress display. On a pre-recorded file that's a nice-to-have. On a stream, it's the whole point.

Inputs

  • audio - the wire, same as the other nodes.
  • language - defaults to English (en-US). (auto-detect) can hand you a leading artifact like Kal- on short clips, and this node's default exists to spare you that.
  • chunk_ms - 100 by default. Leave it unless you're chasing latency.
  • show_live_preview - on by default. This is the setting that draws the partial text on the node while the session runs; turn it off if you only care about the final string.
  • use_model_rate - on, and it should be. Resamples to 16 kHz, which is what the model wants. Turn it off only if you have a reason to stream at the native rate.
  • server_url - the base HTTP URL. It gets converted to ws:// (or wss:// from https://) internally.

There is no model input on this node, and that's worth knowing: it always auto-detects from /v1/models. If your server has more than one transcription model loaded, you can't pin which one streaming uses. Batch mode can; streaming can't.

Output and installation

transcription - the final committed transcript, as a STRING, plus the inline preview. Wire it anywhere text goes: CLIP Text Encode, a save-text node, Preview Text.

Install is the same as the rest of the pack. Manager → search comfyui_nemotron_asr → restart, or:

cd ComfyUI/custom_nodes
git clone https://github.com/Rakeshcool/comfyui_nemotron_asr

And start NeMo-Speech.cpp yourself first - these nodes never start it.

When it fails

Cannot open realtime WebSocket to ... means the server is up enough to answer health checks but isn't serving the realtime endpoint - an older build, or a server started without the streaming model. Batch mode may still work, which is why this is confusing if you only test the plain node.

Timed out waiting for 'session.updated' - the connection opened but the server never acknowledged the session config. Check that the WebSocket URL didn't get eaten by a proxy.

No final transcript within ...s - the utterance committed and the server never sent completed. The error message includes the last partials it saw, so read them: full text but no final event is a server-side hiccup, empty partials means the audio never arrived in a form it liked. Check use_model_rate and the sample rate before you start rewriting the workflow.

Categoryaudio

Inputs (6)

NameTypeDefaultDescription
audioAUDIOAUDIO to transcribe (from LoadAudio, RecordAudio, etc.).
server_urlSTRINGhttp://127.0.0.1:8080Base URL of the NeMo-Speech.cpp server.
languageCOMBOEnglish (en-US)Languages supported by Nemotron ASR. '(auto-detect)' lets the server decide.
chunk_msINT10020–1000Size of the PCM chunks streamed to the server, in milliseconds.
show_live_previewBOOLEANtrueShow the partial transcription live on the node while streaming.
use_model_rateBOOLEANtrueResample to 16 kHz (the model's input rate) before streaming.

Outputs (1)

NameTypeDescription
transcriptionSTRING