H3 MS GPU Set
Aiming H3 MultiStream at the Right Cards
- gpus
Two nodes in this pack are the ones that actually use your GPUs - H3 MultiStream (the transformer split) and H3 MS VAE Split Decode. Left to themselves, both grab every visible GPU. That's the right default on a dedicated render box and the wrong one on the workstation where cuda:1 is your display card, or where the third slot is running a second ComfyUI for a client job. H3 MS GPU Set is how you tell both of them which cards they're allowed to touch, in what order, and roughly how much of each to expect.
It's a small node and it computes nothing. But if you have more than two cards, or any card you care about keeping free, this is the one you wire up before you start complaining that the split is slower than it should be.
What it does, exactly
The node validates your strings and packages them into a single H3MS_GPUS value. The real work happens the first time a consumer runs: that value gets resolved against the model's own device into a rank plan, and the plan gets logged as a [GPUs] line in the console.
Rank 0 is always the GPU the model already lives on - whatever Select Model Device or Select VAE Device pointed at. Everything you list is the order of the ranks after that. That's the rule to hold onto, because it's what makes gpus behave differently from how you'd read it.
The inputs you'll actually touch
gpus takes auto (every visible CUDA device) or a list like 0,1,3. It's tolerant about formatting - cuda:0 works, semicolons work - but it will not tolerate a card that doesn't exist.
exclude is the more useful one in practice. 2 there means "not that card," and it's how you keep a card driving your monitors out of the split.
shares is relative speed per selected GPU, same order as gpus (or by index when you're on auto), e.g. 1,1,0.7 for a power-capped card. Note the asymmetry the tooltip is honest about: the transformer split sizes each GPU's attention heads and tokens by its share, but the VAE split divides its chunks evenly. So shares will balance sampling and do nothing for your decode.
min_free_vram_gb skips GPUs that don't have the room when the plan is made - once, at first use, not per step. It never skips the model's own GPU.
max_gpus (1–8) is the cap. Set it to 1 and the model runs unsplit while the caches still work - genuinely handy as an A/B switch when you're trying to work out whether the split is helping on your hardware.
The single output is gpus (type H3MS_GPUS). Wire it into H3 MultiStream's optional gpus input and/or H3 MS VAE Split Decode's optional gpus input. One GPU Set node can feed both; there's no reason to run two.
H3 MS GPU Set (gpus) -> H3 MultiStream (gpus)
-> H3 MS VAE Split Decode (gpus)
If you skip this node entirely, both consumers fall back to every visible GPU, or to their own second_gpu integer - which is ignored the moment a GPU set is connected, so don't set both and wonder which won.
Installing it
Same as the rest of the pack. ComfyUI Manager, search ComfyUI-H3-MultiStream, or:
cd ComfyUI/custom_nodes
git clone https://github.com/martonsagi/Comfy-H3-MultiStream ComfyUI-H3-MultiStream
Restart ComfyUI. The node lands under advanced/model. There are no Python dependencies to install - the pack's pyproject.toml declares an empty dependency list and everything it imports already ships with ComfyUI. It does require ComfyUI 0.35.0 or newer, Linux for the VAE split, and NVIDIA CUDA cards.
Where it goes wrong
The validation errors are unusually specific, which is a favour:
cuda:7 does not exist: 4 CUDA device(s) visible (CUDA_VISIBLE_DEVICES / --cuda-device limit what ComfyUI sees)- ComfyUI only sees what its own launch flags andCUDA_VISIBLE_DEVICESexposed, so renumbering can bite you.gpus: cuda:2 listed twice- duplicates are rejected rather than silently deduped.shares: 3 value(s) for 2 GPU(s) (cuda:0, cuda:1)- the count is measured against your selected GPUs, afterexclude, not against everything you typed ingpus. That's the one people trip over.
Two silent-ish behaviours worth knowing. Excluding the model's own GPU is an error, not a quiet fix - rank 0 is not negotiable. And a too-aggressive min_free_vram_gb doesn't complain; it just drops cards until one is left, and then you're running unsplit with no obvious symptom beyond a slow render. The [GPUs] log line tells you what was actually chosen, including anything dropped and why. Read it once after you change anything here.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| gpus | STRING | auto | auto = every visible CUDA GPU, or a list such as 0,1,3. The model's own GPU always takes part as rank 0; the others follow in this order. |
| exclude | STRING | GPUs to leave out, e.g. 2 for a card reserved for another service. | |
| shares | STRING | Optional relative speed per selected GPU (same order as gpus, or by index for auto), e.g. 1,1,0.7 for a slower or power-capped card. H3 MultiStream sizes each GPU's attention heads and tokens by it; the VAE split divides evenly. | |
| min_free_vram_gb | FLOAT | 0.00–1024 | Skip GPUs with less free VRAM than this when the plan is made (first use). Never skips the model's own GPU. 0 = no check. |
| max_gpus | INT | 81–8 | Upper limit on GPUs used. 1 = run unsplit (the caches still work). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| gpus | H3MS_GPUS | — |