TBDub Runtime
The node that decides which Python does the work
- runtime
What it's for
Every other ComfyUI pack runs inside ComfyUI's Python environment and takes its chances with your dependency pile. TBDub does the opposite: generation happens in a separate Python environment - the "runtime" - that a human registered with absolute paths in a config file. The node is deliberately kept free of CUDA, models and upstream code on import.
Which means a workflow can never choose an executable. It can only name a runtime. TBDub Runtime is how it names one, and it's where you make the one decision that actually changes how a job behaves on your machine: what stays in VRAM.
Wire its output into TBDub Generate or TBDub Preprocess. Note that TBDub Doctor does not take this wire - it has its own runtime_id dropdown, so you pick the same runtime twice.
Inputs and outputs
runtime_id - a dropdown built from your tbdub.runtimes.json. Every entry in that file is a full runtime: the venv's python, the pinned upstream_dir, the models_dir, ffmpeg and ffprobe paths, plus timeout_minutes and per-runtime limits (20 s of speech, 1920×1080, 750 source frames, 1 GiB source file by default).
Then the two optional enums that matter.
memory_mode - runtime default just uses whatever the config says. stream keeps the 12.6 GB Student DiT in its file and reads each layer's BF16 weights right before that layer runs. It's the mode the author measured, it costs roughly 11 GiB less GPU/system memory, and it costs speed: about 5.5 seconds per DiT call on the test machine. resident is the upstream default - everything parked on the GPU for the whole job, about 11.7 GiB more than stream. If your card swallows it, resident is faster; if you're already running a browser, stream is what keeps the job from being refused.
decode_mode - official is the upstream VAE decode: needs several GiB more during the final decode. In the one full job that tried it, the process passed 20.5 GiB and the memory guard killed it. frame_chunks runs the decoder's 3D convolutions one frame at a time, about half the decode memory - and changes the output. It is not bit-identical: on seeded random latents at 256–320 px the max difference was around 4 levels out of 255 with a mean of about 0.1, and 512×512 was never measured. The author ships the example workflow using frame_chunks anyway, which tells you what a 64 GB workstation considers realistic.
My read: if you have headroom, official is the honest default because it's the reference output. If your box is marginal, frame_chunks is the difference between a finished video and an error, and honestly nobody is going to spot four levels on a dubbed mouth.
Output is a single TBDUB_RUNTIME value carrying the runtime id plus the two modes.
Install
Same as the rest of the pack - Manager (search TBDub) or:
cd ComfyUI/custom_nodes && git clone https://github.com/hiroki-abe-58/ComfyUI-TBDub
But this node is useless without the runtime. Build the venv (Python 3.10 + CUDA torch + the upstream checkout at the pinned commit + the weights, per docs/SETUP.md), then:
cp ComfyUI/custom_nodes/ComfyUI-TBDub/examples/tbdub.runtimes.example.json \
ComfyUI/user/tbdub.runtimes.json
Edit the absolute paths, restart ComfyUI.
Where people get burned
The dropdown is empty or says "(no runtime configured)." The config file isn't in a location ComfyUI checks. It lives at the root of the ComfyUI user directory (ComfyUI/user/tbdub.runtimes.json) - outside the per-user folders the web API can serve - or at COMFYUI_TBDUB_CONFIG.
The config is strict, and it will reject your typo. Unknown keys fail the file, paths must be absolute and may not contain .., runtime ids have a fixed character set, and env accepts only CUDA_VISIBLE_DEVICES and PYTORCH_CUDA_ALLOC_CONF. There's no silent-ignore path here, which is annoying for five minutes and a gift for the next five years.
"memory admission refused." The pack has a memory guard: a job only starts if the predicted commit charge fits under 95% of the limit minus a 2 GiB margin with 8 GiB of RAM available, and it gets stopped if the commit sits at 95% for five seconds. If you hit this, stream plus frame_chunks is the sane first move, and the thresholds are tunable in the memory_guard block of the config.
Changing memory_mode in the node works, but don't expect it to apply to jobs you already queued. The value rides along with the graph node into that job; a job that already started keeps the mode it started with.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| runtime_id | COMBO | Runtimes come from tbdub.runtimes.json (administrator config), never from the workflow. | |
| memory_modeopt | COMBO | runtime default | stream: the 12.6 GB Student DiT stays in its file and each layer is read right before it runs (patch P2; slower, about 11 GiB less GPU/system memory). resident: the upstream default, everything on the GPU. 'runtime default' uses the runtime's configured mode. |
| decode_modeopt | COMBO | official | official: the upstream VAE decode (needs several GiB more memory during the final decode; one run passed 20.5 GiB process memory before it was stopped). frame_chunks (opt-in): the decoder's 3D convolutions run one frame at a time (patch P4, about half the decode memory); changes the output, NOT bit-identical to the original decoder (on random latents at 256-320 px: max about 4 levels of 255, mean about 0.1; 512x512 not measured). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| runtime | TBDUB_RUNTIME | — |