Nemotron ASR Transcribe
Point it at an AUDIO wire, get words back
- audio
- transcription
Transcription is the least glamorous job in ComfyUI and that is exactly why it's useful. You have a clip and you want the words out of it: a prompt you spoke instead of typed, captions for a Wan or LTX render, a subtitle track, a label for an audio dataset. ComfyUI never really shipped a first-class answer. A user on r/comfyui asking in October 2025 whether there were "any ComfyUI nodes or workflows for S2T models like Whisper" got one reply telling them to go search Manager - that is the honest state of speech-to-text in this ecosystem. Whisper wrappers, plus whatever the TTS packs bolted on the side.
Nemotron ASR Transcribe is the plain one, and the one you'll actually use. AUDIO in, STRING out, text printed right on the node.
The one thing to understand before anything else
This node does not contain a model. It's a client for NeMo-Speech.cpp, a separate server you run yourself that serves NVIDIA's Nemotron ASR - a 0.6B streaming recognition model shipped as a GGUF (the tooltip's example id is .nemotron-3.5-asr-streaming-0.6b.q8_0.gguf). Think llama.cpp's shape, but for speech: the weights live in a small C++ process and your UI stays thin. Default address is http://127.0.0.1:8080, and the pack never starts or stops that server. You do, before you queue.
No API key, no per-call billing, nothing leaves your machine. And a 0.6B q8 model is a few hundred megabytes, not a few gigabytes - the ASR step is the cheap part of whatever you're building, which is the general pattern with audio: the voice tools are cheap, the video they attach to is not.
How it works
The node takes a ComfyUI AUDIO dict - {"waveform": Tensor[B, C, N] float32 in [-1,1], "sample_rate": int} - and converts it in memory to 16-bit mono WAV using numpy and the stdlib wave module. mono mixes the channels down, resample_to optionally resamples. Then it POSTs the WAV as multipart form data to /v1/audio/transcriptions on your server, the OpenAI-compatible shape (model, response_format=json, plus language and prompt when you've set them), and reads text out of the JSON reply.
If model is empty, the node hits /v1/models first and picks the first entry advertising a transcription capability. That's why blank is the sane default.
And if you read node code before installing - in this ecosystem you should - this client is stdlib urllib in five short files. It talks to the URL you type and nowhere else.
The inputs that matter
audio- the wire. LoadAudio, RecordAudio, or anything else that emits AUDIO.language- defaults toEnglish (en-US)since v1.2.0, and you should leave it there unless you know better.(auto-detect)is the option that gives you a junk prefix likeKal-helloon short clips.model- leave empty. It's the manual override for when auto-detect picks wrong.prompt- optional text to bias the vocabulary. Names, jargon, product names. The setting people forget exists, then complain about butchering proper nouns.resample_to-0sends at the native rate.16000is the safe choice for long recordings: smaller upload, and it matches what the model wants anyway.
The output
One output: transcription, a STRING, plus an inline text preview rendered on the node itself (the same widget core's PreviewText uses). Because it's a plain STRING you can wire it into Preview Text to read it, a save-text node to keep it, or CLIP Text Encode if you want to speak your prompt instead of typing it.
Install
ComfyUI Manager, search comfyui_nemotron_asr, install, restart. Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/Rakeshcool/comfyui_nemotron_asr
Restart ComfyUI. No extra packages needed for this node.
Then start the ASR server yourself and prove it's alive before you blame the node:
curl -s http://127.0.0.1:8080/health
curl -s http://127.0.0.1:8080/v1/models
Where it bites
"Cannot reach Nemotron ASR server." The server isn't running, or it's on another port. Nine times out of ten, this is it.
"No model found on Nemotron ASR server." The server is up but has nothing loaded, so enter the model id in the model field.
Batching silently doesn't work. The converter takes the first item of the batch dimension and ignores the rest, with no warning. Feed it four clips, get one transcript - for a folder, run them a clip at a time.
Long audio can time out. The request timeout is 120 seconds and it isn't exposed as an input. A 30-minute podcast on a CPU-only box may not finish inside it. resample_to=16000 helps; splitting the file helps more.
Garbled output usually means the wrong language, not a broken model. Set language explicitly before you go looking for other causes.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | AUDIO to transcribe (from LoadAudio, RecordAudio, etc.). | |
| server_url | STRING | http://127.0.0.1:8080 | Base URL of the NeMo-Speech.cpp server. |
| model | STRING | Model id, e.g. .nemotron-3.5-asr-streaming-0.6b.q8_0.gguf. Leave empty to auto-detect from /v1/models. | |
| language | COMBO | English (en-US) | Languages supported by Nemotron ASR. '(auto-detect)' lets the server decide, which can emit a leading artifact like 'Kal-' on short clips. |
| prompt | STRING | Optional prompt to bias transcription vocabulary. | |
| resample_to | INT | 00–192000 | Resample audio before upload; 0 = send at native sample rate. 16000 is a safe choice for ASR. |
| mono | BOOLEAN | true | Mix down to mono before upload. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| transcription | STRING | — |