Nodes/ComfyUI-latent-ops/LatentOperationSoftmax
ComfyUI Node

LatentOperationSoftmax

Turn a latent axis into probabilities, and wonder why

By hnmr293·Created about a year ago·Updated about a year ago· 2
LatentOperationSoftmax
    • op
    axis-1

    Softmax is the function that turns a row of numbers into a probability distribution: every output positive, all of them summing to 1, with a winner-take-most emphasis on the largest values. LatentOperationSoftmax runs that over one axis of your latent. And here's the honest question you should ask before using it: do you actually want your latent values to sum to 1 along an axis? Because that's a very specific, very aggressive thing to do to a compressed image representation - and it's usually not what a latent wants.

    The mechanism

    def softmax(latent, **kwargs):
        return torch.nn.functional.softmax(latent, dim=axis)
    

    One input: axis (INT, default -1) - the dimension along which the sum-to-1 constraint applies. On a 4D [batch, channels, height, width] latent, the default -1 is width, meaning every row becomes a softmax distribution across its width. axis=1 makes every channel-plane sum to 1 across the four (or sixteen) channels. Nothing else is configurable - no temperature, no alpha, no optional smoothness knob.

    What that does to a latent is severe: softmax is shift-invariant but very much scale-sensitive - it sharpens the contrast between the largest value and everything else along that axis, and the winner-take-most behavior means the non-maximum values get crushed toward zero. Combined with the sum-to-1 constraint, you're telling the decoder "along this axis, the relative dominance of the largest value is the only thing that matters." On a raw image latent, that's usually a recipe for smeared, over-emphasized output - the kind of thing that looks like a mistake until you remember you asked for it.

    So where does it legitimately belong? Softmax is a normalizing operation for scores and attention weights, not for pixel-ish data. If your workflow has already turned a latent region into something score-like - attention maps, a "which channel dominates" analysis, or a feature map you're about to treat as weights for a downstream blend - then this node is exactly the right tool, and the pack's sibling LatentOperationSoftmin (the negated mirror) covers the "minimize rather than maximize" case. On raw latents for image generation, reach for LatentOperationSigmoid (bounded, not sum-to-1) or LatentOperationNormalizeMinMax (bounded, outlier-sensitive) instead. Softmax is a scalpel for score-like data, and using it on image data is how you learn why it's a scalpel.

    The op output

    Output is op, type LATENT_OPERATION - a deferred closure, exactly like every node in hnmr293/ComfyUI-latent-ops. The pack builds operations and ships no apply node, so you need a LATENT_OPERATION consumer (Sonar's SonarApplyLatentOperationCFG is the one that exists in the wild) or your own apply node. Wire op directly into a VAE Decode and you get a type mismatch - the pack's universal first trap, by design.

    Install

    The standard drill. ComfyUI Manager → search ComfyUI-latent-ops, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/hnmr293/ComfyUI-latent-ops
    

    Restart. No requirements.txt, no model downloads - pure PyTorch. This is hnmr293's private latent workbench (the sd-webui-cutoff / llul author); it has essentially no community footprint, so latent_ops/functions.py is your documentation. Everything registers under hnmr/latent_ops.

    Categoryhnmr/latent_ops

    Inputs (1)

    NameTypeDefaultDescription
    axisINT-1-10000–10000

    Outputs (1)

    NameTypeDescription
    opLATENT_OPERATION