StyleGAN Direction Sweep
Render the filmstrip before you commit
- stylegan_model
- stylegan_latent
- directions
- IMAGE
Here's the awkward truth about unsupervised direction discovery: neither GANSpace nor SeFa tells you what the directions do. You get ten anonymous axes and no labels. The sane response is to render each candidate at a range of strengths and look at it, and that's exactly what this node does - one node, one component, a strip of images from min_strength to max_strength so you can see where an edit starts working and where it falls apart.
It's the single most useful node in the pack for actual work, and it's the one people skip, then spend an hour tuning ApplyStyleGANDirection blind.
How it works
You give it the model, a latent, and a directions bundle. It picks out one direction, applies the same layer mask you'd apply in the apply node, and then renders steps frames - walking the strength linearly from min_strength to max_strength and synthesising the whole face at each step. Straight through the generator, no sampling schedule, so each frame is a full forward pass. On a 3090 that's milliseconds per frame; the pack's own README measures bulk generation at 64 images/sec before ComfyUI's tensor-to-PIL preview path bottlenecks it.
Output is a single IMAGE batch, one frame per step, ordered by strength. Preview it, save it, or drag it to a Grid Image style node - you're looking for the frame where the effect is clear and the face is still a face.
One behaviour worth knowing because it's genuinely helpful: the node registers the per-frame latents against the output image tensor, so if you save the sweep with the core SaveImage node, each frame in the strip gets its own exact latent embedded in the PNG. You can eyeball a strip, pull out the frame you liked, and load it straight back with LoadStyleGANLatentImg - no seed hunting.
What you set
stylegan_model, stylegan_latent, directions, component_index - same meaning as in ApplyStyleGANDirection, and clamped the same way, so an out-of-range index silently gives you the last component.
Then the range: min_strength (default -3), max_strength (default 3), steps (default 7, min 2, max 64). The defaults assume a GANSpace bundle's one-sigma scaling. If you're sweeping SeFa components, widen it - something like -15 to 15 - or you'll render seven nearly identical frames and conclude the direction does nothing. There's nothing stopping you from putting min above max; you just get the strip in reverse.
mask is the same seven-option layer mask: total (0xFFFF), coarse (0xFF00), mid (0x0FF0), fine (0x00FF), plus the three interleaved alt patterns. Coarse for structure and expression, fine for texture and color. Sweeping the same component under two different masks is a legitimate, quick way to find out how localised an axis is.
noise_mode is the one optional input, const or random, defaulting to const. Leave it on const while you evaluate a direction - random noise per step turns a clean comparison into a jitter test, since you can't tell whether a change in the freckles came from your strength or the noise draw.
The workflow it slots into
Discover → sweep → apply. Read the strip, note which component and which strength gave you the edit you want, then delete the sweep and wire ApplyStyleGANDirection with those exact numbers. Two sweeps in series - one for the component hunt, one to fine-tune the knee - is normal. The pack's README example does exactly this: BroGANv1.2.0, GANSpace component_02, coarse mask, sweep 0→9 in 4 steps, and you can watch the smile edit go from subtle to clean to visibly ghosted at +9.
Install
Manager → search ComfyUI-StyleGan (publisher dflfd), or clone into ComfyUI/custom_nodes and restart:
cd ComfyUI/custom_nodes
git clone https://github.com/dfl/ComfyUI-StyleGan
Checkpoints go in ComfyUI/models/stylegan/ (.pkl gets cached to .safetensors on first load). This node renders, so unlike the discovery nodes it does need the runtime-compiled CUDA kernels - CUDA Toolkit, ninja, and MSVC or GCC, with the first run spending 30–60s on Setting up PyTorch plugin ... Done. If that build fails, a sweep is where you'll notice first: discovery works, rendering doesn't.
Where people get burned
- Seven identical frames. Wrong strength scale for the discovery method. GANSpace ±3, SeFa ±15.
- Only the first image in your batch changes. The sweep takes
stylegan_latent[0:1]- one latent. Generating a batch of eight and sweeping won't give you eight strips. - Ghosting past the knee. Double features, hair artifacts. That's the direction running out of validity, not a bug. The README's example degrades visibly past 7–8.
- Apple Silicon, StyleGAN3. The README warns synthesis output can differ between PyTorch versions on MPS; a sweep that looks systematically wrong is worth a version swap before you throw the direction away.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| stylegan_model | STYLEGAN | — | |
| stylegan_latent | STYLEGAN_LATENT | — | |
| directions | STYLEGAN_DIRECTIONS | — | |
| component_index | INT | 0 | — |
| min_strength | FLOAT | -3.00-50–50 | — |
| max_strength | FLOAT | 3.00-50–50 | — |
| steps | INT | 72–64 | — |
| mask | COMBO | 7 options: total (0xFFFF), coarse (0xFF00), mid (0x0FF0), fine (0x00FF), alt1 (0xF0F0), alt2 (0x0F0F), +1 | |
| noise_modeopt | COMBO | const | 2 options: const, random |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |