TF Latent Preview (PCA)
See the structure edits act on, for almost free
- levels
- palette_from
- pipeline
- images
TF Decode Levels gives you the pretty pictures, but if you want to understand what the edit nodes are actually operating on, TF Latent Preview is the node you'll stare at. It renders the raw token grid as a PCA false-color image - each token's DINOv2 feature vector projected down to three RGB-ish dimensions - and what you see is the region structure of the latent itself, not what that structure looks like as pixels. This is the layer where a feature edit or a shape edit happens, so seeing it directly is how you predict what an edit will do.
The differences from decoding are the point. First, it's cheap: no ViT-XL decoder pass, just a PCA projection, so previewing all four levels costs a rounding error next to decoding them. On an 8 GB card where decoding all four levels means cutting corners, this is the preview that still fits. Second, it shows you something decoding hides. Two tokens that look like similar texture in the decoded RGB might be far apart in feature space, and the edit tools don't care about pixels at all - they move feature vectors around. When the README says a region map clusters tokens "by cosine similarity," this PCA view is what that clustering looks like: patches of near-constant color are the semantic regions, and the boundaries between them are where edits actually bite.
Inputs mirror TF Decode Levels closely: which picks all levels, the final one, or a named level; size is the output width (rounded so each token is a whole number of pixels - 512 on a 16×16 grid is 32 pixels per token); label_levels and sheet_layout behave exactly as they do on the decode node, contact sheet being the default that keeps all four levels visible at once. level_override stays at -1 for any released checkpoint. The output is a single images IMAGE.
The one optional input that's genuinely worth knowing is palette_from. PCA colors are fitted to whatever you're previewing, so two trajectories previewed separately get colored on different axes and you can't compare them by eye. Wire a second trajectory into palette_from and both are fitted jointly, on the same axes, which is exactly what you want when comparing a before and after. And pipeline is, as everywhere in this pack, only needed for trajectories loaded from disk via TF Load Levels - otherwise the trajectory carries its own.
Where people get caught: because it's cheap, it's tempting to treat this as the "real" preview and skip decoding. It's a map of the territory, not the territory - if you want to judge what the image will look like, decode. If you want to know whether an edit landed where you think, this shows you the structure, and TF Compare Levels shows you numerically what moved.
Install
Pack-wide facts, same as its siblings: Manager → search Trajectory Forcing, or git clone https://github.com/korayulusan/ComfyUI-TrajectoryForcing into custom_nodes/. The pack runs JAX inside ComfyUI and generally needs its own Python 3.11 venv on CUDA 12; requirements.txt is empty on purpose, install.py adds the JAX stack or declines with a reason. When it declines, follow the README's env/setup.sh route. For a quick health check:
cd ComfyUI/custom_nodes/ComfyUI-TrajectoryForcing
python -m tf_nodes.doctor
Wire a TF Region Map in alongside this preview and the two views line up - same structure, one as PCA color and one as numbered clusters - which is the easiest way to learn to read either.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| levels | TF_LEVELS | — | |
| which | COMBO | Which levels to render. Naming a level here replaces the old mode-plus-number pair, which left a number that did nothing in two of its three modes. | |
| size | INT | 51264–2048 | Approximate output width; rounded so each token is a whole number of pixels. |
| label_levels | BOOLEAN | true | — |
| sheet_layout | COMBO | 'contact sheet' stitches the level tiles into one image -- a row up to six, a near-square grid beyond -- so they can be seen at once. 'separate frames' returns a batch instead, which ComfyUI shows one at a time but which SaveImage can write as one file each. | |
| level_override | INT | -1-1–15 | -1 (auto) follows the dropdown above. Set a level number only for a model with more than 4 levels, which no released checkpoint has. It wins over the dropdown when set. |
| palette_fromopt | TF_LEVELS | Fit the PCA colours jointly with this trajectory too, so two images being compared are coloured on the same axes. | |
| pipelineopt | TF_PIPELINE | Usually unnecessary: the trajectory carries the pipeline that made it. Wire it for a trajectory from TF Load Levels. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |