CLIPTextEncodeWithStats
See exactly how many tokens your prompt actually ate
- clip
- CONDITIONING
- STRING
- IMAGE
Ever written a prompt you were sure was fine, gotten output that ignored half of it, and had no way to prove why? That's what CLIPTextEncodeWithStats is for. It's a drop-in swap for the stock CLIPTextEncode node that tells you - in plain numbers - how many tokens your prompt actually split into, which batch each chunk landed in, and what the tokenizer thought each word weighed. Same inputs, same conditioning out, but you finally get to see the sausage being made.
How it works
The stock node keeps the tokenization invisible. This one grabs the tokenized output (it calls the CLIP tokenizer with word IDs, the same path the normal node uses under the hood) and counts what's actually there. You get a per-batch breakdown: how many tokens, how many words, the weighted total per word, and the text that landed in that chunk. All of it is built on ComfyUI's own tokenizer code, so what you're reading is the real thing - not a guess at what the model saw.
Then it does something charmingly janky: it renders that table as an image using a bundled monospace font and hands it to you as an IMAGE output. Wire that into a PreviewImage node and the stats appear in your UI every run. The author will happily tell you it's an ugly solution that works, and honestly that's the whole vibe of this node.
The inputs and outputs that matter
- text - your prompt, multiline, exactly like the stock node.
- clip - whatever CLIP model you're using (SD 1.5, SDXL, Illustrious, Pony, pick your poison).
Three outputs, and the first one is why you can swap this in without breaking your workflow:
- CONDITIONING - identical to what CLIPTextEncode emits (it even returns the pooled output), so it plugs straight into your sampler.
- STRING - the same statistics as JSON, if you want to pipe them somewhere or log them.
- IMAGE - the rendered stats table. Send it to PreviewImage.
Why you actually want this
The 77-token CLIP chunking is still real for the SD 1.5 / SDXL family - Illustrious, NoobAI, Pony, all of them. When your prompt runs past the boundary, the tokenizer splits it into multiple batches, and what lands in batch two gets weaker conditioning than batch one. This node shows you the split: if you see "total" row tokens way past 77, you now know exactly which words fell off the edge and can reorder or cut. That's the difference between guessing at a weak prompt and knowing.
One honest caveat: this is built around the SD 1.x/SDXL tokenizer path, so the "batch" concept it measures is that world's concept. On newer LLM-encoded models (Flux-style T5, or anything that wraps your prompt in a chat template) there's no 77-token boundary to debug against, and the stats get less interesting fast. Use it where the limit actually exists.
Also worth knowing: it can't update live. The litegraph frontend won't compute the table as you type, so the stats refresh when you hit Queue. That's the "not capable of live calculation" limitation the author flags - run it once, read the table, adjust.
Installing it
This is one of four nodes in the ULTools for ComfyUI pack (jkrauss82/ultools-comfyui), a hobby project by jkrauss82. Install the whole pack once and you get all of them. Easiest via ComfyUI Manager: search "ULTools for ComfyUI". Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/jkrauss82/ultools-comfyui
cd ultools-comfyui
pip install -r requirements.txt # pandas, numpy, piexif
Then restart ComfyUI. That's it - no model downloads, no weights, no heavy dependencies. It's a small, honest little tool from a pack the author himself calls a hobby project, so don't expect rapid fixes - but for "why did my prompt half-work," it answers the question instantly.
If you're on SD 1.5 or SDXL and you've ever stared at a prompt wondering where it went wrong, this is the easiest diagnostic node you'll add all week. Swap it in, read the table, swap it back out - or just leave it, since the conditioning output is identical anyway.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — | |
| clip | CLIP | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| CONDITIONING | CONDITIONING | — |
| STRING | STRING | — |
| IMAGE | IMAGE | — |