CLIP Text Encode (Batch)
Give Every Latent Its Own Text
- clip
- texts
- CONDITIONING
This is the node the whole pack exists for, and it's the answer to a question you've probably already asked: how do I give different prompts to different frames (or different images in one batch)?
Default ComfyUI is blunt here. The regular CLIP Text Encode turns one prompt into one conditioning, and that conditioning gets applied to every latent in the batch - so all 16 AnimateDiff frames get the same text, all 8 images in a batch get the same text. This node breaks that wall. Feed it N strings and it returns a single CONDITIONING whose batch dimension is N: latent #3 gets prompt #3, frame #7 gets prompt #7. If you've ever wanted a video that starts as a cat and becomes a dog, or a prompt sweep without re-queueing a dozen times, this is the ComfyUI-native way to do it - the equivalent of A1111's alternating prompts, minus the UI bloat.
How it actually works (read from the source, because the README is just a screenshot). For each string it does the normal tokenize + encode_from_tokens with the pooled output. Then comes the clever part. The per-prompt conditionings are each [1, tokens, 768], and token counts differ - one prompt might fill 77 tokens, another only 12. To concatenate them along the batch axis they must have equal token length, so the node computes the LCM of all token counts and repeats each conditioning along the token axis until they line up. The code comments why that's safe: attn(q, [k]*n, [v]*n) == attn(q, k, v) - duplicate key/value pairs don't change softmax attention, they just double its weight. Then it concatenates everything along the batch axis and does the same for the pooled outputs, so SDXL-style models that read pooled_output also get a per-latent vector.
The inputs that matter. Two, both required:
clip- the CLIP model from your checkpoint or a dedicated CLIP loader.texts- a BATCH_STRING, i.e. a Python list of strings. You get that from this pack's Batch String node, not from typing into a widget.
Output is a single CONDITIONING. Wire it into a KSampler exactly like the normal encode node.
The wiring recipe:
Batch String (add N inputs, type N prompts)
└─> CLIP Text Encode (Batch)
└─> KSampler + Empty Latent Image with batch size = N
Where people get burned:
- The string count must equal the latent batch size. N prompts with a batch of 8 latents is a shape error at best, garbage at worst. Count them like your GPU's life depends on it, because it does (your VRAM).
- The LCM padding can blow up. One 77-token prompt and one 12-token prompt gives LCM(77, 12) = 924 tokens for the short one, and attention scales with sequence length. Keep prompts roughly similar in length, ideally near 77, or memory usage creeps up fast.
- It's not a drop-in for the built-in node. It only eats BATCH_STRING, so you can't drag a text widget into it. That's what Batch String is for.
- This pack is frozen (last commit March 2024) but dependency-free and still works - laksjdjf, the author, also made the regional-conditioning Attention Couple nodes, so this is conditioning-nerd territory done right.
Install. ComfyUI Manager → search "Batch-Condition-ComfyUI" → install → restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/laksjdjf/Batch-Condition-ComfyUI
# restart ComfyUI
No requirements.txt, no model downloads, torch only. You'll find the node under the conditioning_batch menu folder. If you're doing per-frame prompt videos, this is the least painful tool for it - which is exactly what ComfyUI's ecosystem is for when the form-based UIs run out of buttons.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| clip | CLIP | — | |
| texts | BATCH_STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| CONDITIONING | CONDITIONING | — |