LatentOperationSELU
The self-normalizing activation that mostly normalizes for you
- op
SELU - Scaled Exponential Linear Unit - is the activation function from the 2017 "Self-Normalizing Neural Networks" paper. Its party trick: under the right conditions it pushes activations toward zero mean and unit variance by itself, which is why it was pitched as a way to train deep nets without batch normalization. Applied to a latent, what you get is ELU with a fixed gain: negatives decay smoothly toward a floor instead of dying, positives pass through scaled. It's a specific flavor of "gentle nonlinear edit" - and it has a naming trap hiding inside it.
The mechanism
def selu(latent, **kwargs):
return torch.nn.functional.selu(latent * alpha)
One input: alpha (FLOAT, default 1.0), the input gain shared by every activation node in this pack. Here's the trap: PyTorch's F.selu already has its own hardcoded parameters - scale = 1.0507... and alpha = 1.67326... - baked in. The alpha input on this node does not control the ELU's alpha; it multiplies the latent before the built-in SELU runs. So the thing you can tune is the input gain, not the shape of the curve. Set alpha = 1 and you get canonical SELU; crank it and you're feeding an amplified latent into a fixed-shape function. That's worth knowing before you go hunting for the "leak parameter" that doesn't exist.
Why you'd reach for it
SELU sits in a useful spot among the pack's activations. Compared to LatentOperationReLU, it doesn't zero the negative half of the distribution - negatives compress smoothly toward the SELU floor (around −1.758 for unit input), so information survives. Compared to LatentOperationLeakyReLU, the negative branch is a curve, not a straight leak. And unlike LatentOperationNormalize, which rescales by computing statistics, SELU approximately keeps distributions self-similar by construction - that's the "self-normalizing" property, and it's why SELU-on-a-latent tends to feel like a gentler, more stable edit than a hard rectification. If you want an activation flavor that won't shove your latent's distribution off-kilter, this is one of the safer ones. If you want the exact statistics guaranteed, pair it with one of the pack's normalize nodes afterward.
The op output
Output is op, type LATENT_OPERATION - a deferred closure, as with every node in this pack. ComfyUI-latent-ops builds operations and ships no apply node, so you need a consumer of LATENT_OPERATION (Sonar's SonarApplyLatentOperationCFG is the known one) or your own apply node. Plugging op straight into a VAE Decode gets you a type mismatch - the pack's universal first trap, and it's by design.
Install
Same drill. ComfyUI Manager → search ComfyUI-latent-ops, or git clone https://github.com/hnmr293/ComfyUI-latent-ops into ComfyUI/custom_nodes, then restart. No requirements.txt, no model downloads, plain PyTorch. It's hnmr293's private workbench (sd-webui-cutoff, llul), essentially unmarketed, so latent_ops/functions.py is your documentation. Everything lives under hnmr/latent_ops.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| alpha | FLOAT | 1.0000-10000–10000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| op | LATENT_OPERATION | — |