Model Bending
The flagship node for poking any UNet layer
- model
- bending_module
- MODEL
This is the node that gives the pack its name. Model Bending lets you grab the activations of any layer inside a diffusion UNet - SD 1.5, SDXL, even Flux's transformer - and rewrite them mid-sampling with a bending module: multiply, add, threshold, rotate, sobel, whatever. You give it a module path, it hacks a forward hook onto that layer, and for the duration of the run every activation that flows through gets bent.
It's low-level, it's deliberately weird, and it produces some of the most striking accidental images you'll get out of ComfyUI. The README's showcase gif of a portrait rotating 0–360° as the UNet's middle_block.2.out_layers activations spin is exactly what this node does. It's also not a production tool - it's a laboratory instrument. You use it to explore a model, break it on purpose, and find variations that prompt engineering never will.
How it works
Bending needs three things: a path to a module, a module to apply, and a way to inject it. The path is a dot-separated address like middle_block.2.out_layers, which you find with the Model Inspector node. The pack clones your model, resolves that path on the UNet, then installs a model_function_wrapper that registers a forward hook on the target module right before each sampling step and removes it after. The module's output is pushed through your BENDING_MODULE, and the hook reads the sampler's sigma schedule to know which denoising step it's on - which is what powers selective step bending.
You can also chain these: each Model Bending node wraps the previous wrapper, so multiple bends compose, and the hook cleanup in a finally block keeps parallel branches from leaking hooks into each other.
Inputs that matter
- path (
STRING) - dot-separated module path, relative to the diffusion model. Comma-separate several paths to bend them all with one module. Theprocess_pathhelper strips architecture prefixes, so you can paste paths verbatim from the Inspector. Leave empty and the node quietly returns your model unbent. - bending_module (
BENDING_MODULE) - from any (Bending) module node: Multiply Scalar, Rotate, Threshold, Scale, Sobel, Add Scalar, Add Noise, or Latent Operation To Module for custom ops. - steps_to_bend_str (
STRING, default"*") - which denoising steps to bend.*(default) means all. Otherwise comma-separated steps and ranges:"5","0-10","10-","-10". - max_denoising_steps (
INT, default200) - caps the range parser so"10-"doesn't run past the end of a short schedule.
Output is a single MODEL, wired into the sampler.
Installing
cd ComfyUI/custom_nodes
git clone https://github.com/abuzreq/ComfyUI-Model-Bending
Restart ComfyUI and refresh your browser - or search ComfyUI-Model-Bending in ComfyUI Manager. The README's manual snippet says to clone into ComfyUI-Web-Bend-Demo; that's leftover copy-paste, use ComfyUI-Model-Bending as the folder name. Dependencies are kornia and scikit-learn, no model files to fetch.
Where people get burned
The big one: if path doesn't resolve, the node logs a warning and continues - you get an unbent image with zero error, which is confusing until you know the warning. And if your path resolves to a module list (nn.ModuleList) rather than a leaf module, it can't be hooked and is skipped; hook a specific child instead. Start with a small effect at every step, then use steps_to_bend_str to isolate a step once you've found something. Extreme values will produce garbage - that's the point, it's a breaking tool. And on Flux (a transformer, not a Conv UNet), the block/layer convenience nodes won't help you; use this node with a path you pulled from the Interactive Bending Web UI, which is the tested path for Flux.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| bending_module | BENDING_MODULE | — | |
| path | STRING | — | |
| steps_to_bend_stropt | STRING | * | — |
| max_denoising_stepsopt | INT | 200 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | — |