Subtitle (QwenASR)
The QwenASR Subtitle node
- audio
- TEXT
- SUBTITLES
- LANUGAGE
- OUTPUT_PATH
If you've ever subtitled a video by hand, you know the job is 10% transcription and 90% sitting there nudging timestamps. This node does both halves locally: it transcribes with Qwen3-ASR, then runs a forced aligner over the audio to get word-accurate timestamps, and hands you clean, split-up subtitle lines - optionally written straight to an .srt or .txt file. Same author, same pack, same install as the plain ASR (QwenASR) node - this one just does more of the subtitle choreography for you.
It's the node I'd actually reach for when the end goal is captions rather than "give me the text." Podcasts, YouTube dubs, video with dialogue - you wire it once, get a timestamped script, and either eyeball the lines or save the SRT and move on. There's no separate model download drama either: the aligner (Qwen3-ForcedAligner-0.6B) is another local model cached under ComfyUI/models/Qwen3-ASR/ and auto-fetched on first use.
How it works
The pipeline is: transcribe with timestamps → let the forced aligner refine word boundaries → group the tokens into subtitle lines. The grouping is where the subtitles get their shape, and it's driven by a few knobs. Lines are split when the text hits a sentence-ending punctuation mark (handles CJK punctuation too - . !? and friends), when a silence gap exceeds max_gap_sec, or when a line would exceed max_chars. The default split_mode is "punctuation or pause or length," which is the balanced setting the README recommends for real subtitles; the other five modes are just the combinations of those three signals, for when you want lines to break only on pauses, or only on punctuation.
Two details worth knowing. First, the SUBTITLES output is always the timestamped lines in 12.34-56.78: text format - the output_format input only controls whether a file also gets saved. Second, CJK text is joined without spaces so Chinese subtitles don't end up with phantom gaps.
The inputs that matter
The basics are shared with the ASR node - audio, model (0.6B vs 1.7B), language, hints, precision - and then it gets interesting:
- forced_aligner -
Qwen/Qwen3-ForcedAligner-0.6Bby default, orNoneto skip timestamps entirely. This is the switch that decides whether you get a transcript or a subtitle file. - split_mode / max_gap_sec / max_chars - the sentence-splitting controls above.
max_charsdefaults to 40, which reads well for most languages. - max_inference_batch_size - 32 by default. Lower this if transcription OOMs on a small GPU; it's the author's own knob for "avoid OOM."
- output_format (
none/txt/srt) and output_path - file saving only. Leaveoutput_formatonnoneand you just get strings in the graph. Setsrtwith an empty path and files land inComfyUI/output/ComfyUI-QwenASR/with a timestamped name.
Outputs: TEXT (the full transcript), SUBTITLES (the timestamped lines), LANUGAGE (yes, that typo is in the schema - it's the detected language), and OUTPUT_PATH (the saved file, or an empty string if you didn't save one). Wire SUBTITLES to ShowText to preview the lines, or skip the file save entirely and let OUTPUT_PATH feed a downstream video-burning node.
Installing
Identical to the rest of the pack: ComfyUI Manager (search QwenASR), or:
cd ComfyUI/custom_nodes
git clone https://github.com/1038lab/ComfyUI-QwenASR.git
cd ComfyUI-QwenASR
pip install -r requirements.txt
Restart after. Note that this node pulls two models on first use - the ASR model and the aligner - so the first run's download is chunkier than the plain ASR node. Same dependency caveat applies: it needs a recent transformers>=4.57, torchaudio, and the tokenizer trio (nagisa, soynlp, DyNet38).
Common issues
- Timestamps that don't line up with the audio - community reports on release flagged that the forced aligner lags the ASR model on some languages (Hindi was a notable miss). If your language's timestamps look wrong, set
forced_alignertoNone: you lose precise cues but keep a perfectly good transcript. - OOM on long or batch audio - drop
max_inference_batch_sizetoward 8–16. Long files chunk automatically, so a slow but steady run beats a crash. - "I set srt but no file appeared" - check
output_path. Relative paths resolve against ComfyUI's output folder, andoutput_formatwon't do anything unless you've also given it somewhere to write. - First run looks frozen - it's downloading two models. Watch the console.
It's a young pack, so polish isn't guaranteed everywhere - but for turning spoken audio into actual subtitles without leaving ComfyUI, it's currently the cleanest option around.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | Audio input to transcribe. | |
| modelopt | COMBO | Qwen/Qwen3-ASR-0.6B | Choose the ASR model size. |
| precisionopt | COMBO | bf16 | Inference precision. |
| attentionopt | COMBO | auto | Attention backend override. |
| forced_aligneropt | COMBO | Qwen/Qwen3-ForcedAligner-0.6B | Forced aligner for timestamped subtitles. |
| languageopt | COMBO | auto | Force language or auto-detect. |
| hintsopt | STRING | Optional hints/keywords (names, terms) to improve recognition. | |
| output_formatopt | COMBO | none | File save format only (does not change subtitle output). |
| output_pathopt | STRING | Optional output file path (relative goes to ComfyUI output). | |
| split_modeopt | COMBO | split_by_punctuation_or_pause_or_length | Sentence splitting strategy. |
| max_gap_secopt | FLOAT | 0.60–8 | Max silence gap to keep the same sentence. |
| max_charsopt | INT | 400–200 | Optional max characters per line (0 = no limit). |
| max_inference_batch_sizeopt | INT | 321–256 | Batch size for inference/alignment to avoid OOM. |
| max_new_tokensopt | INT | 2561–2048 | Max new tokens per chunk. |
| unload_modelsopt | BOOLEAN | true | Unload cached model after inference. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| TEXT | STRING | — |
| SUBTITLES | STRING | — |
| LANUGAGE | STRING | — |
| OUTPUT_PATH | STRING | — |